@@ -7,7 +7,7 @@ discard block |
||
7 | 7 | use EventEspresso\core\libraries\rest_api\Model_Data_Translator; |
8 | 8 | |
9 | 9 | if (! defined('EVENT_ESPRESSO_VERSION')) { |
10 | - exit('No direct script access allowed'); |
|
10 | + exit('No direct script access allowed'); |
|
11 | 11 | } |
12 | 12 | |
13 | 13 | |
@@ -25,1106 +25,1106 @@ discard block |
||
25 | 25 | |
26 | 26 | |
27 | 27 | |
28 | - /** |
|
29 | - * @var Calculated_Model_Fields |
|
30 | - */ |
|
31 | - protected $_fields_calculator; |
|
32 | - |
|
33 | - |
|
34 | - |
|
35 | - /** |
|
36 | - * Read constructor. |
|
37 | - */ |
|
38 | - public function __construct() |
|
39 | - { |
|
40 | - parent::__construct(); |
|
41 | - $this->_fields_calculator = new Calculated_Model_Fields(); |
|
42 | - } |
|
43 | - |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * Handles requests to get all (or a filtered subset) of entities for a particular model |
|
48 | - * |
|
49 | - * @param \WP_REST_Request $request |
|
50 | - * @return \WP_REST_Response|\WP_Error |
|
51 | - */ |
|
52 | - public static function handle_request_get_all(\WP_REST_Request $request) |
|
53 | - { |
|
54 | - $controller = new Read(); |
|
55 | - try { |
|
56 | - $matches = $controller->parse_route( |
|
57 | - $request->get_route(), |
|
58 | - '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~', |
|
59 | - array('version', 'model') |
|
60 | - ); |
|
61 | - $controller->set_requested_version($matches['version']); |
|
62 | - $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
|
63 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
64 | - return $controller->send_response( |
|
65 | - new \WP_Error( |
|
66 | - 'endpoint_parsing_error', |
|
67 | - sprintf( |
|
68 | - __('There is no model for endpoint %s. Please contact event espresso support', |
|
69 | - 'event_espresso'), |
|
70 | - $model_name_singular |
|
71 | - ) |
|
72 | - ) |
|
73 | - ); |
|
74 | - } |
|
75 | - return $controller->send_response( |
|
76 | - $controller->get_entities_from_model( |
|
77 | - $controller->get_model_version_info()->load_model($model_name_singular), |
|
78 | - $request |
|
79 | - ) |
|
80 | - ); |
|
81 | - } catch (\Exception $e) { |
|
82 | - return $controller->send_response($e); |
|
83 | - } |
|
84 | - } |
|
85 | - |
|
86 | - |
|
87 | - |
|
88 | - /** |
|
89 | - * Gets a single entity related to the model indicated in the path and its id |
|
90 | - * |
|
91 | - * @param \WP_REST_Request $request |
|
92 | - * @return \WP_REST_Response|\WP_Error |
|
93 | - */ |
|
94 | - public static function handle_request_get_one(\WP_REST_Request $request) |
|
95 | - { |
|
96 | - $controller = new Read(); |
|
97 | - try { |
|
98 | - $matches = $controller->parse_route( |
|
99 | - $request->get_route(), |
|
100 | - '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~', |
|
101 | - array('version', 'model', 'id')); |
|
102 | - $controller->set_requested_version($matches['version']); |
|
103 | - $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
|
104 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
105 | - return $controller->send_response( |
|
106 | - new \WP_Error( |
|
107 | - 'endpoint_parsing_error', |
|
108 | - sprintf( |
|
109 | - __('There is no model for endpoint %s. Please contact event espresso support', |
|
110 | - 'event_espresso'), |
|
111 | - $model_name_singular |
|
112 | - ) |
|
113 | - ) |
|
114 | - ); |
|
115 | - } |
|
116 | - return $controller->send_response( |
|
117 | - $controller->get_entity_from_model( |
|
118 | - $controller->get_model_version_info()->load_model($model_name_singular), |
|
119 | - $request |
|
120 | - ) |
|
121 | - ); |
|
122 | - } catch (\Exception $e) { |
|
123 | - return $controller->send_response($e); |
|
124 | - } |
|
125 | - } |
|
126 | - |
|
127 | - |
|
128 | - |
|
129 | - /** |
|
130 | - * Gets all the related entities (or if its a belongs-to relation just the one) |
|
131 | - * to the item with the given id |
|
132 | - * |
|
133 | - * @param \WP_REST_Request $request |
|
134 | - * @return \WP_REST_Response|\WP_Error |
|
135 | - */ |
|
136 | - public static function handle_request_get_related(\WP_REST_Request $request) |
|
137 | - { |
|
138 | - $controller = new Read(); |
|
139 | - try { |
|
140 | - $matches = $controller->parse_route( |
|
141 | - $request->get_route(), |
|
142 | - '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~', |
|
143 | - array('version', 'model', 'id', 'related_model') |
|
144 | - ); |
|
145 | - $controller->set_requested_version($matches['version']); |
|
146 | - $main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
|
147 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) { |
|
148 | - return $controller->send_response( |
|
149 | - new \WP_Error( |
|
150 | - 'endpoint_parsing_error', |
|
151 | - sprintf( |
|
152 | - __('There is no model for endpoint %s. Please contact event espresso support', |
|
153 | - 'event_espresso'), |
|
154 | - $main_model_name_singular |
|
155 | - ) |
|
156 | - ) |
|
157 | - ); |
|
158 | - } |
|
159 | - $main_model = $controller->get_model_version_info()->load_model($main_model_name_singular); |
|
160 | - //assume the related model name is plural and try to find the model's name |
|
161 | - $related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']); |
|
162 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
163 | - //so the word didn't singularize well. Maybe that's just because it's a singular word? |
|
164 | - $related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']); |
|
165 | - } |
|
166 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
167 | - return $controller->send_response( |
|
168 | - new \WP_Error( |
|
169 | - 'endpoint_parsing_error', |
|
170 | - sprintf( |
|
171 | - __('There is no model for endpoint %s. Please contact event espresso support', |
|
172 | - 'event_espresso'), |
|
173 | - $related_model_name_singular |
|
174 | - ) |
|
175 | - ) |
|
176 | - ); |
|
177 | - } |
|
178 | - return $controller->send_response( |
|
179 | - $controller->get_entities_from_relation( |
|
180 | - $request->get_param('id'), |
|
181 | - $main_model->related_settings_for($related_model_name_singular), |
|
182 | - $request |
|
183 | - ) |
|
184 | - ); |
|
185 | - } catch (\Exception $e) { |
|
186 | - return $controller->send_response($e); |
|
187 | - } |
|
188 | - } |
|
189 | - |
|
190 | - |
|
191 | - |
|
192 | - /** |
|
193 | - * Gets a collection for the given model and filters |
|
194 | - * |
|
195 | - * @param \EEM_Base $model |
|
196 | - * @param \WP_REST_Request $request |
|
197 | - * @return array|\WP_Error |
|
198 | - */ |
|
199 | - public function get_entities_from_model($model, $request) |
|
200 | - { |
|
201 | - $query_params = $this->create_model_query_params($model, $request->get_params()); |
|
202 | - if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) { |
|
203 | - $model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
204 | - return new \WP_Error( |
|
205 | - sprintf('rest_%s_cannot_list', $model_name_plural), |
|
206 | - sprintf( |
|
207 | - __('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'), |
|
208 | - $model_name_plural, |
|
209 | - Capabilities::get_missing_permissions_string($model, $query_params['caps']) |
|
210 | - ), |
|
211 | - array('status' => 403) |
|
212 | - ); |
|
213 | - } |
|
214 | - if (! $request->get_header('no_rest_headers')) { |
|
215 | - $this->_set_headers_from_query_params($model, $query_params); |
|
216 | - } |
|
217 | - /** @type array $results */ |
|
218 | - $results = $model->get_all_wpdb_results($query_params); |
|
219 | - $nice_results = array(); |
|
220 | - foreach ($results as $result) { |
|
221 | - $nice_results[] = $this->create_entity_from_wpdb_result( |
|
222 | - $model, |
|
223 | - $result, |
|
224 | - $request |
|
225 | - ); |
|
226 | - } |
|
227 | - return $nice_results; |
|
228 | - } |
|
229 | - |
|
230 | - |
|
231 | - |
|
232 | - /** |
|
233 | - * @param array $primary_model_query_params query params for finding the item from which |
|
234 | - * relations will be based |
|
235 | - * @param \EE_Model_Relation_Base $relation |
|
236 | - * @param \WP_REST_Request $request |
|
237 | - * @return \WP_Error|array |
|
238 | - */ |
|
239 | - protected function _get_entities_from_relation($primary_model_query_params, $relation, $request) |
|
240 | - { |
|
241 | - $context = $this->validate_context($request->get_param('caps')); |
|
242 | - $model = $relation->get_this_model(); |
|
243 | - $related_model = $relation->get_other_model(); |
|
244 | - if (! isset($primary_model_query_params[0])) { |
|
245 | - $primary_model_query_params[0] = array(); |
|
246 | - } |
|
247 | - //check if they can access the 1st model object |
|
248 | - $primary_model_query_params = array( |
|
249 | - 0 => $primary_model_query_params[0], |
|
250 | - 'limit' => 1, |
|
251 | - ); |
|
252 | - if ($model instanceof \EEM_Soft_Delete_Base) { |
|
253 | - $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params); |
|
254 | - } |
|
255 | - $restricted_query_params = $primary_model_query_params; |
|
256 | - $restricted_query_params['caps'] = $context; |
|
257 | - $this->_set_debug_info('main model query params', $restricted_query_params); |
|
258 | - $this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context)); |
|
259 | - if ( |
|
260 | - ! ( |
|
261 | - Capabilities::current_user_has_partial_access_to($related_model, $context) |
|
262 | - && $model->exists($restricted_query_params) |
|
263 | - ) |
|
264 | - ) { |
|
265 | - if ($relation instanceof \EE_Belongs_To_Relation) { |
|
266 | - $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name()); |
|
267 | - } else { |
|
268 | - $related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name()); |
|
269 | - } |
|
270 | - return new \WP_Error( |
|
271 | - sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural), |
|
272 | - sprintf( |
|
273 | - __('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s', |
|
274 | - 'event_espresso'), |
|
275 | - $related_model_name_maybe_plural, |
|
276 | - $relation->get_this_model()->get_this_model_name(), |
|
277 | - implode( |
|
278 | - ',', |
|
279 | - array_keys( |
|
280 | - Capabilities::get_missing_permissions($related_model, $context) |
|
281 | - ) |
|
282 | - ) |
|
283 | - ), |
|
284 | - array('status' => 403) |
|
285 | - ); |
|
286 | - } |
|
287 | - $query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params()); |
|
288 | - foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) { |
|
289 | - $query_params[0][$relation->get_this_model()->get_this_model_name() |
|
290 | - . '.' |
|
291 | - . $where_condition_key] = $where_condition_value; |
|
292 | - } |
|
293 | - $query_params['default_where_conditions'] = 'none'; |
|
294 | - $query_params['caps'] = $context; |
|
295 | - if (! $request->get_header('no_rest_headers')) { |
|
296 | - $this->_set_headers_from_query_params($relation->get_other_model(), $query_params); |
|
297 | - } |
|
298 | - /** @type array $results */ |
|
299 | - $results = $relation->get_other_model()->get_all_wpdb_results($query_params); |
|
300 | - $nice_results = array(); |
|
301 | - foreach ($results as $result) { |
|
302 | - $nice_result = $this->create_entity_from_wpdb_result( |
|
303 | - $relation->get_other_model(), |
|
304 | - $result, |
|
305 | - $request |
|
306 | - ); |
|
307 | - if ($relation instanceof \EE_HABTM_Relation) { |
|
308 | - //put the unusual stuff (properties from the HABTM relation) first, and make sure |
|
309 | - //if there are conflicts we prefer the properties from the main model |
|
310 | - $join_model_result = $this->create_entity_from_wpdb_result( |
|
311 | - $relation->get_join_model(), |
|
312 | - $result, |
|
313 | - $request |
|
314 | - ); |
|
315 | - $joined_result = array_merge($nice_result, $join_model_result); |
|
316 | - //but keep the meta stuff from the main model |
|
317 | - if (isset($nice_result['meta'])) { |
|
318 | - $joined_result['meta'] = $nice_result['meta']; |
|
319 | - } |
|
320 | - $nice_result = $joined_result; |
|
321 | - } |
|
322 | - $nice_results[] = $nice_result; |
|
323 | - } |
|
324 | - if ($relation instanceof \EE_Belongs_To_Relation) { |
|
325 | - return array_shift($nice_results); |
|
326 | - } else { |
|
327 | - return $nice_results; |
|
328 | - } |
|
329 | - } |
|
330 | - |
|
331 | - |
|
332 | - |
|
333 | - /** |
|
334 | - * Gets the collection for given relation object |
|
335 | - * The same as Read::get_entities_from_model(), except if the relation |
|
336 | - * is a HABTM relation, in which case it merges any non-foreign-key fields from |
|
337 | - * the join-model-object into the results |
|
338 | - * |
|
339 | - * @param string $id the ID of the thing we are fetching related stuff from |
|
340 | - * @param \EE_Model_Relation_Base $relation |
|
341 | - * @param \WP_REST_Request $request |
|
342 | - * @return array|\WP_Error |
|
343 | - * @throws \EE_Error |
|
344 | - */ |
|
345 | - public function get_entities_from_relation($id, $relation, $request) |
|
346 | - { |
|
347 | - if (! $relation->get_this_model()->has_primary_key_field()) { |
|
348 | - throw new \EE_Error( |
|
349 | - sprintf( |
|
350 | - __('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s', |
|
351 | - 'event_espresso'), |
|
352 | - $relation->get_this_model()->get_this_model_name() |
|
353 | - ) |
|
354 | - ); |
|
355 | - } |
|
356 | - return $this->_get_entities_from_relation( |
|
357 | - array( |
|
358 | - array( |
|
359 | - $relation->get_this_model()->primary_key_name() => $id, |
|
360 | - ), |
|
361 | - ), |
|
362 | - $relation, |
|
363 | - $request |
|
364 | - ); |
|
365 | - } |
|
366 | - |
|
367 | - |
|
368 | - |
|
369 | - /** |
|
370 | - * Sets the headers that are based on the model and query params, |
|
371 | - * like the total records. This should only be called on the original request |
|
372 | - * from the client, not on subsequent internal |
|
373 | - * |
|
374 | - * @param \EEM_Base $model |
|
375 | - * @param array $query_params |
|
376 | - * @return void |
|
377 | - */ |
|
378 | - protected function _set_headers_from_query_params($model, $query_params) |
|
379 | - { |
|
380 | - $this->_set_debug_info('model query params', $query_params); |
|
381 | - $this->_set_debug_info('missing caps', |
|
382 | - Capabilities::get_missing_permissions_string($model, $query_params['caps'])); |
|
383 | - //normally the limit to a 2-part array, where the 2nd item is the limit |
|
384 | - if (! isset($query_params['limit'])) { |
|
385 | - $query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit(); |
|
386 | - } |
|
387 | - if (is_array($query_params['limit'])) { |
|
388 | - $limit_parts = $query_params['limit']; |
|
389 | - } else { |
|
390 | - $limit_parts = explode(',', $query_params['limit']); |
|
391 | - if (count($limit_parts) == 1) { |
|
392 | - $limit_parts = array(0, $limit_parts[0]); |
|
393 | - } |
|
394 | - } |
|
395 | - //remove the group by and having parts of the query, as those will |
|
396 | - //make the sql query return an array of values, instead of just a single value |
|
397 | - unset($query_params['group_by'], $query_params['having'], $query_params['limit']); |
|
398 | - $count = $model->count($query_params, null, true); |
|
399 | - $pages = $count / $limit_parts[1]; |
|
400 | - $this->_set_response_header('Total', $count, false); |
|
401 | - $this->_set_response_header('PageSize', $limit_parts[1], false); |
|
402 | - $this->_set_response_header('TotalPages', ceil($pages), false); |
|
403 | - } |
|
404 | - |
|
405 | - |
|
406 | - |
|
407 | - /** |
|
408 | - * Changes database results into REST API entities |
|
409 | - * |
|
410 | - * @param \EEM_Base $model |
|
411 | - * @param array $db_row like results from $wpdb->get_results() |
|
412 | - * @param \WP_REST_Request $rest_request |
|
413 | - * @param string $deprecated no longer used |
|
414 | - * @return array ready for being converted into json for sending to client |
|
415 | - */ |
|
416 | - public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null) |
|
417 | - { |
|
418 | - if (! $rest_request instanceof \WP_REST_Request) { |
|
419 | - //ok so this was called in the old style, where the 3rd arg was |
|
420 | - //$include, and the 4th arg was $context |
|
421 | - //now setup the request just to avoid fatal errors, although we won't be able |
|
422 | - //to truly make use of it because it's kinda devoid of info |
|
423 | - $rest_request = new \WP_REST_Request(); |
|
424 | - $rest_request->set_param('include', $rest_request); |
|
425 | - $rest_request->set_param('caps', $deprecated); |
|
426 | - } |
|
427 | - if ($rest_request->get_param('caps') == null) { |
|
428 | - $rest_request->set_param('caps', \EEM_Base::caps_read); |
|
429 | - } |
|
430 | - $entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row); |
|
431 | - $entity_array = $this->_add_extra_fields($model, $db_row, $entity_array); |
|
432 | - $entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array); |
|
433 | - $entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request); |
|
434 | - $entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row); |
|
435 | - $entity_array = apply_filters( |
|
436 | - 'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal', |
|
437 | - $entity_array, |
|
438 | - $model, |
|
439 | - $rest_request->get_param('caps'), |
|
440 | - $rest_request, |
|
441 | - $this |
|
442 | - ); |
|
443 | - $result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields( |
|
444 | - $entity_array, |
|
445 | - $model, |
|
446 | - $rest_request->get_param('caps'), |
|
447 | - $this->get_model_version_info(), |
|
448 | - $model->get_index_primary_key_string( |
|
449 | - $model->deduce_fields_n_values_from_cols_n_values($db_row) |
|
450 | - ) |
|
451 | - ); |
|
452 | - $this->_set_debug_info( |
|
453 | - 'inaccessible fields', |
|
454 | - array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields)) |
|
455 | - ); |
|
456 | - return apply_filters( |
|
457 | - 'FHEE__Read__create_entity_from_wpdb_results__entity_return', |
|
458 | - $result_without_inaccessible_fields, |
|
459 | - $model, |
|
460 | - $rest_request->get_param('caps') |
|
461 | - ); |
|
462 | - } |
|
463 | - |
|
464 | - |
|
465 | - |
|
466 | - /** |
|
467 | - * Creates a REST entity array (JSON object we're going to return in the response, but |
|
468 | - * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry), |
|
469 | - * from $wpdb->get_row( $sql, ARRAY_A) |
|
470 | - * |
|
471 | - * @param \EEM_Base $model |
|
472 | - * @param array $db_row |
|
473 | - * @return array entity mostly ready for converting to JSON and sending in the response |
|
474 | - */ |
|
475 | - protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row) |
|
476 | - { |
|
477 | - $result = $model->deduce_fields_n_values_from_cols_n_values($db_row); |
|
478 | - $result = array_intersect_key($result, |
|
479 | - $this->get_model_version_info()->fields_on_model_in_this_version($model)); |
|
480 | - foreach ($result as $field_name => $raw_field_value) { |
|
481 | - $field_obj = $model->field_settings_for($field_name); |
|
482 | - $field_value = $field_obj->prepare_for_set_from_db($raw_field_value); |
|
483 | - if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) { |
|
484 | - unset($result[$field_name]); |
|
485 | - } elseif ( |
|
486 | - $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format()) |
|
487 | - ) { |
|
488 | - $result[$field_name] = array( |
|
489 | - 'raw' => $field_obj->prepare_for_get($field_value), |
|
490 | - 'rendered' => $field_obj->prepare_for_pretty_echoing($field_value), |
|
491 | - ); |
|
492 | - } elseif ( |
|
493 | - $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format()) |
|
494 | - ) { |
|
495 | - $result[$field_name] = array( |
|
496 | - 'raw' => $field_obj->prepare_for_get($field_value), |
|
497 | - 'pretty' => $field_obj->prepare_for_pretty_echoing($field_value), |
|
498 | - ); |
|
499 | - } elseif ($field_obj instanceof \EE_Datetime_Field) { |
|
500 | - if ($field_value instanceof \DateTime) { |
|
501 | - $timezone = $field_value->getTimezone(); |
|
502 | - $field_value->setTimezone(new \DateTimeZone('UTC')); |
|
503 | - $result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json( |
|
504 | - $field_obj, |
|
505 | - $field_value, |
|
506 | - $this->get_model_version_info()->requested_version() |
|
507 | - ); |
|
508 | - $field_value->setTimezone($timezone); |
|
509 | - $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json( |
|
510 | - $field_obj, |
|
511 | - $field_value, |
|
512 | - $this->get_model_version_info()->requested_version() |
|
513 | - ); |
|
514 | - } |
|
515 | - } else { |
|
516 | - $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json( |
|
517 | - $field_obj, |
|
518 | - $field_obj->prepare_for_get($field_value), |
|
519 | - $this->get_model_version_info()->requested_version() |
|
520 | - ); |
|
521 | - } |
|
522 | - } |
|
523 | - return $result; |
|
524 | - } |
|
525 | - |
|
526 | - |
|
527 | - |
|
528 | - /** |
|
529 | - * Adds a few extra fields to the entity response |
|
530 | - * |
|
531 | - * @param \EEM_Base $model |
|
532 | - * @param array $db_row |
|
533 | - * @param array $entity_array |
|
534 | - * @return array modified entity |
|
535 | - */ |
|
536 | - protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array) |
|
537 | - { |
|
538 | - if ($model instanceof \EEM_CPT_Base) { |
|
539 | - $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]); |
|
540 | - } |
|
541 | - return $entity_array; |
|
542 | - } |
|
543 | - |
|
544 | - |
|
545 | - |
|
546 | - /** |
|
547 | - * Gets links we want to add to the response |
|
548 | - * |
|
549 | - * @global \WP_REST_Server $wp_rest_server |
|
550 | - * @param \EEM_Base $model |
|
551 | - * @param array $db_row |
|
552 | - * @param array $entity_array |
|
553 | - * @return array the _links item in the entity |
|
554 | - */ |
|
555 | - protected function _get_entity_links($model, $db_row, $entity_array) |
|
556 | - { |
|
557 | - //add basic links |
|
558 | - $links = array(); |
|
559 | - if ($model->has_primary_key_field()) { |
|
560 | - $links['self'] = array( |
|
561 | - array( |
|
562 | - 'href' => $this->get_versioned_link_to( |
|
563 | - \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
564 | - . '/' |
|
565 | - . $entity_array[$model->primary_key_name()] |
|
566 | - ), |
|
567 | - ), |
|
568 | - ); |
|
569 | - } |
|
570 | - $links['collection'] = array( |
|
571 | - array( |
|
572 | - 'href' => $this->get_versioned_link_to( |
|
573 | - \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
574 | - ), |
|
575 | - ), |
|
576 | - ); |
|
577 | - //add links to related models |
|
578 | - if ($model->has_primary_key_field()) { |
|
579 | - foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) { |
|
580 | - $related_model_part = Read::get_related_entity_name($relation_name, $relation_obj); |
|
581 | - $links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array( |
|
582 | - array( |
|
583 | - 'href' => $this->get_versioned_link_to( |
|
584 | - \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
585 | - . '/' |
|
586 | - . $entity_array[$model->primary_key_name()] |
|
587 | - . '/' |
|
588 | - . $related_model_part |
|
589 | - ), |
|
590 | - 'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false, |
|
591 | - ), |
|
592 | - ); |
|
593 | - } |
|
594 | - } |
|
595 | - return $links; |
|
596 | - } |
|
597 | - |
|
598 | - |
|
599 | - |
|
600 | - /** |
|
601 | - * Adds the included models indicated in the request to the entity provided |
|
602 | - * |
|
603 | - * @param \EEM_Base $model |
|
604 | - * @param \WP_REST_Request $rest_request |
|
605 | - * @param array $entity_array |
|
606 | - * @param array $db_row |
|
607 | - * @return array the modified entity |
|
608 | - */ |
|
609 | - protected function _include_requested_models( |
|
610 | - \EEM_Base $model, |
|
611 | - \WP_REST_Request $rest_request, |
|
612 | - $entity_array, |
|
613 | - $db_row = array() |
|
614 | - ) { |
|
615 | - //if $db_row not included, hope the entity array has what we need |
|
616 | - if (! $db_row) { |
|
617 | - $db_row = $entity_array; |
|
618 | - } |
|
619 | - $includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), ''); |
|
620 | - $includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model); |
|
621 | - //if they passed in * or didn't specify any includes, return everything |
|
622 | - if (! in_array('*', $includes_for_this_model) |
|
623 | - && ! empty($includes_for_this_model) |
|
624 | - ) { |
|
625 | - if ($model->has_primary_key_field()) { |
|
626 | - //always include the primary key. ya just gotta know that at least |
|
627 | - $includes_for_this_model[] = $model->primary_key_name(); |
|
628 | - } |
|
629 | - if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) { |
|
630 | - $includes_for_this_model[] = '_calculated_fields'; |
|
631 | - } |
|
632 | - $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model)); |
|
633 | - } |
|
634 | - $relation_settings = $this->get_model_version_info()->relation_settings($model); |
|
635 | - foreach ($relation_settings as $relation_name => $relation_obj) { |
|
636 | - $related_fields_to_include = $this->explode_and_get_items_prefixed_with( |
|
637 | - $rest_request->get_param('include'), |
|
638 | - $relation_name |
|
639 | - ); |
|
640 | - $related_fields_to_calculate = $this->explode_and_get_items_prefixed_with( |
|
641 | - $rest_request->get_param('calculate'), |
|
642 | - $relation_name |
|
643 | - ); |
|
644 | - //did they specify they wanted to include a related model, or |
|
645 | - //specific fields from a related model? |
|
646 | - //or did they specify to calculate a field from a related model? |
|
647 | - if ($related_fields_to_include || $related_fields_to_calculate) { |
|
648 | - //if so, we should include at least some part of the related model |
|
649 | - $pretend_related_request = new \WP_REST_Request(); |
|
650 | - $pretend_related_request->set_query_params( |
|
651 | - array( |
|
652 | - 'caps' => $rest_request->get_param('caps'), |
|
653 | - 'include' => $related_fields_to_include, |
|
654 | - 'calculate' => $related_fields_to_calculate, |
|
655 | - ) |
|
656 | - ); |
|
657 | - $pretend_related_request->add_header('no_rest_headers', true); |
|
658 | - $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID( |
|
659 | - $model->get_index_primary_key_string( |
|
660 | - $model->deduce_fields_n_values_from_cols_n_values($db_row) |
|
661 | - ) |
|
662 | - ); |
|
663 | - $related_results = $this->_get_entities_from_relation( |
|
664 | - $primary_model_query_params, |
|
665 | - $relation_obj, |
|
666 | - $pretend_related_request |
|
667 | - ); |
|
668 | - $entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results |
|
669 | - instanceof |
|
670 | - \WP_Error |
|
671 | - ? null |
|
672 | - : $related_results; |
|
673 | - } |
|
674 | - } |
|
675 | - return $entity_array; |
|
676 | - } |
|
677 | - |
|
678 | - |
|
679 | - |
|
680 | - /** |
|
681 | - * Returns a new array with all the names of models removed. Eg |
|
682 | - * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' ) |
|
683 | - * |
|
684 | - * @param array $arr |
|
685 | - * @return array |
|
686 | - */ |
|
687 | - private function _remove_model_names_from_array($arr) |
|
688 | - { |
|
689 | - return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models)); |
|
690 | - } |
|
691 | - |
|
692 | - |
|
693 | - |
|
694 | - /** |
|
695 | - * Gets the calculated fields for the response |
|
696 | - * |
|
697 | - * @param \EEM_Base $model |
|
698 | - * @param array $wpdb_row |
|
699 | - * @param \WP_REST_Request $rest_request |
|
700 | - * @return \stdClass the _calculations item in the entity |
|
701 | - */ |
|
702 | - protected function _get_entity_calculations($model, $wpdb_row, $rest_request) |
|
703 | - { |
|
704 | - $calculated_fields = $this->explode_and_get_items_prefixed_with( |
|
705 | - $rest_request->get_param('calculate'), |
|
706 | - '' |
|
707 | - ); |
|
708 | - //note: setting calculate=* doesn't do anything |
|
709 | - $calculated_fields_to_return = new \stdClass(); |
|
710 | - foreach ($calculated_fields as $field_to_calculate) { |
|
711 | - try { |
|
712 | - $calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json( |
|
713 | - null, |
|
714 | - $this->_fields_calculator->retrieve_calculated_field_value( |
|
715 | - $model, |
|
716 | - $field_to_calculate, |
|
717 | - $wpdb_row, |
|
718 | - $rest_request, |
|
719 | - $this |
|
720 | - ), |
|
721 | - $this->get_model_version_info()->requested_version() |
|
722 | - ); |
|
723 | - } catch (Rest_Exception $e) { |
|
724 | - //if we don't have permission to read it, just leave it out. but let devs know about the problem |
|
725 | - $this->_set_response_header( |
|
726 | - 'Notices-Field-Calculation-Errors[' |
|
727 | - . $e->get_string_code() |
|
728 | - . '][' |
|
729 | - . $model->get_this_model_name() |
|
730 | - . '][' |
|
731 | - . $field_to_calculate |
|
732 | - . ']', |
|
733 | - $e->getMessage(), |
|
734 | - true |
|
735 | - ); |
|
736 | - } |
|
737 | - } |
|
738 | - return $calculated_fields_to_return; |
|
739 | - } |
|
740 | - |
|
741 | - |
|
742 | - |
|
743 | - /** |
|
744 | - * Gets the full URL to the resource, taking the requested version into account |
|
745 | - * |
|
746 | - * @param string $link_part_after_version_and_slash eg "events/10/datetimes" |
|
747 | - * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes" |
|
748 | - */ |
|
749 | - public function get_versioned_link_to($link_part_after_version_and_slash) |
|
750 | - { |
|
751 | - return rest_url( |
|
752 | - \EED_Core_Rest_Api::ee_api_namespace |
|
753 | - . $this->get_model_version_info()->requested_version() |
|
754 | - . '/' |
|
755 | - . $link_part_after_version_and_slash |
|
756 | - ); |
|
757 | - } |
|
758 | - |
|
759 | - |
|
760 | - |
|
761 | - /** |
|
762 | - * Gets the correct lowercase name for the relation in the API according |
|
763 | - * to the relation's type |
|
764 | - * |
|
765 | - * @param string $relation_name |
|
766 | - * @param \EE_Model_Relation_Base $relation_obj |
|
767 | - * @return string |
|
768 | - */ |
|
769 | - public static function get_related_entity_name($relation_name, $relation_obj) |
|
770 | - { |
|
771 | - if ($relation_obj instanceof \EE_Belongs_To_Relation) { |
|
772 | - return strtolower($relation_name); |
|
773 | - } else { |
|
774 | - return \EEH_Inflector::pluralize_and_lower($relation_name); |
|
775 | - } |
|
776 | - } |
|
777 | - |
|
778 | - |
|
779 | - |
|
780 | - /** |
|
781 | - * Gets the one model object with the specified id for the specified model |
|
782 | - * |
|
783 | - * @param \EEM_Base $model |
|
784 | - * @param \WP_REST_Request $request |
|
785 | - * @return array|\WP_Error |
|
786 | - */ |
|
787 | - public function get_entity_from_model($model, $request) |
|
788 | - { |
|
789 | - $query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1); |
|
790 | - if ($model instanceof \EEM_Soft_Delete_Base) { |
|
791 | - $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
792 | - } |
|
793 | - $restricted_query_params = $query_params; |
|
794 | - $restricted_query_params['caps'] = $this->validate_context($request->get_param('caps')); |
|
795 | - $this->_set_debug_info('model query params', $restricted_query_params); |
|
796 | - $model_rows = $model->get_all_wpdb_results($restricted_query_params); |
|
797 | - if (! empty ($model_rows)) { |
|
798 | - return $this->create_entity_from_wpdb_result( |
|
799 | - $model, |
|
800 | - array_shift($model_rows), |
|
801 | - $request); |
|
802 | - } else { |
|
803 | - //ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities |
|
804 | - $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
805 | - $model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params); |
|
806 | - if (! empty($model_rows_found_sans_restrictions)) { |
|
807 | - //you got shafted- it existed but we didn't want to tell you! |
|
808 | - return new \WP_Error( |
|
809 | - 'rest_user_cannot_read', |
|
810 | - sprintf( |
|
811 | - __('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'), |
|
812 | - strtolower($model->get_this_model_name()), |
|
813 | - Capabilities::get_missing_permissions_string( |
|
814 | - $model, |
|
815 | - $this->validate_context($request->get_param('caps'))) |
|
816 | - ), |
|
817 | - array('status' => 403) |
|
818 | - ); |
|
819 | - } else { |
|
820 | - //it's not you. It just doesn't exist |
|
821 | - return new \WP_Error( |
|
822 | - sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
823 | - sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
824 | - array('status' => 404) |
|
825 | - ); |
|
826 | - } |
|
827 | - } |
|
828 | - } |
|
829 | - |
|
830 | - |
|
831 | - |
|
832 | - /** |
|
833 | - * If a context is provided which isn't valid, maybe it was added in a future |
|
834 | - * version so just treat it as a default read |
|
835 | - * |
|
836 | - * @param string $context |
|
837 | - * @return string array key of EEM_Base::cap_contexts_to_cap_action_map() |
|
838 | - */ |
|
839 | - public function validate_context($context) |
|
840 | - { |
|
841 | - if (! $context) { |
|
842 | - $context = \EEM_Base::caps_read; |
|
843 | - } |
|
844 | - $valid_contexts = \EEM_Base::valid_cap_contexts(); |
|
845 | - if (in_array($context, $valid_contexts)) { |
|
846 | - return $context; |
|
847 | - } else { |
|
848 | - return \EEM_Base::caps_read; |
|
849 | - } |
|
850 | - } |
|
851 | - |
|
852 | - |
|
853 | - |
|
854 | - /** |
|
855 | - * Verifies the passed in value is an allowable default where conditions value. |
|
856 | - * |
|
857 | - * @param $default_query_params |
|
858 | - * @return string |
|
859 | - */ |
|
860 | - public function validate_default_query_params($default_query_params) |
|
861 | - { |
|
862 | - $valid_default_where_conditions_for_api_calls = array( |
|
863 | - \EEM_Base::default_where_conditions_all, |
|
864 | - \EEM_Base::default_where_conditions_minimum_all, |
|
865 | - \EEM_Base::default_where_conditions_minimum_others, |
|
866 | - ); |
|
867 | - if (! $default_query_params) { |
|
868 | - $default_query_params = \EEM_Base::default_where_conditions_all; |
|
869 | - } |
|
870 | - if ( |
|
871 | - in_array( |
|
872 | - $default_query_params, |
|
873 | - $valid_default_where_conditions_for_api_calls, |
|
874 | - true |
|
875 | - ) |
|
876 | - ) { |
|
877 | - return $default_query_params; |
|
878 | - } else { |
|
879 | - return \EEM_Base::default_where_conditions_all; |
|
880 | - } |
|
881 | - } |
|
882 | - |
|
883 | - |
|
884 | - |
|
885 | - /** |
|
886 | - * Translates API filter get parameter into $query_params array used by EEM_Base::get_all(). |
|
887 | - * Note: right now the query parameter keys for fields (and related fields) |
|
888 | - * can be left as-is, but it's quite possible this will change someday. |
|
889 | - * Also, this method's contents might be candidate for moving to Model_Data_Translator |
|
890 | - * |
|
891 | - * @param \EEM_Base $model |
|
892 | - * @param array $query_parameters from $_GET parameter @see Read:handle_request_get_all |
|
893 | - * @return array like what EEM_Base::get_all() expects or FALSE to indicate |
|
894 | - * that absolutely no results should be returned |
|
895 | - * @throws \EE_Error |
|
896 | - */ |
|
897 | - public function create_model_query_params($model, $query_parameters) |
|
898 | - { |
|
899 | - $model_query_params = array(); |
|
900 | - if (isset($query_parameters['where'])) { |
|
901 | - $model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models( |
|
902 | - $query_parameters['where'], |
|
903 | - $model, |
|
904 | - $this->get_model_version_info()->requested_version() |
|
905 | - ); |
|
906 | - } |
|
907 | - if (isset($query_parameters['order_by'])) { |
|
908 | - $order_by = $query_parameters['order_by']; |
|
909 | - } elseif (isset($query_parameters['orderby'])) { |
|
910 | - $order_by = $query_parameters['orderby']; |
|
911 | - } else { |
|
912 | - $order_by = null; |
|
913 | - } |
|
914 | - if ($order_by !== null) { |
|
915 | - if (is_array($order_by)) { |
|
916 | - $order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by); |
|
917 | - } else { |
|
918 | - //it's a single item |
|
919 | - $order_by = Model_Data_Translator::prepare_field_name_from_json($order_by); |
|
920 | - } |
|
921 | - $model_query_params['order_by'] = $order_by; |
|
922 | - } |
|
923 | - if (isset($query_parameters['group_by'])) { |
|
924 | - $group_by = $query_parameters['group_by']; |
|
925 | - } elseif (isset($query_parameters['groupby'])) { |
|
926 | - $group_by = $query_parameters['groupby']; |
|
927 | - } else { |
|
928 | - $group_by = array_keys($model->get_combined_primary_key_fields()); |
|
929 | - } |
|
930 | - //make sure they're all real names |
|
931 | - if (is_array($group_by)) { |
|
932 | - $group_by = Model_Data_Translator::prepare_field_names_from_json($group_by); |
|
933 | - } |
|
934 | - if ($group_by !== null) { |
|
935 | - $model_query_params['group_by'] = $group_by; |
|
936 | - } |
|
937 | - if (isset($query_parameters['having'])) { |
|
938 | - $model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models( |
|
939 | - $query_parameters['having'], |
|
940 | - $model, |
|
941 | - $this->get_model_version_info()->requested_version() |
|
942 | - ); |
|
943 | - } |
|
944 | - if (isset($query_parameters['order'])) { |
|
945 | - $model_query_params['order'] = $query_parameters['order']; |
|
946 | - } |
|
947 | - if (isset($query_parameters['mine'])) { |
|
948 | - $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params); |
|
949 | - } |
|
950 | - if (isset($query_parameters['limit'])) { |
|
951 | - //limit should be either a string like '23' or '23,43', or an array with two items in it |
|
952 | - if (! is_array($query_parameters['limit'])) { |
|
953 | - $limit_array = explode(',', (string)$query_parameters['limit']); |
|
954 | - } else { |
|
955 | - $limit_array = $query_parameters['limit']; |
|
956 | - } |
|
957 | - $sanitized_limit = array(); |
|
958 | - foreach ($limit_array as $key => $limit_part) { |
|
959 | - if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) { |
|
960 | - throw new \EE_Error( |
|
961 | - sprintf( |
|
962 | - __('An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.', |
|
963 | - 'event_espresso'), |
|
964 | - wp_json_encode($query_parameters['limit']) |
|
965 | - ) |
|
966 | - ); |
|
967 | - } |
|
968 | - $sanitized_limit[] = (int)$limit_part; |
|
969 | - } |
|
970 | - $model_query_params['limit'] = implode(',', $sanitized_limit); |
|
971 | - } else { |
|
972 | - $model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit(); |
|
973 | - } |
|
974 | - if (isset($query_parameters['caps'])) { |
|
975 | - $model_query_params['caps'] = $this->validate_context($query_parameters['caps']); |
|
976 | - } else { |
|
977 | - $model_query_params['caps'] = \EEM_Base::caps_read; |
|
978 | - } |
|
979 | - if (isset($query_parameters['default_where_conditions'])) { |
|
980 | - $model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']); |
|
981 | - } |
|
982 | - return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model); |
|
983 | - } |
|
984 | - |
|
985 | - |
|
986 | - |
|
987 | - /** |
|
988 | - * Changes the REST-style query params for use in the models |
|
989 | - * |
|
990 | - * @deprecated |
|
991 | - * @param \EEM_Base $model |
|
992 | - * @param array $query_params sub-array from @see EEM_Base::get_all() |
|
993 | - * @return array |
|
994 | - */ |
|
995 | - public function prepare_rest_query_params_key_for_models($model, $query_params) |
|
996 | - { |
|
997 | - $model_ready_query_params = array(); |
|
998 | - foreach ($query_params as $key => $value) { |
|
999 | - if (is_array($value)) { |
|
1000 | - $model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value); |
|
1001 | - } else { |
|
1002 | - $model_ready_query_params[$key] = $value; |
|
1003 | - } |
|
1004 | - } |
|
1005 | - return $model_ready_query_params; |
|
1006 | - } |
|
1007 | - |
|
1008 | - |
|
1009 | - |
|
1010 | - /** |
|
1011 | - * @deprecated |
|
1012 | - * @param $model |
|
1013 | - * @param $query_params |
|
1014 | - * @return array |
|
1015 | - */ |
|
1016 | - public function prepare_rest_query_params_values_for_models($model, $query_params) |
|
1017 | - { |
|
1018 | - $model_ready_query_params = array(); |
|
1019 | - foreach ($query_params as $key => $value) { |
|
1020 | - if (is_array($value)) { |
|
1021 | - $model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value); |
|
1022 | - } else { |
|
1023 | - $model_ready_query_params[$key] = $value; |
|
1024 | - } |
|
1025 | - } |
|
1026 | - return $model_ready_query_params; |
|
1027 | - } |
|
1028 | - |
|
1029 | - |
|
1030 | - |
|
1031 | - /** |
|
1032 | - * Explodes the string on commas, and only returns items with $prefix followed by a period. |
|
1033 | - * If no prefix is specified, returns items with no period. |
|
1034 | - * |
|
1035 | - * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' ) |
|
1036 | - * @param string $prefix "Event" or "foobar" |
|
1037 | - * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified |
|
1038 | - * we only return strings starting with that and a period; if no prefix was |
|
1039 | - * specified we return all items containing NO periods |
|
1040 | - */ |
|
1041 | - public function explode_and_get_items_prefixed_with($string_to_explode, $prefix) |
|
1042 | - { |
|
1043 | - if (is_string($string_to_explode)) { |
|
1044 | - $exploded_contents = explode(',', $string_to_explode); |
|
1045 | - } else if (is_array($string_to_explode)) { |
|
1046 | - $exploded_contents = $string_to_explode; |
|
1047 | - } else { |
|
1048 | - $exploded_contents = array(); |
|
1049 | - } |
|
1050 | - //if the string was empty, we want an empty array |
|
1051 | - $exploded_contents = array_filter($exploded_contents); |
|
1052 | - $contents_with_prefix = array(); |
|
1053 | - foreach ($exploded_contents as $item) { |
|
1054 | - $item = trim($item); |
|
1055 | - //if no prefix was provided, so we look for items with no "." in them |
|
1056 | - if (! $prefix) { |
|
1057 | - //does this item have a period? |
|
1058 | - if (strpos($item, '.') === false) { |
|
1059 | - //if not, then its what we're looking for |
|
1060 | - $contents_with_prefix[] = $item; |
|
1061 | - } |
|
1062 | - } else if (strpos($item, $prefix . '.') === 0) { |
|
1063 | - //this item has the prefix and a period, grab it |
|
1064 | - $contents_with_prefix[] = substr( |
|
1065 | - $item, |
|
1066 | - strpos($item, $prefix . '.') + strlen($prefix . '.') |
|
1067 | - ); |
|
1068 | - } else if ($item === $prefix) { |
|
1069 | - //this item is JUST the prefix |
|
1070 | - //so let's grab everything after, which is a blank string |
|
1071 | - $contents_with_prefix[] = ''; |
|
1072 | - } |
|
1073 | - } |
|
1074 | - return $contents_with_prefix; |
|
1075 | - } |
|
1076 | - |
|
1077 | - |
|
1078 | - |
|
1079 | - /** |
|
1080 | - * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with. |
|
1081 | - * Deprecated because its return values were really quite confusing- sometimes it returned |
|
1082 | - * an empty array (when the include string was blank or '*') or sometimes it returned |
|
1083 | - * array('*') (when you provided a model and a model of that kind was found). |
|
1084 | - * Parses the $include_string so we fetch all the field names relating to THIS model |
|
1085 | - * (ie have NO period in them), or for the provided model (ie start with the model |
|
1086 | - * name and then a period). |
|
1087 | - * @param string $include_string @see Read:handle_request_get_all |
|
1088 | - * @param string $model_name |
|
1089 | - * @return array of fields for this model. If $model_name is provided, then |
|
1090 | - * the fields for that model, with the model's name removed from each. |
|
1091 | - * If $include_string was blank or '*' returns an empty array |
|
1092 | - */ |
|
1093 | - public function extract_includes_for_this_model($include_string, $model_name = null) |
|
1094 | - { |
|
1095 | - if (is_array($include_string)) { |
|
1096 | - $include_string = implode(',', $include_string); |
|
1097 | - } |
|
1098 | - if ($include_string === '*' || $include_string === '') { |
|
1099 | - return array(); |
|
1100 | - } |
|
1101 | - $includes = explode(',', $include_string); |
|
1102 | - $extracted_fields_to_include = array(); |
|
1103 | - if ($model_name) { |
|
1104 | - foreach ($includes as $field_to_include) { |
|
1105 | - $field_to_include = trim($field_to_include); |
|
1106 | - if (strpos($field_to_include, $model_name . '.') === 0) { |
|
1107 | - //found the model name at the exact start |
|
1108 | - $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include); |
|
1109 | - $extracted_fields_to_include[] = $field_sans_model_name; |
|
1110 | - } elseif ($field_to_include == $model_name) { |
|
1111 | - $extracted_fields_to_include[] = '*'; |
|
1112 | - } |
|
1113 | - } |
|
1114 | - } else { |
|
1115 | - //look for ones with no period |
|
1116 | - foreach ($includes as $field_to_include) { |
|
1117 | - $field_to_include = trim($field_to_include); |
|
1118 | - if ( |
|
1119 | - strpos($field_to_include, '.') === false |
|
1120 | - && ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include) |
|
1121 | - ) { |
|
1122 | - $extracted_fields_to_include[] = $field_to_include; |
|
1123 | - } |
|
1124 | - } |
|
1125 | - } |
|
1126 | - return $extracted_fields_to_include; |
|
1127 | - } |
|
28 | + /** |
|
29 | + * @var Calculated_Model_Fields |
|
30 | + */ |
|
31 | + protected $_fields_calculator; |
|
32 | + |
|
33 | + |
|
34 | + |
|
35 | + /** |
|
36 | + * Read constructor. |
|
37 | + */ |
|
38 | + public function __construct() |
|
39 | + { |
|
40 | + parent::__construct(); |
|
41 | + $this->_fields_calculator = new Calculated_Model_Fields(); |
|
42 | + } |
|
43 | + |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * Handles requests to get all (or a filtered subset) of entities for a particular model |
|
48 | + * |
|
49 | + * @param \WP_REST_Request $request |
|
50 | + * @return \WP_REST_Response|\WP_Error |
|
51 | + */ |
|
52 | + public static function handle_request_get_all(\WP_REST_Request $request) |
|
53 | + { |
|
54 | + $controller = new Read(); |
|
55 | + try { |
|
56 | + $matches = $controller->parse_route( |
|
57 | + $request->get_route(), |
|
58 | + '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~', |
|
59 | + array('version', 'model') |
|
60 | + ); |
|
61 | + $controller->set_requested_version($matches['version']); |
|
62 | + $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
|
63 | + if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
64 | + return $controller->send_response( |
|
65 | + new \WP_Error( |
|
66 | + 'endpoint_parsing_error', |
|
67 | + sprintf( |
|
68 | + __('There is no model for endpoint %s. Please contact event espresso support', |
|
69 | + 'event_espresso'), |
|
70 | + $model_name_singular |
|
71 | + ) |
|
72 | + ) |
|
73 | + ); |
|
74 | + } |
|
75 | + return $controller->send_response( |
|
76 | + $controller->get_entities_from_model( |
|
77 | + $controller->get_model_version_info()->load_model($model_name_singular), |
|
78 | + $request |
|
79 | + ) |
|
80 | + ); |
|
81 | + } catch (\Exception $e) { |
|
82 | + return $controller->send_response($e); |
|
83 | + } |
|
84 | + } |
|
85 | + |
|
86 | + |
|
87 | + |
|
88 | + /** |
|
89 | + * Gets a single entity related to the model indicated in the path and its id |
|
90 | + * |
|
91 | + * @param \WP_REST_Request $request |
|
92 | + * @return \WP_REST_Response|\WP_Error |
|
93 | + */ |
|
94 | + public static function handle_request_get_one(\WP_REST_Request $request) |
|
95 | + { |
|
96 | + $controller = new Read(); |
|
97 | + try { |
|
98 | + $matches = $controller->parse_route( |
|
99 | + $request->get_route(), |
|
100 | + '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~', |
|
101 | + array('version', 'model', 'id')); |
|
102 | + $controller->set_requested_version($matches['version']); |
|
103 | + $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
|
104 | + if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
105 | + return $controller->send_response( |
|
106 | + new \WP_Error( |
|
107 | + 'endpoint_parsing_error', |
|
108 | + sprintf( |
|
109 | + __('There is no model for endpoint %s. Please contact event espresso support', |
|
110 | + 'event_espresso'), |
|
111 | + $model_name_singular |
|
112 | + ) |
|
113 | + ) |
|
114 | + ); |
|
115 | + } |
|
116 | + return $controller->send_response( |
|
117 | + $controller->get_entity_from_model( |
|
118 | + $controller->get_model_version_info()->load_model($model_name_singular), |
|
119 | + $request |
|
120 | + ) |
|
121 | + ); |
|
122 | + } catch (\Exception $e) { |
|
123 | + return $controller->send_response($e); |
|
124 | + } |
|
125 | + } |
|
126 | + |
|
127 | + |
|
128 | + |
|
129 | + /** |
|
130 | + * Gets all the related entities (or if its a belongs-to relation just the one) |
|
131 | + * to the item with the given id |
|
132 | + * |
|
133 | + * @param \WP_REST_Request $request |
|
134 | + * @return \WP_REST_Response|\WP_Error |
|
135 | + */ |
|
136 | + public static function handle_request_get_related(\WP_REST_Request $request) |
|
137 | + { |
|
138 | + $controller = new Read(); |
|
139 | + try { |
|
140 | + $matches = $controller->parse_route( |
|
141 | + $request->get_route(), |
|
142 | + '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~', |
|
143 | + array('version', 'model', 'id', 'related_model') |
|
144 | + ); |
|
145 | + $controller->set_requested_version($matches['version']); |
|
146 | + $main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
|
147 | + if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) { |
|
148 | + return $controller->send_response( |
|
149 | + new \WP_Error( |
|
150 | + 'endpoint_parsing_error', |
|
151 | + sprintf( |
|
152 | + __('There is no model for endpoint %s. Please contact event espresso support', |
|
153 | + 'event_espresso'), |
|
154 | + $main_model_name_singular |
|
155 | + ) |
|
156 | + ) |
|
157 | + ); |
|
158 | + } |
|
159 | + $main_model = $controller->get_model_version_info()->load_model($main_model_name_singular); |
|
160 | + //assume the related model name is plural and try to find the model's name |
|
161 | + $related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']); |
|
162 | + if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
163 | + //so the word didn't singularize well. Maybe that's just because it's a singular word? |
|
164 | + $related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']); |
|
165 | + } |
|
166 | + if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
167 | + return $controller->send_response( |
|
168 | + new \WP_Error( |
|
169 | + 'endpoint_parsing_error', |
|
170 | + sprintf( |
|
171 | + __('There is no model for endpoint %s. Please contact event espresso support', |
|
172 | + 'event_espresso'), |
|
173 | + $related_model_name_singular |
|
174 | + ) |
|
175 | + ) |
|
176 | + ); |
|
177 | + } |
|
178 | + return $controller->send_response( |
|
179 | + $controller->get_entities_from_relation( |
|
180 | + $request->get_param('id'), |
|
181 | + $main_model->related_settings_for($related_model_name_singular), |
|
182 | + $request |
|
183 | + ) |
|
184 | + ); |
|
185 | + } catch (\Exception $e) { |
|
186 | + return $controller->send_response($e); |
|
187 | + } |
|
188 | + } |
|
189 | + |
|
190 | + |
|
191 | + |
|
192 | + /** |
|
193 | + * Gets a collection for the given model and filters |
|
194 | + * |
|
195 | + * @param \EEM_Base $model |
|
196 | + * @param \WP_REST_Request $request |
|
197 | + * @return array|\WP_Error |
|
198 | + */ |
|
199 | + public function get_entities_from_model($model, $request) |
|
200 | + { |
|
201 | + $query_params = $this->create_model_query_params($model, $request->get_params()); |
|
202 | + if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) { |
|
203 | + $model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
204 | + return new \WP_Error( |
|
205 | + sprintf('rest_%s_cannot_list', $model_name_plural), |
|
206 | + sprintf( |
|
207 | + __('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'), |
|
208 | + $model_name_plural, |
|
209 | + Capabilities::get_missing_permissions_string($model, $query_params['caps']) |
|
210 | + ), |
|
211 | + array('status' => 403) |
|
212 | + ); |
|
213 | + } |
|
214 | + if (! $request->get_header('no_rest_headers')) { |
|
215 | + $this->_set_headers_from_query_params($model, $query_params); |
|
216 | + } |
|
217 | + /** @type array $results */ |
|
218 | + $results = $model->get_all_wpdb_results($query_params); |
|
219 | + $nice_results = array(); |
|
220 | + foreach ($results as $result) { |
|
221 | + $nice_results[] = $this->create_entity_from_wpdb_result( |
|
222 | + $model, |
|
223 | + $result, |
|
224 | + $request |
|
225 | + ); |
|
226 | + } |
|
227 | + return $nice_results; |
|
228 | + } |
|
229 | + |
|
230 | + |
|
231 | + |
|
232 | + /** |
|
233 | + * @param array $primary_model_query_params query params for finding the item from which |
|
234 | + * relations will be based |
|
235 | + * @param \EE_Model_Relation_Base $relation |
|
236 | + * @param \WP_REST_Request $request |
|
237 | + * @return \WP_Error|array |
|
238 | + */ |
|
239 | + protected function _get_entities_from_relation($primary_model_query_params, $relation, $request) |
|
240 | + { |
|
241 | + $context = $this->validate_context($request->get_param('caps')); |
|
242 | + $model = $relation->get_this_model(); |
|
243 | + $related_model = $relation->get_other_model(); |
|
244 | + if (! isset($primary_model_query_params[0])) { |
|
245 | + $primary_model_query_params[0] = array(); |
|
246 | + } |
|
247 | + //check if they can access the 1st model object |
|
248 | + $primary_model_query_params = array( |
|
249 | + 0 => $primary_model_query_params[0], |
|
250 | + 'limit' => 1, |
|
251 | + ); |
|
252 | + if ($model instanceof \EEM_Soft_Delete_Base) { |
|
253 | + $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params); |
|
254 | + } |
|
255 | + $restricted_query_params = $primary_model_query_params; |
|
256 | + $restricted_query_params['caps'] = $context; |
|
257 | + $this->_set_debug_info('main model query params', $restricted_query_params); |
|
258 | + $this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context)); |
|
259 | + if ( |
|
260 | + ! ( |
|
261 | + Capabilities::current_user_has_partial_access_to($related_model, $context) |
|
262 | + && $model->exists($restricted_query_params) |
|
263 | + ) |
|
264 | + ) { |
|
265 | + if ($relation instanceof \EE_Belongs_To_Relation) { |
|
266 | + $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name()); |
|
267 | + } else { |
|
268 | + $related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name()); |
|
269 | + } |
|
270 | + return new \WP_Error( |
|
271 | + sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural), |
|
272 | + sprintf( |
|
273 | + __('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s', |
|
274 | + 'event_espresso'), |
|
275 | + $related_model_name_maybe_plural, |
|
276 | + $relation->get_this_model()->get_this_model_name(), |
|
277 | + implode( |
|
278 | + ',', |
|
279 | + array_keys( |
|
280 | + Capabilities::get_missing_permissions($related_model, $context) |
|
281 | + ) |
|
282 | + ) |
|
283 | + ), |
|
284 | + array('status' => 403) |
|
285 | + ); |
|
286 | + } |
|
287 | + $query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params()); |
|
288 | + foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) { |
|
289 | + $query_params[0][$relation->get_this_model()->get_this_model_name() |
|
290 | + . '.' |
|
291 | + . $where_condition_key] = $where_condition_value; |
|
292 | + } |
|
293 | + $query_params['default_where_conditions'] = 'none'; |
|
294 | + $query_params['caps'] = $context; |
|
295 | + if (! $request->get_header('no_rest_headers')) { |
|
296 | + $this->_set_headers_from_query_params($relation->get_other_model(), $query_params); |
|
297 | + } |
|
298 | + /** @type array $results */ |
|
299 | + $results = $relation->get_other_model()->get_all_wpdb_results($query_params); |
|
300 | + $nice_results = array(); |
|
301 | + foreach ($results as $result) { |
|
302 | + $nice_result = $this->create_entity_from_wpdb_result( |
|
303 | + $relation->get_other_model(), |
|
304 | + $result, |
|
305 | + $request |
|
306 | + ); |
|
307 | + if ($relation instanceof \EE_HABTM_Relation) { |
|
308 | + //put the unusual stuff (properties from the HABTM relation) first, and make sure |
|
309 | + //if there are conflicts we prefer the properties from the main model |
|
310 | + $join_model_result = $this->create_entity_from_wpdb_result( |
|
311 | + $relation->get_join_model(), |
|
312 | + $result, |
|
313 | + $request |
|
314 | + ); |
|
315 | + $joined_result = array_merge($nice_result, $join_model_result); |
|
316 | + //but keep the meta stuff from the main model |
|
317 | + if (isset($nice_result['meta'])) { |
|
318 | + $joined_result['meta'] = $nice_result['meta']; |
|
319 | + } |
|
320 | + $nice_result = $joined_result; |
|
321 | + } |
|
322 | + $nice_results[] = $nice_result; |
|
323 | + } |
|
324 | + if ($relation instanceof \EE_Belongs_To_Relation) { |
|
325 | + return array_shift($nice_results); |
|
326 | + } else { |
|
327 | + return $nice_results; |
|
328 | + } |
|
329 | + } |
|
330 | + |
|
331 | + |
|
332 | + |
|
333 | + /** |
|
334 | + * Gets the collection for given relation object |
|
335 | + * The same as Read::get_entities_from_model(), except if the relation |
|
336 | + * is a HABTM relation, in which case it merges any non-foreign-key fields from |
|
337 | + * the join-model-object into the results |
|
338 | + * |
|
339 | + * @param string $id the ID of the thing we are fetching related stuff from |
|
340 | + * @param \EE_Model_Relation_Base $relation |
|
341 | + * @param \WP_REST_Request $request |
|
342 | + * @return array|\WP_Error |
|
343 | + * @throws \EE_Error |
|
344 | + */ |
|
345 | + public function get_entities_from_relation($id, $relation, $request) |
|
346 | + { |
|
347 | + if (! $relation->get_this_model()->has_primary_key_field()) { |
|
348 | + throw new \EE_Error( |
|
349 | + sprintf( |
|
350 | + __('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s', |
|
351 | + 'event_espresso'), |
|
352 | + $relation->get_this_model()->get_this_model_name() |
|
353 | + ) |
|
354 | + ); |
|
355 | + } |
|
356 | + return $this->_get_entities_from_relation( |
|
357 | + array( |
|
358 | + array( |
|
359 | + $relation->get_this_model()->primary_key_name() => $id, |
|
360 | + ), |
|
361 | + ), |
|
362 | + $relation, |
|
363 | + $request |
|
364 | + ); |
|
365 | + } |
|
366 | + |
|
367 | + |
|
368 | + |
|
369 | + /** |
|
370 | + * Sets the headers that are based on the model and query params, |
|
371 | + * like the total records. This should only be called on the original request |
|
372 | + * from the client, not on subsequent internal |
|
373 | + * |
|
374 | + * @param \EEM_Base $model |
|
375 | + * @param array $query_params |
|
376 | + * @return void |
|
377 | + */ |
|
378 | + protected function _set_headers_from_query_params($model, $query_params) |
|
379 | + { |
|
380 | + $this->_set_debug_info('model query params', $query_params); |
|
381 | + $this->_set_debug_info('missing caps', |
|
382 | + Capabilities::get_missing_permissions_string($model, $query_params['caps'])); |
|
383 | + //normally the limit to a 2-part array, where the 2nd item is the limit |
|
384 | + if (! isset($query_params['limit'])) { |
|
385 | + $query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit(); |
|
386 | + } |
|
387 | + if (is_array($query_params['limit'])) { |
|
388 | + $limit_parts = $query_params['limit']; |
|
389 | + } else { |
|
390 | + $limit_parts = explode(',', $query_params['limit']); |
|
391 | + if (count($limit_parts) == 1) { |
|
392 | + $limit_parts = array(0, $limit_parts[0]); |
|
393 | + } |
|
394 | + } |
|
395 | + //remove the group by and having parts of the query, as those will |
|
396 | + //make the sql query return an array of values, instead of just a single value |
|
397 | + unset($query_params['group_by'], $query_params['having'], $query_params['limit']); |
|
398 | + $count = $model->count($query_params, null, true); |
|
399 | + $pages = $count / $limit_parts[1]; |
|
400 | + $this->_set_response_header('Total', $count, false); |
|
401 | + $this->_set_response_header('PageSize', $limit_parts[1], false); |
|
402 | + $this->_set_response_header('TotalPages', ceil($pages), false); |
|
403 | + } |
|
404 | + |
|
405 | + |
|
406 | + |
|
407 | + /** |
|
408 | + * Changes database results into REST API entities |
|
409 | + * |
|
410 | + * @param \EEM_Base $model |
|
411 | + * @param array $db_row like results from $wpdb->get_results() |
|
412 | + * @param \WP_REST_Request $rest_request |
|
413 | + * @param string $deprecated no longer used |
|
414 | + * @return array ready for being converted into json for sending to client |
|
415 | + */ |
|
416 | + public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null) |
|
417 | + { |
|
418 | + if (! $rest_request instanceof \WP_REST_Request) { |
|
419 | + //ok so this was called in the old style, where the 3rd arg was |
|
420 | + //$include, and the 4th arg was $context |
|
421 | + //now setup the request just to avoid fatal errors, although we won't be able |
|
422 | + //to truly make use of it because it's kinda devoid of info |
|
423 | + $rest_request = new \WP_REST_Request(); |
|
424 | + $rest_request->set_param('include', $rest_request); |
|
425 | + $rest_request->set_param('caps', $deprecated); |
|
426 | + } |
|
427 | + if ($rest_request->get_param('caps') == null) { |
|
428 | + $rest_request->set_param('caps', \EEM_Base::caps_read); |
|
429 | + } |
|
430 | + $entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row); |
|
431 | + $entity_array = $this->_add_extra_fields($model, $db_row, $entity_array); |
|
432 | + $entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array); |
|
433 | + $entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request); |
|
434 | + $entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row); |
|
435 | + $entity_array = apply_filters( |
|
436 | + 'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal', |
|
437 | + $entity_array, |
|
438 | + $model, |
|
439 | + $rest_request->get_param('caps'), |
|
440 | + $rest_request, |
|
441 | + $this |
|
442 | + ); |
|
443 | + $result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields( |
|
444 | + $entity_array, |
|
445 | + $model, |
|
446 | + $rest_request->get_param('caps'), |
|
447 | + $this->get_model_version_info(), |
|
448 | + $model->get_index_primary_key_string( |
|
449 | + $model->deduce_fields_n_values_from_cols_n_values($db_row) |
|
450 | + ) |
|
451 | + ); |
|
452 | + $this->_set_debug_info( |
|
453 | + 'inaccessible fields', |
|
454 | + array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields)) |
|
455 | + ); |
|
456 | + return apply_filters( |
|
457 | + 'FHEE__Read__create_entity_from_wpdb_results__entity_return', |
|
458 | + $result_without_inaccessible_fields, |
|
459 | + $model, |
|
460 | + $rest_request->get_param('caps') |
|
461 | + ); |
|
462 | + } |
|
463 | + |
|
464 | + |
|
465 | + |
|
466 | + /** |
|
467 | + * Creates a REST entity array (JSON object we're going to return in the response, but |
|
468 | + * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry), |
|
469 | + * from $wpdb->get_row( $sql, ARRAY_A) |
|
470 | + * |
|
471 | + * @param \EEM_Base $model |
|
472 | + * @param array $db_row |
|
473 | + * @return array entity mostly ready for converting to JSON and sending in the response |
|
474 | + */ |
|
475 | + protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row) |
|
476 | + { |
|
477 | + $result = $model->deduce_fields_n_values_from_cols_n_values($db_row); |
|
478 | + $result = array_intersect_key($result, |
|
479 | + $this->get_model_version_info()->fields_on_model_in_this_version($model)); |
|
480 | + foreach ($result as $field_name => $raw_field_value) { |
|
481 | + $field_obj = $model->field_settings_for($field_name); |
|
482 | + $field_value = $field_obj->prepare_for_set_from_db($raw_field_value); |
|
483 | + if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) { |
|
484 | + unset($result[$field_name]); |
|
485 | + } elseif ( |
|
486 | + $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format()) |
|
487 | + ) { |
|
488 | + $result[$field_name] = array( |
|
489 | + 'raw' => $field_obj->prepare_for_get($field_value), |
|
490 | + 'rendered' => $field_obj->prepare_for_pretty_echoing($field_value), |
|
491 | + ); |
|
492 | + } elseif ( |
|
493 | + $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format()) |
|
494 | + ) { |
|
495 | + $result[$field_name] = array( |
|
496 | + 'raw' => $field_obj->prepare_for_get($field_value), |
|
497 | + 'pretty' => $field_obj->prepare_for_pretty_echoing($field_value), |
|
498 | + ); |
|
499 | + } elseif ($field_obj instanceof \EE_Datetime_Field) { |
|
500 | + if ($field_value instanceof \DateTime) { |
|
501 | + $timezone = $field_value->getTimezone(); |
|
502 | + $field_value->setTimezone(new \DateTimeZone('UTC')); |
|
503 | + $result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json( |
|
504 | + $field_obj, |
|
505 | + $field_value, |
|
506 | + $this->get_model_version_info()->requested_version() |
|
507 | + ); |
|
508 | + $field_value->setTimezone($timezone); |
|
509 | + $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json( |
|
510 | + $field_obj, |
|
511 | + $field_value, |
|
512 | + $this->get_model_version_info()->requested_version() |
|
513 | + ); |
|
514 | + } |
|
515 | + } else { |
|
516 | + $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json( |
|
517 | + $field_obj, |
|
518 | + $field_obj->prepare_for_get($field_value), |
|
519 | + $this->get_model_version_info()->requested_version() |
|
520 | + ); |
|
521 | + } |
|
522 | + } |
|
523 | + return $result; |
|
524 | + } |
|
525 | + |
|
526 | + |
|
527 | + |
|
528 | + /** |
|
529 | + * Adds a few extra fields to the entity response |
|
530 | + * |
|
531 | + * @param \EEM_Base $model |
|
532 | + * @param array $db_row |
|
533 | + * @param array $entity_array |
|
534 | + * @return array modified entity |
|
535 | + */ |
|
536 | + protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array) |
|
537 | + { |
|
538 | + if ($model instanceof \EEM_CPT_Base) { |
|
539 | + $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]); |
|
540 | + } |
|
541 | + return $entity_array; |
|
542 | + } |
|
543 | + |
|
544 | + |
|
545 | + |
|
546 | + /** |
|
547 | + * Gets links we want to add to the response |
|
548 | + * |
|
549 | + * @global \WP_REST_Server $wp_rest_server |
|
550 | + * @param \EEM_Base $model |
|
551 | + * @param array $db_row |
|
552 | + * @param array $entity_array |
|
553 | + * @return array the _links item in the entity |
|
554 | + */ |
|
555 | + protected function _get_entity_links($model, $db_row, $entity_array) |
|
556 | + { |
|
557 | + //add basic links |
|
558 | + $links = array(); |
|
559 | + if ($model->has_primary_key_field()) { |
|
560 | + $links['self'] = array( |
|
561 | + array( |
|
562 | + 'href' => $this->get_versioned_link_to( |
|
563 | + \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
564 | + . '/' |
|
565 | + . $entity_array[$model->primary_key_name()] |
|
566 | + ), |
|
567 | + ), |
|
568 | + ); |
|
569 | + } |
|
570 | + $links['collection'] = array( |
|
571 | + array( |
|
572 | + 'href' => $this->get_versioned_link_to( |
|
573 | + \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
574 | + ), |
|
575 | + ), |
|
576 | + ); |
|
577 | + //add links to related models |
|
578 | + if ($model->has_primary_key_field()) { |
|
579 | + foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) { |
|
580 | + $related_model_part = Read::get_related_entity_name($relation_name, $relation_obj); |
|
581 | + $links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array( |
|
582 | + array( |
|
583 | + 'href' => $this->get_versioned_link_to( |
|
584 | + \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
|
585 | + . '/' |
|
586 | + . $entity_array[$model->primary_key_name()] |
|
587 | + . '/' |
|
588 | + . $related_model_part |
|
589 | + ), |
|
590 | + 'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false, |
|
591 | + ), |
|
592 | + ); |
|
593 | + } |
|
594 | + } |
|
595 | + return $links; |
|
596 | + } |
|
597 | + |
|
598 | + |
|
599 | + |
|
600 | + /** |
|
601 | + * Adds the included models indicated in the request to the entity provided |
|
602 | + * |
|
603 | + * @param \EEM_Base $model |
|
604 | + * @param \WP_REST_Request $rest_request |
|
605 | + * @param array $entity_array |
|
606 | + * @param array $db_row |
|
607 | + * @return array the modified entity |
|
608 | + */ |
|
609 | + protected function _include_requested_models( |
|
610 | + \EEM_Base $model, |
|
611 | + \WP_REST_Request $rest_request, |
|
612 | + $entity_array, |
|
613 | + $db_row = array() |
|
614 | + ) { |
|
615 | + //if $db_row not included, hope the entity array has what we need |
|
616 | + if (! $db_row) { |
|
617 | + $db_row = $entity_array; |
|
618 | + } |
|
619 | + $includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), ''); |
|
620 | + $includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model); |
|
621 | + //if they passed in * or didn't specify any includes, return everything |
|
622 | + if (! in_array('*', $includes_for_this_model) |
|
623 | + && ! empty($includes_for_this_model) |
|
624 | + ) { |
|
625 | + if ($model->has_primary_key_field()) { |
|
626 | + //always include the primary key. ya just gotta know that at least |
|
627 | + $includes_for_this_model[] = $model->primary_key_name(); |
|
628 | + } |
|
629 | + if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) { |
|
630 | + $includes_for_this_model[] = '_calculated_fields'; |
|
631 | + } |
|
632 | + $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model)); |
|
633 | + } |
|
634 | + $relation_settings = $this->get_model_version_info()->relation_settings($model); |
|
635 | + foreach ($relation_settings as $relation_name => $relation_obj) { |
|
636 | + $related_fields_to_include = $this->explode_and_get_items_prefixed_with( |
|
637 | + $rest_request->get_param('include'), |
|
638 | + $relation_name |
|
639 | + ); |
|
640 | + $related_fields_to_calculate = $this->explode_and_get_items_prefixed_with( |
|
641 | + $rest_request->get_param('calculate'), |
|
642 | + $relation_name |
|
643 | + ); |
|
644 | + //did they specify they wanted to include a related model, or |
|
645 | + //specific fields from a related model? |
|
646 | + //or did they specify to calculate a field from a related model? |
|
647 | + if ($related_fields_to_include || $related_fields_to_calculate) { |
|
648 | + //if so, we should include at least some part of the related model |
|
649 | + $pretend_related_request = new \WP_REST_Request(); |
|
650 | + $pretend_related_request->set_query_params( |
|
651 | + array( |
|
652 | + 'caps' => $rest_request->get_param('caps'), |
|
653 | + 'include' => $related_fields_to_include, |
|
654 | + 'calculate' => $related_fields_to_calculate, |
|
655 | + ) |
|
656 | + ); |
|
657 | + $pretend_related_request->add_header('no_rest_headers', true); |
|
658 | + $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID( |
|
659 | + $model->get_index_primary_key_string( |
|
660 | + $model->deduce_fields_n_values_from_cols_n_values($db_row) |
|
661 | + ) |
|
662 | + ); |
|
663 | + $related_results = $this->_get_entities_from_relation( |
|
664 | + $primary_model_query_params, |
|
665 | + $relation_obj, |
|
666 | + $pretend_related_request |
|
667 | + ); |
|
668 | + $entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results |
|
669 | + instanceof |
|
670 | + \WP_Error |
|
671 | + ? null |
|
672 | + : $related_results; |
|
673 | + } |
|
674 | + } |
|
675 | + return $entity_array; |
|
676 | + } |
|
677 | + |
|
678 | + |
|
679 | + |
|
680 | + /** |
|
681 | + * Returns a new array with all the names of models removed. Eg |
|
682 | + * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' ) |
|
683 | + * |
|
684 | + * @param array $arr |
|
685 | + * @return array |
|
686 | + */ |
|
687 | + private function _remove_model_names_from_array($arr) |
|
688 | + { |
|
689 | + return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models)); |
|
690 | + } |
|
691 | + |
|
692 | + |
|
693 | + |
|
694 | + /** |
|
695 | + * Gets the calculated fields for the response |
|
696 | + * |
|
697 | + * @param \EEM_Base $model |
|
698 | + * @param array $wpdb_row |
|
699 | + * @param \WP_REST_Request $rest_request |
|
700 | + * @return \stdClass the _calculations item in the entity |
|
701 | + */ |
|
702 | + protected function _get_entity_calculations($model, $wpdb_row, $rest_request) |
|
703 | + { |
|
704 | + $calculated_fields = $this->explode_and_get_items_prefixed_with( |
|
705 | + $rest_request->get_param('calculate'), |
|
706 | + '' |
|
707 | + ); |
|
708 | + //note: setting calculate=* doesn't do anything |
|
709 | + $calculated_fields_to_return = new \stdClass(); |
|
710 | + foreach ($calculated_fields as $field_to_calculate) { |
|
711 | + try { |
|
712 | + $calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json( |
|
713 | + null, |
|
714 | + $this->_fields_calculator->retrieve_calculated_field_value( |
|
715 | + $model, |
|
716 | + $field_to_calculate, |
|
717 | + $wpdb_row, |
|
718 | + $rest_request, |
|
719 | + $this |
|
720 | + ), |
|
721 | + $this->get_model_version_info()->requested_version() |
|
722 | + ); |
|
723 | + } catch (Rest_Exception $e) { |
|
724 | + //if we don't have permission to read it, just leave it out. but let devs know about the problem |
|
725 | + $this->_set_response_header( |
|
726 | + 'Notices-Field-Calculation-Errors[' |
|
727 | + . $e->get_string_code() |
|
728 | + . '][' |
|
729 | + . $model->get_this_model_name() |
|
730 | + . '][' |
|
731 | + . $field_to_calculate |
|
732 | + . ']', |
|
733 | + $e->getMessage(), |
|
734 | + true |
|
735 | + ); |
|
736 | + } |
|
737 | + } |
|
738 | + return $calculated_fields_to_return; |
|
739 | + } |
|
740 | + |
|
741 | + |
|
742 | + |
|
743 | + /** |
|
744 | + * Gets the full URL to the resource, taking the requested version into account |
|
745 | + * |
|
746 | + * @param string $link_part_after_version_and_slash eg "events/10/datetimes" |
|
747 | + * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes" |
|
748 | + */ |
|
749 | + public function get_versioned_link_to($link_part_after_version_and_slash) |
|
750 | + { |
|
751 | + return rest_url( |
|
752 | + \EED_Core_Rest_Api::ee_api_namespace |
|
753 | + . $this->get_model_version_info()->requested_version() |
|
754 | + . '/' |
|
755 | + . $link_part_after_version_and_slash |
|
756 | + ); |
|
757 | + } |
|
758 | + |
|
759 | + |
|
760 | + |
|
761 | + /** |
|
762 | + * Gets the correct lowercase name for the relation in the API according |
|
763 | + * to the relation's type |
|
764 | + * |
|
765 | + * @param string $relation_name |
|
766 | + * @param \EE_Model_Relation_Base $relation_obj |
|
767 | + * @return string |
|
768 | + */ |
|
769 | + public static function get_related_entity_name($relation_name, $relation_obj) |
|
770 | + { |
|
771 | + if ($relation_obj instanceof \EE_Belongs_To_Relation) { |
|
772 | + return strtolower($relation_name); |
|
773 | + } else { |
|
774 | + return \EEH_Inflector::pluralize_and_lower($relation_name); |
|
775 | + } |
|
776 | + } |
|
777 | + |
|
778 | + |
|
779 | + |
|
780 | + /** |
|
781 | + * Gets the one model object with the specified id for the specified model |
|
782 | + * |
|
783 | + * @param \EEM_Base $model |
|
784 | + * @param \WP_REST_Request $request |
|
785 | + * @return array|\WP_Error |
|
786 | + */ |
|
787 | + public function get_entity_from_model($model, $request) |
|
788 | + { |
|
789 | + $query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1); |
|
790 | + if ($model instanceof \EEM_Soft_Delete_Base) { |
|
791 | + $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
792 | + } |
|
793 | + $restricted_query_params = $query_params; |
|
794 | + $restricted_query_params['caps'] = $this->validate_context($request->get_param('caps')); |
|
795 | + $this->_set_debug_info('model query params', $restricted_query_params); |
|
796 | + $model_rows = $model->get_all_wpdb_results($restricted_query_params); |
|
797 | + if (! empty ($model_rows)) { |
|
798 | + return $this->create_entity_from_wpdb_result( |
|
799 | + $model, |
|
800 | + array_shift($model_rows), |
|
801 | + $request); |
|
802 | + } else { |
|
803 | + //ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities |
|
804 | + $lowercase_model_name = strtolower($model->get_this_model_name()); |
|
805 | + $model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params); |
|
806 | + if (! empty($model_rows_found_sans_restrictions)) { |
|
807 | + //you got shafted- it existed but we didn't want to tell you! |
|
808 | + return new \WP_Error( |
|
809 | + 'rest_user_cannot_read', |
|
810 | + sprintf( |
|
811 | + __('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'), |
|
812 | + strtolower($model->get_this_model_name()), |
|
813 | + Capabilities::get_missing_permissions_string( |
|
814 | + $model, |
|
815 | + $this->validate_context($request->get_param('caps'))) |
|
816 | + ), |
|
817 | + array('status' => 403) |
|
818 | + ); |
|
819 | + } else { |
|
820 | + //it's not you. It just doesn't exist |
|
821 | + return new \WP_Error( |
|
822 | + sprintf('rest_%s_invalid_id', $lowercase_model_name), |
|
823 | + sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name), |
|
824 | + array('status' => 404) |
|
825 | + ); |
|
826 | + } |
|
827 | + } |
|
828 | + } |
|
829 | + |
|
830 | + |
|
831 | + |
|
832 | + /** |
|
833 | + * If a context is provided which isn't valid, maybe it was added in a future |
|
834 | + * version so just treat it as a default read |
|
835 | + * |
|
836 | + * @param string $context |
|
837 | + * @return string array key of EEM_Base::cap_contexts_to_cap_action_map() |
|
838 | + */ |
|
839 | + public function validate_context($context) |
|
840 | + { |
|
841 | + if (! $context) { |
|
842 | + $context = \EEM_Base::caps_read; |
|
843 | + } |
|
844 | + $valid_contexts = \EEM_Base::valid_cap_contexts(); |
|
845 | + if (in_array($context, $valid_contexts)) { |
|
846 | + return $context; |
|
847 | + } else { |
|
848 | + return \EEM_Base::caps_read; |
|
849 | + } |
|
850 | + } |
|
851 | + |
|
852 | + |
|
853 | + |
|
854 | + /** |
|
855 | + * Verifies the passed in value is an allowable default where conditions value. |
|
856 | + * |
|
857 | + * @param $default_query_params |
|
858 | + * @return string |
|
859 | + */ |
|
860 | + public function validate_default_query_params($default_query_params) |
|
861 | + { |
|
862 | + $valid_default_where_conditions_for_api_calls = array( |
|
863 | + \EEM_Base::default_where_conditions_all, |
|
864 | + \EEM_Base::default_where_conditions_minimum_all, |
|
865 | + \EEM_Base::default_where_conditions_minimum_others, |
|
866 | + ); |
|
867 | + if (! $default_query_params) { |
|
868 | + $default_query_params = \EEM_Base::default_where_conditions_all; |
|
869 | + } |
|
870 | + if ( |
|
871 | + in_array( |
|
872 | + $default_query_params, |
|
873 | + $valid_default_where_conditions_for_api_calls, |
|
874 | + true |
|
875 | + ) |
|
876 | + ) { |
|
877 | + return $default_query_params; |
|
878 | + } else { |
|
879 | + return \EEM_Base::default_where_conditions_all; |
|
880 | + } |
|
881 | + } |
|
882 | + |
|
883 | + |
|
884 | + |
|
885 | + /** |
|
886 | + * Translates API filter get parameter into $query_params array used by EEM_Base::get_all(). |
|
887 | + * Note: right now the query parameter keys for fields (and related fields) |
|
888 | + * can be left as-is, but it's quite possible this will change someday. |
|
889 | + * Also, this method's contents might be candidate for moving to Model_Data_Translator |
|
890 | + * |
|
891 | + * @param \EEM_Base $model |
|
892 | + * @param array $query_parameters from $_GET parameter @see Read:handle_request_get_all |
|
893 | + * @return array like what EEM_Base::get_all() expects or FALSE to indicate |
|
894 | + * that absolutely no results should be returned |
|
895 | + * @throws \EE_Error |
|
896 | + */ |
|
897 | + public function create_model_query_params($model, $query_parameters) |
|
898 | + { |
|
899 | + $model_query_params = array(); |
|
900 | + if (isset($query_parameters['where'])) { |
|
901 | + $model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models( |
|
902 | + $query_parameters['where'], |
|
903 | + $model, |
|
904 | + $this->get_model_version_info()->requested_version() |
|
905 | + ); |
|
906 | + } |
|
907 | + if (isset($query_parameters['order_by'])) { |
|
908 | + $order_by = $query_parameters['order_by']; |
|
909 | + } elseif (isset($query_parameters['orderby'])) { |
|
910 | + $order_by = $query_parameters['orderby']; |
|
911 | + } else { |
|
912 | + $order_by = null; |
|
913 | + } |
|
914 | + if ($order_by !== null) { |
|
915 | + if (is_array($order_by)) { |
|
916 | + $order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by); |
|
917 | + } else { |
|
918 | + //it's a single item |
|
919 | + $order_by = Model_Data_Translator::prepare_field_name_from_json($order_by); |
|
920 | + } |
|
921 | + $model_query_params['order_by'] = $order_by; |
|
922 | + } |
|
923 | + if (isset($query_parameters['group_by'])) { |
|
924 | + $group_by = $query_parameters['group_by']; |
|
925 | + } elseif (isset($query_parameters['groupby'])) { |
|
926 | + $group_by = $query_parameters['groupby']; |
|
927 | + } else { |
|
928 | + $group_by = array_keys($model->get_combined_primary_key_fields()); |
|
929 | + } |
|
930 | + //make sure they're all real names |
|
931 | + if (is_array($group_by)) { |
|
932 | + $group_by = Model_Data_Translator::prepare_field_names_from_json($group_by); |
|
933 | + } |
|
934 | + if ($group_by !== null) { |
|
935 | + $model_query_params['group_by'] = $group_by; |
|
936 | + } |
|
937 | + if (isset($query_parameters['having'])) { |
|
938 | + $model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models( |
|
939 | + $query_parameters['having'], |
|
940 | + $model, |
|
941 | + $this->get_model_version_info()->requested_version() |
|
942 | + ); |
|
943 | + } |
|
944 | + if (isset($query_parameters['order'])) { |
|
945 | + $model_query_params['order'] = $query_parameters['order']; |
|
946 | + } |
|
947 | + if (isset($query_parameters['mine'])) { |
|
948 | + $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params); |
|
949 | + } |
|
950 | + if (isset($query_parameters['limit'])) { |
|
951 | + //limit should be either a string like '23' or '23,43', or an array with two items in it |
|
952 | + if (! is_array($query_parameters['limit'])) { |
|
953 | + $limit_array = explode(',', (string)$query_parameters['limit']); |
|
954 | + } else { |
|
955 | + $limit_array = $query_parameters['limit']; |
|
956 | + } |
|
957 | + $sanitized_limit = array(); |
|
958 | + foreach ($limit_array as $key => $limit_part) { |
|
959 | + if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) { |
|
960 | + throw new \EE_Error( |
|
961 | + sprintf( |
|
962 | + __('An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.', |
|
963 | + 'event_espresso'), |
|
964 | + wp_json_encode($query_parameters['limit']) |
|
965 | + ) |
|
966 | + ); |
|
967 | + } |
|
968 | + $sanitized_limit[] = (int)$limit_part; |
|
969 | + } |
|
970 | + $model_query_params['limit'] = implode(',', $sanitized_limit); |
|
971 | + } else { |
|
972 | + $model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit(); |
|
973 | + } |
|
974 | + if (isset($query_parameters['caps'])) { |
|
975 | + $model_query_params['caps'] = $this->validate_context($query_parameters['caps']); |
|
976 | + } else { |
|
977 | + $model_query_params['caps'] = \EEM_Base::caps_read; |
|
978 | + } |
|
979 | + if (isset($query_parameters['default_where_conditions'])) { |
|
980 | + $model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']); |
|
981 | + } |
|
982 | + return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model); |
|
983 | + } |
|
984 | + |
|
985 | + |
|
986 | + |
|
987 | + /** |
|
988 | + * Changes the REST-style query params for use in the models |
|
989 | + * |
|
990 | + * @deprecated |
|
991 | + * @param \EEM_Base $model |
|
992 | + * @param array $query_params sub-array from @see EEM_Base::get_all() |
|
993 | + * @return array |
|
994 | + */ |
|
995 | + public function prepare_rest_query_params_key_for_models($model, $query_params) |
|
996 | + { |
|
997 | + $model_ready_query_params = array(); |
|
998 | + foreach ($query_params as $key => $value) { |
|
999 | + if (is_array($value)) { |
|
1000 | + $model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value); |
|
1001 | + } else { |
|
1002 | + $model_ready_query_params[$key] = $value; |
|
1003 | + } |
|
1004 | + } |
|
1005 | + return $model_ready_query_params; |
|
1006 | + } |
|
1007 | + |
|
1008 | + |
|
1009 | + |
|
1010 | + /** |
|
1011 | + * @deprecated |
|
1012 | + * @param $model |
|
1013 | + * @param $query_params |
|
1014 | + * @return array |
|
1015 | + */ |
|
1016 | + public function prepare_rest_query_params_values_for_models($model, $query_params) |
|
1017 | + { |
|
1018 | + $model_ready_query_params = array(); |
|
1019 | + foreach ($query_params as $key => $value) { |
|
1020 | + if (is_array($value)) { |
|
1021 | + $model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value); |
|
1022 | + } else { |
|
1023 | + $model_ready_query_params[$key] = $value; |
|
1024 | + } |
|
1025 | + } |
|
1026 | + return $model_ready_query_params; |
|
1027 | + } |
|
1028 | + |
|
1029 | + |
|
1030 | + |
|
1031 | + /** |
|
1032 | + * Explodes the string on commas, and only returns items with $prefix followed by a period. |
|
1033 | + * If no prefix is specified, returns items with no period. |
|
1034 | + * |
|
1035 | + * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' ) |
|
1036 | + * @param string $prefix "Event" or "foobar" |
|
1037 | + * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified |
|
1038 | + * we only return strings starting with that and a period; if no prefix was |
|
1039 | + * specified we return all items containing NO periods |
|
1040 | + */ |
|
1041 | + public function explode_and_get_items_prefixed_with($string_to_explode, $prefix) |
|
1042 | + { |
|
1043 | + if (is_string($string_to_explode)) { |
|
1044 | + $exploded_contents = explode(',', $string_to_explode); |
|
1045 | + } else if (is_array($string_to_explode)) { |
|
1046 | + $exploded_contents = $string_to_explode; |
|
1047 | + } else { |
|
1048 | + $exploded_contents = array(); |
|
1049 | + } |
|
1050 | + //if the string was empty, we want an empty array |
|
1051 | + $exploded_contents = array_filter($exploded_contents); |
|
1052 | + $contents_with_prefix = array(); |
|
1053 | + foreach ($exploded_contents as $item) { |
|
1054 | + $item = trim($item); |
|
1055 | + //if no prefix was provided, so we look for items with no "." in them |
|
1056 | + if (! $prefix) { |
|
1057 | + //does this item have a period? |
|
1058 | + if (strpos($item, '.') === false) { |
|
1059 | + //if not, then its what we're looking for |
|
1060 | + $contents_with_prefix[] = $item; |
|
1061 | + } |
|
1062 | + } else if (strpos($item, $prefix . '.') === 0) { |
|
1063 | + //this item has the prefix and a period, grab it |
|
1064 | + $contents_with_prefix[] = substr( |
|
1065 | + $item, |
|
1066 | + strpos($item, $prefix . '.') + strlen($prefix . '.') |
|
1067 | + ); |
|
1068 | + } else if ($item === $prefix) { |
|
1069 | + //this item is JUST the prefix |
|
1070 | + //so let's grab everything after, which is a blank string |
|
1071 | + $contents_with_prefix[] = ''; |
|
1072 | + } |
|
1073 | + } |
|
1074 | + return $contents_with_prefix; |
|
1075 | + } |
|
1076 | + |
|
1077 | + |
|
1078 | + |
|
1079 | + /** |
|
1080 | + * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with. |
|
1081 | + * Deprecated because its return values were really quite confusing- sometimes it returned |
|
1082 | + * an empty array (when the include string was blank or '*') or sometimes it returned |
|
1083 | + * array('*') (when you provided a model and a model of that kind was found). |
|
1084 | + * Parses the $include_string so we fetch all the field names relating to THIS model |
|
1085 | + * (ie have NO period in them), or for the provided model (ie start with the model |
|
1086 | + * name and then a period). |
|
1087 | + * @param string $include_string @see Read:handle_request_get_all |
|
1088 | + * @param string $model_name |
|
1089 | + * @return array of fields for this model. If $model_name is provided, then |
|
1090 | + * the fields for that model, with the model's name removed from each. |
|
1091 | + * If $include_string was blank or '*' returns an empty array |
|
1092 | + */ |
|
1093 | + public function extract_includes_for_this_model($include_string, $model_name = null) |
|
1094 | + { |
|
1095 | + if (is_array($include_string)) { |
|
1096 | + $include_string = implode(',', $include_string); |
|
1097 | + } |
|
1098 | + if ($include_string === '*' || $include_string === '') { |
|
1099 | + return array(); |
|
1100 | + } |
|
1101 | + $includes = explode(',', $include_string); |
|
1102 | + $extracted_fields_to_include = array(); |
|
1103 | + if ($model_name) { |
|
1104 | + foreach ($includes as $field_to_include) { |
|
1105 | + $field_to_include = trim($field_to_include); |
|
1106 | + if (strpos($field_to_include, $model_name . '.') === 0) { |
|
1107 | + //found the model name at the exact start |
|
1108 | + $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include); |
|
1109 | + $extracted_fields_to_include[] = $field_sans_model_name; |
|
1110 | + } elseif ($field_to_include == $model_name) { |
|
1111 | + $extracted_fields_to_include[] = '*'; |
|
1112 | + } |
|
1113 | + } |
|
1114 | + } else { |
|
1115 | + //look for ones with no period |
|
1116 | + foreach ($includes as $field_to_include) { |
|
1117 | + $field_to_include = trim($field_to_include); |
|
1118 | + if ( |
|
1119 | + strpos($field_to_include, '.') === false |
|
1120 | + && ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include) |
|
1121 | + ) { |
|
1122 | + $extracted_fields_to_include[] = $field_to_include; |
|
1123 | + } |
|
1124 | + } |
|
1125 | + } |
|
1126 | + return $extracted_fields_to_include; |
|
1127 | + } |
|
1128 | 1128 | } |
1129 | 1129 | |
1130 | 1130 |
@@ -6,7 +6,7 @@ discard block |
||
6 | 6 | use EventEspresso\core\libraries\rest_api\Rest_Exception; |
7 | 7 | use EventEspresso\core\libraries\rest_api\Model_Data_Translator; |
8 | 8 | |
9 | -if (! defined('EVENT_ESPRESSO_VERSION')) { |
|
9 | +if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
|
10 | 10 | exit('No direct script access allowed'); |
11 | 11 | } |
12 | 12 | |
@@ -55,12 +55,12 @@ discard block |
||
55 | 55 | try { |
56 | 56 | $matches = $controller->parse_route( |
57 | 57 | $request->get_route(), |
58 | - '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~', |
|
58 | + '~'.\EED_Core_Rest_Api::ee_api_namespace_for_regex.'(.*)~', |
|
59 | 59 | array('version', 'model') |
60 | 60 | ); |
61 | 61 | $controller->set_requested_version($matches['version']); |
62 | 62 | $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
63 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
63 | + if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
64 | 64 | return $controller->send_response( |
65 | 65 | new \WP_Error( |
66 | 66 | 'endpoint_parsing_error', |
@@ -97,11 +97,11 @@ discard block |
||
97 | 97 | try { |
98 | 98 | $matches = $controller->parse_route( |
99 | 99 | $request->get_route(), |
100 | - '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~', |
|
100 | + '~'.\EED_Core_Rest_Api::ee_api_namespace_for_regex.'(.*)/(.*)~', |
|
101 | 101 | array('version', 'model', 'id')); |
102 | 102 | $controller->set_requested_version($matches['version']); |
103 | 103 | $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
104 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
104 | + if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) { |
|
105 | 105 | return $controller->send_response( |
106 | 106 | new \WP_Error( |
107 | 107 | 'endpoint_parsing_error', |
@@ -139,12 +139,12 @@ discard block |
||
139 | 139 | try { |
140 | 140 | $matches = $controller->parse_route( |
141 | 141 | $request->get_route(), |
142 | - '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~', |
|
142 | + '~'.\EED_Core_Rest_Api::ee_api_namespace_for_regex.'(.*)/(.*)/(.*)~', |
|
143 | 143 | array('version', 'model', 'id', 'related_model') |
144 | 144 | ); |
145 | 145 | $controller->set_requested_version($matches['version']); |
146 | 146 | $main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']); |
147 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) { |
|
147 | + if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) { |
|
148 | 148 | return $controller->send_response( |
149 | 149 | new \WP_Error( |
150 | 150 | 'endpoint_parsing_error', |
@@ -159,11 +159,11 @@ discard block |
||
159 | 159 | $main_model = $controller->get_model_version_info()->load_model($main_model_name_singular); |
160 | 160 | //assume the related model name is plural and try to find the model's name |
161 | 161 | $related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']); |
162 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
162 | + if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
163 | 163 | //so the word didn't singularize well. Maybe that's just because it's a singular word? |
164 | 164 | $related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']); |
165 | 165 | } |
166 | - if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
166 | + if ( ! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) { |
|
167 | 167 | return $controller->send_response( |
168 | 168 | new \WP_Error( |
169 | 169 | 'endpoint_parsing_error', |
@@ -199,7 +199,7 @@ discard block |
||
199 | 199 | public function get_entities_from_model($model, $request) |
200 | 200 | { |
201 | 201 | $query_params = $this->create_model_query_params($model, $request->get_params()); |
202 | - if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) { |
|
202 | + if ( ! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) { |
|
203 | 203 | $model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
204 | 204 | return new \WP_Error( |
205 | 205 | sprintf('rest_%s_cannot_list', $model_name_plural), |
@@ -211,7 +211,7 @@ discard block |
||
211 | 211 | array('status' => 403) |
212 | 212 | ); |
213 | 213 | } |
214 | - if (! $request->get_header('no_rest_headers')) { |
|
214 | + if ( ! $request->get_header('no_rest_headers')) { |
|
215 | 215 | $this->_set_headers_from_query_params($model, $query_params); |
216 | 216 | } |
217 | 217 | /** @type array $results */ |
@@ -241,7 +241,7 @@ discard block |
||
241 | 241 | $context = $this->validate_context($request->get_param('caps')); |
242 | 242 | $model = $relation->get_this_model(); |
243 | 243 | $related_model = $relation->get_other_model(); |
244 | - if (! isset($primary_model_query_params[0])) { |
|
244 | + if ( ! isset($primary_model_query_params[0])) { |
|
245 | 245 | $primary_model_query_params[0] = array(); |
246 | 246 | } |
247 | 247 | //check if they can access the 1st model object |
@@ -292,7 +292,7 @@ discard block |
||
292 | 292 | } |
293 | 293 | $query_params['default_where_conditions'] = 'none'; |
294 | 294 | $query_params['caps'] = $context; |
295 | - if (! $request->get_header('no_rest_headers')) { |
|
295 | + if ( ! $request->get_header('no_rest_headers')) { |
|
296 | 296 | $this->_set_headers_from_query_params($relation->get_other_model(), $query_params); |
297 | 297 | } |
298 | 298 | /** @type array $results */ |
@@ -344,7 +344,7 @@ discard block |
||
344 | 344 | */ |
345 | 345 | public function get_entities_from_relation($id, $relation, $request) |
346 | 346 | { |
347 | - if (! $relation->get_this_model()->has_primary_key_field()) { |
|
347 | + if ( ! $relation->get_this_model()->has_primary_key_field()) { |
|
348 | 348 | throw new \EE_Error( |
349 | 349 | sprintf( |
350 | 350 | __('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s', |
@@ -381,7 +381,7 @@ discard block |
||
381 | 381 | $this->_set_debug_info('missing caps', |
382 | 382 | Capabilities::get_missing_permissions_string($model, $query_params['caps'])); |
383 | 383 | //normally the limit to a 2-part array, where the 2nd item is the limit |
384 | - if (! isset($query_params['limit'])) { |
|
384 | + if ( ! isset($query_params['limit'])) { |
|
385 | 385 | $query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit(); |
386 | 386 | } |
387 | 387 | if (is_array($query_params['limit'])) { |
@@ -415,7 +415,7 @@ discard block |
||
415 | 415 | */ |
416 | 416 | public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null) |
417 | 417 | { |
418 | - if (! $rest_request instanceof \WP_REST_Request) { |
|
418 | + if ( ! $rest_request instanceof \WP_REST_Request) { |
|
419 | 419 | //ok so this was called in the old style, where the 3rd arg was |
420 | 420 | //$include, and the 4th arg was $context |
421 | 421 | //now setup the request just to avoid fatal errors, although we won't be able |
@@ -500,7 +500,7 @@ discard block |
||
500 | 500 | if ($field_value instanceof \DateTime) { |
501 | 501 | $timezone = $field_value->getTimezone(); |
502 | 502 | $field_value->setTimezone(new \DateTimeZone('UTC')); |
503 | - $result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json( |
|
503 | + $result[$field_name.'_gmt'] = Model_Data_Translator::prepare_field_value_for_json( |
|
504 | 504 | $field_obj, |
505 | 505 | $field_value, |
506 | 506 | $this->get_model_version_info()->requested_version() |
@@ -578,7 +578,7 @@ discard block |
||
578 | 578 | if ($model->has_primary_key_field()) { |
579 | 579 | foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) { |
580 | 580 | $related_model_part = Read::get_related_entity_name($relation_name, $relation_obj); |
581 | - $links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array( |
|
581 | + $links[\EED_Core_Rest_Api::ee_api_link_namespace.$related_model_part] = array( |
|
582 | 582 | array( |
583 | 583 | 'href' => $this->get_versioned_link_to( |
584 | 584 | \EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) |
@@ -613,13 +613,13 @@ discard block |
||
613 | 613 | $db_row = array() |
614 | 614 | ) { |
615 | 615 | //if $db_row not included, hope the entity array has what we need |
616 | - if (! $db_row) { |
|
616 | + if ( ! $db_row) { |
|
617 | 617 | $db_row = $entity_array; |
618 | 618 | } |
619 | 619 | $includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), ''); |
620 | 620 | $includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model); |
621 | 621 | //if they passed in * or didn't specify any includes, return everything |
622 | - if (! in_array('*', $includes_for_this_model) |
|
622 | + if ( ! in_array('*', $includes_for_this_model) |
|
623 | 623 | && ! empty($includes_for_this_model) |
624 | 624 | ) { |
625 | 625 | if ($model->has_primary_key_field()) { |
@@ -794,7 +794,7 @@ discard block |
||
794 | 794 | $restricted_query_params['caps'] = $this->validate_context($request->get_param('caps')); |
795 | 795 | $this->_set_debug_info('model query params', $restricted_query_params); |
796 | 796 | $model_rows = $model->get_all_wpdb_results($restricted_query_params); |
797 | - if (! empty ($model_rows)) { |
|
797 | + if ( ! empty ($model_rows)) { |
|
798 | 798 | return $this->create_entity_from_wpdb_result( |
799 | 799 | $model, |
800 | 800 | array_shift($model_rows), |
@@ -803,7 +803,7 @@ discard block |
||
803 | 803 | //ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities |
804 | 804 | $lowercase_model_name = strtolower($model->get_this_model_name()); |
805 | 805 | $model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params); |
806 | - if (! empty($model_rows_found_sans_restrictions)) { |
|
806 | + if ( ! empty($model_rows_found_sans_restrictions)) { |
|
807 | 807 | //you got shafted- it existed but we didn't want to tell you! |
808 | 808 | return new \WP_Error( |
809 | 809 | 'rest_user_cannot_read', |
@@ -838,7 +838,7 @@ discard block |
||
838 | 838 | */ |
839 | 839 | public function validate_context($context) |
840 | 840 | { |
841 | - if (! $context) { |
|
841 | + if ( ! $context) { |
|
842 | 842 | $context = \EEM_Base::caps_read; |
843 | 843 | } |
844 | 844 | $valid_contexts = \EEM_Base::valid_cap_contexts(); |
@@ -864,7 +864,7 @@ discard block |
||
864 | 864 | \EEM_Base::default_where_conditions_minimum_all, |
865 | 865 | \EEM_Base::default_where_conditions_minimum_others, |
866 | 866 | ); |
867 | - if (! $default_query_params) { |
|
867 | + if ( ! $default_query_params) { |
|
868 | 868 | $default_query_params = \EEM_Base::default_where_conditions_all; |
869 | 869 | } |
870 | 870 | if ( |
@@ -949,14 +949,14 @@ discard block |
||
949 | 949 | } |
950 | 950 | if (isset($query_parameters['limit'])) { |
951 | 951 | //limit should be either a string like '23' or '23,43', or an array with two items in it |
952 | - if (! is_array($query_parameters['limit'])) { |
|
953 | - $limit_array = explode(',', (string)$query_parameters['limit']); |
|
952 | + if ( ! is_array($query_parameters['limit'])) { |
|
953 | + $limit_array = explode(',', (string) $query_parameters['limit']); |
|
954 | 954 | } else { |
955 | 955 | $limit_array = $query_parameters['limit']; |
956 | 956 | } |
957 | 957 | $sanitized_limit = array(); |
958 | 958 | foreach ($limit_array as $key => $limit_part) { |
959 | - if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) { |
|
959 | + if ($this->_debug_mode && ( ! is_numeric($limit_part) || count($sanitized_limit) > 2)) { |
|
960 | 960 | throw new \EE_Error( |
961 | 961 | sprintf( |
962 | 962 | __('An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.', |
@@ -965,7 +965,7 @@ discard block |
||
965 | 965 | ) |
966 | 966 | ); |
967 | 967 | } |
968 | - $sanitized_limit[] = (int)$limit_part; |
|
968 | + $sanitized_limit[] = (int) $limit_part; |
|
969 | 969 | } |
970 | 970 | $model_query_params['limit'] = implode(',', $sanitized_limit); |
971 | 971 | } else { |
@@ -1053,17 +1053,17 @@ discard block |
||
1053 | 1053 | foreach ($exploded_contents as $item) { |
1054 | 1054 | $item = trim($item); |
1055 | 1055 | //if no prefix was provided, so we look for items with no "." in them |
1056 | - if (! $prefix) { |
|
1056 | + if ( ! $prefix) { |
|
1057 | 1057 | //does this item have a period? |
1058 | 1058 | if (strpos($item, '.') === false) { |
1059 | 1059 | //if not, then its what we're looking for |
1060 | 1060 | $contents_with_prefix[] = $item; |
1061 | 1061 | } |
1062 | - } else if (strpos($item, $prefix . '.') === 0) { |
|
1062 | + } else if (strpos($item, $prefix.'.') === 0) { |
|
1063 | 1063 | //this item has the prefix and a period, grab it |
1064 | 1064 | $contents_with_prefix[] = substr( |
1065 | 1065 | $item, |
1066 | - strpos($item, $prefix . '.') + strlen($prefix . '.') |
|
1066 | + strpos($item, $prefix.'.') + strlen($prefix.'.') |
|
1067 | 1067 | ); |
1068 | 1068 | } else if ($item === $prefix) { |
1069 | 1069 | //this item is JUST the prefix |
@@ -1103,9 +1103,9 @@ discard block |
||
1103 | 1103 | if ($model_name) { |
1104 | 1104 | foreach ($includes as $field_to_include) { |
1105 | 1105 | $field_to_include = trim($field_to_include); |
1106 | - if (strpos($field_to_include, $model_name . '.') === 0) { |
|
1106 | + if (strpos($field_to_include, $model_name.'.') === 0) { |
|
1107 | 1107 | //found the model name at the exact start |
1108 | - $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include); |
|
1108 | + $field_sans_model_name = str_replace($model_name.'.', '', $field_to_include); |
|
1109 | 1109 | $extracted_fields_to_include[] = $field_sans_model_name; |
1110 | 1110 | } elseif ($field_to_include == $model_name) { |
1111 | 1111 | $extracted_fields_to_include[] = '*'; |
@@ -1,5 +1,5 @@ discard block |
||
1 | 1 | <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
2 | - exit('No direct script access allowed'); |
|
2 | + exit('No direct script access allowed'); |
|
3 | 3 | } |
4 | 4 | EE_Registry::instance()->load_class('Processor_Base'); |
5 | 5 | |
@@ -16,737 +16,737 @@ discard block |
||
16 | 16 | class EE_Payment_Processor extends EE_Processor_Base |
17 | 17 | { |
18 | 18 | |
19 | - /** |
|
20 | - * @var EE_Payment_Processor $_instance |
|
21 | - * @access private |
|
22 | - */ |
|
23 | - private static $_instance; |
|
24 | - |
|
25 | - |
|
26 | - |
|
27 | - /** |
|
28 | - * @singleton method used to instantiate class object |
|
29 | - * @access public |
|
30 | - * @return EE_Payment_Processor instance |
|
31 | - */ |
|
32 | - public static function instance() |
|
33 | - { |
|
34 | - // check if class object is instantiated |
|
35 | - if ( ! self::$_instance instanceof EE_Payment_Processor) { |
|
36 | - self::$_instance = new self(); |
|
37 | - } |
|
38 | - return self::$_instance; |
|
39 | - } |
|
40 | - |
|
41 | - |
|
42 | - |
|
43 | - /** |
|
44 | - *private constructor to prevent direct creation |
|
45 | - * |
|
46 | - * @Constructor |
|
47 | - * @access private |
|
48 | - */ |
|
49 | - private function __construct() |
|
50 | - { |
|
51 | - do_action('AHEE__EE_Payment_Processor__construct'); |
|
52 | - add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
53 | - } |
|
54 | - |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
59 | - * appropriately. Saves the payment that is generated |
|
60 | - * |
|
61 | - * @param EE_Payment_Method $payment_method |
|
62 | - * @param EE_Transaction $transaction |
|
63 | - * @param float $amount if only part of the transaction is to be paid for, how much. |
|
64 | - * Leave null if payment is for the full amount owing |
|
65 | - * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
66 | - * Receive_form_submission() should have |
|
67 | - * already been called on the billing form |
|
68 | - * (ie, its inputs should have their normalized values set). |
|
69 | - * @param string $return_url string used mostly by offsite gateways to specify |
|
70 | - * where to go AFTER the offsite gateway |
|
71 | - * @param string $method like 'CART', indicates who the client who called this was |
|
72 | - * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
73 | - * @param boolean $update_txn whether or not to call |
|
74 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
75 | - * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
76 | - * @return \EE_Payment |
|
77 | - * @throws \EE_Error |
|
78 | - */ |
|
79 | - public function process_payment( |
|
80 | - EE_Payment_Method $payment_method, |
|
81 | - EE_Transaction $transaction, |
|
82 | - $amount = null, |
|
83 | - $billing_form = null, |
|
84 | - $return_url = null, |
|
85 | - $method = 'CART', |
|
86 | - $by_admin = false, |
|
87 | - $update_txn = true, |
|
88 | - $cancel_url = '' |
|
89 | - ) { |
|
90 | - if ((float)$amount < 0) { |
|
91 | - throw new EE_Error( |
|
92 | - sprintf( |
|
93 | - __( |
|
94 | - 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
95 | - 'event_espresso' |
|
96 | - ), |
|
97 | - $amount, |
|
98 | - $transaction->ID() |
|
99 | - ) |
|
100 | - ); |
|
101 | - } |
|
102 | - // verify payment method |
|
103 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method, true); |
|
104 | - // verify transaction |
|
105 | - EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
106 | - $transaction->set_payment_method_ID($payment_method->ID()); |
|
107 | - // verify payment method type |
|
108 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
109 | - $payment = $payment_method->type_obj()->process_payment( |
|
110 | - $transaction, |
|
111 | - min($amount, $transaction->remaining()),//make sure we don't overcharge |
|
112 | - $billing_form, |
|
113 | - $return_url, |
|
114 | - add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
115 | - $method, |
|
116 | - $by_admin |
|
117 | - ); |
|
118 | - // check if payment method uses an off-site gateway |
|
119 | - if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
120 | - // don't process payments for off-site gateways yet because no payment has occurred yet |
|
121 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
122 | - } |
|
123 | - return $payment; |
|
124 | - } else { |
|
125 | - EE_Error::add_error( |
|
126 | - sprintf( |
|
127 | - __('A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', 'event_espresso'), |
|
128 | - '<br/>', |
|
129 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
130 | - ), __FILE__, __FUNCTION__, __LINE__ |
|
131 | - ); |
|
132 | - return null; |
|
133 | - } |
|
134 | - } |
|
135 | - |
|
136 | - |
|
137 | - |
|
138 | - /** |
|
139 | - * @param EE_Transaction|int $transaction |
|
140 | - * @param EE_Payment_Method $payment_method |
|
141 | - * @throws EE_Error |
|
142 | - * @return string |
|
143 | - */ |
|
144 | - public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
145 | - { |
|
146 | - /** @type \EE_Transaction $transaction */ |
|
147 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
148 | - $primary_reg = $transaction->primary_registration(); |
|
149 | - if ( ! $primary_reg instanceof EE_Registration) { |
|
150 | - throw new EE_Error( |
|
151 | - sprintf( |
|
152 | - __( |
|
153 | - "Cannot get IPN URL for transaction with ID %d because it has no primary registration", |
|
154 | - "event_espresso" |
|
155 | - ), |
|
156 | - $transaction->ID() |
|
157 | - ) |
|
158 | - ); |
|
159 | - } |
|
160 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method, true); |
|
161 | - $url = add_query_arg( |
|
162 | - array( |
|
163 | - 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
164 | - 'ee_payment_method' => $payment_method->slug(), |
|
165 | - ), |
|
166 | - EE_Registry::instance()->CFG->core->txn_page_url() |
|
167 | - ); |
|
168 | - return $url; |
|
169 | - } |
|
170 | - |
|
171 | - |
|
172 | - |
|
173 | - /** |
|
174 | - * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
175 | - * we can easily find what registration the IPN is for and what payment method. |
|
176 | - * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
177 | - * If a payment is found for the IPN info, it is saved. |
|
178 | - * |
|
179 | - * @param array $_req_data eg $_REQUEST |
|
180 | - * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
181 | - * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
182 | - * @param boolean $update_txn whether or not to call |
|
183 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
184 | - * @param bool $separate_IPN_request whether the IPN uses a separate request ( true like PayPal ) |
|
185 | - * or is processed manually ( false like Mijireh ) |
|
186 | - * @throws EE_Error |
|
187 | - * @throws Exception |
|
188 | - * @return EE_Payment |
|
189 | - */ |
|
190 | - public function process_ipn( |
|
191 | - $_req_data, |
|
192 | - $transaction = null, |
|
193 | - $payment_method = null, |
|
194 | - $update_txn = true, |
|
195 | - $separate_IPN_request = true |
|
196 | - ) { |
|
197 | - EE_Registry::instance()->load_model('Change_Log'); |
|
198 | - $_req_data = $this->_remove_unusable_characters_from_array((array)$_req_data); |
|
199 | - EE_Processor_Base::set_IPN($separate_IPN_request); |
|
200 | - $obj_for_log = null; |
|
201 | - if ($transaction instanceof EE_Transaction) { |
|
202 | - $obj_for_log = $transaction; |
|
203 | - if ($payment_method instanceof EE_Payment_Method) { |
|
204 | - $obj_for_log = EEM_Payment::instance()->get_one( |
|
205 | - array( |
|
206 | - array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
207 | - 'order_by' => array('PAY_timestamp' => 'desc'), |
|
208 | - ) |
|
209 | - ); |
|
210 | - } |
|
211 | - } else if ($payment_method instanceof EE_Payment) { |
|
212 | - $obj_for_log = $payment_method; |
|
213 | - } |
|
214 | - $log = EEM_Change_Log::instance()->log( |
|
215 | - EEM_Change_Log::type_gateway, |
|
216 | - array('IPN data received' => $_req_data), |
|
217 | - $obj_for_log |
|
218 | - ); |
|
219 | - try { |
|
220 | - /** |
|
221 | - * @var EE_Payment $payment |
|
222 | - */ |
|
223 | - $payment = null; |
|
224 | - if ($transaction && $payment_method) { |
|
225 | - /** @type EE_Transaction $transaction */ |
|
226 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
227 | - /** @type EE_Payment_Method $payment_method */ |
|
228 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
229 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
230 | - try { |
|
231 | - $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
232 | - $log->set_object($payment); |
|
233 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
234 | - EEM_Change_Log::instance()->log( |
|
235 | - EEM_Change_Log::type_gateway, |
|
236 | - array( |
|
237 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
238 | - 'current_url' => EEH_URL::current_url(), |
|
239 | - 'payment' => $e->getPaymentProperties(), |
|
240 | - 'IPN_data' => $e->getIpnData(), |
|
241 | - ), |
|
242 | - $obj_for_log |
|
243 | - ); |
|
244 | - return $e->getPayment(); |
|
245 | - } |
|
246 | - } else { |
|
247 | - // not a payment |
|
248 | - EE_Error::add_error( |
|
249 | - sprintf( |
|
250 | - __('A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', 'event_espresso'), |
|
251 | - '<br/>', |
|
252 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
253 | - ), |
|
254 | - __FILE__, __FUNCTION__, __LINE__ |
|
255 | - ); |
|
256 | - } |
|
257 | - } else { |
|
258 | - //that's actually pretty ok. The IPN just wasn't able |
|
259 | - //to identify which transaction or payment method this was for |
|
260 | - // give all active payment methods a chance to claim it |
|
261 | - $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
262 | - foreach ($active_payment_methods as $active_payment_method) { |
|
263 | - try { |
|
264 | - $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
265 | - $payment_method = $active_payment_method; |
|
266 | - EEM_Change_Log::instance()->log( |
|
267 | - EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment |
|
268 | - ); |
|
269 | - break; |
|
270 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
271 | - EEM_Change_Log::instance()->log( |
|
272 | - EEM_Change_Log::type_gateway, |
|
273 | - array( |
|
274 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
275 | - 'current_url' => EEH_URL::current_url(), |
|
276 | - 'payment' => $e->getPaymentProperties(), |
|
277 | - 'IPN_data' => $e->getIpnData(), |
|
278 | - ), |
|
279 | - $obj_for_log |
|
280 | - ); |
|
281 | - return $e->getPayment(); |
|
282 | - } catch (EE_Error $e) { |
|
283 | - //that's fine- it apparently couldn't handle the IPN |
|
284 | - } |
|
285 | - } |
|
286 | - } |
|
287 | - // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
288 | - if ($payment instanceof EE_Payment) { |
|
289 | - $payment->save(); |
|
290 | - // update the TXN |
|
291 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn, $separate_IPN_request); |
|
292 | - } else { |
|
293 | - //we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
294 | - if ($payment_method) { |
|
295 | - EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment_method); |
|
296 | - } elseif ($transaction) { |
|
297 | - EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $transaction); |
|
298 | - } |
|
299 | - } |
|
300 | - return $payment; |
|
301 | - } catch (EE_Error $e) { |
|
302 | - do_action( |
|
303 | - 'AHEE__log', __FILE__, __FUNCTION__, sprintf( |
|
304 | - __('Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', 'event_espresso'), |
|
305 | - print_r($transaction, true), |
|
306 | - print_r($_req_data, true), |
|
307 | - $e->getMessage() |
|
308 | - ) |
|
309 | - ); |
|
310 | - throw $e; |
|
311 | - } |
|
312 | - } |
|
313 | - |
|
314 | - |
|
315 | - |
|
316 | - /** |
|
317 | - * Removes any non-printable illegal characters from the input, |
|
318 | - * which might cause a raucous when trying to insert into the database |
|
319 | - * |
|
320 | - * @param array $request_data |
|
321 | - * @return array |
|
322 | - */ |
|
323 | - protected function _remove_unusable_characters_from_array(array $request_data) |
|
324 | - { |
|
325 | - $return_data = array(); |
|
326 | - foreach ($request_data as $key => $value) { |
|
327 | - $return_data[$this->_remove_unusable_characters($key)] = $this->_remove_unusable_characters($value); |
|
328 | - } |
|
329 | - return $return_data; |
|
330 | - } |
|
331 | - |
|
332 | - |
|
333 | - |
|
334 | - /** |
|
335 | - * Removes any non-printable illegal characters from the input, |
|
336 | - * which might cause a raucous when trying to insert into the database |
|
337 | - * |
|
338 | - * @param string $request_data |
|
339 | - * @return string |
|
340 | - */ |
|
341 | - protected function _remove_unusable_characters($request_data) |
|
342 | - { |
|
343 | - return preg_replace('/[^[:print:]]/', '', $request_data); |
|
344 | - } |
|
345 | - |
|
346 | - |
|
347 | - |
|
348 | - /** |
|
349 | - * Should be called just before displaying the payment attempt results to the user, |
|
350 | - * when the payment attempt has finished. Some payment methods may have special |
|
351 | - * logic to perform here. For example, if process_payment() happens on a special request |
|
352 | - * and then the user is redirected to a page that displays the payment's status, this |
|
353 | - * should be called while loading the page that displays the payment's status. If the user is |
|
354 | - * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
355 | - * provider. |
|
356 | - * |
|
357 | - * @param EE_Transaction|int $transaction |
|
358 | - * @param bool $update_txn whether or not to call |
|
359 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
360 | - * @throws \EE_Error |
|
361 | - * @return EE_Payment |
|
362 | - * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
363 | - * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
364 | - */ |
|
365 | - public function finalize_payment_for($transaction, $update_txn = true) |
|
366 | - { |
|
367 | - /** @var $transaction EE_Transaction */ |
|
368 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
369 | - $last_payment_method = $transaction->payment_method(); |
|
370 | - if ($last_payment_method instanceof EE_Payment_Method) { |
|
371 | - $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
372 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
373 | - return $payment; |
|
374 | - } else { |
|
375 | - return null; |
|
376 | - } |
|
377 | - } |
|
378 | - |
|
379 | - |
|
380 | - |
|
381 | - /** |
|
382 | - * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
383 | - * |
|
384 | - * @param EE_Payment_Method $payment_method |
|
385 | - * @param EE_Payment $payment_to_refund |
|
386 | - * @param array $refund_info |
|
387 | - * @return EE_Payment |
|
388 | - * @throws \EE_Error |
|
389 | - */ |
|
390 | - public function process_refund( |
|
391 | - EE_Payment_Method $payment_method, |
|
392 | - EE_Payment $payment_to_refund, |
|
393 | - $refund_info = array() |
|
394 | - ) { |
|
395 | - if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
396 | - $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
397 | - $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
398 | - } |
|
399 | - return $payment_to_refund; |
|
400 | - } |
|
401 | - |
|
402 | - |
|
403 | - |
|
404 | - /** |
|
405 | - * This should be called each time there may have been an update to a |
|
406 | - * payment on a transaction (ie, we asked for a payment to process a |
|
407 | - * payment for a transaction, or we told a payment method about an IPN, or |
|
408 | - * we told a payment method to |
|
409 | - * "finalize_payment_for" (a transaction), or we told a payment method to |
|
410 | - * process a refund. This should handle firing the correct hooks to |
|
411 | - * indicate |
|
412 | - * what exactly happened and updating the transaction appropriately). This |
|
413 | - * could be integrated directly into EE_Transaction upon save, but we want |
|
414 | - * this logic to be separate from 'normal' plain-jane saving and updating |
|
415 | - * of transactions and payments, and to be tied to payment processing. |
|
416 | - * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
417 | - * of previous code to decide whether or not to save (because the payment passed into |
|
418 | - * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
419 | - * in which case we only want that payment object for some temporary usage during this request, |
|
420 | - * but we don't want it to be saved). |
|
421 | - * |
|
422 | - * @param EE_Transaction|int $transaction |
|
423 | - * @param EE_Payment $payment |
|
424 | - * @param boolean $update_txn |
|
425 | - * whether or not to call |
|
426 | - * EE_Transaction_Processor:: |
|
427 | - * update_transaction_and_registrations_after_checkout_or_payment() |
|
428 | - * (you can save 1 DB query if you know you're going |
|
429 | - * to save it later instead) |
|
430 | - * @param bool $IPN |
|
431 | - * if processing IPNs or other similar payment |
|
432 | - * related activities that occur in alternate |
|
433 | - * requests than the main one that is processing the |
|
434 | - * TXN, then set this to true to check whether the |
|
435 | - * TXN is locked before updating |
|
436 | - * @throws \EE_Error |
|
437 | - */ |
|
438 | - public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
439 | - { |
|
440 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
441 | - /** @type EE_Transaction $transaction */ |
|
442 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
443 | - // can we freely update the TXN at this moment? |
|
444 | - if ($IPN && $transaction->is_locked()) { |
|
445 | - // don't update the transaction at this exact moment |
|
446 | - // because the TXN is active in another request |
|
447 | - EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
448 | - time(), |
|
449 | - $transaction->ID(), |
|
450 | - $payment->ID() |
|
451 | - ); |
|
452 | - } else { |
|
453 | - // verify payment and that it has been saved |
|
454 | - if ($payment instanceof EE_Payment && $payment->ID()) { |
|
455 | - if ( |
|
456 | - $payment->payment_method() instanceof EE_Payment_Method |
|
457 | - && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
458 | - ) { |
|
459 | - $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
460 | - // update TXN registrations with payment info |
|
461 | - $this->process_registration_payments($transaction, $payment); |
|
462 | - } |
|
463 | - $do_action = $payment->just_approved() |
|
464 | - ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
465 | - : $do_action; |
|
466 | - } else { |
|
467 | - // send out notifications |
|
468 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
469 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
470 | - } |
|
471 | - if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
472 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
473 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
474 | - // set new value for total paid |
|
475 | - $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
476 | - // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
477 | - if ($update_txn) { |
|
478 | - $this->_post_payment_processing($transaction, $payment, $IPN); |
|
479 | - } |
|
480 | - } |
|
481 | - // granular hook for others to use. |
|
482 | - do_action($do_action, $transaction, $payment); |
|
483 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
484 | - //global hook for others to use. |
|
485 | - do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
486 | - } |
|
487 | - } |
|
488 | - |
|
489 | - |
|
490 | - |
|
491 | - /** |
|
492 | - * update registrations REG_paid field after successful payment and link registrations with payment |
|
493 | - * |
|
494 | - * @param EE_Transaction $transaction |
|
495 | - * @param EE_Payment $payment |
|
496 | - * @param EE_Registration[] $registrations |
|
497 | - * @throws \EE_Error |
|
498 | - */ |
|
499 | - public function process_registration_payments( |
|
500 | - EE_Transaction $transaction, |
|
501 | - EE_Payment $payment, |
|
502 | - $registrations = array() |
|
503 | - ) { |
|
504 | - // only process if payment was successful |
|
505 | - if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
506 | - return; |
|
507 | - } |
|
508 | - //EEM_Registration::instance()->show_next_x_db_queries(); |
|
509 | - if (empty($registrations)) { |
|
510 | - // find registrations with monies owing that can receive a payment |
|
511 | - $registrations = $transaction->registrations( |
|
512 | - array( |
|
513 | - array( |
|
514 | - // only these reg statuses can receive payments |
|
515 | - 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
516 | - 'REG_final_price' => array('!=', 0), |
|
517 | - 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
518 | - ), |
|
519 | - ) |
|
520 | - ); |
|
521 | - } |
|
522 | - // still nothing ??!?? |
|
523 | - if (empty($registrations)) { |
|
524 | - return; |
|
525 | - } |
|
526 | - // todo: break out the following logic into a separate strategy class |
|
527 | - // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
528 | - // todo: which would apply payments using the capitalist "first come first paid" approach |
|
529 | - // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
530 | - // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
531 | - // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
532 | - $refund = $payment->is_a_refund(); |
|
533 | - // how much is available to apply to registrations? |
|
534 | - $available_payment_amount = abs($payment->amount()); |
|
535 | - foreach ($registrations as $registration) { |
|
536 | - if ($registration instanceof EE_Registration) { |
|
537 | - // nothing left? |
|
538 | - if ($available_payment_amount <= 0) { |
|
539 | - break; |
|
540 | - } |
|
541 | - if ($refund) { |
|
542 | - $available_payment_amount = $this->process_registration_refund($registration, $payment, $available_payment_amount); |
|
543 | - } else { |
|
544 | - $available_payment_amount = $this->process_registration_payment($registration, $payment, $available_payment_amount); |
|
545 | - } |
|
546 | - } |
|
547 | - } |
|
548 | - if ($available_payment_amount > 0 && apply_filters('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', false)) { |
|
549 | - EE_Error::add_attention( |
|
550 | - sprintf( |
|
551 | - __('A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
552 | - 'event_espresso'), |
|
553 | - EEH_Template::format_currency($available_payment_amount), |
|
554 | - implode(', ', array_keys($registrations)), |
|
555 | - '<br/>', |
|
556 | - EEH_Template::format_currency($payment->amount()) |
|
557 | - ), |
|
558 | - __FILE__, __FUNCTION__, __LINE__ |
|
559 | - ); |
|
560 | - } |
|
561 | - } |
|
562 | - |
|
563 | - |
|
564 | - |
|
565 | - /** |
|
566 | - * update registration REG_paid field after successful payment and link registration with payment |
|
567 | - * |
|
568 | - * @param EE_Registration $registration |
|
569 | - * @param EE_Payment $payment |
|
570 | - * @param float $available_payment_amount |
|
571 | - * @return float |
|
572 | - * @throws \EE_Error |
|
573 | - */ |
|
574 | - public function process_registration_payment( |
|
575 | - EE_Registration $registration, |
|
576 | - EE_Payment $payment, |
|
577 | - $available_payment_amount = 0.00 |
|
578 | - ) { |
|
579 | - $owing = $registration->final_price() - $registration->paid(); |
|
580 | - if ($owing > 0) { |
|
581 | - // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
582 | - $payment_amount = min($available_payment_amount, $owing); |
|
583 | - // update $available_payment_amount |
|
584 | - $available_payment_amount -= $payment_amount; |
|
585 | - //calculate and set new REG_paid |
|
586 | - $registration->set_paid($registration->paid() + $payment_amount); |
|
587 | - // now save it |
|
588 | - $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
589 | - } |
|
590 | - return $available_payment_amount; |
|
591 | - } |
|
592 | - |
|
593 | - |
|
594 | - |
|
595 | - /** |
|
596 | - * update registration REG_paid field after successful payment and link registration with payment |
|
597 | - * |
|
598 | - * @param EE_Registration $registration |
|
599 | - * @param EE_Payment $payment |
|
600 | - * @param float $payment_amount |
|
601 | - * @return void |
|
602 | - * @throws \EE_Error |
|
603 | - */ |
|
604 | - protected function _apply_registration_payment( |
|
605 | - EE_Registration $registration, |
|
606 | - EE_Payment $payment, |
|
607 | - $payment_amount = 0.00 |
|
608 | - ) { |
|
609 | - // find any existing reg payment records for this registration and payment |
|
610 | - $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
611 | - array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
612 | - ); |
|
613 | - // if existing registration payment exists |
|
614 | - if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
615 | - // then update that record |
|
616 | - $existing_reg_payment->set_amount($payment_amount); |
|
617 | - $existing_reg_payment->save(); |
|
618 | - } else { |
|
619 | - // or add new relation between registration and payment and set amount |
|
620 | - $registration->_add_relation_to($payment, 'Payment', array('RPY_amount' => $payment_amount)); |
|
621 | - // make it stick |
|
622 | - $registration->save(); |
|
623 | - } |
|
624 | - } |
|
625 | - |
|
626 | - |
|
627 | - |
|
628 | - /** |
|
629 | - * update registration REG_paid field after refund and link registration with payment |
|
630 | - * |
|
631 | - * @param EE_Registration $registration |
|
632 | - * @param EE_Payment $payment |
|
633 | - * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
634 | - * @return float |
|
635 | - * @throws \EE_Error |
|
636 | - */ |
|
637 | - public function process_registration_refund( |
|
638 | - EE_Registration $registration, |
|
639 | - EE_Payment $payment, |
|
640 | - $available_refund_amount = 0.00 |
|
641 | - ) { |
|
642 | - //EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
643 | - if ($registration->paid() > 0) { |
|
644 | - // ensure $available_refund_amount is NOT negative |
|
645 | - $available_refund_amount = (float)abs($available_refund_amount); |
|
646 | - // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
647 | - $refund_amount = min($available_refund_amount, (float)$registration->paid()); |
|
648 | - // update $available_payment_amount |
|
649 | - $available_refund_amount -= $refund_amount; |
|
650 | - //calculate and set new REG_paid |
|
651 | - $registration->set_paid($registration->paid() - $refund_amount); |
|
652 | - // convert payment amount back to a negative value for storage in the db |
|
653 | - $refund_amount = (float)abs($refund_amount) * -1; |
|
654 | - // now save it |
|
655 | - $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
656 | - } |
|
657 | - return $available_refund_amount; |
|
658 | - } |
|
659 | - |
|
660 | - |
|
661 | - |
|
662 | - /** |
|
663 | - * Process payments and transaction after payment process completed. |
|
664 | - * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
665 | - * if this request happens to be processing an IPN, |
|
666 | - * then we will also set the Payment Options Reg Step to completed, |
|
667 | - * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
668 | - * |
|
669 | - * @param EE_Transaction $transaction |
|
670 | - * @param EE_Payment $payment |
|
671 | - * @param bool $IPN |
|
672 | - * @throws \EE_Error |
|
673 | - */ |
|
674 | - protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
675 | - { |
|
676 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
677 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
678 | - // is the Payment Options Reg Step completed ? |
|
679 | - $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
680 | - // if the Payment Options Reg Step is completed... |
|
681 | - $revisit = $payment_options_step_completed === true ? true : false; |
|
682 | - // then this is kinda sorta a revisit with regards to payments at least |
|
683 | - $transaction_processor->set_revisit($revisit); |
|
684 | - // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
685 | - if ( |
|
686 | - $IPN |
|
687 | - && $payment_options_step_completed !== true |
|
688 | - && ($payment->is_approved() || $payment->is_pending()) |
|
689 | - ) { |
|
690 | - $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
691 | - 'payment_options' |
|
692 | - ); |
|
693 | - } |
|
694 | - // maybe update status, but don't save transaction just yet |
|
695 | - $transaction->update_status_based_on_total_paid(false); |
|
696 | - // check if 'finalize_registration' step has been completed... |
|
697 | - $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
698 | - // if this is an IPN and the final step has not been initiated |
|
699 | - if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
700 | - // and if it hasn't already been set as being started... |
|
701 | - $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
702 | - } |
|
703 | - $transaction->save(); |
|
704 | - // because the above will return false if the final step was not fully completed, we need to check again... |
|
705 | - if ($IPN && $finalized !== false) { |
|
706 | - // and if we are all good to go, then send out notifications |
|
707 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
708 | - //ok, now process the transaction according to the payment |
|
709 | - $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($transaction, $payment); |
|
710 | - } |
|
711 | - // DEBUG LOG |
|
712 | - $payment_method = $payment->payment_method(); |
|
713 | - if ($payment_method instanceof EE_Payment_Method) { |
|
714 | - $payment_method_type_obj = $payment_method->type_obj(); |
|
715 | - if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
716 | - $gateway = $payment_method_type_obj->get_gateway(); |
|
717 | - if ($gateway instanceof EE_Gateway) { |
|
718 | - $gateway->log( |
|
719 | - array( |
|
720 | - 'message' => __('Post Payment Transaction Details', 'event_espresso'), |
|
721 | - 'transaction' => $transaction->model_field_array(), |
|
722 | - 'finalized' => $finalized, |
|
723 | - 'IPN' => $IPN, |
|
724 | - 'deliver_notifications' => has_filter( |
|
725 | - 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
726 | - ), |
|
727 | - ), |
|
728 | - $payment |
|
729 | - ); |
|
730 | - } |
|
731 | - } |
|
732 | - } |
|
733 | - } |
|
734 | - |
|
735 | - |
|
736 | - |
|
737 | - /** |
|
738 | - * Force posts to PayPal to use TLS v1.2. See: |
|
739 | - * https://core.trac.wordpress.org/ticket/36320 |
|
740 | - * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
741 | - * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
742 | - * This will affect paypal standard, pro, express, and payflow. |
|
743 | - */ |
|
744 | - public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
745 | - { |
|
746 | - if (strstr($url, 'https://') && strstr($url, '.paypal.com')) { |
|
747 | - //Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
748 | - //instead of the constant because it might not be defined |
|
749 | - curl_setopt($handle, CURLOPT_SSLVERSION, 1); |
|
750 | - } |
|
751 | - } |
|
19 | + /** |
|
20 | + * @var EE_Payment_Processor $_instance |
|
21 | + * @access private |
|
22 | + */ |
|
23 | + private static $_instance; |
|
24 | + |
|
25 | + |
|
26 | + |
|
27 | + /** |
|
28 | + * @singleton method used to instantiate class object |
|
29 | + * @access public |
|
30 | + * @return EE_Payment_Processor instance |
|
31 | + */ |
|
32 | + public static function instance() |
|
33 | + { |
|
34 | + // check if class object is instantiated |
|
35 | + if ( ! self::$_instance instanceof EE_Payment_Processor) { |
|
36 | + self::$_instance = new self(); |
|
37 | + } |
|
38 | + return self::$_instance; |
|
39 | + } |
|
40 | + |
|
41 | + |
|
42 | + |
|
43 | + /** |
|
44 | + *private constructor to prevent direct creation |
|
45 | + * |
|
46 | + * @Constructor |
|
47 | + * @access private |
|
48 | + */ |
|
49 | + private function __construct() |
|
50 | + { |
|
51 | + do_action('AHEE__EE_Payment_Processor__construct'); |
|
52 | + add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
53 | + } |
|
54 | + |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
59 | + * appropriately. Saves the payment that is generated |
|
60 | + * |
|
61 | + * @param EE_Payment_Method $payment_method |
|
62 | + * @param EE_Transaction $transaction |
|
63 | + * @param float $amount if only part of the transaction is to be paid for, how much. |
|
64 | + * Leave null if payment is for the full amount owing |
|
65 | + * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
66 | + * Receive_form_submission() should have |
|
67 | + * already been called on the billing form |
|
68 | + * (ie, its inputs should have their normalized values set). |
|
69 | + * @param string $return_url string used mostly by offsite gateways to specify |
|
70 | + * where to go AFTER the offsite gateway |
|
71 | + * @param string $method like 'CART', indicates who the client who called this was |
|
72 | + * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
73 | + * @param boolean $update_txn whether or not to call |
|
74 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
75 | + * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
76 | + * @return \EE_Payment |
|
77 | + * @throws \EE_Error |
|
78 | + */ |
|
79 | + public function process_payment( |
|
80 | + EE_Payment_Method $payment_method, |
|
81 | + EE_Transaction $transaction, |
|
82 | + $amount = null, |
|
83 | + $billing_form = null, |
|
84 | + $return_url = null, |
|
85 | + $method = 'CART', |
|
86 | + $by_admin = false, |
|
87 | + $update_txn = true, |
|
88 | + $cancel_url = '' |
|
89 | + ) { |
|
90 | + if ((float)$amount < 0) { |
|
91 | + throw new EE_Error( |
|
92 | + sprintf( |
|
93 | + __( |
|
94 | + 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
95 | + 'event_espresso' |
|
96 | + ), |
|
97 | + $amount, |
|
98 | + $transaction->ID() |
|
99 | + ) |
|
100 | + ); |
|
101 | + } |
|
102 | + // verify payment method |
|
103 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method, true); |
|
104 | + // verify transaction |
|
105 | + EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
106 | + $transaction->set_payment_method_ID($payment_method->ID()); |
|
107 | + // verify payment method type |
|
108 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
109 | + $payment = $payment_method->type_obj()->process_payment( |
|
110 | + $transaction, |
|
111 | + min($amount, $transaction->remaining()),//make sure we don't overcharge |
|
112 | + $billing_form, |
|
113 | + $return_url, |
|
114 | + add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
115 | + $method, |
|
116 | + $by_admin |
|
117 | + ); |
|
118 | + // check if payment method uses an off-site gateway |
|
119 | + if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
120 | + // don't process payments for off-site gateways yet because no payment has occurred yet |
|
121 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
122 | + } |
|
123 | + return $payment; |
|
124 | + } else { |
|
125 | + EE_Error::add_error( |
|
126 | + sprintf( |
|
127 | + __('A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', 'event_espresso'), |
|
128 | + '<br/>', |
|
129 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
130 | + ), __FILE__, __FUNCTION__, __LINE__ |
|
131 | + ); |
|
132 | + return null; |
|
133 | + } |
|
134 | + } |
|
135 | + |
|
136 | + |
|
137 | + |
|
138 | + /** |
|
139 | + * @param EE_Transaction|int $transaction |
|
140 | + * @param EE_Payment_Method $payment_method |
|
141 | + * @throws EE_Error |
|
142 | + * @return string |
|
143 | + */ |
|
144 | + public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
145 | + { |
|
146 | + /** @type \EE_Transaction $transaction */ |
|
147 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
148 | + $primary_reg = $transaction->primary_registration(); |
|
149 | + if ( ! $primary_reg instanceof EE_Registration) { |
|
150 | + throw new EE_Error( |
|
151 | + sprintf( |
|
152 | + __( |
|
153 | + "Cannot get IPN URL for transaction with ID %d because it has no primary registration", |
|
154 | + "event_espresso" |
|
155 | + ), |
|
156 | + $transaction->ID() |
|
157 | + ) |
|
158 | + ); |
|
159 | + } |
|
160 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method, true); |
|
161 | + $url = add_query_arg( |
|
162 | + array( |
|
163 | + 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
164 | + 'ee_payment_method' => $payment_method->slug(), |
|
165 | + ), |
|
166 | + EE_Registry::instance()->CFG->core->txn_page_url() |
|
167 | + ); |
|
168 | + return $url; |
|
169 | + } |
|
170 | + |
|
171 | + |
|
172 | + |
|
173 | + /** |
|
174 | + * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
175 | + * we can easily find what registration the IPN is for and what payment method. |
|
176 | + * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
177 | + * If a payment is found for the IPN info, it is saved. |
|
178 | + * |
|
179 | + * @param array $_req_data eg $_REQUEST |
|
180 | + * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
181 | + * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
182 | + * @param boolean $update_txn whether or not to call |
|
183 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
184 | + * @param bool $separate_IPN_request whether the IPN uses a separate request ( true like PayPal ) |
|
185 | + * or is processed manually ( false like Mijireh ) |
|
186 | + * @throws EE_Error |
|
187 | + * @throws Exception |
|
188 | + * @return EE_Payment |
|
189 | + */ |
|
190 | + public function process_ipn( |
|
191 | + $_req_data, |
|
192 | + $transaction = null, |
|
193 | + $payment_method = null, |
|
194 | + $update_txn = true, |
|
195 | + $separate_IPN_request = true |
|
196 | + ) { |
|
197 | + EE_Registry::instance()->load_model('Change_Log'); |
|
198 | + $_req_data = $this->_remove_unusable_characters_from_array((array)$_req_data); |
|
199 | + EE_Processor_Base::set_IPN($separate_IPN_request); |
|
200 | + $obj_for_log = null; |
|
201 | + if ($transaction instanceof EE_Transaction) { |
|
202 | + $obj_for_log = $transaction; |
|
203 | + if ($payment_method instanceof EE_Payment_Method) { |
|
204 | + $obj_for_log = EEM_Payment::instance()->get_one( |
|
205 | + array( |
|
206 | + array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
207 | + 'order_by' => array('PAY_timestamp' => 'desc'), |
|
208 | + ) |
|
209 | + ); |
|
210 | + } |
|
211 | + } else if ($payment_method instanceof EE_Payment) { |
|
212 | + $obj_for_log = $payment_method; |
|
213 | + } |
|
214 | + $log = EEM_Change_Log::instance()->log( |
|
215 | + EEM_Change_Log::type_gateway, |
|
216 | + array('IPN data received' => $_req_data), |
|
217 | + $obj_for_log |
|
218 | + ); |
|
219 | + try { |
|
220 | + /** |
|
221 | + * @var EE_Payment $payment |
|
222 | + */ |
|
223 | + $payment = null; |
|
224 | + if ($transaction && $payment_method) { |
|
225 | + /** @type EE_Transaction $transaction */ |
|
226 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
227 | + /** @type EE_Payment_Method $payment_method */ |
|
228 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
229 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
230 | + try { |
|
231 | + $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
232 | + $log->set_object($payment); |
|
233 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
234 | + EEM_Change_Log::instance()->log( |
|
235 | + EEM_Change_Log::type_gateway, |
|
236 | + array( |
|
237 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
238 | + 'current_url' => EEH_URL::current_url(), |
|
239 | + 'payment' => $e->getPaymentProperties(), |
|
240 | + 'IPN_data' => $e->getIpnData(), |
|
241 | + ), |
|
242 | + $obj_for_log |
|
243 | + ); |
|
244 | + return $e->getPayment(); |
|
245 | + } |
|
246 | + } else { |
|
247 | + // not a payment |
|
248 | + EE_Error::add_error( |
|
249 | + sprintf( |
|
250 | + __('A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', 'event_espresso'), |
|
251 | + '<br/>', |
|
252 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
253 | + ), |
|
254 | + __FILE__, __FUNCTION__, __LINE__ |
|
255 | + ); |
|
256 | + } |
|
257 | + } else { |
|
258 | + //that's actually pretty ok. The IPN just wasn't able |
|
259 | + //to identify which transaction or payment method this was for |
|
260 | + // give all active payment methods a chance to claim it |
|
261 | + $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
262 | + foreach ($active_payment_methods as $active_payment_method) { |
|
263 | + try { |
|
264 | + $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
265 | + $payment_method = $active_payment_method; |
|
266 | + EEM_Change_Log::instance()->log( |
|
267 | + EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment |
|
268 | + ); |
|
269 | + break; |
|
270 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
271 | + EEM_Change_Log::instance()->log( |
|
272 | + EEM_Change_Log::type_gateway, |
|
273 | + array( |
|
274 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
275 | + 'current_url' => EEH_URL::current_url(), |
|
276 | + 'payment' => $e->getPaymentProperties(), |
|
277 | + 'IPN_data' => $e->getIpnData(), |
|
278 | + ), |
|
279 | + $obj_for_log |
|
280 | + ); |
|
281 | + return $e->getPayment(); |
|
282 | + } catch (EE_Error $e) { |
|
283 | + //that's fine- it apparently couldn't handle the IPN |
|
284 | + } |
|
285 | + } |
|
286 | + } |
|
287 | + // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
288 | + if ($payment instanceof EE_Payment) { |
|
289 | + $payment->save(); |
|
290 | + // update the TXN |
|
291 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn, $separate_IPN_request); |
|
292 | + } else { |
|
293 | + //we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
294 | + if ($payment_method) { |
|
295 | + EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment_method); |
|
296 | + } elseif ($transaction) { |
|
297 | + EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $transaction); |
|
298 | + } |
|
299 | + } |
|
300 | + return $payment; |
|
301 | + } catch (EE_Error $e) { |
|
302 | + do_action( |
|
303 | + 'AHEE__log', __FILE__, __FUNCTION__, sprintf( |
|
304 | + __('Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', 'event_espresso'), |
|
305 | + print_r($transaction, true), |
|
306 | + print_r($_req_data, true), |
|
307 | + $e->getMessage() |
|
308 | + ) |
|
309 | + ); |
|
310 | + throw $e; |
|
311 | + } |
|
312 | + } |
|
313 | + |
|
314 | + |
|
315 | + |
|
316 | + /** |
|
317 | + * Removes any non-printable illegal characters from the input, |
|
318 | + * which might cause a raucous when trying to insert into the database |
|
319 | + * |
|
320 | + * @param array $request_data |
|
321 | + * @return array |
|
322 | + */ |
|
323 | + protected function _remove_unusable_characters_from_array(array $request_data) |
|
324 | + { |
|
325 | + $return_data = array(); |
|
326 | + foreach ($request_data as $key => $value) { |
|
327 | + $return_data[$this->_remove_unusable_characters($key)] = $this->_remove_unusable_characters($value); |
|
328 | + } |
|
329 | + return $return_data; |
|
330 | + } |
|
331 | + |
|
332 | + |
|
333 | + |
|
334 | + /** |
|
335 | + * Removes any non-printable illegal characters from the input, |
|
336 | + * which might cause a raucous when trying to insert into the database |
|
337 | + * |
|
338 | + * @param string $request_data |
|
339 | + * @return string |
|
340 | + */ |
|
341 | + protected function _remove_unusable_characters($request_data) |
|
342 | + { |
|
343 | + return preg_replace('/[^[:print:]]/', '', $request_data); |
|
344 | + } |
|
345 | + |
|
346 | + |
|
347 | + |
|
348 | + /** |
|
349 | + * Should be called just before displaying the payment attempt results to the user, |
|
350 | + * when the payment attempt has finished. Some payment methods may have special |
|
351 | + * logic to perform here. For example, if process_payment() happens on a special request |
|
352 | + * and then the user is redirected to a page that displays the payment's status, this |
|
353 | + * should be called while loading the page that displays the payment's status. If the user is |
|
354 | + * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
355 | + * provider. |
|
356 | + * |
|
357 | + * @param EE_Transaction|int $transaction |
|
358 | + * @param bool $update_txn whether or not to call |
|
359 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
360 | + * @throws \EE_Error |
|
361 | + * @return EE_Payment |
|
362 | + * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
363 | + * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
364 | + */ |
|
365 | + public function finalize_payment_for($transaction, $update_txn = true) |
|
366 | + { |
|
367 | + /** @var $transaction EE_Transaction */ |
|
368 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
369 | + $last_payment_method = $transaction->payment_method(); |
|
370 | + if ($last_payment_method instanceof EE_Payment_Method) { |
|
371 | + $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
372 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
373 | + return $payment; |
|
374 | + } else { |
|
375 | + return null; |
|
376 | + } |
|
377 | + } |
|
378 | + |
|
379 | + |
|
380 | + |
|
381 | + /** |
|
382 | + * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
383 | + * |
|
384 | + * @param EE_Payment_Method $payment_method |
|
385 | + * @param EE_Payment $payment_to_refund |
|
386 | + * @param array $refund_info |
|
387 | + * @return EE_Payment |
|
388 | + * @throws \EE_Error |
|
389 | + */ |
|
390 | + public function process_refund( |
|
391 | + EE_Payment_Method $payment_method, |
|
392 | + EE_Payment $payment_to_refund, |
|
393 | + $refund_info = array() |
|
394 | + ) { |
|
395 | + if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
396 | + $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
397 | + $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
398 | + } |
|
399 | + return $payment_to_refund; |
|
400 | + } |
|
401 | + |
|
402 | + |
|
403 | + |
|
404 | + /** |
|
405 | + * This should be called each time there may have been an update to a |
|
406 | + * payment on a transaction (ie, we asked for a payment to process a |
|
407 | + * payment for a transaction, or we told a payment method about an IPN, or |
|
408 | + * we told a payment method to |
|
409 | + * "finalize_payment_for" (a transaction), or we told a payment method to |
|
410 | + * process a refund. This should handle firing the correct hooks to |
|
411 | + * indicate |
|
412 | + * what exactly happened and updating the transaction appropriately). This |
|
413 | + * could be integrated directly into EE_Transaction upon save, but we want |
|
414 | + * this logic to be separate from 'normal' plain-jane saving and updating |
|
415 | + * of transactions and payments, and to be tied to payment processing. |
|
416 | + * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
417 | + * of previous code to decide whether or not to save (because the payment passed into |
|
418 | + * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
419 | + * in which case we only want that payment object for some temporary usage during this request, |
|
420 | + * but we don't want it to be saved). |
|
421 | + * |
|
422 | + * @param EE_Transaction|int $transaction |
|
423 | + * @param EE_Payment $payment |
|
424 | + * @param boolean $update_txn |
|
425 | + * whether or not to call |
|
426 | + * EE_Transaction_Processor:: |
|
427 | + * update_transaction_and_registrations_after_checkout_or_payment() |
|
428 | + * (you can save 1 DB query if you know you're going |
|
429 | + * to save it later instead) |
|
430 | + * @param bool $IPN |
|
431 | + * if processing IPNs or other similar payment |
|
432 | + * related activities that occur in alternate |
|
433 | + * requests than the main one that is processing the |
|
434 | + * TXN, then set this to true to check whether the |
|
435 | + * TXN is locked before updating |
|
436 | + * @throws \EE_Error |
|
437 | + */ |
|
438 | + public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
439 | + { |
|
440 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
441 | + /** @type EE_Transaction $transaction */ |
|
442 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
443 | + // can we freely update the TXN at this moment? |
|
444 | + if ($IPN && $transaction->is_locked()) { |
|
445 | + // don't update the transaction at this exact moment |
|
446 | + // because the TXN is active in another request |
|
447 | + EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
448 | + time(), |
|
449 | + $transaction->ID(), |
|
450 | + $payment->ID() |
|
451 | + ); |
|
452 | + } else { |
|
453 | + // verify payment and that it has been saved |
|
454 | + if ($payment instanceof EE_Payment && $payment->ID()) { |
|
455 | + if ( |
|
456 | + $payment->payment_method() instanceof EE_Payment_Method |
|
457 | + && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
458 | + ) { |
|
459 | + $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
460 | + // update TXN registrations with payment info |
|
461 | + $this->process_registration_payments($transaction, $payment); |
|
462 | + } |
|
463 | + $do_action = $payment->just_approved() |
|
464 | + ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
465 | + : $do_action; |
|
466 | + } else { |
|
467 | + // send out notifications |
|
468 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
469 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
470 | + } |
|
471 | + if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
472 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
473 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
474 | + // set new value for total paid |
|
475 | + $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
476 | + // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
477 | + if ($update_txn) { |
|
478 | + $this->_post_payment_processing($transaction, $payment, $IPN); |
|
479 | + } |
|
480 | + } |
|
481 | + // granular hook for others to use. |
|
482 | + do_action($do_action, $transaction, $payment); |
|
483 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
484 | + //global hook for others to use. |
|
485 | + do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
486 | + } |
|
487 | + } |
|
488 | + |
|
489 | + |
|
490 | + |
|
491 | + /** |
|
492 | + * update registrations REG_paid field after successful payment and link registrations with payment |
|
493 | + * |
|
494 | + * @param EE_Transaction $transaction |
|
495 | + * @param EE_Payment $payment |
|
496 | + * @param EE_Registration[] $registrations |
|
497 | + * @throws \EE_Error |
|
498 | + */ |
|
499 | + public function process_registration_payments( |
|
500 | + EE_Transaction $transaction, |
|
501 | + EE_Payment $payment, |
|
502 | + $registrations = array() |
|
503 | + ) { |
|
504 | + // only process if payment was successful |
|
505 | + if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
506 | + return; |
|
507 | + } |
|
508 | + //EEM_Registration::instance()->show_next_x_db_queries(); |
|
509 | + if (empty($registrations)) { |
|
510 | + // find registrations with monies owing that can receive a payment |
|
511 | + $registrations = $transaction->registrations( |
|
512 | + array( |
|
513 | + array( |
|
514 | + // only these reg statuses can receive payments |
|
515 | + 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
516 | + 'REG_final_price' => array('!=', 0), |
|
517 | + 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
518 | + ), |
|
519 | + ) |
|
520 | + ); |
|
521 | + } |
|
522 | + // still nothing ??!?? |
|
523 | + if (empty($registrations)) { |
|
524 | + return; |
|
525 | + } |
|
526 | + // todo: break out the following logic into a separate strategy class |
|
527 | + // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
528 | + // todo: which would apply payments using the capitalist "first come first paid" approach |
|
529 | + // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
530 | + // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
531 | + // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
532 | + $refund = $payment->is_a_refund(); |
|
533 | + // how much is available to apply to registrations? |
|
534 | + $available_payment_amount = abs($payment->amount()); |
|
535 | + foreach ($registrations as $registration) { |
|
536 | + if ($registration instanceof EE_Registration) { |
|
537 | + // nothing left? |
|
538 | + if ($available_payment_amount <= 0) { |
|
539 | + break; |
|
540 | + } |
|
541 | + if ($refund) { |
|
542 | + $available_payment_amount = $this->process_registration_refund($registration, $payment, $available_payment_amount); |
|
543 | + } else { |
|
544 | + $available_payment_amount = $this->process_registration_payment($registration, $payment, $available_payment_amount); |
|
545 | + } |
|
546 | + } |
|
547 | + } |
|
548 | + if ($available_payment_amount > 0 && apply_filters('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', false)) { |
|
549 | + EE_Error::add_attention( |
|
550 | + sprintf( |
|
551 | + __('A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
552 | + 'event_espresso'), |
|
553 | + EEH_Template::format_currency($available_payment_amount), |
|
554 | + implode(', ', array_keys($registrations)), |
|
555 | + '<br/>', |
|
556 | + EEH_Template::format_currency($payment->amount()) |
|
557 | + ), |
|
558 | + __FILE__, __FUNCTION__, __LINE__ |
|
559 | + ); |
|
560 | + } |
|
561 | + } |
|
562 | + |
|
563 | + |
|
564 | + |
|
565 | + /** |
|
566 | + * update registration REG_paid field after successful payment and link registration with payment |
|
567 | + * |
|
568 | + * @param EE_Registration $registration |
|
569 | + * @param EE_Payment $payment |
|
570 | + * @param float $available_payment_amount |
|
571 | + * @return float |
|
572 | + * @throws \EE_Error |
|
573 | + */ |
|
574 | + public function process_registration_payment( |
|
575 | + EE_Registration $registration, |
|
576 | + EE_Payment $payment, |
|
577 | + $available_payment_amount = 0.00 |
|
578 | + ) { |
|
579 | + $owing = $registration->final_price() - $registration->paid(); |
|
580 | + if ($owing > 0) { |
|
581 | + // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
582 | + $payment_amount = min($available_payment_amount, $owing); |
|
583 | + // update $available_payment_amount |
|
584 | + $available_payment_amount -= $payment_amount; |
|
585 | + //calculate and set new REG_paid |
|
586 | + $registration->set_paid($registration->paid() + $payment_amount); |
|
587 | + // now save it |
|
588 | + $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
589 | + } |
|
590 | + return $available_payment_amount; |
|
591 | + } |
|
592 | + |
|
593 | + |
|
594 | + |
|
595 | + /** |
|
596 | + * update registration REG_paid field after successful payment and link registration with payment |
|
597 | + * |
|
598 | + * @param EE_Registration $registration |
|
599 | + * @param EE_Payment $payment |
|
600 | + * @param float $payment_amount |
|
601 | + * @return void |
|
602 | + * @throws \EE_Error |
|
603 | + */ |
|
604 | + protected function _apply_registration_payment( |
|
605 | + EE_Registration $registration, |
|
606 | + EE_Payment $payment, |
|
607 | + $payment_amount = 0.00 |
|
608 | + ) { |
|
609 | + // find any existing reg payment records for this registration and payment |
|
610 | + $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
611 | + array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
612 | + ); |
|
613 | + // if existing registration payment exists |
|
614 | + if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
615 | + // then update that record |
|
616 | + $existing_reg_payment->set_amount($payment_amount); |
|
617 | + $existing_reg_payment->save(); |
|
618 | + } else { |
|
619 | + // or add new relation between registration and payment and set amount |
|
620 | + $registration->_add_relation_to($payment, 'Payment', array('RPY_amount' => $payment_amount)); |
|
621 | + // make it stick |
|
622 | + $registration->save(); |
|
623 | + } |
|
624 | + } |
|
625 | + |
|
626 | + |
|
627 | + |
|
628 | + /** |
|
629 | + * update registration REG_paid field after refund and link registration with payment |
|
630 | + * |
|
631 | + * @param EE_Registration $registration |
|
632 | + * @param EE_Payment $payment |
|
633 | + * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
634 | + * @return float |
|
635 | + * @throws \EE_Error |
|
636 | + */ |
|
637 | + public function process_registration_refund( |
|
638 | + EE_Registration $registration, |
|
639 | + EE_Payment $payment, |
|
640 | + $available_refund_amount = 0.00 |
|
641 | + ) { |
|
642 | + //EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
643 | + if ($registration->paid() > 0) { |
|
644 | + // ensure $available_refund_amount is NOT negative |
|
645 | + $available_refund_amount = (float)abs($available_refund_amount); |
|
646 | + // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
647 | + $refund_amount = min($available_refund_amount, (float)$registration->paid()); |
|
648 | + // update $available_payment_amount |
|
649 | + $available_refund_amount -= $refund_amount; |
|
650 | + //calculate and set new REG_paid |
|
651 | + $registration->set_paid($registration->paid() - $refund_amount); |
|
652 | + // convert payment amount back to a negative value for storage in the db |
|
653 | + $refund_amount = (float)abs($refund_amount) * -1; |
|
654 | + // now save it |
|
655 | + $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
656 | + } |
|
657 | + return $available_refund_amount; |
|
658 | + } |
|
659 | + |
|
660 | + |
|
661 | + |
|
662 | + /** |
|
663 | + * Process payments and transaction after payment process completed. |
|
664 | + * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
665 | + * if this request happens to be processing an IPN, |
|
666 | + * then we will also set the Payment Options Reg Step to completed, |
|
667 | + * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
668 | + * |
|
669 | + * @param EE_Transaction $transaction |
|
670 | + * @param EE_Payment $payment |
|
671 | + * @param bool $IPN |
|
672 | + * @throws \EE_Error |
|
673 | + */ |
|
674 | + protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
675 | + { |
|
676 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
677 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
678 | + // is the Payment Options Reg Step completed ? |
|
679 | + $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
680 | + // if the Payment Options Reg Step is completed... |
|
681 | + $revisit = $payment_options_step_completed === true ? true : false; |
|
682 | + // then this is kinda sorta a revisit with regards to payments at least |
|
683 | + $transaction_processor->set_revisit($revisit); |
|
684 | + // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
685 | + if ( |
|
686 | + $IPN |
|
687 | + && $payment_options_step_completed !== true |
|
688 | + && ($payment->is_approved() || $payment->is_pending()) |
|
689 | + ) { |
|
690 | + $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
691 | + 'payment_options' |
|
692 | + ); |
|
693 | + } |
|
694 | + // maybe update status, but don't save transaction just yet |
|
695 | + $transaction->update_status_based_on_total_paid(false); |
|
696 | + // check if 'finalize_registration' step has been completed... |
|
697 | + $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
698 | + // if this is an IPN and the final step has not been initiated |
|
699 | + if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
700 | + // and if it hasn't already been set as being started... |
|
701 | + $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
702 | + } |
|
703 | + $transaction->save(); |
|
704 | + // because the above will return false if the final step was not fully completed, we need to check again... |
|
705 | + if ($IPN && $finalized !== false) { |
|
706 | + // and if we are all good to go, then send out notifications |
|
707 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
708 | + //ok, now process the transaction according to the payment |
|
709 | + $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($transaction, $payment); |
|
710 | + } |
|
711 | + // DEBUG LOG |
|
712 | + $payment_method = $payment->payment_method(); |
|
713 | + if ($payment_method instanceof EE_Payment_Method) { |
|
714 | + $payment_method_type_obj = $payment_method->type_obj(); |
|
715 | + if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
716 | + $gateway = $payment_method_type_obj->get_gateway(); |
|
717 | + if ($gateway instanceof EE_Gateway) { |
|
718 | + $gateway->log( |
|
719 | + array( |
|
720 | + 'message' => __('Post Payment Transaction Details', 'event_espresso'), |
|
721 | + 'transaction' => $transaction->model_field_array(), |
|
722 | + 'finalized' => $finalized, |
|
723 | + 'IPN' => $IPN, |
|
724 | + 'deliver_notifications' => has_filter( |
|
725 | + 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
726 | + ), |
|
727 | + ), |
|
728 | + $payment |
|
729 | + ); |
|
730 | + } |
|
731 | + } |
|
732 | + } |
|
733 | + } |
|
734 | + |
|
735 | + |
|
736 | + |
|
737 | + /** |
|
738 | + * Force posts to PayPal to use TLS v1.2. See: |
|
739 | + * https://core.trac.wordpress.org/ticket/36320 |
|
740 | + * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
741 | + * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
742 | + * This will affect paypal standard, pro, express, and payflow. |
|
743 | + */ |
|
744 | + public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
745 | + { |
|
746 | + if (strstr($url, 'https://') && strstr($url, '.paypal.com')) { |
|
747 | + //Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
748 | + //instead of the constant because it might not be defined |
|
749 | + curl_setopt($handle, CURLOPT_SSLVERSION, 1); |
|
750 | + } |
|
751 | + } |
|
752 | 752 | } |
@@ -5,7 +5,7 @@ discard block |
||
5 | 5 | * |
6 | 6 | * allows gateways to be used by different systems other than Event Espresso |
7 | 7 | */ |
8 | -interface EEI_Payment extends EEI_Base{ |
|
8 | +interface EEI_Payment extends EEI_Base { |
|
9 | 9 | |
10 | 10 | /** |
11 | 11 | * @return string indicating which the payment is approved, pending, cancelled or failed |
@@ -153,7 +153,7 @@ discard block |
||
153 | 153 | /** |
154 | 154 | * Interface EEI_Payment_Method |
155 | 155 | */ |
156 | -interface EEI_Payment_Method{ |
|
156 | +interface EEI_Payment_Method { |
|
157 | 157 | |
158 | 158 | } |
159 | 159 | |
@@ -172,7 +172,7 @@ discard block |
||
172 | 172 | * @param string $model_name |
173 | 173 | * @return EE_Log |
174 | 174 | */ |
175 | - public function gateway_log($message,$id,$model_name); |
|
175 | + public function gateway_log($message, $id, $model_name); |
|
176 | 176 | } |
177 | 177 | |
178 | 178 |
@@ -44,77 +44,76 @@ discard block |
||
44 | 44 | */ |
45 | 45 | protected $_image_url; |
46 | 46 | |
47 | - /** |
|
48 | - * gateway URL variable |
|
49 | - * |
|
50 | - * @var string |
|
51 | - */ |
|
52 | - protected $_base_gateway_url = ''; |
|
53 | - |
|
54 | - |
|
55 | - |
|
56 | - /** |
|
57 | - * EEG_Paypal_Express constructor. |
|
58 | - */ |
|
59 | - public function __construct() |
|
60 | - { |
|
61 | - $this->_currencies_supported = array( |
|
62 | - 'USD', |
|
63 | - 'AUD', |
|
64 | - 'BRL', |
|
65 | - 'CAD', |
|
66 | - 'CZK', |
|
67 | - 'DKK', |
|
68 | - 'EUR', |
|
69 | - 'HKD', |
|
70 | - 'HUF', |
|
71 | - 'ILS', |
|
72 | - 'JPY', |
|
73 | - 'MYR', |
|
74 | - 'MXN', |
|
75 | - 'NOK', |
|
76 | - 'NZD', |
|
77 | - 'PHP', |
|
78 | - 'PLN', |
|
79 | - 'GBP', |
|
80 | - 'RUB', |
|
81 | - 'SGD', |
|
82 | - 'SEK', |
|
83 | - 'CHF', |
|
84 | - 'TWD', |
|
85 | - 'THB', |
|
86 | - 'TRY' |
|
87 | - ); |
|
88 | - parent::__construct(); |
|
89 | - } |
|
90 | - |
|
91 | - |
|
92 | - |
|
93 | - /** |
|
94 | - * Sets the gateway URL variable based on whether debug mode is enabled or not. |
|
47 | + /** |
|
48 | + * gateway URL variable |
|
49 | + * |
|
50 | + * @var string |
|
51 | + */ |
|
52 | + protected $_base_gateway_url = ''; |
|
53 | + |
|
54 | + |
|
55 | + |
|
56 | + /** |
|
57 | + * EEG_Paypal_Express constructor. |
|
58 | + */ |
|
59 | + public function __construct() |
|
60 | + { |
|
61 | + $this->_currencies_supported = array( |
|
62 | + 'USD', |
|
63 | + 'AUD', |
|
64 | + 'BRL', |
|
65 | + 'CAD', |
|
66 | + 'CZK', |
|
67 | + 'DKK', |
|
68 | + 'EUR', |
|
69 | + 'HKD', |
|
70 | + 'HUF', |
|
71 | + 'ILS', |
|
72 | + 'JPY', |
|
73 | + 'MYR', |
|
74 | + 'MXN', |
|
75 | + 'NOK', |
|
76 | + 'NZD', |
|
77 | + 'PHP', |
|
78 | + 'PLN', |
|
79 | + 'GBP', |
|
80 | + 'RUB', |
|
81 | + 'SGD', |
|
82 | + 'SEK', |
|
83 | + 'CHF', |
|
84 | + 'TWD', |
|
85 | + 'THB', |
|
86 | + 'TRY' |
|
87 | + ); |
|
88 | + parent::__construct(); |
|
89 | + } |
|
90 | + |
|
95 | 91 | |
92 | + |
|
93 | + /** |
|
94 | + * Sets the gateway URL variable based on whether debug mode is enabled or not. |
|
96 | 95 | * |
97 | 96 | *@param array $settings_array |
98 | 97 | */ |
99 | 98 | public function set_settings( $settings_array ) { |
100 | 99 | parent::set_settings($settings_array); |
101 | 100 | // Redirect URL. |
102 | - $this->_base_gateway_url = $this->_debug_mode |
|
103 | - ? 'https://api-3t.sandbox.paypal.com/nvp' |
|
104 | - : 'https://api-3t.paypal.com/nvp'; |
|
101 | + $this->_base_gateway_url = $this->_debug_mode |
|
102 | + ? 'https://api-3t.sandbox.paypal.com/nvp' |
|
103 | + : 'https://api-3t.paypal.com/nvp'; |
|
105 | 104 | } |
106 | 105 | |
107 | 106 | |
108 | 107 | |
109 | - /** |
|
110 | - * @param EEI_Payment $payment |
|
111 | - * @param array $billing_info |
|
112 | - * @param string $return_url |
|
113 | - * @param string $notify_url |
|
114 | - * @param string $cancel_url |
|
115 | - * @return \EE_Payment|\EEI_Payment |
|
116 | - * @throws \EE_Error |
|
117 | - */ |
|
108 | + /** |
|
109 | + * @param EEI_Payment $payment |
|
110 | + * @param array $billing_info |
|
111 | + * @param string $return_url |
|
112 | + * @param string $notify_url |
|
113 | + * @param string $cancel_url |
|
114 | + * @return \EE_Payment|\EEI_Payment |
|
115 | + * @throws \EE_Error |
|
116 | + */ |
|
118 | 117 | public function set_redirection_info( $payment, $billing_info = array(), $return_url = NULL, $notify_url = NULL, $cancel_url = NULL ) { |
119 | 118 | if ( ! $payment instanceof EEI_Payment ) { |
120 | 119 | $payment->set_gateway_response( __( 'Error. No associated payment was found.', 'event_espresso' ) ); |
@@ -202,9 +201,9 @@ discard block |
||
202 | 201 | $token_request_dtls['L_PAYMENTREQUEST_0_NUMBER'.$item_num] = $item_num + 1; |
203 | 202 | // Item quantity. |
204 | 203 | $token_request_dtls['L_PAYMENTREQUEST_0_QTY'.$item_num] = 1; |
205 | - // Digital item is sold. |
|
206 | - $token_request_dtls['L_PAYMENTREQUEST_0_ITEMCATEGORY'.$item_num] = 'Physical'; |
|
207 | - $item_num++; |
|
204 | + // Digital item is sold. |
|
205 | + $token_request_dtls['L_PAYMENTREQUEST_0_ITEMCATEGORY'.$item_num] = 'Physical'; |
|
206 | + $item_num++; |
|
208 | 207 | } |
209 | 208 | } else { |
210 | 209 | // Just one Item. |
@@ -272,7 +271,6 @@ discard block |
||
272 | 271 | |
273 | 272 | |
274 | 273 | /** |
275 | - |
|
276 | 274 | * @param array $update_info { |
277 | 275 | * @type string $gateway_txn_id |
278 | 276 | * @type string status an EEMI_Payment status |
@@ -292,8 +290,8 @@ discard block |
||
292 | 290 | return $payment; |
293 | 291 | } |
294 | 292 | $primary_registrant = $transaction->primary_registration(); |
295 | - $payment_details = $payment->details(); |
|
296 | - // Check if we still have the token. |
|
293 | + $payment_details = $payment->details(); |
|
294 | + // Check if we still have the token. |
|
297 | 295 | if ( ! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN']) ) { |
298 | 296 | $payment->set_status( $this->_pay_model->failed_status() ); |
299 | 297 | return $payment; |
@@ -402,36 +400,36 @@ discard block |
||
402 | 400 | */ |
403 | 401 | public function _ppExpress_check_response( $request_response ) { |
404 | 402 | if (empty($request_response['body']) || is_wp_error( $request_response ) ) { |
405 | - // If we got here then there was an error in this request. |
|
406 | - return array('status' => false, 'args' => $request_response); |
|
407 | - } |
|
408 | - $response_args = array(); |
|
409 | - parse_str( urldecode($request_response['body']), $response_args ); |
|
410 | - if ( ! isset($response_args['ACK'])) { |
|
411 | - return array('status' => false, 'args' => $request_response); |
|
412 | - } |
|
413 | - if ( |
|
414 | - $response_args['ACK'] === 'Success' |
|
415 | - && ( |
|
416 | - isset($response_args['PAYERID']) |
|
417 | - || isset($response_args['PAYMENTINFO_0_TRANSACTIONID']) |
|
418 | - || (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed') |
|
419 | - || isset($response_args['TOKEN']) |
|
420 | - ) |
|
421 | - ) { |
|
422 | - // Response status OK, return response parameters for further processing. |
|
423 | - return array('status' => true, 'args' => $response_args); |
|
424 | - } else { |
|
425 | - $errors = $this->_get_errors($response_args); |
|
426 | - return array('status' => false, 'args' => $errors); |
|
427 | - } |
|
403 | + // If we got here then there was an error in this request. |
|
404 | + return array('status' => false, 'args' => $request_response); |
|
405 | + } |
|
406 | + $response_args = array(); |
|
407 | + parse_str( urldecode($request_response['body']), $response_args ); |
|
408 | + if ( ! isset($response_args['ACK'])) { |
|
409 | + return array('status' => false, 'args' => $request_response); |
|
410 | + } |
|
411 | + if ( |
|
412 | + $response_args['ACK'] === 'Success' |
|
413 | + && ( |
|
414 | + isset($response_args['PAYERID']) |
|
415 | + || isset($response_args['PAYMENTINFO_0_TRANSACTIONID']) |
|
416 | + || (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed') |
|
417 | + || isset($response_args['TOKEN']) |
|
418 | + ) |
|
419 | + ) { |
|
420 | + // Response status OK, return response parameters for further processing. |
|
421 | + return array('status' => true, 'args' => $response_args); |
|
422 | + } else { |
|
423 | + $errors = $this->_get_errors($response_args); |
|
424 | + return array('status' => false, 'args' => $errors); |
|
425 | + } |
|
428 | 426 | } |
429 | 427 | |
430 | 428 | |
431 | 429 | /** |
432 | - * Log a "Cleared" request. |
|
433 | - * |
|
434 | - * @param array $request |
|
430 | + * Log a "Cleared" request. |
|
431 | + * |
|
432 | + * @param array $request |
|
435 | 433 | * @param EEI_Payment $payment |
436 | 434 | * @param string $info |
437 | 435 | * @return void |
@@ -454,17 +452,17 @@ discard block |
||
454 | 452 | $n = 0; |
455 | 453 | while ( isset($data_array["L_ERRORCODE{$n}"]) ) { |
456 | 454 | $l_error_code = isset($data_array["L_ERRORCODE{$n}"]) |
457 | - ? $data_array["L_ERRORCODE{$n}"] |
|
458 | - : ''; |
|
455 | + ? $data_array["L_ERRORCODE{$n}"] |
|
456 | + : ''; |
|
459 | 457 | $l_severity_code = isset($data_array["L_SEVERITYCODE{$n}"]) |
460 | - ? $data_array["L_SEVERITYCODE{$n}"] |
|
461 | - : ''; |
|
458 | + ? $data_array["L_SEVERITYCODE{$n}"] |
|
459 | + : ''; |
|
462 | 460 | $l_short_message = isset($data_array["L_SHORTMESSAGE{$n}"]) |
463 | - ? $data_array["L_SHORTMESSAGE{$n}"] |
|
464 | - : ''; |
|
461 | + ? $data_array["L_SHORTMESSAGE{$n}"] |
|
462 | + : ''; |
|
465 | 463 | $l_long_message = isset($data_array["L_LONGMESSAGE{$n}"]) |
466 | - ? $data_array["L_LONGMESSAGE{$n}"] |
|
467 | - : ''; |
|
464 | + ? $data_array["L_LONGMESSAGE{$n}"] |
|
465 | + : ''; |
|
468 | 466 | |
469 | 467 | if ( $n === 0 ) { |
470 | 468 | $errors = array( |
@@ -1,4 +1,4 @@ discard block |
||
1 | -<?php if ( ! defined( 'EVENT_ESPRESSO_VERSION' )) { exit('NO direct script access allowed'); } |
|
1 | +<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('NO direct script access allowed'); } |
|
2 | 2 | |
3 | 3 | /** |
4 | 4 | * ---------------------------------------------- |
@@ -96,7 +96,7 @@ discard block |
||
96 | 96 | * |
97 | 97 | *@param array $settings_array |
98 | 98 | */ |
99 | - public function set_settings( $settings_array ) { |
|
99 | + public function set_settings($settings_array) { |
|
100 | 100 | parent::set_settings($settings_array); |
101 | 101 | // Redirect URL. |
102 | 102 | $this->_base_gateway_url = $this->_debug_mode |
@@ -115,19 +115,19 @@ discard block |
||
115 | 115 | * @return \EE_Payment|\EEI_Payment |
116 | 116 | * @throws \EE_Error |
117 | 117 | */ |
118 | - public function set_redirection_info( $payment, $billing_info = array(), $return_url = NULL, $notify_url = NULL, $cancel_url = NULL ) { |
|
119 | - if ( ! $payment instanceof EEI_Payment ) { |
|
120 | - $payment->set_gateway_response( __( 'Error. No associated payment was found.', 'event_espresso' ) ); |
|
121 | - $payment->set_status( $this->_pay_model->failed_status() ); |
|
118 | + public function set_redirection_info($payment, $billing_info = array(), $return_url = NULL, $notify_url = NULL, $cancel_url = NULL) { |
|
119 | + if ( ! $payment instanceof EEI_Payment) { |
|
120 | + $payment->set_gateway_response(__('Error. No associated payment was found.', 'event_espresso')); |
|
121 | + $payment->set_status($this->_pay_model->failed_status()); |
|
122 | 122 | return $payment; |
123 | 123 | } |
124 | 124 | $transaction = $payment->transaction(); |
125 | - if ( ! $transaction instanceof EEI_Transaction ) { |
|
126 | - $payment->set_gateway_response( __( 'Could not process this payment because it has no associated transaction.', 'event_espresso' ) ); |
|
127 | - $payment->set_status( $this->_pay_model->failed_status() ); |
|
125 | + if ( ! $transaction instanceof EEI_Transaction) { |
|
126 | + $payment->set_gateway_response(__('Could not process this payment because it has no associated transaction.', 'event_espresso')); |
|
127 | + $payment->set_status($this->_pay_model->failed_status()); |
|
128 | 128 | return $payment; |
129 | 129 | } |
130 | - $order_description = substr( $this->_format_order_description($payment), 0, 127 ); |
|
130 | + $order_description = substr($this->_format_order_description($payment), 0, 127); |
|
131 | 131 | $primary_registration = $transaction->primary_registration(); |
132 | 132 | $primary_attendee = $primary_registration instanceof EE_Registration ? $primary_registration->attendee() : false; |
133 | 133 | $locale = explode('-', get_bloginfo('language')); |
@@ -141,37 +141,37 @@ discard block |
||
141 | 141 | 'RETURNURL' => $return_url, |
142 | 142 | 'CANCELURL' => $cancel_url, |
143 | 143 | 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale', |
144 | - 'SOLUTIONTYPE' => 'Sole', // Buyer does not need to create a PayPal account to check out. This is referred to as PayPal Account Optional. |
|
145 | - 'BUTTONSOURCE' => 'EventEspresso_SP',//EE will blow up if you change this |
|
144 | + 'SOLUTIONTYPE' => 'Sole', // Buyer does not need to create a PayPal account to check out. This is referred to as PayPal Account Optional. |
|
145 | + 'BUTTONSOURCE' => 'EventEspresso_SP', //EE will blow up if you change this |
|
146 | 146 | 'LOCALECODE' => $locale[1] // Locale of the pages displayed by PayPal during Express Checkout. |
147 | 147 | ); |
148 | 148 | |
149 | 149 | // Show itemized list. |
150 | - if ( $this->_money->compare_floats( $payment->amount(), $transaction->total(), '==' ) ) { |
|
150 | + if ($this->_money->compare_floats($payment->amount(), $transaction->total(), '==')) { |
|
151 | 151 | $item_num = 0; |
152 | 152 | $itemized_sum = 0; |
153 | 153 | $total_line_items = $transaction->total_line_item(); |
154 | 154 | // Go through each item in the list. |
155 | - foreach ( $total_line_items->get_items() as $line_item ) { |
|
156 | - if ( $line_item instanceof EE_Line_Item ) { |
|
155 | + foreach ($total_line_items->get_items() as $line_item) { |
|
156 | + if ($line_item instanceof EE_Line_Item) { |
|
157 | 157 | // PayPal doesn't like line items with 0.00 amount, so we may skip those. |
158 | - if ( EEH_Money::compare_floats( $line_item->total(), '0.00', '==' ) ) { |
|
158 | + if (EEH_Money::compare_floats($line_item->total(), '0.00', '==')) { |
|
159 | 159 | continue; |
160 | 160 | } |
161 | 161 | |
162 | 162 | $unit_price = $line_item->unit_price(); |
163 | 163 | $line_item_quantity = $line_item->quantity(); |
164 | 164 | // This is a discount. |
165 | - if ( $line_item->is_percent() ) { |
|
165 | + if ($line_item->is_percent()) { |
|
166 | 166 | $unit_price = $line_item->total(); |
167 | 167 | $line_item_quantity = 1; |
168 | 168 | } |
169 | 169 | // Item Name. |
170 | - $token_request_dtls['L_PAYMENTREQUEST_0_NAME'.$item_num] = substr($this->_format_line_item_name( $line_item, $payment), 0, 127); |
|
170 | + $token_request_dtls['L_PAYMENTREQUEST_0_NAME'.$item_num] = substr($this->_format_line_item_name($line_item, $payment), 0, 127); |
|
171 | 171 | // Item description. |
172 | - $token_request_dtls['L_PAYMENTREQUEST_0_DESC'.$item_num] = substr($this->_format_line_item_desc( $line_item, $payment), 0, 127); |
|
172 | + $token_request_dtls['L_PAYMENTREQUEST_0_DESC'.$item_num] = substr($this->_format_line_item_desc($line_item, $payment), 0, 127); |
|
173 | 173 | // Cost of individual item. |
174 | - $token_request_dtls['L_PAYMENTREQUEST_0_AMT'.$item_num] = $this->format_currency( $unit_price ); |
|
174 | + $token_request_dtls['L_PAYMENTREQUEST_0_AMT'.$item_num] = $this->format_currency($unit_price); |
|
175 | 175 | // Item Number. |
176 | 176 | $token_request_dtls['L_PAYMENTREQUEST_0_NUMBER'.$item_num] = $item_num + 1; |
177 | 177 | // Item quantity. |
@@ -188,16 +188,16 @@ discard block |
||
188 | 188 | $token_request_dtls['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0'; |
189 | 189 | $token_request_dtls['PAYMENTREQUEST_0_HANDLINGAMT'] = '0'; |
190 | 190 | |
191 | - $itemized_sum_diff_from_txn_total = round( $transaction->total() - $itemized_sum - $total_line_items->get_total_tax(), 2 ); |
|
191 | + $itemized_sum_diff_from_txn_total = round($transaction->total() - $itemized_sum - $total_line_items->get_total_tax(), 2); |
|
192 | 192 | // If we were not able to recognize some item like promotion, surcharge or cancellation, |
193 | 193 | // add the difference as an extra line item. |
194 | - if ( $this->_money->compare_floats( $itemized_sum_diff_from_txn_total, 0, '!=' ) ) { |
|
194 | + if ($this->_money->compare_floats($itemized_sum_diff_from_txn_total, 0, '!=')) { |
|
195 | 195 | // Item Name. |
196 | - $token_request_dtls['L_PAYMENTREQUEST_0_NAME'.$item_num] = substr( __( 'Other (promotion/surcharge/cancellation)', 'event_espresso' ), 0, 127 ); |
|
196 | + $token_request_dtls['L_PAYMENTREQUEST_0_NAME'.$item_num] = substr(__('Other (promotion/surcharge/cancellation)', 'event_espresso'), 0, 127); |
|
197 | 197 | // Item description. |
198 | 198 | $token_request_dtls['L_PAYMENTREQUEST_0_DESC'.$item_num] = ''; |
199 | 199 | // Cost of individual item. |
200 | - $token_request_dtls['L_PAYMENTREQUEST_0_AMT'.$item_num] = $this->format_currency( $itemized_sum_diff_from_txn_total ); |
|
200 | + $token_request_dtls['L_PAYMENTREQUEST_0_AMT'.$item_num] = $this->format_currency($itemized_sum_diff_from_txn_total); |
|
201 | 201 | // Item Number. |
202 | 202 | $token_request_dtls['L_PAYMENTREQUEST_0_NUMBER'.$item_num] = $item_num + 1; |
203 | 203 | // Item quantity. |
@@ -209,11 +209,11 @@ discard block |
||
209 | 209 | } else { |
210 | 210 | // Just one Item. |
211 | 211 | // Item Name. |
212 | - $token_request_dtls['L_PAYMENTREQUEST_0_NAME0'] = substr( $this->_format_partial_payment_line_item_name($payment), 0, 127 ); |
|
212 | + $token_request_dtls['L_PAYMENTREQUEST_0_NAME0'] = substr($this->_format_partial_payment_line_item_name($payment), 0, 127); |
|
213 | 213 | // Item description. |
214 | - $token_request_dtls['L_PAYMENTREQUEST_0_DESC0'] = substr( $this->_format_partial_payment_line_item_desc($payment), 0, 127 ); |
|
214 | + $token_request_dtls['L_PAYMENTREQUEST_0_DESC0'] = substr($this->_format_partial_payment_line_item_desc($payment), 0, 127); |
|
215 | 215 | // Cost of individual item. |
216 | - $token_request_dtls['L_PAYMENTREQUEST_0_AMT0'] = $this->format_currency( $payment->amount() ); |
|
216 | + $token_request_dtls['L_PAYMENTREQUEST_0_AMT0'] = $this->format_currency($payment->amount()); |
|
217 | 217 | // Item Number. |
218 | 218 | $token_request_dtls['L_PAYMENTREQUEST_0_NUMBER0'] = 1; |
219 | 219 | // Item quantity. |
@@ -221,14 +221,14 @@ discard block |
||
221 | 221 | // Digital item is sold. |
222 | 222 | $token_request_dtls['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical'; |
223 | 223 | // Item's sales S/H and tax amount. |
224 | - $token_request_dtls['PAYMENTREQUEST_0_ITEMAMT'] = $this->format_currency( $payment->amount() ); |
|
224 | + $token_request_dtls['PAYMENTREQUEST_0_ITEMAMT'] = $this->format_currency($payment->amount()); |
|
225 | 225 | $token_request_dtls['PAYMENTREQUEST_0_TAXAMT'] = '0'; |
226 | 226 | $token_request_dtls['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0'; |
227 | 227 | $token_request_dtls['PAYMENTREQUEST_0_HANDLINGAMT'] = '0'; |
228 | 228 | } |
229 | 229 | // Automatically filling out shipping and contact information. |
230 | - if ( $this->_request_shipping_addr && $primary_attendee instanceof EEI_Attendee ) { |
|
231 | - $token_request_dtls['NOSHIPPING'] = '2'; // If you do not pass the shipping address, PayPal obtains it from the buyer's account profile. |
|
230 | + if ($this->_request_shipping_addr && $primary_attendee instanceof EEI_Attendee) { |
|
231 | + $token_request_dtls['NOSHIPPING'] = '2'; // If you do not pass the shipping address, PayPal obtains it from the buyer's account profile. |
|
232 | 232 | $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET'] = $primary_attendee->address(); |
233 | 233 | $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $primary_attendee->address2(); |
234 | 234 | $token_request_dtls['PAYMENTREQUEST_0_SHIPTOCITY'] = $primary_attendee->city(); |
@@ -237,34 +237,34 @@ discard block |
||
237 | 237 | $token_request_dtls['PAYMENTREQUEST_0_SHIPTOZIP'] = $primary_attendee->zip(); |
238 | 238 | $token_request_dtls['PAYMENTREQUEST_0_EMAIL'] = $primary_attendee->email(); |
239 | 239 | $token_request_dtls['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $primary_attendee->phone(); |
240 | - } elseif ( ! $this->_request_shipping_addr ) { |
|
240 | + } elseif ( ! $this->_request_shipping_addr) { |
|
241 | 241 | // Do not request shipping details on the PP Checkout page. |
242 | 242 | $token_request_dtls['NOSHIPPING'] = '1'; |
243 | 243 | $token_request_dtls['REQCONFIRMSHIPPING'] = '0'; |
244 | 244 | |
245 | 245 | } |
246 | 246 | // Used a business/personal logo on the PayPal page. |
247 | - if ( ! empty($this->_image_url) ) { |
|
247 | + if ( ! empty($this->_image_url)) { |
|
248 | 248 | $token_request_dtls['LOGOIMG'] = $this->_image_url; |
249 | 249 | } |
250 | 250 | // Request PayPal token. |
251 | - $token_request_response = $this->_ppExpress_request( $token_request_dtls, 'Payment Token', $payment ); |
|
252 | - $token_rstatus = $this->_ppExpress_check_response( $token_request_response ); |
|
253 | - $response_args = ( isset($token_rstatus['args']) && is_array($token_rstatus['args']) ) ? $token_rstatus['args'] : array(); |
|
254 | - if ( $token_rstatus['status'] ) { |
|
251 | + $token_request_response = $this->_ppExpress_request($token_request_dtls, 'Payment Token', $payment); |
|
252 | + $token_rstatus = $this->_ppExpress_check_response($token_request_response); |
|
253 | + $response_args = (isset($token_rstatus['args']) && is_array($token_rstatus['args'])) ? $token_rstatus['args'] : array(); |
|
254 | + if ($token_rstatus['status']) { |
|
255 | 255 | // We got the Token so we may continue with the payment and redirect the client. |
256 | - $payment->set_details( $response_args ); |
|
256 | + $payment->set_details($response_args); |
|
257 | 257 | |
258 | 258 | $gateway_url = $this->_debug_mode ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com'; |
259 | - $payment->set_redirect_url( $gateway_url . '/checkoutnow?useraction=commit&cmd=_express-checkout&token=' . $response_args['TOKEN'] ); |
|
259 | + $payment->set_redirect_url($gateway_url.'/checkoutnow?useraction=commit&cmd=_express-checkout&token='.$response_args['TOKEN']); |
|
260 | 260 | } else { |
261 | - if ( isset($response_args['L_ERRORCODE']) ) { |
|
262 | - $payment->set_gateway_response( $response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE'] ); |
|
261 | + if (isset($response_args['L_ERRORCODE'])) { |
|
262 | + $payment->set_gateway_response($response_args['L_ERRORCODE'].'; '.$response_args['L_SHORTMESSAGE']); |
|
263 | 263 | } else { |
264 | - $payment->set_gateway_response( __( 'Error occurred while trying to setup the Express Checkout.', 'event_espresso' ) ); |
|
264 | + $payment->set_gateway_response(__('Error occurred while trying to setup the Express Checkout.', 'event_espresso')); |
|
265 | 265 | } |
266 | - $payment->set_details( $response_args ); |
|
267 | - $payment->set_status( $this->_pay_model->failed_status() ); |
|
266 | + $payment->set_details($response_args); |
|
267 | + $payment->set_status($this->_pay_model->failed_status()); |
|
268 | 268 | } |
269 | 269 | |
270 | 270 | return $payment; |
@@ -280,22 +280,22 @@ discard block |
||
280 | 280 | * @param EEI_Transaction $transaction |
281 | 281 | * @return EEI_Payment |
282 | 282 | */ |
283 | - public function handle_payment_update( $update_info, $transaction ) { |
|
283 | + public function handle_payment_update($update_info, $transaction) { |
|
284 | 284 | $payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : null; |
285 | 285 | |
286 | - if ( $payment instanceof EEI_Payment ) { |
|
287 | - $this->log( array( 'Return from Authorization' => $update_info ), $payment ); |
|
286 | + if ($payment instanceof EEI_Payment) { |
|
287 | + $this->log(array('Return from Authorization' => $update_info), $payment); |
|
288 | 288 | $transaction = $payment->transaction(); |
289 | - if ( ! $transaction instanceof EEI_Transaction ) { |
|
290 | - $payment->set_gateway_response( __( 'Could not process this payment because it has no associated transaction.', 'event_espresso' ) ); |
|
291 | - $payment->set_status( $this->_pay_model->failed_status() ); |
|
289 | + if ( ! $transaction instanceof EEI_Transaction) { |
|
290 | + $payment->set_gateway_response(__('Could not process this payment because it has no associated transaction.', 'event_espresso')); |
|
291 | + $payment->set_status($this->_pay_model->failed_status()); |
|
292 | 292 | return $payment; |
293 | 293 | } |
294 | 294 | $primary_registrant = $transaction->primary_registration(); |
295 | 295 | $payment_details = $payment->details(); |
296 | 296 | // Check if we still have the token. |
297 | - if ( ! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN']) ) { |
|
298 | - $payment->set_status( $this->_pay_model->failed_status() ); |
|
297 | + if ( ! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) { |
|
298 | + $payment->set_status($this->_pay_model->failed_status()); |
|
299 | 299 | return $payment; |
300 | 300 | } |
301 | 301 | |
@@ -304,10 +304,10 @@ discard block |
||
304 | 304 | 'TOKEN' => $payment_details['TOKEN'] |
305 | 305 | ); |
306 | 306 | // Request Customer Details. |
307 | - $cdetails_request_response = $this->_ppExpress_request( $cdetails_request_dtls, 'Customer Details', $payment ); |
|
308 | - $cdetails_rstatus = $this->_ppExpress_check_response( $cdetails_request_response ); |
|
309 | - $cdata_response_args = ( isset($cdetails_rstatus['args']) && is_array($cdetails_rstatus['args']) ) ? $cdetails_rstatus['args'] : array(); |
|
310 | - if ( $cdetails_rstatus['status'] ) { |
|
307 | + $cdetails_request_response = $this->_ppExpress_request($cdetails_request_dtls, 'Customer Details', $payment); |
|
308 | + $cdetails_rstatus = $this->_ppExpress_check_response($cdetails_request_response); |
|
309 | + $cdata_response_args = (isset($cdetails_rstatus['args']) && is_array($cdetails_rstatus['args'])) ? $cdetails_rstatus['args'] : array(); |
|
310 | + if ($cdetails_rstatus['status']) { |
|
311 | 311 | // We got the PayerID so now we can Complete the transaction. |
312 | 312 | $docheckout_request_dtls = array( |
313 | 313 | 'METHOD' => 'DoExpressCheckoutPayment', |
@@ -318,39 +318,39 @@ discard block |
||
318 | 318 | 'PAYMENTREQUEST_0_CURRENCYCODE' => $payment->currency_code() |
319 | 319 | ); |
320 | 320 | // Payment Checkout/Capture. |
321 | - $docheckout_request_response = $this->_ppExpress_request( $docheckout_request_dtls, 'Do Payment', $payment ); |
|
322 | - $docheckout_rstatus = $this->_ppExpress_check_response( $docheckout_request_response ); |
|
323 | - $docheckout_response_args = ( isset($docheckout_rstatus['args']) && is_array($docheckout_rstatus['args']) ) ? $docheckout_rstatus['args'] : array(); |
|
324 | - if ( $docheckout_rstatus['status'] ) { |
|
321 | + $docheckout_request_response = $this->_ppExpress_request($docheckout_request_dtls, 'Do Payment', $payment); |
|
322 | + $docheckout_rstatus = $this->_ppExpress_check_response($docheckout_request_response); |
|
323 | + $docheckout_response_args = (isset($docheckout_rstatus['args']) && is_array($docheckout_rstatus['args'])) ? $docheckout_rstatus['args'] : array(); |
|
324 | + if ($docheckout_rstatus['status']) { |
|
325 | 325 | // All is well, payment approved. |
326 | 326 | $primary_registration_code = $primary_registrant instanceof EE_Registration ? $primary_registrant->reg_code() : ''; |
327 | - $payment->set_extra_accntng( $primary_registration_code ); |
|
328 | - $payment->set_amount( isset($docheckout_response_args['PAYMENTINFO_0_AMT']) ? (float) $docheckout_response_args['PAYMENTINFO_0_AMT'] : 0 ); |
|
329 | - $payment->set_txn_id_chq_nmbr( isset( $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'] ) ? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'] : null ); |
|
330 | - $payment->set_details( $cdata_response_args ); |
|
331 | - $payment->set_gateway_response( isset( $docheckout_response_args['PAYMENTINFO_0_ACK'] ) ? $docheckout_response_args['PAYMENTINFO_0_ACK'] : '' ); |
|
332 | - $payment->set_status( $this->_pay_model->approved_status() ); |
|
327 | + $payment->set_extra_accntng($primary_registration_code); |
|
328 | + $payment->set_amount(isset($docheckout_response_args['PAYMENTINFO_0_AMT']) ? (float) $docheckout_response_args['PAYMENTINFO_0_AMT'] : 0); |
|
329 | + $payment->set_txn_id_chq_nmbr(isset($docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID']) ? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'] : null); |
|
330 | + $payment->set_details($cdata_response_args); |
|
331 | + $payment->set_gateway_response(isset($docheckout_response_args['PAYMENTINFO_0_ACK']) ? $docheckout_response_args['PAYMENTINFO_0_ACK'] : ''); |
|
332 | + $payment->set_status($this->_pay_model->approved_status()); |
|
333 | 333 | } else { |
334 | - if ( isset($docheckout_response_args['L_ERRORCODE']) ) { |
|
335 | - $payment->set_gateway_response( $docheckout_response_args['L_ERRORCODE'] . '; ' . $docheckout_response_args['L_SHORTMESSAGE'] ); |
|
334 | + if (isset($docheckout_response_args['L_ERRORCODE'])) { |
|
335 | + $payment->set_gateway_response($docheckout_response_args['L_ERRORCODE'].'; '.$docheckout_response_args['L_SHORTMESSAGE']); |
|
336 | 336 | } else { |
337 | - $payment->set_gateway_response( __( 'Error occurred while trying to Capture the funds.', 'event_espresso' ) ); |
|
337 | + $payment->set_gateway_response(__('Error occurred while trying to Capture the funds.', 'event_espresso')); |
|
338 | 338 | } |
339 | - $payment->set_details( $docheckout_response_args ); |
|
340 | - $payment->set_status( $this->_pay_model->declined_status() ); |
|
339 | + $payment->set_details($docheckout_response_args); |
|
340 | + $payment->set_status($this->_pay_model->declined_status()); |
|
341 | 341 | } |
342 | 342 | } else { |
343 | - if ( isset($cdata_response_args['L_ERRORCODE']) ) { |
|
344 | - $payment->set_gateway_response( $cdata_response_args['L_ERRORCODE'] . '; ' . $cdata_response_args['L_SHORTMESSAGE'] ); |
|
343 | + if (isset($cdata_response_args['L_ERRORCODE'])) { |
|
344 | + $payment->set_gateway_response($cdata_response_args['L_ERRORCODE'].'; '.$cdata_response_args['L_SHORTMESSAGE']); |
|
345 | 345 | } else { |
346 | - $payment->set_gateway_response( __( 'Error occurred while trying to get payment Details from PayPal.', 'event_espresso' ) ); |
|
346 | + $payment->set_gateway_response(__('Error occurred while trying to get payment Details from PayPal.', 'event_espresso')); |
|
347 | 347 | } |
348 | - $payment->set_details( $cdata_response_args ); |
|
349 | - $payment->set_status( $this->_pay_model->failed_status() ); |
|
348 | + $payment->set_details($cdata_response_args); |
|
349 | + $payment->set_status($this->_pay_model->failed_status()); |
|
350 | 350 | } |
351 | 351 | } else { |
352 | - $payment->set_gateway_response( __( 'Error occurred while trying to process the payment.', 'event_espresso' ) ); |
|
353 | - $payment->set_status( $this->_pay_model->failed_status() ); |
|
352 | + $payment->set_gateway_response(__('Error occurred while trying to process the payment.', 'event_espresso')); |
|
353 | + $payment->set_status($this->_pay_model->failed_status()); |
|
354 | 354 | } |
355 | 355 | |
356 | 356 | return $payment; |
@@ -365,16 +365,16 @@ discard block |
||
365 | 365 | * @param EEI_Payment $payment |
366 | 366 | * @return mixed |
367 | 367 | */ |
368 | - public function _ppExpress_request( $request_params, $request_text, $payment ) { |
|
368 | + public function _ppExpress_request($request_params, $request_text, $payment) { |
|
369 | 369 | $request_dtls = array( |
370 | 370 | 'VERSION' => '204.0', |
371 | - 'USER' => urlencode( $this->_api_username ), |
|
372 | - 'PWD' => urlencode( $this->_api_password ), |
|
373 | - 'SIGNATURE' => urlencode( $this->_api_signature ) |
|
371 | + 'USER' => urlencode($this->_api_username), |
|
372 | + 'PWD' => urlencode($this->_api_password), |
|
373 | + 'SIGNATURE' => urlencode($this->_api_signature) |
|
374 | 374 | ); |
375 | - $dtls = array_merge( $request_dtls, $request_params ); |
|
375 | + $dtls = array_merge($request_dtls, $request_params); |
|
376 | 376 | |
377 | - $this->_log_clean_request( $dtls, $payment, $request_text . ' Request' ); |
|
377 | + $this->_log_clean_request($dtls, $payment, $request_text.' Request'); |
|
378 | 378 | // Request Customer Details. |
379 | 379 | $request_response = wp_remote_post( |
380 | 380 | $this->_base_gateway_url, |
@@ -384,11 +384,11 @@ discard block |
||
384 | 384 | 'httpversion' => '1.1', |
385 | 385 | 'cookies' => array(), |
386 | 386 | 'headers' => array(), |
387 | - 'body' => http_build_query( $dtls ) |
|
387 | + 'body' => http_build_query($dtls) |
|
388 | 388 | ) |
389 | 389 | ); |
390 | 390 | // Log the response. |
391 | - $this->log( array( $request_text . ' Response' => $request_response), $payment ); |
|
391 | + $this->log(array($request_text.' Response' => $request_response), $payment); |
|
392 | 392 | |
393 | 393 | return $request_response; |
394 | 394 | } |
@@ -400,13 +400,13 @@ discard block |
||
400 | 400 | * @param mixed $request_response |
401 | 401 | * @return array |
402 | 402 | */ |
403 | - public function _ppExpress_check_response( $request_response ) { |
|
404 | - if (empty($request_response['body']) || is_wp_error( $request_response ) ) { |
|
403 | + public function _ppExpress_check_response($request_response) { |
|
404 | + if (empty($request_response['body']) || is_wp_error($request_response)) { |
|
405 | 405 | // If we got here then there was an error in this request. |
406 | 406 | return array('status' => false, 'args' => $request_response); |
407 | 407 | } |
408 | 408 | $response_args = array(); |
409 | - parse_str( urldecode($request_response['body']), $response_args ); |
|
409 | + parse_str(urldecode($request_response['body']), $response_args); |
|
410 | 410 | if ( ! isset($response_args['ACK'])) { |
411 | 411 | return array('status' => false, 'args' => $request_response); |
412 | 412 | } |
@@ -436,10 +436,10 @@ discard block |
||
436 | 436 | * @param string $info |
437 | 437 | * @return void |
438 | 438 | */ |
439 | - private function _log_clean_request($request, $payment, $info ) { |
|
439 | + private function _log_clean_request($request, $payment, $info) { |
|
440 | 440 | $cleaned_request_data = $request; |
441 | 441 | unset($cleaned_request_data['PWD'], $cleaned_request_data['USER'], $cleaned_request_data['SIGNATURE']); |
442 | - $this->log( array($info => $cleaned_request_data), $payment ); |
|
442 | + $this->log(array($info => $cleaned_request_data), $payment); |
|
443 | 443 | } |
444 | 444 | |
445 | 445 | |
@@ -449,10 +449,10 @@ discard block |
||
449 | 449 | * @param array $data_array |
450 | 450 | * @return array |
451 | 451 | */ |
452 | - private function _get_errors( $data_array ) { |
|
452 | + private function _get_errors($data_array) { |
|
453 | 453 | $errors = array(); |
454 | 454 | $n = 0; |
455 | - while ( isset($data_array["L_ERRORCODE{$n}"]) ) { |
|
455 | + while (isset($data_array["L_ERRORCODE{$n}"])) { |
|
456 | 456 | $l_error_code = isset($data_array["L_ERRORCODE{$n}"]) |
457 | 457 | ? $data_array["L_ERRORCODE{$n}"] |
458 | 458 | : ''; |
@@ -466,7 +466,7 @@ discard block |
||
466 | 466 | ? $data_array["L_LONGMESSAGE{$n}"] |
467 | 467 | : ''; |
468 | 468 | |
469 | - if ( $n === 0 ) { |
|
469 | + if ($n === 0) { |
|
470 | 470 | $errors = array( |
471 | 471 | 'L_ERRORCODE' => $l_error_code, |
472 | 472 | 'L_SHORTMESSAGE' => $l_short_message, |
@@ -474,10 +474,10 @@ discard block |
||
474 | 474 | 'L_SEVERITYCODE' => $l_severity_code |
475 | 475 | ); |
476 | 476 | } else { |
477 | - $errors['L_ERRORCODE'] .= ', ' . $l_error_code; |
|
478 | - $errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message; |
|
479 | - $errors['L_LONGMESSAGE'] .= ', ' . $l_long_message; |
|
480 | - $errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code; |
|
477 | + $errors['L_ERRORCODE'] .= ', '.$l_error_code; |
|
478 | + $errors['L_SHORTMESSAGE'] .= ', '.$l_short_message; |
|
479 | + $errors['L_LONGMESSAGE'] .= ', '.$l_long_message; |
|
480 | + $errors['L_SEVERITYCODE'] .= ', '.$l_severity_code; |
|
481 | 481 | } |
482 | 482 | |
483 | 483 | $n++; |
@@ -17,216 +17,214 @@ |
||
17 | 17 | class TableManager extends \EE_Base |
18 | 18 | { |
19 | 19 | |
20 | - /** |
|
21 | - * @var TableAnalysis $table_analysis |
|
22 | - */ |
|
23 | - private $table_analysis; |
|
24 | - |
|
25 | - |
|
26 | - |
|
27 | - /** |
|
28 | - * TableManager constructor. |
|
29 | - * |
|
30 | - * @param TableAnalysis $TableAnalysis |
|
31 | - */ |
|
32 | - public function __construct(TableAnalysis $TableAnalysis) |
|
33 | - { |
|
34 | - $this->table_analysis = $TableAnalysis; |
|
35 | - } |
|
36 | - |
|
37 | - |
|
38 | - |
|
39 | - /** |
|
40 | - * Gets the injected table analyzer, or throws an exception |
|
41 | - * |
|
42 | - * @return TableAnalysis |
|
43 | - * @throws \EE_Error |
|
44 | - */ |
|
45 | - protected function getTableAnalysis() |
|
46 | - { |
|
47 | - if ($this->table_analysis instanceof TableAnalysis) { |
|
48 | - return $this->table_analysis; |
|
49 | - } else { |
|
50 | - throw new \EE_Error( |
|
51 | - sprintf( |
|
52 | - __('Table analysis class on class %1$s is not set properly.', 'event_espresso'), |
|
53 | - get_class($this) |
|
54 | - ) |
|
55 | - ); |
|
56 | - } |
|
57 | - } |
|
58 | - |
|
59 | - |
|
60 | - |
|
61 | - /** |
|
62 | - * @param string $table_name which can optionally start with $wpdb->prefix or not |
|
63 | - * @param string $column_name |
|
64 | - * @param string $column_info |
|
65 | - * @return bool|false|int |
|
66 | - */ |
|
67 | - public function addColumn($table_name, $column_name, $column_info = 'INT UNSIGNED NOT NULL') |
|
68 | - { |
|
69 | - if (apply_filters('FHEE__EEH_Activation__add_column_if_it_doesnt_exist__short_circuit', false)) { |
|
70 | - return false; |
|
71 | - } |
|
72 | - global $wpdb; |
|
73 | - $full_table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
74 | - $columns = $this->getTableColumns($table_name); |
|
75 | - if ( ! in_array($column_name, $columns)) { |
|
76 | - $alter_query = "ALTER TABLE {$full_table_name} ADD {$column_name} {$column_info}"; |
|
77 | - return $wpdb->query($alter_query); |
|
78 | - } |
|
79 | - return true; |
|
80 | - } |
|
81 | - |
|
82 | - |
|
83 | - |
|
84 | - /** |
|
85 | - * Gets the name of all columns on the table. $table_name can |
|
86 | - * optionally start with $wpdb->prefix or not |
|
87 | - * |
|
88 | - * @global \wpdb $wpdb |
|
89 | - * @param string $table_name |
|
90 | - * @return array |
|
91 | - */ |
|
92 | - public function getTableColumns($table_name) |
|
93 | - { |
|
94 | - global $wpdb; |
|
95 | - $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
96 | - $field_array = array(); |
|
97 | - if ( ! empty($table_name)) { |
|
98 | - $columns = $wpdb->get_results("SHOW COLUMNS FROM {$table_name} "); |
|
99 | - if ($columns !== false) { |
|
100 | - foreach ($columns as $column) { |
|
101 | - $field_array[] = $column->Field; |
|
102 | - } |
|
103 | - } |
|
104 | - } |
|
105 | - return $field_array; |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - |
|
110 | - /** |
|
111 | - * Drops the specified table from the database. $table_name can |
|
112 | - * optionally start with $wpdb->prefix or not |
|
113 | - * |
|
114 | - * @global \wpdb $wpdb |
|
115 | - * @param string $table_name |
|
116 | - * @return int |
|
117 | - */ |
|
118 | - public function dropTable($table_name) |
|
119 | - { |
|
120 | - global $wpdb; |
|
121 | - if ($this->getTableAnalysis()->tableExists($table_name)) { |
|
122 | - $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
123 | - return $wpdb->query("DROP TABLE IF EXISTS {$table_name}"); |
|
124 | - } |
|
125 | - return 0; |
|
126 | - } |
|
127 | - |
|
128 | - |
|
129 | - |
|
130 | - /** |
|
131 | - * Drops all the tables mentioned in a single MYSQL query. Double-checks |
|
132 | - * each table name provided has a wpdb prefix attached, and that it exists. |
|
133 | - * Returns the list actually deleted |
|
134 | - * |
|
135 | - * @global WPDB $wpdb |
|
136 | - * @param array $table_names |
|
137 | - * @return array of table names which we deleted |
|
138 | - */ |
|
139 | - public function dropTables($table_names) |
|
140 | - { |
|
141 | - $tables_to_delete = array(); |
|
142 | - foreach ($table_names as $table_name) { |
|
143 | - $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
144 | - if ($this->getTableAnalysis()->tableExists($table_name)) { |
|
145 | - $tables_to_delete[] = $table_name; |
|
146 | - } |
|
147 | - } |
|
148 | - if( ! empty( $tables_to_delete ) ) { |
|
149 | - global $wpdb; |
|
150 | - $wpdb->query('DROP TABLE ' . implode(', ', $tables_to_delete)); |
|
151 | - } |
|
152 | - return $tables_to_delete; |
|
153 | - } |
|
154 | - |
|
155 | - |
|
156 | - |
|
157 | - /** |
|
158 | - * Drops the specified index from the specified table. $table_name can |
|
159 | - * optionally start with $wpdb->prefix or not |
|
160 | - |
|
161 | - * |
|
20 | + /** |
|
21 | + * @var TableAnalysis $table_analysis |
|
22 | + */ |
|
23 | + private $table_analysis; |
|
24 | + |
|
25 | + |
|
26 | + |
|
27 | + /** |
|
28 | + * TableManager constructor. |
|
29 | + * |
|
30 | + * @param TableAnalysis $TableAnalysis |
|
31 | + */ |
|
32 | + public function __construct(TableAnalysis $TableAnalysis) |
|
33 | + { |
|
34 | + $this->table_analysis = $TableAnalysis; |
|
35 | + } |
|
36 | + |
|
37 | + |
|
38 | + |
|
39 | + /** |
|
40 | + * Gets the injected table analyzer, or throws an exception |
|
41 | + * |
|
42 | + * @return TableAnalysis |
|
43 | + * @throws \EE_Error |
|
44 | + */ |
|
45 | + protected function getTableAnalysis() |
|
46 | + { |
|
47 | + if ($this->table_analysis instanceof TableAnalysis) { |
|
48 | + return $this->table_analysis; |
|
49 | + } else { |
|
50 | + throw new \EE_Error( |
|
51 | + sprintf( |
|
52 | + __('Table analysis class on class %1$s is not set properly.', 'event_espresso'), |
|
53 | + get_class($this) |
|
54 | + ) |
|
55 | + ); |
|
56 | + } |
|
57 | + } |
|
58 | + |
|
59 | + |
|
60 | + |
|
61 | + /** |
|
62 | + * @param string $table_name which can optionally start with $wpdb->prefix or not |
|
63 | + * @param string $column_name |
|
64 | + * @param string $column_info |
|
65 | + * @return bool|false|int |
|
66 | + */ |
|
67 | + public function addColumn($table_name, $column_name, $column_info = 'INT UNSIGNED NOT NULL') |
|
68 | + { |
|
69 | + if (apply_filters('FHEE__EEH_Activation__add_column_if_it_doesnt_exist__short_circuit', false)) { |
|
70 | + return false; |
|
71 | + } |
|
72 | + global $wpdb; |
|
73 | + $full_table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
74 | + $columns = $this->getTableColumns($table_name); |
|
75 | + if ( ! in_array($column_name, $columns)) { |
|
76 | + $alter_query = "ALTER TABLE {$full_table_name} ADD {$column_name} {$column_info}"; |
|
77 | + return $wpdb->query($alter_query); |
|
78 | + } |
|
79 | + return true; |
|
80 | + } |
|
81 | + |
|
82 | + |
|
83 | + |
|
84 | + /** |
|
85 | + * Gets the name of all columns on the table. $table_name can |
|
86 | + * optionally start with $wpdb->prefix or not |
|
87 | + * |
|
88 | + * @global \wpdb $wpdb |
|
89 | + * @param string $table_name |
|
90 | + * @return array |
|
91 | + */ |
|
92 | + public function getTableColumns($table_name) |
|
93 | + { |
|
94 | + global $wpdb; |
|
95 | + $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
96 | + $field_array = array(); |
|
97 | + if ( ! empty($table_name)) { |
|
98 | + $columns = $wpdb->get_results("SHOW COLUMNS FROM {$table_name} "); |
|
99 | + if ($columns !== false) { |
|
100 | + foreach ($columns as $column) { |
|
101 | + $field_array[] = $column->Field; |
|
102 | + } |
|
103 | + } |
|
104 | + } |
|
105 | + return $field_array; |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + |
|
110 | + /** |
|
111 | + * Drops the specified table from the database. $table_name can |
|
112 | + * optionally start with $wpdb->prefix or not |
|
113 | + * |
|
114 | + * @global \wpdb $wpdb |
|
115 | + * @param string $table_name |
|
116 | + * @return int |
|
117 | + */ |
|
118 | + public function dropTable($table_name) |
|
119 | + { |
|
120 | + global $wpdb; |
|
121 | + if ($this->getTableAnalysis()->tableExists($table_name)) { |
|
122 | + $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
123 | + return $wpdb->query("DROP TABLE IF EXISTS {$table_name}"); |
|
124 | + } |
|
125 | + return 0; |
|
126 | + } |
|
127 | + |
|
128 | + |
|
129 | + |
|
130 | + /** |
|
131 | + * Drops all the tables mentioned in a single MYSQL query. Double-checks |
|
132 | + * each table name provided has a wpdb prefix attached, and that it exists. |
|
133 | + * Returns the list actually deleted |
|
134 | + * |
|
135 | + * @global WPDB $wpdb |
|
136 | + * @param array $table_names |
|
137 | + * @return array of table names which we deleted |
|
138 | + */ |
|
139 | + public function dropTables($table_names) |
|
140 | + { |
|
141 | + $tables_to_delete = array(); |
|
142 | + foreach ($table_names as $table_name) { |
|
143 | + $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
144 | + if ($this->getTableAnalysis()->tableExists($table_name)) { |
|
145 | + $tables_to_delete[] = $table_name; |
|
146 | + } |
|
147 | + } |
|
148 | + if( ! empty( $tables_to_delete ) ) { |
|
149 | + global $wpdb; |
|
150 | + $wpdb->query('DROP TABLE ' . implode(', ', $tables_to_delete)); |
|
151 | + } |
|
152 | + return $tables_to_delete; |
|
153 | + } |
|
154 | + |
|
155 | + |
|
156 | + |
|
157 | + /** |
|
158 | + * Drops the specified index from the specified table. $table_name can |
|
159 | + * optionally start with $wpdb->prefix or not |
|
160 | + * |
|
162 | 161 | *@global \wpdb $wpdb |
163 | - * @param string $table_name |
|
164 | - * @param string $index_name |
|
165 | - * @return int |
|
166 | - */ |
|
167 | - public function dropIndex($table_name, $index_name) |
|
168 | - { |
|
169 | - if (apply_filters('FHEE__EEH_Activation__drop_index__short_circuit', false)) { |
|
170 | - return false; |
|
171 | - } |
|
172 | - global $wpdb; |
|
173 | - $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
174 | - $index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'"; |
|
175 | - if ( |
|
176 | - $this->getTableAnalysis()->tableExists($table_name) |
|
177 | - && $wpdb->get_var($index_exists_query) |
|
178 | - === $table_name //using get_var with the $index_exists_query returns the table's name |
|
179 | - ) { |
|
180 | - return $wpdb->query("ALTER TABLE {$table_name} DROP INDEX {$index_name}"); |
|
181 | - } |
|
182 | - return 0; |
|
183 | - } |
|
184 | - |
|
185 | - |
|
186 | - |
|
187 | - /** |
|
188 | - * Just creates the requested table. $table_name can |
|
189 | - * optionally start with $wpdb->prefix or not |
|
190 | - |
|
191 | - * |
|
162 | + * @param string $table_name |
|
163 | + * @param string $index_name |
|
164 | + * @return int |
|
165 | + */ |
|
166 | + public function dropIndex($table_name, $index_name) |
|
167 | + { |
|
168 | + if (apply_filters('FHEE__EEH_Activation__drop_index__short_circuit', false)) { |
|
169 | + return false; |
|
170 | + } |
|
171 | + global $wpdb; |
|
172 | + $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
173 | + $index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'"; |
|
174 | + if ( |
|
175 | + $this->getTableAnalysis()->tableExists($table_name) |
|
176 | + && $wpdb->get_var($index_exists_query) |
|
177 | + === $table_name //using get_var with the $index_exists_query returns the table's name |
|
178 | + ) { |
|
179 | + return $wpdb->query("ALTER TABLE {$table_name} DROP INDEX {$index_name}"); |
|
180 | + } |
|
181 | + return 0; |
|
182 | + } |
|
183 | + |
|
184 | + |
|
185 | + |
|
186 | + /** |
|
187 | + * Just creates the requested table. $table_name can |
|
188 | + * optionally start with $wpdb->prefix or not |
|
189 | + * |
|
192 | 190 | *@param string $table_name |
193 | - * @param string $create_sql defining the table's columns and indexes |
|
194 | - * @param string $engine (no need to specify "ENGINE=", that's implied) |
|
195 | - * @return void |
|
196 | - * @throws \EE_Error |
|
197 | - */ |
|
198 | - public function createTable($table_name, $create_sql, $engine = 'MyISAM') |
|
199 | - { |
|
200 | - // does $sql contain valid column information? ( LPT: https://regex101.com/ is great for working out regex patterns ) |
|
201 | - if (preg_match('((((.*?))(,\s))+)', $create_sql, $valid_column_data)) { |
|
202 | - $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
203 | - /** @var \wpdb $wpdb */ |
|
204 | - global $wpdb; |
|
205 | - $SQL = "CREATE TABLE {$table_name} ( {$create_sql} ) ENGINE={$engine} " . $wpdb->get_charset_collate(); |
|
206 | - |
|
207 | - //get $wpdb to echo errors, but buffer them. This way at least WE know an error |
|
208 | - //happened. And then we can choose to tell the end user |
|
209 | - $old_show_errors_policy = $wpdb->show_errors(true); |
|
210 | - $old_error_suppression_policy = $wpdb->suppress_errors(false); |
|
211 | - ob_start(); |
|
212 | - dbDelta($SQL); |
|
213 | - $output = ob_get_contents(); |
|
214 | - ob_end_clean(); |
|
215 | - $wpdb->show_errors($old_show_errors_policy); |
|
216 | - $wpdb->suppress_errors($old_error_suppression_policy); |
|
217 | - if ( ! empty($output)) { |
|
218 | - throw new \EE_Error($output); |
|
219 | - } |
|
220 | - } else { |
|
221 | - throw new \EE_Error( |
|
222 | - sprintf( |
|
223 | - __('The following table creation SQL does not contain valid information about the table columns: %1$s %2$s', |
|
224 | - 'event_espresso'), |
|
225 | - '<br />', |
|
226 | - $create_sql |
|
227 | - ) |
|
228 | - ); |
|
229 | - } |
|
230 | - } |
|
191 | + * @param string $create_sql defining the table's columns and indexes |
|
192 | + * @param string $engine (no need to specify "ENGINE=", that's implied) |
|
193 | + * @return void |
|
194 | + * @throws \EE_Error |
|
195 | + */ |
|
196 | + public function createTable($table_name, $create_sql, $engine = 'MyISAM') |
|
197 | + { |
|
198 | + // does $sql contain valid column information? ( LPT: https://regex101.com/ is great for working out regex patterns ) |
|
199 | + if (preg_match('((((.*?))(,\s))+)', $create_sql, $valid_column_data)) { |
|
200 | + $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
|
201 | + /** @var \wpdb $wpdb */ |
|
202 | + global $wpdb; |
|
203 | + $SQL = "CREATE TABLE {$table_name} ( {$create_sql} ) ENGINE={$engine} " . $wpdb->get_charset_collate(); |
|
204 | + |
|
205 | + //get $wpdb to echo errors, but buffer them. This way at least WE know an error |
|
206 | + //happened. And then we can choose to tell the end user |
|
207 | + $old_show_errors_policy = $wpdb->show_errors(true); |
|
208 | + $old_error_suppression_policy = $wpdb->suppress_errors(false); |
|
209 | + ob_start(); |
|
210 | + dbDelta($SQL); |
|
211 | + $output = ob_get_contents(); |
|
212 | + ob_end_clean(); |
|
213 | + $wpdb->show_errors($old_show_errors_policy); |
|
214 | + $wpdb->suppress_errors($old_error_suppression_policy); |
|
215 | + if ( ! empty($output)) { |
|
216 | + throw new \EE_Error($output); |
|
217 | + } |
|
218 | + } else { |
|
219 | + throw new \EE_Error( |
|
220 | + sprintf( |
|
221 | + __('The following table creation SQL does not contain valid information about the table columns: %1$s %2$s', |
|
222 | + 'event_espresso'), |
|
223 | + '<br />', |
|
224 | + $create_sql |
|
225 | + ) |
|
226 | + ); |
|
227 | + } |
|
228 | + } |
|
231 | 229 | |
232 | 230 | } |
@@ -145,9 +145,9 @@ discard block |
||
145 | 145 | $tables_to_delete[] = $table_name; |
146 | 146 | } |
147 | 147 | } |
148 | - if( ! empty( $tables_to_delete ) ) { |
|
148 | + if ( ! empty($tables_to_delete)) { |
|
149 | 149 | global $wpdb; |
150 | - $wpdb->query('DROP TABLE ' . implode(', ', $tables_to_delete)); |
|
150 | + $wpdb->query('DROP TABLE '.implode(', ', $tables_to_delete)); |
|
151 | 151 | } |
152 | 152 | return $tables_to_delete; |
153 | 153 | } |
@@ -202,7 +202,7 @@ discard block |
||
202 | 202 | $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name); |
203 | 203 | /** @var \wpdb $wpdb */ |
204 | 204 | global $wpdb; |
205 | - $SQL = "CREATE TABLE {$table_name} ( {$create_sql} ) ENGINE={$engine} " . $wpdb->get_charset_collate(); |
|
205 | + $SQL = "CREATE TABLE {$table_name} ( {$create_sql} ) ENGINE={$engine} ".$wpdb->get_charset_collate(); |
|
206 | 206 | |
207 | 207 | //get $wpdb to echo errors, but buffer them. This way at least WE know an error |
208 | 208 | //happened. And then we can choose to tell the end user |
@@ -1,16 +1,16 @@ discard block |
||
1 | 1 | <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); } |
2 | 2 | /** |
3 | - * |
|
4 | - * Class EE_SPCO_Reg_Step_Attendee_Information |
|
5 | - * |
|
6 | - * Description |
|
7 | - * |
|
8 | - * @package Event Espresso |
|
9 | - * @subpackage core |
|
10 | - * @author Brent Christensen |
|
11 | - * @since 4.5.0 |
|
12 | - * |
|
13 | - */ |
|
3 | + * |
|
4 | + * Class EE_SPCO_Reg_Step_Attendee_Information |
|
5 | + * |
|
6 | + * Description |
|
7 | + * |
|
8 | + * @package Event Espresso |
|
9 | + * @subpackage core |
|
10 | + * @author Brent Christensen |
|
11 | + * @since 4.5.0 |
|
12 | + * |
|
13 | + */ |
|
14 | 14 | class EE_SPCO_Reg_Step_Attendee_Information extends EE_SPCO_Reg_Step { |
15 | 15 | |
16 | 16 | /** |
@@ -135,33 +135,33 @@ discard block |
||
135 | 135 | $registration instanceof EE_Registration |
136 | 136 | && $this->checkout->visit_allows_processing_of_this_registration( $registration ) |
137 | 137 | ) { |
138 | - $attendee_reg_form = $this->_registrations_reg_form($registration); |
|
139 | - if ($attendee_reg_form instanceof EE_Form_Section_Proper) { |
|
140 | - $subsections[$registration->reg_url_link()] = $attendee_reg_form; |
|
141 | - if ( ! $this->checkout->admin_request) { |
|
142 | - $template_args['registrations'][$registration->reg_url_link()] = $registration; |
|
143 | - $template_args['ticket_count'][$registration->ticket()->ID()] = isset( |
|
144 | - $template_args['ticket_count'][$registration->ticket()->ID()] |
|
145 | - ) |
|
146 | - ? $template_args['ticket_count'][$registration->ticket()->ID()] + 1 |
|
147 | - : 1; |
|
148 | - $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
149 | - $this->checkout->cart->get_grand_total(), |
|
150 | - 'Ticket', |
|
151 | - array($registration->ticket()->ID()) |
|
152 | - ); |
|
153 | - $ticket_line_item = is_array($ticket_line_item) |
|
154 | - ? reset($ticket_line_item) |
|
155 | - : $ticket_line_item; |
|
156 | - $template_args['ticket_line_item'][$registration->ticket() |
|
157 | - ->ID()] = $Line_Item_Display->display_line_item( |
|
158 | - $ticket_line_item |
|
159 | - ); |
|
160 | - } |
|
161 | - } |
|
162 | - if ($registration->is_primary_registrant()) { |
|
163 | - $primary_registrant = $registration->reg_url_link(); |
|
164 | - } |
|
138 | + $attendee_reg_form = $this->_registrations_reg_form($registration); |
|
139 | + if ($attendee_reg_form instanceof EE_Form_Section_Proper) { |
|
140 | + $subsections[$registration->reg_url_link()] = $attendee_reg_form; |
|
141 | + if ( ! $this->checkout->admin_request) { |
|
142 | + $template_args['registrations'][$registration->reg_url_link()] = $registration; |
|
143 | + $template_args['ticket_count'][$registration->ticket()->ID()] = isset( |
|
144 | + $template_args['ticket_count'][$registration->ticket()->ID()] |
|
145 | + ) |
|
146 | + ? $template_args['ticket_count'][$registration->ticket()->ID()] + 1 |
|
147 | + : 1; |
|
148 | + $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
149 | + $this->checkout->cart->get_grand_total(), |
|
150 | + 'Ticket', |
|
151 | + array($registration->ticket()->ID()) |
|
152 | + ); |
|
153 | + $ticket_line_item = is_array($ticket_line_item) |
|
154 | + ? reset($ticket_line_item) |
|
155 | + : $ticket_line_item; |
|
156 | + $template_args['ticket_line_item'][$registration->ticket() |
|
157 | + ->ID()] = $Line_Item_Display->display_line_item( |
|
158 | + $ticket_line_item |
|
159 | + ); |
|
160 | + } |
|
161 | + } |
|
162 | + if ($registration->is_primary_registrant()) { |
|
163 | + $primary_registrant = $registration->reg_url_link(); |
|
164 | + } |
|
165 | 165 | } |
166 | 166 | } |
167 | 167 | // print_copy_info ? |
@@ -173,7 +173,7 @@ discard block |
||
173 | 173 | // generate hidden input |
174 | 174 | if ( |
175 | 175 | isset( $subsections[ $primary_registrant ] ) |
176 | - && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper |
|
176 | + && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper |
|
177 | 177 | ) { |
178 | 178 | $subsections[ $primary_registrant ]->add_subsections( $copy_options, 'primary_registrant', false ); |
179 | 179 | } |
@@ -208,35 +208,35 @@ discard block |
||
208 | 208 | */ |
209 | 209 | private function _registrations_reg_form( EE_Registration $registration ) { |
210 | 210 | static $attendee_nmbr = 1; |
211 | - $form_args = array(); |
|
211 | + $form_args = array(); |
|
212 | 212 | // verify that registration has valid event |
213 | 213 | if ( $registration->event() instanceof EE_Event ) { |
214 | 214 | $question_groups = $registration->event()->question_groups( |
215 | - array( |
|
216 | - array( |
|
217 | - 'Event.EVT_ID' => $registration->event()->ID(), |
|
218 | - 'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false |
|
219 | - ), |
|
220 | - 'order_by' => array('QSG_order' => 'ASC') |
|
221 | - ) |
|
222 | - ); |
|
215 | + array( |
|
216 | + array( |
|
217 | + 'Event.EVT_ID' => $registration->event()->ID(), |
|
218 | + 'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false |
|
219 | + ), |
|
220 | + 'order_by' => array('QSG_order' => 'ASC') |
|
221 | + ) |
|
222 | + ); |
|
223 | 223 | if ( $question_groups ) { |
224 | - // array of params to pass to parent constructor |
|
225 | - $form_args = array( |
|
226 | - 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
227 | - 'html_class' => 'ee-reg-form-attendee-dv', |
|
228 | - 'html_style' => $this->checkout->admin_request |
|
229 | - ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
|
230 | - : '', |
|
231 | - 'subsections' => array(), |
|
232 | - 'layout_strategy' => new EE_Fieldset_Section_Layout( |
|
233 | - array( |
|
234 | - 'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text', |
|
235 | - 'legend_text' => sprintf(__('Attendee %d', 'event_espresso'), $attendee_nmbr) |
|
236 | - ) |
|
237 | - ) |
|
238 | - ); |
|
239 | - foreach ( $question_groups as $question_group ) { |
|
224 | + // array of params to pass to parent constructor |
|
225 | + $form_args = array( |
|
226 | + 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
227 | + 'html_class' => 'ee-reg-form-attendee-dv', |
|
228 | + 'html_style' => $this->checkout->admin_request |
|
229 | + ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
|
230 | + : '', |
|
231 | + 'subsections' => array(), |
|
232 | + 'layout_strategy' => new EE_Fieldset_Section_Layout( |
|
233 | + array( |
|
234 | + 'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text', |
|
235 | + 'legend_text' => sprintf(__('Attendee %d', 'event_espresso'), $attendee_nmbr) |
|
236 | + ) |
|
237 | + ) |
|
238 | + ); |
|
239 | + foreach ( $question_groups as $question_group ) { |
|
240 | 240 | if ( $question_group instanceof EE_Question_Group ) { |
241 | 241 | $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form( |
242 | 242 | $registration, |
@@ -244,19 +244,19 @@ discard block |
||
244 | 244 | ); |
245 | 245 | } |
246 | 246 | } |
247 | - // add hidden input |
|
248 | - $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input( |
|
249 | - $registration |
|
250 | - ); |
|
251 | - // if we have question groups for additional attendees, then display the copy options |
|
247 | + // add hidden input |
|
248 | + $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input( |
|
249 | + $registration |
|
250 | + ); |
|
251 | + // if we have question groups for additional attendees, then display the copy options |
|
252 | 252 | $this->_print_copy_info = $attendee_nmbr > 1 ? true : $this->_print_copy_info; |
253 | - if ($registration->is_primary_registrant()) { |
|
254 | - // generate hidden input |
|
255 | - $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs($registration); |
|
256 | - } |
|
257 | - } |
|
253 | + if ($registration->is_primary_registrant()) { |
|
254 | + // generate hidden input |
|
255 | + $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs($registration); |
|
256 | + } |
|
257 | + } |
|
258 | 258 | } |
259 | - $attendee_nmbr++; |
|
259 | + $attendee_nmbr++; |
|
260 | 260 | return ! empty($form_args) ? new EE_Form_Section_Proper( $form_args ) : null; |
261 | 261 | } |
262 | 262 | |
@@ -889,7 +889,7 @@ discard block |
||
889 | 889 | if ( isset( $valid_data[ $reg_url_link ] ) ) { |
890 | 890 | // do we need to copy basic info from primary attendee ? |
891 | 891 | $copy_primary = isset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ) |
892 | - && absint( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ) === 0 |
|
892 | + && absint( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ) === 0 |
|
893 | 893 | ? true |
894 | 894 | : false; |
895 | 895 | // filter form input data for this registration |
@@ -1064,7 +1064,7 @@ discard block |
||
1064 | 1064 | ? $form_input |
1065 | 1065 | : $form_input . '-' . $registration->reg_url_link(); |
1066 | 1066 | $answer_is_obj = isset( $this->_registration_answers[ $answer_cache_id ] ) |
1067 | - && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer |
|
1067 | + && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer |
|
1068 | 1068 | ? true |
1069 | 1069 | : false; |
1070 | 1070 | //rename form_inputs if they are EE_Attendee properties |
@@ -1184,7 +1184,7 @@ discard block |
||
1184 | 1184 | // then attempt to copy them from the primary attendee |
1185 | 1185 | if ( |
1186 | 1186 | $this->checkout->primary_attendee_obj instanceof EE_Attendee |
1187 | - && ! isset( $attendee_data['ATT_fname'], $attendee_data['ATT_email'] ) |
|
1187 | + && ! isset( $attendee_data['ATT_fname'], $attendee_data['ATT_email'] ) |
|
1188 | 1188 | ) { |
1189 | 1189 | return $this->checkout->primary_attendee_obj; |
1190 | 1190 | } |
@@ -1302,7 +1302,7 @@ discard block |
||
1302 | 1302 | } |
1303 | 1303 | foreach ( $critical_attendee_details as $critical_attendee_detail ) { |
1304 | 1304 | if ( ! isset( $attendee_data[ $critical_attendee_detail ] ) |
1305 | - || empty( $attendee_data[ $critical_attendee_detail ] ) |
|
1305 | + || empty( $attendee_data[ $critical_attendee_detail ] ) |
|
1306 | 1306 | ) { |
1307 | 1307 | $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get( |
1308 | 1308 | $critical_attendee_detail |
@@ -41,21 +41,21 @@ discard block |
||
41 | 41 | * @access public |
42 | 42 | * @param EE_Checkout $checkout |
43 | 43 | */ |
44 | - public function __construct( EE_Checkout $checkout ) { |
|
44 | + public function __construct(EE_Checkout $checkout) { |
|
45 | 45 | $this->_slug = 'attendee_information'; |
46 | 46 | $this->_name = __('Attendee Information', 'event_espresso'); |
47 | - $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php'; |
|
47 | + $this->_template = SPCO_REG_STEPS_PATH.$this->_slug.DS.'attendee_info_main.template.php'; |
|
48 | 48 | $this->checkout = $checkout; |
49 | 49 | $this->_reset_success_message(); |
50 | 50 | $this->set_instructions( |
51 | - __( 'Please answer the following registration questions before proceeding.', 'event_espresso' ) |
|
51 | + __('Please answer the following registration questions before proceeding.', 'event_espresso') |
|
52 | 52 | ); |
53 | 53 | } |
54 | 54 | |
55 | 55 | |
56 | 56 | |
57 | 57 | public function translate_js_strings() { |
58 | - EE_Registry::$i18n_js_strings['required_field'] = __( ' is a required question.', 'event_espresso' ); |
|
58 | + EE_Registry::$i18n_js_strings['required_field'] = __(' is a required question.', 'event_espresso'); |
|
59 | 59 | EE_Registry::$i18n_js_strings['required_multi_field'] = __( |
60 | 60 | ' is a required question. Please enter a value for at least one of the options.', |
61 | 61 | 'event_espresso' |
@@ -115,7 +115,7 @@ discard block |
||
115 | 115 | // calculate taxes |
116 | 116 | $Line_Item_Display->display_line_item( |
117 | 117 | $this->checkout->cart->get_grand_total(), |
118 | - array( 'set_tax_rate' => true ) |
|
118 | + array('set_tax_rate' => true) |
|
119 | 119 | ); |
120 | 120 | /** @var $subsections EE_Form_Section_Proper[] */ |
121 | 121 | $subsections = array( |
@@ -127,13 +127,13 @@ discard block |
||
127 | 127 | 'ticket_count' => array() |
128 | 128 | ); |
129 | 129 | // grab the saved registrations from the transaction |
130 | - $registrations = $this->checkout->transaction->registrations( $this->checkout->reg_cache_where_params ); |
|
131 | - if ( $registrations ) { |
|
132 | - foreach ( $registrations as $registration ) { |
|
130 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
131 | + if ($registrations) { |
|
132 | + foreach ($registrations as $registration) { |
|
133 | 133 | // can this registration be processed during this visit ? |
134 | 134 | if ( |
135 | 135 | $registration instanceof EE_Registration |
136 | - && $this->checkout->visit_allows_processing_of_this_registration( $registration ) |
|
136 | + && $this->checkout->visit_allows_processing_of_this_registration($registration) |
|
137 | 137 | ) { |
138 | 138 | $attendee_reg_form = $this->_registrations_reg_form($registration); |
139 | 139 | if ($attendee_reg_form instanceof EE_Form_Section_Proper) { |
@@ -165,17 +165,17 @@ discard block |
||
165 | 165 | } |
166 | 166 | } |
167 | 167 | // print_copy_info ? |
168 | - if ( $primary_registrant && ! $this->checkout->admin_request && count( $registrations ) > 1 ) { |
|
168 | + if ($primary_registrant && ! $this->checkout->admin_request && count($registrations) > 1) { |
|
169 | 169 | // TODO: add admin option for toggling copy attendee info, then use that value to change $this->_print_copy_info |
170 | 170 | $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info |
171 | 171 | ? $this->_copy_attendee_info_form() |
172 | 172 | : $this->_auto_copy_attendee_info(); |
173 | 173 | // generate hidden input |
174 | 174 | if ( |
175 | - isset( $subsections[ $primary_registrant ] ) |
|
176 | - && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper |
|
175 | + isset($subsections[$primary_registrant]) |
|
176 | + && $subsections[$primary_registrant] instanceof EE_Form_Section_Proper |
|
177 | 177 | ) { |
178 | - $subsections[ $primary_registrant ]->add_subsections( $copy_options, 'primary_registrant', false ); |
|
178 | + $subsections[$primary_registrant]->add_subsections($copy_options, 'primary_registrant', false); |
|
179 | 179 | } |
180 | 180 | } |
181 | 181 | |
@@ -187,8 +187,7 @@ discard block |
||
187 | 187 | 'html_id' => $this->reg_form_name(), |
188 | 188 | 'subsections' => $subsections, |
189 | 189 | 'layout_strategy' => $this->checkout->admin_request ? |
190 | - new EE_Div_Per_Section_Layout() : |
|
191 | - new EE_Template_Layout( |
|
190 | + new EE_Div_Per_Section_Layout() : new EE_Template_Layout( |
|
192 | 191 | array( |
193 | 192 | 'layout_template_file' => $this->_template, // layout_template |
194 | 193 | 'template_args' => $template_args |
@@ -206,11 +205,11 @@ discard block |
||
206 | 205 | * @return EE_Form_Section_Proper |
207 | 206 | * @throws \EE_Error |
208 | 207 | */ |
209 | - private function _registrations_reg_form( EE_Registration $registration ) { |
|
208 | + private function _registrations_reg_form(EE_Registration $registration) { |
|
210 | 209 | static $attendee_nmbr = 1; |
211 | 210 | $form_args = array(); |
212 | 211 | // verify that registration has valid event |
213 | - if ( $registration->event() instanceof EE_Event ) { |
|
212 | + if ($registration->event() instanceof EE_Event) { |
|
214 | 213 | $question_groups = $registration->event()->question_groups( |
215 | 214 | array( |
216 | 215 | array( |
@@ -220,10 +219,10 @@ discard block |
||
220 | 219 | 'order_by' => array('QSG_order' => 'ASC') |
221 | 220 | ) |
222 | 221 | ); |
223 | - if ( $question_groups ) { |
|
222 | + if ($question_groups) { |
|
224 | 223 | // array of params to pass to parent constructor |
225 | 224 | $form_args = array( |
226 | - 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
225 | + 'html_id' => 'ee-registration-'.$registration->reg_url_link(), |
|
227 | 226 | 'html_class' => 'ee-reg-form-attendee-dv', |
228 | 227 | 'html_style' => $this->checkout->admin_request |
229 | 228 | ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
@@ -236,9 +235,9 @@ discard block |
||
236 | 235 | ) |
237 | 236 | ) |
238 | 237 | ); |
239 | - foreach ( $question_groups as $question_group ) { |
|
240 | - if ( $question_group instanceof EE_Question_Group ) { |
|
241 | - $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form( |
|
238 | + foreach ($question_groups as $question_group) { |
|
239 | + if ($question_group instanceof EE_Question_Group) { |
|
240 | + $form_args['subsections'][$question_group->identifier()] = $this->_question_group_reg_form( |
|
242 | 241 | $registration, |
243 | 242 | $question_group |
244 | 243 | ); |
@@ -257,7 +256,7 @@ discard block |
||
257 | 256 | } |
258 | 257 | } |
259 | 258 | $attendee_nmbr++; |
260 | - return ! empty($form_args) ? new EE_Form_Section_Proper( $form_args ) : null; |
|
259 | + return ! empty($form_args) ? new EE_Form_Section_Proper($form_args) : null; |
|
261 | 260 | } |
262 | 261 | |
263 | 262 | |
@@ -278,7 +277,7 @@ discard block |
||
278 | 277 | // generate hidden input |
279 | 278 | return new EE_Hidden_Input( |
280 | 279 | array( |
281 | - 'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(), |
|
280 | + 'html_id' => 'additional-attendee-reg-info-'.$registration->reg_url_link(), |
|
282 | 281 | 'default' => $additional_attendee_reg_info |
283 | 282 | ) |
284 | 283 | ); |
@@ -292,26 +291,26 @@ discard block |
||
292 | 291 | * @return EE_Form_Section_Proper |
293 | 292 | * @throws \EE_Error |
294 | 293 | */ |
295 | - private function _question_group_reg_form( EE_Registration $registration, EE_Question_Group $question_group ){ |
|
294 | + private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group) { |
|
296 | 295 | // array of params to pass to parent constructor |
297 | 296 | $form_args = array( |
298 | - 'html_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier(), |
|
297 | + 'html_id' => 'ee-reg-form-qstn-grp-'.$question_group->identifier(), |
|
299 | 298 | 'html_class' => $this->checkout->admin_request |
300 | 299 | ? 'form-table ee-reg-form-qstn-grp-dv' |
301 | 300 | : 'ee-reg-form-qstn-grp-dv', |
302 | - 'html_label_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-lbl', |
|
301 | + 'html_label_id' => 'ee-reg-form-qstn-grp-'.$question_group->identifier().'-lbl', |
|
303 | 302 | 'subsections' => array( |
304 | - 'reg_form_qstn_grp_hdr' => $this->_question_group_header( $question_group ) |
|
303 | + 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group) |
|
305 | 304 | ), |
306 | 305 | 'layout_strategy' => $this->checkout->admin_request |
307 | 306 | ? new EE_Admin_Two_Column_Layout() |
308 | 307 | : new EE_Div_Per_Section_Layout() |
309 | 308 | ); |
310 | 309 | // where params |
311 | - $query_params = array( 'QST_deleted' => 0 ); |
|
310 | + $query_params = array('QST_deleted' => 0); |
|
312 | 311 | // don't load admin only questions on the frontend |
313 | - if ( ! $this->checkout->admin_request ) { |
|
314 | - $query_params['QST_admin_only'] = array( '!=', true ); |
|
312 | + if ( ! $this->checkout->admin_request) { |
|
313 | + $query_params['QST_admin_only'] = array('!=', true); |
|
315 | 314 | } |
316 | 315 | $questions = $question_group->get_many_related( |
317 | 316 | 'Question', |
@@ -333,10 +332,10 @@ discard block |
||
333 | 332 | ) |
334 | 333 | ); |
335 | 334 | // loop thru questions |
336 | - foreach ( $questions as $question ) { |
|
337 | - if( $question instanceof EE_Question ){ |
|
335 | + foreach ($questions as $question) { |
|
336 | + if ($question instanceof EE_Question) { |
|
338 | 337 | $identifier = $question->is_system_question() ? $question->system_ID() : $question->ID(); |
339 | - $form_args['subsections'][ $identifier ] = $this->reg_form_question( $registration, $question ); |
|
338 | + $form_args['subsections'][$identifier] = $this->reg_form_question($registration, $question); |
|
340 | 339 | } |
341 | 340 | } |
342 | 341 | $form_args['subsections'] = apply_filters( |
@@ -357,7 +356,7 @@ discard block |
||
357 | 356 | ) |
358 | 357 | ); |
359 | 358 | // d( $form_args ); |
360 | - $question_group_reg_form = new EE_Form_Section_Proper( $form_args ); |
|
359 | + $question_group_reg_form = new EE_Form_Section_Proper($form_args); |
|
361 | 360 | return apply_filters( |
362 | 361 | 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form', |
363 | 362 | $question_group_reg_form, |
@@ -374,11 +373,11 @@ discard block |
||
374 | 373 | * @param EE_Question_Group $question_group |
375 | 374 | * @return EE_Form_Section_HTML |
376 | 375 | */ |
377 | - private function _question_group_header( EE_Question_Group $question_group ){ |
|
376 | + private function _question_group_header(EE_Question_Group $question_group) { |
|
378 | 377 | $html = ''; |
379 | 378 | // group_name |
380 | - if ( $question_group->show_group_name() && $question_group->name() !== '' ) { |
|
381 | - if ( $this->checkout->admin_request ) { |
|
379 | + if ($question_group->show_group_name() && $question_group->name() !== '') { |
|
380 | + if ($this->checkout->admin_request) { |
|
382 | 381 | $html .= EEH_HTML::br(); |
383 | 382 | $html .= EEH_HTML::h3( |
384 | 383 | $question_group->name(), |
@@ -392,7 +391,7 @@ discard block |
||
392 | 391 | } |
393 | 392 | } |
394 | 393 | // group_desc |
395 | - if ( $question_group->show_group_desc() && $question_group->desc() !== '' ) { |
|
394 | + if ($question_group->show_group_desc() && $question_group->desc() !== '') { |
|
396 | 395 | $html .= EEH_HTML::p( |
397 | 396 | $question_group->desc(), |
398 | 397 | '', |
@@ -402,7 +401,7 @@ discard block |
||
402 | 401 | ); |
403 | 402 | |
404 | 403 | } |
405 | - return new EE_Form_Section_HTML( $html ); |
|
404 | + return new EE_Form_Section_HTML($html); |
|
406 | 405 | } |
407 | 406 | |
408 | 407 | |
@@ -412,7 +411,7 @@ discard block |
||
412 | 411 | * @return EE_Form_Section_Proper |
413 | 412 | * @throws \EE_Error |
414 | 413 | */ |
415 | - private function _copy_attendee_info_form(){ |
|
414 | + private function _copy_attendee_info_form() { |
|
416 | 415 | // array of params to pass to parent constructor |
417 | 416 | return new EE_Form_Section_Proper( |
418 | 417 | array( |
@@ -441,7 +440,7 @@ discard block |
||
441 | 440 | private function _auto_copy_attendee_info() { |
442 | 441 | return new EE_Form_Section_HTML( |
443 | 442 | EEH_Template::locate_template( |
444 | - SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php', |
|
443 | + SPCO_REG_STEPS_PATH.$this->_slug.DS.'_auto_copy_attendee_info.template.php', |
|
445 | 444 | apply_filters( |
446 | 445 | 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
447 | 446 | array() |
@@ -465,32 +464,32 @@ discard block |
||
465 | 464 | $copy_attendee_info_inputs = array(); |
466 | 465 | $prev_ticket = NULL; |
467 | 466 | // grab the saved registrations from the transaction |
468 | - $registrations = $this->checkout->transaction->registrations( $this->checkout->reg_cache_where_params ); |
|
469 | - foreach ( $registrations as $registration ) { |
|
467 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
468 | + foreach ($registrations as $registration) { |
|
470 | 469 | // for all attendees other than the primary attendee |
471 | - if ( $registration instanceof EE_Registration && ! $registration->is_primary_registrant() ) { |
|
470 | + if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) { |
|
472 | 471 | // if this is a new ticket OR if this is the very first additional attendee after the primary attendee |
473 | - if ( $registration->ticket()->ID() !== $prev_ticket ) { |
|
472 | + if ($registration->ticket()->ID() !== $prev_ticket) { |
|
474 | 473 | $item_name = $registration->ticket()->name(); |
475 | 474 | $item_name .= $registration->ticket()->description() !== '' |
476 | - ? ' - ' . $registration->ticket()->description() |
|
475 | + ? ' - '.$registration->ticket()->description() |
|
477 | 476 | : ''; |
478 | - $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']' ] = new EE_Form_Section_HTML( |
|
479 | - '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>' |
|
477 | + $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-'.$registration->ticket()->ID().']'] = new EE_Form_Section_HTML( |
|
478 | + '<h6 class="spco-copy-attendee-event-hdr">'.$item_name.'</h6>' |
|
480 | 479 | ); |
481 | 480 | $prev_ticket = $registration->ticket()->ID(); |
482 | 481 | } |
483 | 482 | |
484 | - $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] = new |
|
483 | + $copy_attendee_info_inputs['spco_copy_attendee_chk['.$registration->ID().']'] = new |
|
485 | 484 | EE_Checkbox_Multi_Input( |
486 | 485 | array( |
487 | 486 | $registration->ID() => sprintf( |
488 | - __( 'Attendee #%s', 'event_espresso' ), |
|
487 | + __('Attendee #%s', 'event_espresso'), |
|
489 | 488 | $registration->count() |
490 | 489 | ) |
491 | 490 | ), |
492 | 491 | array( |
493 | - 'html_id' => 'spco-copy-attendee-chk-' . $registration->reg_url_link(), |
|
492 | + 'html_id' => 'spco-copy-attendee-chk-'.$registration->reg_url_link(), |
|
494 | 493 | 'html_class' => 'spco-copy-attendee-chk ee-do-not-validate', |
495 | 494 | 'display_html_label_text' => false |
496 | 495 | ) |
@@ -510,7 +509,7 @@ discard block |
||
510 | 509 | * @return EE_Form_Input_Base |
511 | 510 | * @throws \EE_Error |
512 | 511 | */ |
513 | - private function _additional_primary_registrant_inputs( EE_Registration $registration ){ |
|
512 | + private function _additional_primary_registrant_inputs(EE_Registration $registration) { |
|
514 | 513 | // generate hidden input |
515 | 514 | return new EE_Hidden_Input( |
516 | 515 | array( |
@@ -529,7 +528,7 @@ discard block |
||
529 | 528 | * @return EE_Form_Input_Base |
530 | 529 | * @throws \EE_Error |
531 | 530 | */ |
532 | - public function reg_form_question( EE_Registration $registration, EE_Question $question ){ |
|
531 | + public function reg_form_question(EE_Registration $registration, EE_Question $question) { |
|
533 | 532 | |
534 | 533 | // if this question was for an attendee detail, then check for that answer |
535 | 534 | $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value( |
@@ -538,32 +537,32 @@ discard block |
||
538 | 537 | ); |
539 | 538 | $answer = $answer_value === null |
540 | 539 | ? EEM_Answer::instance()->get_one( |
541 | - array( array( 'QST_ID' => $question->ID(), 'REG_ID' => $registration->ID() ) ) |
|
540 | + array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
542 | 541 | ) |
543 | 542 | : null; |
544 | 543 | // if NOT returning to edit an existing registration |
545 | 544 | // OR if this question is for an attendee property |
546 | 545 | // OR we still don't have an EE_Answer object |
547 | - if( $answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link() ) { |
|
546 | + if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) { |
|
548 | 547 | // create an EE_Answer object for storing everything in |
549 | - $answer = EE_Answer::new_instance ( array( |
|
548 | + $answer = EE_Answer::new_instance(array( |
|
550 | 549 | 'QST_ID'=> $question->ID(), |
551 | 550 | 'REG_ID'=> $registration->ID() |
552 | 551 | )); |
553 | 552 | } |
554 | 553 | // verify instance |
555 | - if( $answer instanceof EE_Answer ){ |
|
556 | - if ( ! empty( $answer_value )) { |
|
557 | - $answer->set( 'ANS_value', $answer_value ); |
|
554 | + if ($answer instanceof EE_Answer) { |
|
555 | + if ( ! empty($answer_value)) { |
|
556 | + $answer->set('ANS_value', $answer_value); |
|
558 | 557 | } |
559 | - $answer->cache( 'Question', $question ); |
|
558 | + $answer->cache('Question', $question); |
|
560 | 559 | //remember system ID had a bug where sometimes it could be null |
561 | - $answer_cache_id =$question->is_system_question() |
|
562 | - ? $question->system_ID() . '-' . $registration->reg_url_link() |
|
563 | - : $question->ID() . '-' . $registration->reg_url_link(); |
|
564 | - $registration->cache( 'Answer', $answer, $answer_cache_id ); |
|
560 | + $answer_cache_id = $question->is_system_question() |
|
561 | + ? $question->system_ID().'-'.$registration->reg_url_link() |
|
562 | + : $question->ID().'-'.$registration->reg_url_link(); |
|
563 | + $registration->cache('Answer', $answer, $answer_cache_id); |
|
565 | 564 | } |
566 | - return $this->_generate_question_input( $registration, $question, $answer ); |
|
565 | + return $this->_generate_question_input($registration, $question, $answer); |
|
567 | 566 | |
568 | 567 | } |
569 | 568 | |
@@ -576,46 +575,46 @@ discard block |
||
576 | 575 | * @return EE_Form_Input_Base |
577 | 576 | * @throws \EE_Error |
578 | 577 | */ |
579 | - private function _generate_question_input( EE_Registration $registration, EE_Question $question, $answer ){ |
|
578 | + private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer) { |
|
580 | 579 | $identifier = $question->is_system_question() ? $question->system_ID() : $question->ID(); |
581 | - $this->_required_questions[ $identifier ] = $question->required() ? true : false; |
|
580 | + $this->_required_questions[$identifier] = $question->required() ? true : false; |
|
582 | 581 | add_filter( |
583 | 582 | 'FHEE__EE_Question__generate_form_input__country_options', |
584 | - array( $this, 'use_cached_countries_for_form_input' ), |
|
583 | + array($this, 'use_cached_countries_for_form_input'), |
|
585 | 584 | 10, |
586 | 585 | 4 |
587 | 586 | ); |
588 | 587 | add_filter( |
589 | 588 | 'FHEE__EE_Question__generate_form_input__state_options', |
590 | - array( $this, 'use_cached_states_for_form_input' ), |
|
589 | + array($this, 'use_cached_states_for_form_input'), |
|
591 | 590 | 10, |
592 | 591 | 4 |
593 | 592 | ); |
594 | 593 | $input_constructor_args = array( |
595 | - 'html_name' => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']', |
|
596 | - 'html_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
597 | - 'html_class' => 'ee-reg-qstn ee-reg-qstn-' . $identifier, |
|
598 | - 'html_label_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
594 | + 'html_name' => 'ee_reg_qstn['.$registration->ID().']['.$identifier.']', |
|
595 | + 'html_id' => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier, |
|
596 | + 'html_class' => 'ee-reg-qstn ee-reg-qstn-'.$identifier, |
|
597 | + 'html_label_id' => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier, |
|
599 | 598 | 'html_label_class' => 'ee-reg-qstn', |
600 | 599 | ); |
601 | - $input_constructor_args['html_label_id'] .= '-lbl'; |
|
602 | - if ( $answer instanceof EE_Answer && $answer->ID() ) { |
|
603 | - $input_constructor_args[ 'html_name' ] .= '[' . $answer->ID() . ']'; |
|
604 | - $input_constructor_args[ 'html_id' ] .= '-' . $answer->ID(); |
|
605 | - $input_constructor_args[ 'html_label_id' ] .= '-' . $answer->ID(); |
|
600 | + $input_constructor_args['html_label_id'] .= '-lbl'; |
|
601 | + if ($answer instanceof EE_Answer && $answer->ID()) { |
|
602 | + $input_constructor_args['html_name'] .= '['.$answer->ID().']'; |
|
603 | + $input_constructor_args['html_id'] .= '-'.$answer->ID(); |
|
604 | + $input_constructor_args['html_label_id'] .= '-'.$answer->ID(); |
|
606 | 605 | } |
607 | - $form_input = $question->generate_form_input( |
|
606 | + $form_input = $question->generate_form_input( |
|
608 | 607 | $registration, |
609 | 608 | $answer, |
610 | 609 | $input_constructor_args |
611 | 610 | ); |
612 | 611 | remove_filter( |
613 | 612 | 'FHEE__EE_Question__generate_form_input__country_options', |
614 | - array( $this, 'use_cached_countries_for_form_input' ) |
|
613 | + array($this, 'use_cached_countries_for_form_input') |
|
615 | 614 | ); |
616 | 615 | remove_filter( |
617 | 616 | 'FHEE__EE_Question__generate_form_input__state_options', |
618 | - array( $this, 'use_cached_states_for_form_input' ) |
|
617 | + array($this, 'use_cached_states_for_form_input') |
|
619 | 618 | ); |
620 | 619 | return $form_input; |
621 | 620 | } |
@@ -637,22 +636,22 @@ discard block |
||
637 | 636 | \EE_Registration $registration = null, |
638 | 637 | \EE_Answer $answer = null |
639 | 638 | ) { |
640 | - $country_options = array( '' => '' ); |
|
639 | + $country_options = array('' => ''); |
|
641 | 640 | // get possibly cached list of countries |
642 | 641 | $countries = $this->checkout->action === 'process_reg_step' |
643 | 642 | ? EEM_Country::instance()->get_all_countries() |
644 | 643 | : EEM_Country::instance()->get_all_active_countries(); |
645 | - if ( ! empty( $countries )) { |
|
646 | - foreach( $countries as $country ){ |
|
647 | - if ( $country instanceof EE_Country ) { |
|
648 | - $country_options[ $country->ID() ] = $country->name(); |
|
644 | + if ( ! empty($countries)) { |
|
645 | + foreach ($countries as $country) { |
|
646 | + if ($country instanceof EE_Country) { |
|
647 | + $country_options[$country->ID()] = $country->name(); |
|
649 | 648 | } |
650 | 649 | } |
651 | 650 | } |
652 | - if( $question instanceof EE_Question |
|
653 | - && $registration instanceof EE_Registration ) { |
|
651 | + if ($question instanceof EE_Question |
|
652 | + && $registration instanceof EE_Registration) { |
|
654 | 653 | $answer = EEM_Answer::instance()->get_one( |
655 | - array( array( 'QST_ID' => $question->ID(), 'REG_ID' => $registration->ID() ) ) |
|
654 | + array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
656 | 655 | ); |
657 | 656 | } else { |
658 | 657 | $answer = EE_Answer::new_instance(); |
@@ -685,14 +684,14 @@ discard block |
||
685 | 684 | \EE_Registration $registration = null, |
686 | 685 | \EE_Answer $answer = null |
687 | 686 | ) { |
688 | - $state_options = array( '' => array( '' => '')); |
|
687 | + $state_options = array('' => array('' => '')); |
|
689 | 688 | $states = $this->checkout->action === 'process_reg_step' |
690 | 689 | ? EEM_State::instance()->get_all_states() |
691 | 690 | : EEM_State::instance()->get_all_active_states(); |
692 | - if ( ! empty( $states )) { |
|
693 | - foreach( $states as $state ){ |
|
694 | - if ( $state instanceof EE_State ) { |
|
695 | - $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name(); |
|
691 | + if ( ! empty($states)) { |
|
692 | + foreach ($states as $state) { |
|
693 | + if ($state instanceof EE_State) { |
|
694 | + $state_options[$state->country()->name()][$state->ID()] = $state->name(); |
|
696 | 695 | } |
697 | 696 | } |
698 | 697 | } |
@@ -720,24 +719,24 @@ discard block |
||
720 | 719 | * @throws \EE_Error |
721 | 720 | */ |
722 | 721 | public function process_reg_step() { |
723 | - do_action( 'AHEE_log', __FILE__, __FUNCTION__, '' ); |
|
722 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
724 | 723 | // grab validated data from form |
725 | 724 | $valid_data = $this->checkout->current_step->valid_data(); |
726 | 725 | // EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
727 | 726 | // EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ ); |
728 | 727 | // if we don't have any $valid_data then something went TERRIBLY WRONG !!! |
729 | - if ( empty( $valid_data )) { |
|
728 | + if (empty($valid_data)) { |
|
730 | 729 | EE_Error::add_error( |
731 | - __( 'No valid question responses were received.', 'event_espresso' ), |
|
730 | + __('No valid question responses were received.', 'event_espresso'), |
|
732 | 731 | __FILE__, |
733 | 732 | __FUNCTION__, |
734 | 733 | __LINE__ |
735 | 734 | ); |
736 | 735 | return false; |
737 | 736 | } |
738 | - if ( ! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg ) { |
|
737 | + if ( ! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
739 | 738 | EE_Error::add_error( |
740 | - __( 'A valid transaction could not be initiated for processing your registrations.', 'event_espresso' ), |
|
739 | + __('A valid transaction could not be initiated for processing your registrations.', 'event_espresso'), |
|
741 | 740 | __FILE__, |
742 | 741 | __FUNCTION__, |
743 | 742 | __LINE__ |
@@ -745,11 +744,11 @@ discard block |
||
745 | 744 | return false; |
746 | 745 | } |
747 | 746 | // get cached registrations |
748 | - $registrations = $this->checkout->transaction->registrations( $this->checkout->reg_cache_where_params ); |
|
747 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
749 | 748 | // verify we got the goods |
750 | - if ( empty( $registrations )) { |
|
749 | + if (empty($registrations)) { |
|
751 | 750 | EE_Error::add_error( |
752 | - __( 'Your form data could not be applied to any valid registrations.', 'event_espresso' ), |
|
751 | + __('Your form data could not be applied to any valid registrations.', 'event_espresso'), |
|
753 | 752 | __FILE__, |
754 | 753 | __FUNCTION__, |
755 | 754 | __LINE__ |
@@ -757,15 +756,15 @@ discard block |
||
757 | 756 | return false; |
758 | 757 | } |
759 | 758 | // extract attendee info from form data and save to model objects |
760 | - $registrations_processed = $this->_process_registrations( $registrations, $valid_data ); |
|
759 | + $registrations_processed = $this->_process_registrations($registrations, $valid_data); |
|
761 | 760 | // if first pass thru SPCO, |
762 | 761 | // then let's check processed registrations against the total number of tickets in the cart |
763 | - if ( $registrations_processed === false ) { |
|
762 | + if ($registrations_processed === false) { |
|
764 | 763 | // but return immediately if the previous step exited early due to errors |
765 | 764 | return false; |
766 | - } else if ( ! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count ) { |
|
765 | + } else if ( ! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
767 | 766 | // generate a correctly translated string for all possible singular/plural combinations |
768 | - if ( $this->checkout->total_ticket_count === 1 && $registrations_processed !== 1 ) { |
|
767 | + if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
|
769 | 768 | $error_msg = sprintf( |
770 | 769 | __( |
771 | 770 | 'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed', |
@@ -774,7 +773,7 @@ discard block |
||
774 | 773 | $this->checkout->total_ticket_count, |
775 | 774 | $registrations_processed |
776 | 775 | ); |
777 | - } else if ( $this->checkout->total_ticket_count !== 1 && $registrations_processed === 1 ) { |
|
776 | + } else if ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) { |
|
778 | 777 | $error_msg = sprintf( |
779 | 778 | __( |
780 | 779 | 'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed', |
@@ -793,17 +792,17 @@ discard block |
||
793 | 792 | $registrations_processed |
794 | 793 | ); |
795 | 794 | } |
796 | - EE_Error::add_error( $error_msg, __FILE__, __FUNCTION__, __LINE__ ); |
|
795 | + EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
797 | 796 | return false; |
798 | 797 | } |
799 | 798 | // mark this reg step as completed |
800 | 799 | $this->set_completed(); |
801 | 800 | $this->_set_success_message( |
802 | - __( 'The Attendee Information Step has been successfully completed.', 'event_espresso' ) |
|
801 | + __('The Attendee Information Step has been successfully completed.', 'event_espresso') |
|
803 | 802 | ); |
804 | 803 | //do action in case a plugin wants to do something with the data submitted in step 1. |
805 | 804 | //passes EE_Single_Page_Checkout, and it's posted data |
806 | - do_action( 'AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data ); |
|
805 | + do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data); |
|
807 | 806 | return true; |
808 | 807 | } |
809 | 808 | |
@@ -817,9 +816,9 @@ discard block |
||
817 | 816 | * @return boolean | int |
818 | 817 | * @throws \EE_Error |
819 | 818 | */ |
820 | - private function _process_registrations( $registrations = array(), $valid_data = array() ) { |
|
819 | + private function _process_registrations($registrations = array(), $valid_data = array()) { |
|
821 | 820 | // load resources and set some defaults |
822 | - EE_Registry::instance()->load_model( 'Attendee' ); |
|
821 | + EE_Registry::instance()->load_model('Attendee'); |
|
823 | 822 | // holder for primary registrant attendee object |
824 | 823 | $this->checkout->primary_attendee_obj = NULL; |
825 | 824 | // array for tracking reg form data for the primary registrant |
@@ -836,9 +835,9 @@ discard block |
||
836 | 835 | // attendee counter |
837 | 836 | $att_nmbr = 0; |
838 | 837 | // grab the saved registrations from the transaction |
839 | - foreach ( $registrations as $registration ) { |
|
838 | + foreach ($registrations as $registration) { |
|
840 | 839 | // verify EE_Registration object |
841 | - if ( ! $registration instanceof EE_Registration ) { |
|
840 | + if ( ! $registration instanceof EE_Registration) { |
|
842 | 841 | EE_Error::add_error( |
843 | 842 | __( |
844 | 843 | 'An invalid Registration object was discovered when attempting to process your registration information.', |
@@ -853,12 +852,12 @@ discard block |
||
853 | 852 | /** @var string $reg_url_link */ |
854 | 853 | $reg_url_link = $registration->reg_url_link(); |
855 | 854 | // reg_url_link exists ? |
856 | - if ( ! empty( $reg_url_link ) ) { |
|
855 | + if ( ! empty($reg_url_link)) { |
|
857 | 856 | // should this registration be processed during this visit ? |
858 | - if ( $this->checkout->visit_allows_processing_of_this_registration( $registration ) ) { |
|
857 | + if ($this->checkout->visit_allows_processing_of_this_registration($registration)) { |
|
859 | 858 | // if NOT revisiting, then let's save the registration now, |
860 | 859 | // so that we have a REG_ID to use when generating other objects |
861 | - if ( ! $this->checkout->revisit ) { |
|
860 | + if ( ! $this->checkout->revisit) { |
|
862 | 861 | $registration->save(); |
863 | 862 | } |
864 | 863 | /** |
@@ -868,7 +867,7 @@ discard block |
||
868 | 867 | * @var bool if true is returned by the plugin then the |
869 | 868 | * registration processing is halted. |
870 | 869 | */ |
871 | - if ( apply_filters( |
|
870 | + if (apply_filters( |
|
872 | 871 | 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process', |
873 | 872 | false, |
874 | 873 | $att_nmbr, |
@@ -876,38 +875,38 @@ discard block |
||
876 | 875 | $registrations, |
877 | 876 | $valid_data, |
878 | 877 | $this |
879 | - ) ) { |
|
878 | + )) { |
|
880 | 879 | return false; |
881 | 880 | } |
882 | 881 | |
883 | 882 | // Houston, we have a registration! |
884 | 883 | $att_nmbr++; |
885 | - $this->_attendee_data[ $reg_url_link ] = array(); |
|
884 | + $this->_attendee_data[$reg_url_link] = array(); |
|
886 | 885 | // grab any existing related answer objects |
887 | 886 | $this->_registration_answers = $registration->answers(); |
888 | 887 | // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ); |
889 | - if ( isset( $valid_data[ $reg_url_link ] ) ) { |
|
888 | + if (isset($valid_data[$reg_url_link])) { |
|
890 | 889 | // do we need to copy basic info from primary attendee ? |
891 | - $copy_primary = isset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ) |
|
892 | - && absint( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ) === 0 |
|
890 | + $copy_primary = isset($valid_data[$reg_url_link]['additional_attendee_reg_info']) |
|
891 | + && absint($valid_data[$reg_url_link]['additional_attendee_reg_info']) === 0 |
|
893 | 892 | ? true |
894 | 893 | : false; |
895 | 894 | // filter form input data for this registration |
896 | - $valid_data[ $reg_url_link ] = (array)apply_filters( |
|
895 | + $valid_data[$reg_url_link] = (array) apply_filters( |
|
897 | 896 | 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
898 | - $valid_data[ $reg_url_link ] |
|
897 | + $valid_data[$reg_url_link] |
|
899 | 898 | ); |
900 | 899 | // EEH_Debug_Tools::printr( $valid_data[ $reg_url_link ], '$valid_data[ $reg_url_link ]', __FILE__, __LINE__ ); |
901 | - if ( isset( $valid_data['primary_attendee'] )) { |
|
902 | - $primary_registrant['line_item_id'] = ! empty( $valid_data['primary_attendee'] ) |
|
900 | + if (isset($valid_data['primary_attendee'])) { |
|
901 | + $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee']) |
|
903 | 902 | ? $valid_data['primary_attendee'] |
904 | 903 | : false; |
905 | - unset( $valid_data['primary_attendee'] ); |
|
904 | + unset($valid_data['primary_attendee']); |
|
906 | 905 | } |
907 | 906 | // now loop through our array of valid post data && process attendee reg forms |
908 | - foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs ) { |
|
909 | - if ( ! in_array( $form_section, $non_input_form_sections )) { |
|
910 | - foreach ( $form_inputs as $form_input => $input_value ) { |
|
907 | + foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) { |
|
908 | + if ( ! in_array($form_section, $non_input_form_sections)) { |
|
909 | + foreach ($form_inputs as $form_input => $input_value) { |
|
911 | 910 | // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ ); |
912 | 911 | // check for critical inputs |
913 | 912 | if ( |
@@ -921,16 +920,16 @@ discard block |
||
921 | 920 | // store a bit of data about the primary attendee |
922 | 921 | if ( |
923 | 922 | $att_nmbr === 1 |
924 | - && ! empty( $input_value ) |
|
923 | + && ! empty($input_value) |
|
925 | 924 | && $reg_url_link === $primary_registrant['line_item_id'] |
926 | 925 | ) { |
927 | - $primary_registrant[ $form_input ] = $input_value; |
|
926 | + $primary_registrant[$form_input] = $input_value; |
|
928 | 927 | } else if ( |
929 | 928 | $copy_primary |
930 | 929 | && $input_value === null |
931 | - && isset( $primary_registrant[ $form_input ] ) |
|
930 | + && isset($primary_registrant[$form_input]) |
|
932 | 931 | ) { |
933 | - $input_value = $primary_registrant[ $form_input ]; |
|
932 | + $input_value = $primary_registrant[$form_input]; |
|
934 | 933 | } |
935 | 934 | // now attempt to save the input data |
936 | 935 | if ( |
@@ -972,55 +971,55 @@ discard block |
||
972 | 971 | // have we met before? |
973 | 972 | $attendee = $this->_find_existing_attendee( |
974 | 973 | $registration, |
975 | - $this->_attendee_data[ $reg_url_link ] |
|
974 | + $this->_attendee_data[$reg_url_link] |
|
976 | 975 | ); |
977 | 976 | // did we find an already existing record for this attendee ? |
978 | - if ( $attendee instanceof EE_Attendee ) { |
|
977 | + if ($attendee instanceof EE_Attendee) { |
|
979 | 978 | $attendee = $this->_update_existing_attendee_data( |
980 | 979 | $attendee, |
981 | - $this->_attendee_data[ $reg_url_link ] |
|
980 | + $this->_attendee_data[$reg_url_link] |
|
982 | 981 | ); |
983 | 982 | } else { |
984 | 983 | // ensure critical details are set for additional attendees |
985 | - $this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1 |
|
984 | + $this->_attendee_data[$reg_url_link] = $att_nmbr > 1 |
|
986 | 985 | ? $this->_copy_critical_attendee_details_from_primary_registrant( |
987 | - $this->_attendee_data[ $reg_url_link ] |
|
986 | + $this->_attendee_data[$reg_url_link] |
|
988 | 987 | ) |
989 | - : $this->_attendee_data[ $reg_url_link ]; |
|
988 | + : $this->_attendee_data[$reg_url_link]; |
|
990 | 989 | $attendee = $this->_create_new_attendee( |
991 | 990 | $registration, |
992 | - $this->_attendee_data[ $reg_url_link ] |
|
991 | + $this->_attendee_data[$reg_url_link] |
|
993 | 992 | ); |
994 | 993 | } |
995 | 994 | // who's #1 ? |
996 | - if ( $att_nmbr === 1 ) { |
|
995 | + if ($att_nmbr === 1) { |
|
997 | 996 | $this->checkout->primary_attendee_obj = $attendee; |
998 | 997 | } |
999 | 998 | } |
1000 | 999 | // EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ ); |
1001 | 1000 | // add relation to registration, set attendee ID, and cache attendee |
1002 | - $this->_associate_attendee_with_registration( $registration, $attendee ); |
|
1001 | + $this->_associate_attendee_with_registration($registration, $attendee); |
|
1003 | 1002 | // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ ); |
1004 | - if ( ! $registration->attendee() instanceof EE_Attendee ) { |
|
1005 | - EE_Error::add_error( sprintf( __( 'Registration %s has an invalid or missing Attendee object.', 'event_espresso' ), $reg_url_link ), __FILE__, __FUNCTION__, __LINE__ ); |
|
1003 | + if ( ! $registration->attendee() instanceof EE_Attendee) { |
|
1004 | + EE_Error::add_error(sprintf(__('Registration %s has an invalid or missing Attendee object.', 'event_espresso'), $reg_url_link), __FILE__, __FUNCTION__, __LINE__); |
|
1006 | 1005 | return false; |
1007 | 1006 | } |
1008 | 1007 | /** @type EE_Registration_Processor $registration_processor */ |
1009 | - $registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' ); |
|
1008 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
1010 | 1009 | // at this point, we should have enough details about the registrant to consider the registration NOT incomplete |
1011 | - $registration_processor->toggle_incomplete_registration_status_to_default( $registration, false ); |
|
1010 | + $registration_processor->toggle_incomplete_registration_status_to_default($registration, false); |
|
1012 | 1011 | // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to abandoned |
1013 | 1012 | $this->checkout->transaction->toggle_failed_transaction_status(); |
1014 | 1013 | // if we've gotten this far, then let's save what we have |
1015 | 1014 | $registration->save(); |
1016 | 1015 | // add relation between TXN and registration |
1017 | - $this->_associate_registration_with_transaction( $registration ); |
|
1016 | + $this->_associate_registration_with_transaction($registration); |
|
1018 | 1017 | } // end of if ( ! $this->checkout->revisit || $this->checkout->primary_revisit || ( $this->checkout->revisit && $this->checkout->reg_url_link == $reg_url_link )) { |
1019 | 1018 | |
1020 | - } else { |
|
1021 | - EE_Error::add_error( __( 'An invalid or missing line item ID was encountered while attempting to process the registration form.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ ); |
|
1019 | + } else { |
|
1020 | + EE_Error::add_error(__('An invalid or missing line item ID was encountered while attempting to process the registration form.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
1022 | 1021 | // remove malformed data |
1023 | - unset( $valid_data[ $reg_url_link ] ); |
|
1022 | + unset($valid_data[$reg_url_link]); |
|
1024 | 1023 | return false; |
1025 | 1024 | } |
1026 | 1025 | |
@@ -1049,26 +1048,26 @@ discard block |
||
1049 | 1048 | // \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ ); |
1050 | 1049 | // allow for plugins to hook in and do their own processing of the form input. |
1051 | 1050 | // For plugins to bypass normal processing here, they just need to return a boolean value. |
1052 | - if ( apply_filters( |
|
1051 | + if (apply_filters( |
|
1053 | 1052 | 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input', |
1054 | 1053 | false, |
1055 | 1054 | $registration, |
1056 | 1055 | $form_input, |
1057 | 1056 | $input_value, |
1058 | 1057 | $this |
1059 | - ) ) { |
|
1058 | + )) { |
|
1060 | 1059 | return true; |
1061 | 1060 | } |
1062 | 1061 | // $answer_cache_id is the key used to find the EE_Answer we want |
1063 | 1062 | $answer_cache_id = $this->checkout->reg_url_link |
1064 | 1063 | ? $form_input |
1065 | - : $form_input . '-' . $registration->reg_url_link(); |
|
1066 | - $answer_is_obj = isset( $this->_registration_answers[ $answer_cache_id ] ) |
|
1067 | - && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer |
|
1064 | + : $form_input.'-'.$registration->reg_url_link(); |
|
1065 | + $answer_is_obj = isset($this->_registration_answers[$answer_cache_id]) |
|
1066 | + && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer |
|
1068 | 1067 | ? true |
1069 | 1068 | : false; |
1070 | 1069 | //rename form_inputs if they are EE_Attendee properties |
1071 | - switch( (string)$form_input ) { |
|
1070 | + switch ((string) $form_input) { |
|
1072 | 1071 | |
1073 | 1072 | case 'state' : |
1074 | 1073 | case 'STA_ID' : |
@@ -1083,32 +1082,32 @@ discard block |
||
1083 | 1082 | break; |
1084 | 1083 | |
1085 | 1084 | default : |
1086 | - $ATT_input = 'ATT_' . $form_input; |
|
1085 | + $ATT_input = 'ATT_'.$form_input; |
|
1087 | 1086 | //EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ ); |
1088 | - $attendee_property = EEM_Attendee::instance()->has_field( $ATT_input ) ? true : false; |
|
1089 | - $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input; |
|
1087 | + $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false; |
|
1088 | + $form_input = $attendee_property ? 'ATT_'.$form_input : $form_input; |
|
1090 | 1089 | } |
1091 | 1090 | // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ ); |
1092 | 1091 | // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ ); |
1093 | 1092 | // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ ); |
1094 | 1093 | // if this form input has a corresponding attendee property |
1095 | - if ( $attendee_property ) { |
|
1096 | - $this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value; |
|
1097 | - if ( $answer_is_obj ) { |
|
1094 | + if ($attendee_property) { |
|
1095 | + $this->_attendee_data[$registration->reg_url_link()][$form_input] = $input_value; |
|
1096 | + if ($answer_is_obj) { |
|
1098 | 1097 | // and delete the corresponding answer since we won't be storing this data in that object |
1099 | - $registration->_remove_relation_to( $this->_registration_answers[ $answer_cache_id ], 'Answer' ); |
|
1100 | - $this->_registration_answers[ $answer_cache_id ]->delete_permanently(); |
|
1098 | + $registration->_remove_relation_to($this->_registration_answers[$answer_cache_id], 'Answer'); |
|
1099 | + $this->_registration_answers[$answer_cache_id]->delete_permanently(); |
|
1101 | 1100 | } |
1102 | 1101 | return true; |
1103 | - } elseif ( $answer_is_obj ) { |
|
1102 | + } elseif ($answer_is_obj) { |
|
1104 | 1103 | // save this data to the answer object |
1105 | - $this->_registration_answers[ $answer_cache_id ]->set_value( $input_value ); |
|
1106 | - $result = $this->_registration_answers[ $answer_cache_id ]->save(); |
|
1104 | + $this->_registration_answers[$answer_cache_id]->set_value($input_value); |
|
1105 | + $result = $this->_registration_answers[$answer_cache_id]->save(); |
|
1107 | 1106 | return $result !== false ? true : false; |
1108 | 1107 | } else { |
1109 | - foreach ( $this->_registration_answers as $answer ) { |
|
1110 | - if ( $answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id ) { |
|
1111 | - $answer->set_value( $input_value ); |
|
1108 | + foreach ($this->_registration_answers as $answer) { |
|
1109 | + if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) { |
|
1110 | + $answer->set_value($input_value); |
|
1112 | 1111 | $result = $answer->save(); |
1113 | 1112 | return $result !== false ? true : false; |
1114 | 1113 | } |
@@ -1130,15 +1129,15 @@ discard block |
||
1130 | 1129 | $form_input = '', |
1131 | 1130 | $input_value = '' |
1132 | 1131 | ) { |
1133 | - if ( empty( $input_value ) ) { |
|
1132 | + if (empty($input_value)) { |
|
1134 | 1133 | // if the form input isn't marked as being required, then just return |
1135 | - if ( ! isset( $this->_required_questions[ $form_input ] ) || ! $this->_required_questions[ $form_input ] ) { |
|
1134 | + if ( ! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) { |
|
1136 | 1135 | return true; |
1137 | 1136 | } |
1138 | - switch ( $form_input ) { |
|
1137 | + switch ($form_input) { |
|
1139 | 1138 | case 'fname' : |
1140 | 1139 | EE_Error::add_error( |
1141 | - __( 'First Name is a required value.', 'event_espresso' ), |
|
1140 | + __('First Name is a required value.', 'event_espresso'), |
|
1142 | 1141 | __FILE__, |
1143 | 1142 | __FUNCTION__, |
1144 | 1143 | __LINE__ |
@@ -1147,7 +1146,7 @@ discard block |
||
1147 | 1146 | break; |
1148 | 1147 | case 'lname' : |
1149 | 1148 | EE_Error::add_error( |
1150 | - __( 'Last Name is a required value.', 'event_espresso' ), |
|
1149 | + __('Last Name is a required value.', 'event_espresso'), |
|
1151 | 1150 | __FILE__, |
1152 | 1151 | __FUNCTION__, |
1153 | 1152 | __LINE__ |
@@ -1156,7 +1155,7 @@ discard block |
||
1156 | 1155 | break; |
1157 | 1156 | case 'email' : |
1158 | 1157 | EE_Error::add_error( |
1159 | - __( 'Please enter a valid email address.', 'event_espresso' ), |
|
1158 | + __('Please enter a valid email address.', 'event_espresso'), |
|
1160 | 1159 | __FILE__, |
1161 | 1160 | __FUNCTION__, |
1162 | 1161 | __LINE__ |
@@ -1178,30 +1177,30 @@ discard block |
||
1178 | 1177 | * @return boolean|EE_Attendee |
1179 | 1178 | * @throws \EE_Error |
1180 | 1179 | */ |
1181 | - private function _find_existing_attendee( EE_Registration $registration, $attendee_data = array() ) { |
|
1180 | + private function _find_existing_attendee(EE_Registration $registration, $attendee_data = array()) { |
|
1182 | 1181 | $existing_attendee = null; |
1183 | 1182 | // if none of the critical properties are set in the incoming attendee data... |
1184 | 1183 | // then attempt to copy them from the primary attendee |
1185 | 1184 | if ( |
1186 | 1185 | $this->checkout->primary_attendee_obj instanceof EE_Attendee |
1187 | - && ! isset( $attendee_data['ATT_fname'], $attendee_data['ATT_email'] ) |
|
1186 | + && ! isset($attendee_data['ATT_fname'], $attendee_data['ATT_email']) |
|
1188 | 1187 | ) { |
1189 | 1188 | return $this->checkout->primary_attendee_obj; |
1190 | 1189 | } |
1191 | 1190 | // does this attendee already exist in the db ? |
1192 | 1191 | // we're searching using a combination of first name, last name, AND email address |
1193 | - $ATT_fname = isset( $attendee_data['ATT_fname'] ) && ! empty( $attendee_data['ATT_fname'] ) |
|
1192 | + $ATT_fname = isset($attendee_data['ATT_fname']) && ! empty($attendee_data['ATT_fname']) |
|
1194 | 1193 | ? $attendee_data['ATT_fname'] |
1195 | 1194 | : ''; |
1196 | - $ATT_lname = isset( $attendee_data['ATT_lname'] ) && ! empty( $attendee_data['ATT_lname'] ) |
|
1195 | + $ATT_lname = isset($attendee_data['ATT_lname']) && ! empty($attendee_data['ATT_lname']) |
|
1197 | 1196 | ? $attendee_data['ATT_lname'] |
1198 | 1197 | : ''; |
1199 | - $ATT_email = isset( $attendee_data['ATT_email'] ) && ! empty( $attendee_data['ATT_email'] ) |
|
1198 | + $ATT_email = isset($attendee_data['ATT_email']) && ! empty($attendee_data['ATT_email']) |
|
1200 | 1199 | ? $attendee_data['ATT_email'] |
1201 | 1200 | : ''; |
1202 | 1201 | // but only if those have values |
1203 | - if ( $ATT_fname && $ATT_lname && $ATT_email ) { |
|
1204 | - $existing_attendee = EEM_Attendee::instance()->find_existing_attendee( array( |
|
1202 | + if ($ATT_fname && $ATT_lname && $ATT_email) { |
|
1203 | + $existing_attendee = EEM_Attendee::instance()->find_existing_attendee(array( |
|
1205 | 1204 | 'ATT_fname' => $ATT_fname, |
1206 | 1205 | 'ATT_lname' => $ATT_lname, |
1207 | 1206 | 'ATT_email' => $ATT_email |
@@ -1225,13 +1224,13 @@ discard block |
||
1225 | 1224 | * @return \EE_Attendee |
1226 | 1225 | * @throws \EE_Error |
1227 | 1226 | */ |
1228 | - private function _update_existing_attendee_data( EE_Attendee $existing_attendee, $attendee_data = array() ) { |
|
1227 | + private function _update_existing_attendee_data(EE_Attendee $existing_attendee, $attendee_data = array()) { |
|
1229 | 1228 | // first remove fname, lname, and email from attendee data |
1230 | - $dont_set = array( 'ATT_fname', 'ATT_lname', 'ATT_email' ); |
|
1229 | + $dont_set = array('ATT_fname', 'ATT_lname', 'ATT_email'); |
|
1231 | 1230 | // now loop thru what's left and add to attendee CPT |
1232 | - foreach ( $attendee_data as $property_name => $property_value ) { |
|
1233 | - if ( ! in_array( $property_name, $dont_set ) && EEM_Attendee::instance()->has_field( $property_name )) { |
|
1234 | - $existing_attendee->set( $property_name, $property_value ); |
|
1231 | + foreach ($attendee_data as $property_name => $property_value) { |
|
1232 | + if ( ! in_array($property_name, $dont_set) && EEM_Attendee::instance()->has_field($property_name)) { |
|
1233 | + $existing_attendee->set($property_name, $property_value); |
|
1235 | 1234 | } |
1236 | 1235 | } |
1237 | 1236 | // better save that now |
@@ -1249,11 +1248,11 @@ discard block |
||
1249 | 1248 | * @return void |
1250 | 1249 | * @throws \EE_Error |
1251 | 1250 | */ |
1252 | - private function _associate_attendee_with_registration( EE_Registration $registration, EE_Attendee $attendee ) { |
|
1251 | + private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee) { |
|
1253 | 1252 | // add relation to attendee |
1254 | - $registration->_add_relation_to( $attendee, 'Attendee' ); |
|
1255 | - $registration->set_attendee_id( $attendee->ID() ); |
|
1256 | - $registration->update_cache_after_object_save( 'Attendee', $attendee ); |
|
1253 | + $registration->_add_relation_to($attendee, 'Attendee'); |
|
1254 | + $registration->set_attendee_id($attendee->ID()); |
|
1255 | + $registration->update_cache_after_object_save('Attendee', $attendee); |
|
1257 | 1256 | } |
1258 | 1257 | |
1259 | 1258 | |
@@ -1265,10 +1264,10 @@ discard block |
||
1265 | 1264 | * @return void |
1266 | 1265 | * @throws \EE_Error |
1267 | 1266 | */ |
1268 | - private function _associate_registration_with_transaction( EE_Registration $registration ) { |
|
1267 | + private function _associate_registration_with_transaction(EE_Registration $registration) { |
|
1269 | 1268 | // add relation to attendee |
1270 | - $this->checkout->transaction->_add_relation_to( $registration, 'Registration' ); |
|
1271 | - $this->checkout->transaction->update_cache_after_object_save( 'Registration', $registration ); |
|
1269 | + $this->checkout->transaction->_add_relation_to($registration, 'Registration'); |
|
1270 | + $this->checkout->transaction->update_cache_after_object_save('Registration', $registration); |
|
1272 | 1271 | } |
1273 | 1272 | |
1274 | 1273 | |
@@ -1281,14 +1280,14 @@ discard block |
||
1281 | 1280 | * @return array |
1282 | 1281 | * @throws \EE_Error |
1283 | 1282 | */ |
1284 | - private function _copy_critical_attendee_details_from_primary_registrant( $attendee_data = array() ) { |
|
1283 | + private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array()) { |
|
1285 | 1284 | // bare minimum critical details include first name, last name, email address |
1286 | - $critical_attendee_details = array( 'ATT_fname', 'ATT_lname', 'ATT_email' ); |
|
1285 | + $critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email'); |
|
1287 | 1286 | // add address info to critical details? |
1288 | - if ( apply_filters( |
|
1287 | + if (apply_filters( |
|
1289 | 1288 | 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
1290 | 1289 | false |
1291 | - ) ) { |
|
1290 | + )) { |
|
1292 | 1291 | $address_details = array( |
1293 | 1292 | 'ATT_address', |
1294 | 1293 | 'ATT_address2', |
@@ -1298,13 +1297,13 @@ discard block |
||
1298 | 1297 | 'ATT_zip', |
1299 | 1298 | 'ATT_phone' |
1300 | 1299 | ); |
1301 | - $critical_attendee_details = array_merge( $critical_attendee_details, $address_details ); |
|
1300 | + $critical_attendee_details = array_merge($critical_attendee_details, $address_details); |
|
1302 | 1301 | } |
1303 | - foreach ( $critical_attendee_details as $critical_attendee_detail ) { |
|
1304 | - if ( ! isset( $attendee_data[ $critical_attendee_detail ] ) |
|
1305 | - || empty( $attendee_data[ $critical_attendee_detail ] ) |
|
1302 | + foreach ($critical_attendee_details as $critical_attendee_detail) { |
|
1303 | + if ( ! isset($attendee_data[$critical_attendee_detail]) |
|
1304 | + || empty($attendee_data[$critical_attendee_detail]) |
|
1306 | 1305 | ) { |
1307 | - $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get( |
|
1306 | + $attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get( |
|
1308 | 1307 | $critical_attendee_detail |
1309 | 1308 | ); |
1310 | 1309 | } |
@@ -1322,11 +1321,11 @@ discard block |
||
1322 | 1321 | * @return \EE_Attendee |
1323 | 1322 | * @throws \EE_Error |
1324 | 1323 | */ |
1325 | - private function _create_new_attendee( EE_Registration $registration, $attendee_data = array() ) { |
|
1324 | + private function _create_new_attendee(EE_Registration $registration, $attendee_data = array()) { |
|
1326 | 1325 | // create new attendee object |
1327 | - $new_attendee = EE_Attendee::new_instance( $attendee_data ); |
|
1326 | + $new_attendee = EE_Attendee::new_instance($attendee_data); |
|
1328 | 1327 | // set author to event creator |
1329 | - $new_attendee->set( 'ATT_author', $registration->event()->wp_user() ); |
|
1328 | + $new_attendee->set('ATT_author', $registration->event()->wp_user()); |
|
1330 | 1329 | $new_attendee->save(); |
1331 | 1330 | return $new_attendee; |
1332 | 1331 | } |
@@ -1343,7 +1342,7 @@ discard block |
||
1343 | 1342 | */ |
1344 | 1343 | public function update_reg_step() { |
1345 | 1344 | // save everything |
1346 | - if ( $this->process_reg_step() ) { |
|
1345 | + if ($this->process_reg_step()) { |
|
1347 | 1346 | $this->checkout->redirect = true; |
1348 | 1347 | $this->checkout->redirect_url = add_query_arg( |
1349 | 1348 | array( |
@@ -1352,7 +1351,7 @@ discard block |
||
1352 | 1351 | ), |
1353 | 1352 | $this->checkout->thank_you_page_url |
1354 | 1353 | ); |
1355 | - $this->checkout->json_response->set_redirect_url( $this->checkout->redirect_url ); |
|
1354 | + $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
1356 | 1355 | return true; |
1357 | 1356 | } |
1358 | 1357 | return false; |
@@ -2,7 +2,7 @@ discard block |
||
2 | 2 | use EventEspresso\core\exceptions\InvalidEntityException; |
3 | 3 | |
4 | 4 | if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
5 | - exit('No direct script access allowed'); |
|
5 | + exit('No direct script access allowed'); |
|
6 | 6 | } |
7 | 7 | |
8 | 8 | |
@@ -17,1709 +17,1709 @@ discard block |
||
17 | 17 | class EED_Single_Page_Checkout extends EED_Module |
18 | 18 | { |
19 | 19 | |
20 | - /** |
|
21 | - * $_initialized - has the SPCO controller already been initialized ? |
|
22 | - * |
|
23 | - * @access private |
|
24 | - * @var bool $_initialized |
|
25 | - */ |
|
26 | - private static $_initialized = false; |
|
27 | - |
|
28 | - |
|
29 | - /** |
|
30 | - * $_checkout_verified - is the EE_Checkout verified as correct for this request ? |
|
31 | - * |
|
32 | - * @access private |
|
33 | - * @var bool $_valid_checkout |
|
34 | - */ |
|
35 | - private static $_checkout_verified = true; |
|
36 | - |
|
37 | - /** |
|
38 | - * $_reg_steps_array - holds initial array of reg steps |
|
39 | - * |
|
40 | - * @access private |
|
41 | - * @var array $_reg_steps_array |
|
42 | - */ |
|
43 | - private static $_reg_steps_array = array(); |
|
44 | - |
|
45 | - /** |
|
46 | - * $checkout - EE_Checkout object for handling the properties of the current checkout process |
|
47 | - * |
|
48 | - * @access public |
|
49 | - * @var EE_Checkout $checkout |
|
50 | - */ |
|
51 | - public $checkout; |
|
52 | - |
|
53 | - |
|
54 | - |
|
55 | - /** |
|
56 | - * @return EED_Single_Page_Checkout |
|
57 | - */ |
|
58 | - public static function instance() |
|
59 | - { |
|
60 | - add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true'); |
|
61 | - return parent::get_instance(__CLASS__); |
|
62 | - } |
|
63 | - |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * @return EE_CART |
|
68 | - */ |
|
69 | - public function cart() |
|
70 | - { |
|
71 | - return $this->checkout->cart; |
|
72 | - } |
|
73 | - |
|
74 | - |
|
75 | - |
|
76 | - /** |
|
77 | - * @return EE_Transaction |
|
78 | - */ |
|
79 | - public function transaction() |
|
80 | - { |
|
81 | - return $this->checkout->transaction; |
|
82 | - } |
|
83 | - |
|
84 | - |
|
85 | - |
|
86 | - /** |
|
87 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
88 | - * |
|
89 | - * @access public |
|
90 | - * @return void |
|
91 | - * @throws \EE_Error |
|
92 | - */ |
|
93 | - public static function set_hooks() |
|
94 | - { |
|
95 | - EED_Single_Page_Checkout::set_definitions(); |
|
96 | - } |
|
97 | - |
|
98 | - |
|
99 | - |
|
100 | - /** |
|
101 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
102 | - * |
|
103 | - * @access public |
|
104 | - * @return void |
|
105 | - * @throws \EE_Error |
|
106 | - */ |
|
107 | - public static function set_hooks_admin() |
|
108 | - { |
|
109 | - EED_Single_Page_Checkout::set_definitions(); |
|
110 | - if ( ! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
111 | - // hook into the top of pre_get_posts to set the reg step routing, which gives other modules or plugins a chance to modify the reg steps, but just before the routes get called |
|
112 | - add_action('pre_get_posts', array('EED_Single_Page_Checkout', 'load_reg_steps'), 1); |
|
113 | - return; |
|
114 | - } |
|
115 | - // going to start an output buffer in case anything gets accidentally output that might disrupt our JSON response |
|
116 | - ob_start(); |
|
117 | - EED_Single_Page_Checkout::load_request_handler(); |
|
118 | - EED_Single_Page_Checkout::load_reg_steps(); |
|
119 | - // set ajax hooks |
|
120 | - add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
121 | - add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
122 | - add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
123 | - add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
124 | - add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
125 | - add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
126 | - } |
|
127 | - |
|
128 | - |
|
129 | - |
|
130 | - /** |
|
131 | - * process ajax request |
|
132 | - * |
|
133 | - * @param string $ajax_action |
|
134 | - * @throws \EE_Error |
|
135 | - */ |
|
136 | - public static function process_ajax_request($ajax_action) |
|
137 | - { |
|
138 | - EE_Registry::instance()->REQ->set('action', $ajax_action); |
|
139 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
140 | - } |
|
141 | - |
|
142 | - |
|
143 | - |
|
144 | - /** |
|
145 | - * ajax display registration step |
|
146 | - * |
|
147 | - * @throws \EE_Error |
|
148 | - */ |
|
149 | - public static function display_reg_step() |
|
150 | - { |
|
151 | - EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step'); |
|
152 | - } |
|
153 | - |
|
154 | - |
|
155 | - |
|
156 | - /** |
|
157 | - * ajax process registration step |
|
158 | - * |
|
159 | - * @throws \EE_Error |
|
160 | - */ |
|
161 | - public static function process_reg_step() |
|
162 | - { |
|
163 | - EED_Single_Page_Checkout::process_ajax_request('process_reg_step'); |
|
164 | - } |
|
165 | - |
|
166 | - |
|
167 | - |
|
168 | - /** |
|
169 | - * ajax process registration step |
|
170 | - * |
|
171 | - * @throws \EE_Error |
|
172 | - */ |
|
173 | - public static function update_reg_step() |
|
174 | - { |
|
175 | - EED_Single_Page_Checkout::process_ajax_request('update_reg_step'); |
|
176 | - } |
|
177 | - |
|
178 | - |
|
179 | - |
|
180 | - /** |
|
181 | - * update_checkout |
|
182 | - * |
|
183 | - * @access public |
|
184 | - * @return void |
|
185 | - * @throws \EE_Error |
|
186 | - */ |
|
187 | - public static function update_checkout() |
|
188 | - { |
|
189 | - EED_Single_Page_Checkout::process_ajax_request('update_checkout'); |
|
190 | - } |
|
191 | - |
|
192 | - |
|
193 | - |
|
194 | - /** |
|
195 | - * load_request_handler |
|
196 | - * |
|
197 | - * @access public |
|
198 | - * @return void |
|
199 | - */ |
|
200 | - public static function load_request_handler() |
|
201 | - { |
|
202 | - // load core Request_Handler class |
|
203 | - if ( ! isset(EE_Registry::instance()->REQ)) { |
|
204 | - EE_Registry::instance()->load_core('Request_Handler'); |
|
205 | - } |
|
206 | - } |
|
207 | - |
|
208 | - |
|
209 | - |
|
210 | - /** |
|
211 | - * set_definitions |
|
212 | - * |
|
213 | - * @access public |
|
214 | - * @return void |
|
215 | - * @throws \EE_Error |
|
216 | - */ |
|
217 | - public static function set_definitions() |
|
218 | - { |
|
219 | - define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS); |
|
220 | - define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS); |
|
221 | - define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS); |
|
222 | - define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS); |
|
223 | - define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS); |
|
224 | - define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS); |
|
225 | - define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS); |
|
226 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true); |
|
227 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf( |
|
228 | - __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s', |
|
229 | - 'event_espresso'), |
|
230 | - '<h4 class="important-notice">', |
|
231 | - '</h4>', |
|
232 | - '<br />', |
|
233 | - '<p>', |
|
234 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
235 | - '">', |
|
236 | - '</a>', |
|
237 | - '</p>' |
|
238 | - ); |
|
239 | - } |
|
240 | - |
|
241 | - |
|
242 | - |
|
243 | - /** |
|
244 | - * load_reg_steps |
|
245 | - * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array |
|
246 | - * |
|
247 | - * @access private |
|
248 | - * @throws EE_Error |
|
249 | - * @return void |
|
250 | - */ |
|
251 | - public static function load_reg_steps() |
|
252 | - { |
|
253 | - static $reg_steps_loaded = false; |
|
254 | - if ($reg_steps_loaded) { |
|
255 | - return; |
|
256 | - } |
|
257 | - // filter list of reg_steps |
|
258 | - $reg_steps_to_load = (array)apply_filters( |
|
259 | - 'AHEE__SPCO__load_reg_steps__reg_steps_to_load', |
|
260 | - EED_Single_Page_Checkout::get_reg_steps() |
|
261 | - ); |
|
262 | - // sort by key (order) |
|
263 | - ksort($reg_steps_to_load); |
|
264 | - // loop through folders |
|
265 | - foreach ($reg_steps_to_load as $order => $reg_step) { |
|
266 | - // we need a |
|
267 | - if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
268 | - // copy over to the reg_steps_array |
|
269 | - EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step; |
|
270 | - // register custom key route for each reg step |
|
271 | - // ie: step=>"slug" - this is the entire reason we load the reg steps array now |
|
272 | - EE_Config::register_route($reg_step['slug'], 'EED_Single_Page_Checkout', 'run', 'step'); |
|
273 | - // add AJAX or other hooks |
|
274 | - if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) { |
|
275 | - // setup autoloaders if necessary |
|
276 | - if ( ! class_exists($reg_step['class_name'])) { |
|
277 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder($reg_step['file_path'], true); |
|
278 | - } |
|
279 | - if (is_callable($reg_step['class_name'], 'set_hooks')) { |
|
280 | - call_user_func(array($reg_step['class_name'], 'set_hooks')); |
|
281 | - } |
|
282 | - } |
|
283 | - } |
|
284 | - } |
|
285 | - $reg_steps_loaded = true; |
|
286 | - } |
|
287 | - |
|
288 | - |
|
289 | - |
|
290 | - /** |
|
291 | - * get_reg_steps |
|
292 | - * |
|
293 | - * @access public |
|
294 | - * @return array |
|
295 | - */ |
|
296 | - public static function get_reg_steps() |
|
297 | - { |
|
298 | - $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps; |
|
299 | - if (empty($reg_steps)) { |
|
300 | - $reg_steps = array( |
|
301 | - 10 => array( |
|
302 | - 'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information', |
|
303 | - 'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information', |
|
304 | - 'slug' => 'attendee_information', |
|
305 | - 'has_hooks' => false, |
|
306 | - ), |
|
307 | - 20 => array( |
|
308 | - 'file_path' => SPCO_REG_STEPS_PATH . 'registration_confirmation', |
|
309 | - 'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation', |
|
310 | - 'slug' => 'registration_confirmation', |
|
311 | - 'has_hooks' => false, |
|
312 | - ), |
|
313 | - 30 => array( |
|
314 | - 'file_path' => SPCO_REG_STEPS_PATH . 'payment_options', |
|
315 | - 'class_name' => 'EE_SPCO_Reg_Step_Payment_Options', |
|
316 | - 'slug' => 'payment_options', |
|
317 | - 'has_hooks' => true, |
|
318 | - ), |
|
319 | - 999 => array( |
|
320 | - 'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration', |
|
321 | - 'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration', |
|
322 | - 'slug' => 'finalize_registration', |
|
323 | - 'has_hooks' => false, |
|
324 | - ), |
|
325 | - ); |
|
326 | - } |
|
327 | - return $reg_steps; |
|
328 | - } |
|
329 | - |
|
330 | - |
|
331 | - |
|
332 | - /** |
|
333 | - * registration_checkout_for_admin |
|
334 | - * |
|
335 | - * @access public |
|
336 | - * @return string |
|
337 | - * @throws \EE_Error |
|
338 | - */ |
|
339 | - public static function registration_checkout_for_admin() |
|
340 | - { |
|
341 | - EED_Single_Page_Checkout::load_reg_steps(); |
|
342 | - EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
343 | - EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step'); |
|
344 | - EE_Registry::instance()->REQ->set('process_form_submission', false); |
|
345 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
346 | - EED_Single_Page_Checkout::instance()->_display_spco_reg_form(); |
|
347 | - return EE_Registry::instance()->REQ->get_output(); |
|
348 | - } |
|
349 | - |
|
350 | - |
|
351 | - |
|
352 | - /** |
|
353 | - * process_registration_from_admin |
|
354 | - * |
|
355 | - * @access public |
|
356 | - * @return \EE_Transaction |
|
357 | - * @throws \EE_Error |
|
358 | - */ |
|
359 | - public static function process_registration_from_admin() |
|
360 | - { |
|
361 | - EED_Single_Page_Checkout::load_reg_steps(); |
|
362 | - EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
363 | - EE_Registry::instance()->REQ->set('action', 'process_reg_step'); |
|
364 | - EE_Registry::instance()->REQ->set('process_form_submission', true); |
|
365 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
366 | - if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) { |
|
367 | - $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps); |
|
368 | - if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) { |
|
369 | - EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step); |
|
370 | - if ($final_reg_step->process_reg_step()) { |
|
371 | - $final_reg_step->set_completed(); |
|
372 | - EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array(); |
|
373 | - return EED_Single_Page_Checkout::instance()->checkout->transaction; |
|
374 | - } |
|
375 | - } |
|
376 | - } |
|
377 | - return null; |
|
378 | - } |
|
379 | - |
|
380 | - |
|
381 | - |
|
382 | - /** |
|
383 | - * run |
|
384 | - * |
|
385 | - * @access public |
|
386 | - * @param WP_Query $WP_Query |
|
387 | - * @return void |
|
388 | - * @throws \EE_Error |
|
389 | - */ |
|
390 | - public function run($WP_Query) |
|
391 | - { |
|
392 | - if ( |
|
393 | - $WP_Query instanceof WP_Query |
|
394 | - && $WP_Query->is_main_query() |
|
395 | - && apply_filters('FHEE__EED_Single_Page_Checkout__run', true) |
|
396 | - && $this->_is_reg_checkout() |
|
397 | - ) { |
|
398 | - $this->_initialize(); |
|
399 | - } |
|
400 | - } |
|
401 | - |
|
402 | - |
|
403 | - |
|
404 | - /** |
|
405 | - * determines whether current url matches reg page url |
|
406 | - * |
|
407 | - * @return bool |
|
408 | - */ |
|
409 | - protected function _is_reg_checkout() |
|
410 | - { |
|
411 | - // get current permalink for reg page without any extra query args |
|
412 | - $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id); |
|
413 | - // get request URI for current request, but without the scheme or host |
|
414 | - $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI'); |
|
415 | - $current_request_uri = html_entity_decode($current_request_uri); |
|
416 | - // get array of query args from the current request URI |
|
417 | - $query_args = \EEH_URL::get_query_string($current_request_uri); |
|
418 | - // grab page id if it is set |
|
419 | - $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0; |
|
420 | - // and remove the page id from the query args (we will re-add it later) |
|
421 | - unset($query_args['page_id']); |
|
422 | - // now strip all query args from current request URI |
|
423 | - $current_request_uri = remove_query_arg(array_flip($query_args), $current_request_uri); |
|
424 | - // and re-add the page id if it was set |
|
425 | - if ($page_id) { |
|
426 | - $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri); |
|
427 | - } |
|
428 | - // remove slashes and ? |
|
429 | - $current_request_uri = trim($current_request_uri, '?/'); |
|
430 | - // is current request URI part of the known full reg page URL ? |
|
431 | - return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false; |
|
432 | - } |
|
433 | - |
|
434 | - |
|
435 | - |
|
436 | - /** |
|
437 | - * run |
|
438 | - * |
|
439 | - * @access public |
|
440 | - * @param WP_Query $WP_Query |
|
441 | - * @return void |
|
442 | - * @throws \EE_Error |
|
443 | - */ |
|
444 | - public static function init($WP_Query) |
|
445 | - { |
|
446 | - EED_Single_Page_Checkout::instance()->run($WP_Query); |
|
447 | - } |
|
448 | - |
|
449 | - |
|
450 | - |
|
451 | - /** |
|
452 | - * _initialize - initial module setup |
|
453 | - * |
|
454 | - * @access private |
|
455 | - * @throws EE_Error |
|
456 | - * @return void |
|
457 | - */ |
|
458 | - private function _initialize() |
|
459 | - { |
|
460 | - // ensure SPCO doesn't run twice |
|
461 | - if (EED_Single_Page_Checkout::$_initialized) { |
|
462 | - return; |
|
463 | - } |
|
464 | - try { |
|
465 | - $this->_verify_session(); |
|
466 | - // setup the EE_Checkout object |
|
467 | - $this->checkout = $this->_initialize_checkout(); |
|
468 | - // filter checkout |
|
469 | - $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout); |
|
470 | - // get the $_GET |
|
471 | - $this->_get_request_vars(); |
|
472 | - if ($this->_block_bots()) { |
|
473 | - return; |
|
474 | - } |
|
475 | - // filter continue_reg |
|
476 | - $this->checkout->continue_reg = apply_filters('FHEE__EED_Single_Page_Checkout__init___continue_reg', true, $this->checkout); |
|
477 | - // load the reg steps array |
|
478 | - if ( ! $this->_load_and_instantiate_reg_steps()) { |
|
479 | - EED_Single_Page_Checkout::$_initialized = true; |
|
480 | - return; |
|
481 | - } |
|
482 | - // set the current step |
|
483 | - $this->checkout->set_current_step($this->checkout->step); |
|
484 | - // and the next step |
|
485 | - $this->checkout->set_next_step(); |
|
486 | - // verify that everything has been setup correctly |
|
487 | - if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) { |
|
488 | - EED_Single_Page_Checkout::$_initialized = true; |
|
489 | - return; |
|
490 | - } |
|
491 | - // lock the transaction |
|
492 | - $this->checkout->transaction->lock(); |
|
493 | - // make sure all of our cached objects are added to their respective model entity mappers |
|
494 | - $this->checkout->refresh_all_entities(); |
|
495 | - // set amount owing |
|
496 | - $this->checkout->amount_owing = $this->checkout->transaction->remaining(); |
|
497 | - // initialize each reg step, which gives them the chance to potentially alter the process |
|
498 | - $this->_initialize_reg_steps(); |
|
499 | - // DEBUG LOG |
|
500 | - //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
501 | - // get reg form |
|
502 | - if( ! $this->_check_form_submission()) { |
|
503 | - EED_Single_Page_Checkout::$_initialized = true; |
|
504 | - return; |
|
505 | - } |
|
506 | - // checkout the action!!! |
|
507 | - $this->_process_form_action(); |
|
508 | - // add some style and make it dance |
|
509 | - $this->add_styles_and_scripts(); |
|
510 | - // kk... SPCO has successfully run |
|
511 | - EED_Single_Page_Checkout::$_initialized = true; |
|
512 | - // set no cache headers and constants |
|
513 | - EE_System::do_not_cache(); |
|
514 | - // add anchor |
|
515 | - add_action('loop_start', array($this, 'set_checkout_anchor'), 1); |
|
516 | - // remove transaction lock |
|
517 | - add_action('shutdown', array($this, 'unlock_transaction'), 1); |
|
518 | - } catch (Exception $e) { |
|
519 | - EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
520 | - } |
|
521 | - } |
|
522 | - |
|
523 | - |
|
524 | - |
|
525 | - /** |
|
526 | - * _verify_session |
|
527 | - * checks that the session is valid and not expired |
|
528 | - * |
|
529 | - * @access private |
|
530 | - * @throws EE_Error |
|
531 | - */ |
|
532 | - private function _verify_session() |
|
533 | - { |
|
534 | - if ( ! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
535 | - throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso')); |
|
536 | - } |
|
537 | - // is session still valid ? |
|
538 | - if (EE_Registry::instance()->SSN->expired() && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '') { |
|
539 | - $this->checkout = new EE_Checkout(); |
|
540 | - EE_Registry::instance()->SSN->reset_cart(); |
|
541 | - EE_Registry::instance()->SSN->reset_checkout(); |
|
542 | - EE_Registry::instance()->SSN->reset_transaction(); |
|
543 | - EE_Error::add_attention(EE_Registry::$i18n_js_strings['registration_expiration_notice'], __FILE__, |
|
544 | - __FUNCTION__, __LINE__); |
|
545 | - EE_Registry::instance()->SSN->reset_expired(); |
|
546 | - } |
|
547 | - } |
|
548 | - |
|
549 | - |
|
550 | - |
|
551 | - /** |
|
552 | - * _initialize_checkout |
|
553 | - * loads and instantiates EE_Checkout |
|
554 | - * |
|
555 | - * @access private |
|
556 | - * @throws EE_Error |
|
557 | - * @return EE_Checkout |
|
558 | - */ |
|
559 | - private function _initialize_checkout() |
|
560 | - { |
|
561 | - // look in session for existing checkout |
|
562 | - /** @type EE_Checkout $checkout */ |
|
563 | - $checkout = EE_Registry::instance()->SSN->checkout(); |
|
564 | - // verify |
|
565 | - if ( ! $checkout instanceof EE_Checkout) { |
|
566 | - // instantiate EE_Checkout object for handling the properties of the current checkout process |
|
567 | - $checkout = EE_Registry::instance()->load_file(SPCO_INC_PATH, 'EE_Checkout', 'class', array(), false); |
|
568 | - } else { |
|
569 | - if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) { |
|
570 | - $this->unlock_transaction(); |
|
571 | - wp_safe_redirect($checkout->redirect_url); |
|
572 | - exit(); |
|
573 | - } |
|
574 | - } |
|
575 | - $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout); |
|
576 | - // verify again |
|
577 | - if ( ! $checkout instanceof EE_Checkout) { |
|
578 | - throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso')); |
|
579 | - } |
|
580 | - // reset anything that needs a clean slate for each request |
|
581 | - $checkout->reset_for_current_request(); |
|
582 | - return $checkout; |
|
583 | - } |
|
584 | - |
|
585 | - |
|
586 | - |
|
587 | - /** |
|
588 | - * _get_request_vars |
|
589 | - * |
|
590 | - * @access private |
|
591 | - * @return void |
|
592 | - * @throws \EE_Error |
|
593 | - */ |
|
594 | - private function _get_request_vars() |
|
595 | - { |
|
596 | - // load classes |
|
597 | - EED_Single_Page_Checkout::load_request_handler(); |
|
598 | - //make sure this request is marked as belonging to EE |
|
599 | - EE_Registry::instance()->REQ->set_espresso_page(true); |
|
600 | - // which step is being requested ? |
|
601 | - $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step()); |
|
602 | - // which step is being edited ? |
|
603 | - $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', ''); |
|
604 | - // and what we're doing on the current step |
|
605 | - $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step'); |
|
606 | - // timestamp |
|
607 | - $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0); |
|
608 | - // returning to edit ? |
|
609 | - $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', ''); |
|
610 | - // or some other kind of revisit ? |
|
611 | - $this->checkout->revisit = filter_var( |
|
612 | - EE_Registry::instance()->REQ->get('revisit', false), |
|
613 | - FILTER_VALIDATE_BOOLEAN |
|
614 | - ); |
|
615 | - // and whether or not to generate a reg form for this request |
|
616 | - $this->checkout->generate_reg_form = filter_var( |
|
617 | - EE_Registry::instance()->REQ->get('generate_reg_form', true), |
|
618 | - FILTER_VALIDATE_BOOLEAN |
|
619 | - ); |
|
620 | - // and whether or not to process a reg form submission for this request |
|
621 | - $this->checkout->process_form_submission = filter_var( |
|
622 | - EE_Registry::instance()->REQ->get( |
|
623 | - 'process_form_submission', |
|
624 | - $this->checkout->action === 'process_reg_step' |
|
625 | - ), |
|
626 | - FILTER_VALIDATE_BOOLEAN |
|
627 | - ); |
|
628 | - $this->checkout->process_form_submission = filter_var( |
|
629 | - $this->checkout->action !== 'display_spco_reg_step' |
|
630 | - ? $this->checkout->process_form_submission |
|
631 | - : false, |
|
632 | - FILTER_VALIDATE_BOOLEAN |
|
633 | - ); |
|
634 | - // $this->_display_request_vars(); |
|
635 | - } |
|
636 | - |
|
637 | - |
|
638 | - |
|
639 | - /** |
|
640 | - * _display_request_vars |
|
641 | - * |
|
642 | - * @access protected |
|
643 | - * @return void |
|
644 | - */ |
|
645 | - protected function _display_request_vars() |
|
646 | - { |
|
647 | - if ( ! WP_DEBUG) { |
|
648 | - return; |
|
649 | - } |
|
650 | - EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__); |
|
651 | - EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__); |
|
652 | - EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__); |
|
653 | - EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__); |
|
654 | - EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__); |
|
655 | - EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__); |
|
656 | - EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__); |
|
657 | - EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__); |
|
658 | - } |
|
659 | - |
|
660 | - |
|
661 | - |
|
662 | - /** |
|
663 | - * _block_bots |
|
664 | - * checks that the incoming request has either of the following set: |
|
665 | - * a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector |
|
666 | - * a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN |
|
667 | - * so if you're not coming from the Ticket Selector nor returning for a valid IP... |
|
668 | - * then where you coming from man? |
|
669 | - * |
|
670 | - * @return boolean |
|
671 | - */ |
|
672 | - private function _block_bots() |
|
673 | - { |
|
674 | - $invalid_checkout_access = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
675 | - if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) { |
|
676 | - return true; |
|
677 | - } |
|
678 | - return false; |
|
679 | - } |
|
680 | - |
|
681 | - |
|
682 | - |
|
683 | - /** |
|
684 | - * _get_first_step |
|
685 | - * gets slug for first step in $_reg_steps_array |
|
686 | - * |
|
687 | - * @access private |
|
688 | - * @throws EE_Error |
|
689 | - * @return string |
|
690 | - */ |
|
691 | - private function _get_first_step() |
|
692 | - { |
|
693 | - $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array); |
|
694 | - return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information'; |
|
695 | - } |
|
696 | - |
|
697 | - |
|
698 | - |
|
699 | - /** |
|
700 | - * _load_and_instantiate_reg_steps |
|
701 | - * instantiates each reg step based on the loaded reg_steps array |
|
702 | - * |
|
703 | - * @access private |
|
704 | - * @throws EE_Error |
|
705 | - * @return bool |
|
706 | - */ |
|
707 | - private function _load_and_instantiate_reg_steps() |
|
708 | - { |
|
709 | - // have reg_steps already been instantiated ? |
|
710 | - if ( |
|
711 | - empty($this->checkout->reg_steps) |
|
712 | - || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout) |
|
713 | - ) { |
|
714 | - // if not, then loop through raw reg steps array |
|
715 | - foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) { |
|
716 | - if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) { |
|
717 | - return false; |
|
718 | - } |
|
719 | - } |
|
720 | - EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true; |
|
721 | - EE_Registry::instance()->CFG->registration->reg_confirmation_last = true; |
|
722 | - // skip the registration_confirmation page ? |
|
723 | - if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) { |
|
724 | - // just remove it from the reg steps array |
|
725 | - $this->checkout->remove_reg_step('registration_confirmation', false); |
|
726 | - } else if ( |
|
727 | - isset($this->checkout->reg_steps['registration_confirmation']) |
|
728 | - && EE_Registry::instance()->CFG->registration->reg_confirmation_last |
|
729 | - ) { |
|
730 | - // set the order to something big like 100 |
|
731 | - $this->checkout->set_reg_step_order('registration_confirmation', 100); |
|
732 | - } |
|
733 | - // filter the array for good luck |
|
734 | - $this->checkout->reg_steps = apply_filters( |
|
735 | - 'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps', |
|
736 | - $this->checkout->reg_steps |
|
737 | - ); |
|
738 | - // finally re-sort based on the reg step class order properties |
|
739 | - $this->checkout->sort_reg_steps(); |
|
740 | - } else { |
|
741 | - foreach ($this->checkout->reg_steps as $reg_step) { |
|
742 | - // set all current step stati to FALSE |
|
743 | - $reg_step->set_is_current_step(false); |
|
744 | - } |
|
745 | - } |
|
746 | - if (empty($this->checkout->reg_steps)) { |
|
747 | - EE_Error::add_error(__('No Reg Steps were loaded..', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
748 | - return false; |
|
749 | - } |
|
750 | - // make reg step details available to JS |
|
751 | - $this->checkout->set_reg_step_JSON_info(); |
|
752 | - return true; |
|
753 | - } |
|
754 | - |
|
755 | - |
|
756 | - |
|
757 | - /** |
|
758 | - * _load_and_instantiate_reg_step |
|
759 | - * |
|
760 | - * @access private |
|
761 | - * @param array $reg_step |
|
762 | - * @param int $order |
|
763 | - * @return bool |
|
764 | - */ |
|
765 | - private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0) |
|
766 | - { |
|
767 | - // we need a file_path, class_name, and slug to add a reg step |
|
768 | - if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
769 | - // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step) |
|
770 | - if ( |
|
771 | - $this->checkout->reg_url_link |
|
772 | - && $this->checkout->step !== $reg_step['slug'] |
|
773 | - && $reg_step['slug'] !== 'finalize_registration' |
|
774 | - ) { |
|
775 | - return true; |
|
776 | - } |
|
777 | - // instantiate step class using file path and class name |
|
778 | - $reg_step_obj = EE_Registry::instance()->load_file( |
|
779 | - $reg_step['file_path'], |
|
780 | - $reg_step['class_name'], |
|
781 | - 'class', |
|
782 | - $this->checkout, |
|
783 | - false |
|
784 | - ); |
|
785 | - // did we gets the goods ? |
|
786 | - if ($reg_step_obj instanceof EE_SPCO_Reg_Step) { |
|
787 | - // set reg step order based on config |
|
788 | - $reg_step_obj->set_order($order); |
|
789 | - // add instantiated reg step object to the master reg steps array |
|
790 | - $this->checkout->add_reg_step($reg_step_obj); |
|
791 | - } else { |
|
792 | - EE_Error::add_error( |
|
793 | - __('The current step could not be set.', 'event_espresso'), |
|
794 | - __FILE__, __FUNCTION__, __LINE__ |
|
795 | - ); |
|
796 | - return false; |
|
797 | - } |
|
798 | - } else { |
|
799 | - if (WP_DEBUG) { |
|
800 | - EE_Error::add_error( |
|
801 | - sprintf( |
|
802 | - __('A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s', 'event_espresso'), |
|
803 | - isset($reg_step['file_path']) ? $reg_step['file_path'] : '', |
|
804 | - isset($reg_step['class_name']) ? $reg_step['class_name'] : '', |
|
805 | - isset($reg_step['slug']) ? $reg_step['slug'] : '', |
|
806 | - '<ul>', |
|
807 | - '<li>', |
|
808 | - '</li>', |
|
809 | - '</ul>' |
|
810 | - ), |
|
811 | - __FILE__, __FUNCTION__, __LINE__ |
|
812 | - ); |
|
813 | - } |
|
814 | - return false; |
|
815 | - } |
|
816 | - return true; |
|
817 | - } |
|
818 | - |
|
819 | - |
|
820 | - |
|
821 | - /** |
|
822 | - * _verify_transaction_and_get_registrations |
|
823 | - * |
|
824 | - * @access private |
|
825 | - * @return bool |
|
826 | - */ |
|
827 | - private function _verify_transaction_and_get_registrations() |
|
828 | - { |
|
829 | - // was there already a valid transaction in the checkout from the session ? |
|
830 | - if ( ! $this->checkout->transaction instanceof EE_Transaction) { |
|
831 | - // get transaction from db or session |
|
832 | - $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin() |
|
833 | - ? $this->_get_transaction_and_cart_for_previous_visit() |
|
834 | - : $this->_get_cart_for_current_session_and_setup_new_transaction(); |
|
835 | - if ( ! $this->checkout->transaction instanceof EE_Transaction) { |
|
836 | - EE_Error::add_error( |
|
837 | - __('Your Registration and Transaction information could not be retrieved from the db.', |
|
838 | - 'event_espresso'), |
|
839 | - __FILE__, __FUNCTION__, __LINE__ |
|
840 | - ); |
|
841 | - $this->checkout->transaction = EE_Transaction::new_instance(); |
|
842 | - // add some style and make it dance |
|
843 | - $this->add_styles_and_scripts(); |
|
844 | - EED_Single_Page_Checkout::$_initialized = true; |
|
845 | - return false; |
|
846 | - } |
|
847 | - // and the registrations for the transaction |
|
848 | - $this->_get_registrations($this->checkout->transaction); |
|
849 | - } |
|
850 | - return true; |
|
851 | - } |
|
852 | - |
|
853 | - |
|
854 | - |
|
855 | - /** |
|
856 | - * _get_transaction_and_cart_for_previous_visit |
|
857 | - * |
|
858 | - * @access private |
|
859 | - * @return mixed EE_Transaction|NULL |
|
860 | - */ |
|
861 | - private function _get_transaction_and_cart_for_previous_visit() |
|
862 | - { |
|
863 | - /** @var $TXN_model EEM_Transaction */ |
|
864 | - $TXN_model = EE_Registry::instance()->load_model('Transaction'); |
|
865 | - // because the reg_url_link is present in the request, this is a return visit to SPCO, so we'll get the transaction data from the db |
|
866 | - $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link); |
|
867 | - // verify transaction |
|
868 | - if ($transaction instanceof EE_Transaction) { |
|
869 | - // and get the cart that was used for that transaction |
|
870 | - $this->checkout->cart = $this->_get_cart_for_transaction($transaction); |
|
871 | - return $transaction; |
|
872 | - } else { |
|
873 | - EE_Error::add_error(__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
874 | - return null; |
|
875 | - } |
|
876 | - } |
|
877 | - |
|
878 | - |
|
879 | - |
|
880 | - /** |
|
881 | - * _get_cart_for_transaction |
|
882 | - * |
|
883 | - * @access private |
|
884 | - * @param EE_Transaction $transaction |
|
885 | - * @return EE_Cart |
|
886 | - */ |
|
887 | - private function _get_cart_for_transaction($transaction) |
|
888 | - { |
|
889 | - return $this->checkout->get_cart_for_transaction($transaction); |
|
890 | - } |
|
891 | - |
|
892 | - |
|
893 | - |
|
894 | - /** |
|
895 | - * get_cart_for_transaction |
|
896 | - * |
|
897 | - * @access public |
|
898 | - * @param EE_Transaction $transaction |
|
899 | - * @return EE_Cart |
|
900 | - */ |
|
901 | - public function get_cart_for_transaction(EE_Transaction $transaction) |
|
902 | - { |
|
903 | - return $this->checkout->get_cart_for_transaction($transaction); |
|
904 | - } |
|
905 | - |
|
906 | - |
|
907 | - |
|
908 | - /** |
|
909 | - * _get_transaction_and_cart_for_current_session |
|
910 | - * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
911 | - * |
|
912 | - * @access private |
|
913 | - * @return EE_Transaction |
|
914 | - * @throws \EE_Error |
|
915 | - */ |
|
916 | - private function _get_cart_for_current_session_and_setup_new_transaction() |
|
917 | - { |
|
918 | - // if there's no transaction, then this is the FIRST visit to SPCO |
|
919 | - // so load up the cart ( passing nothing for the TXN because it doesn't exist yet ) |
|
920 | - $this->checkout->cart = $this->_get_cart_for_transaction(null); |
|
921 | - // and then create a new transaction |
|
922 | - $transaction = $this->_initialize_transaction(); |
|
923 | - // verify transaction |
|
924 | - if ($transaction instanceof EE_Transaction) { |
|
925 | - // save it so that we have an ID for other objects to use |
|
926 | - $transaction->save(); |
|
927 | - // and save TXN data to the cart |
|
928 | - $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID()); |
|
929 | - } else { |
|
930 | - EE_Error::add_error(__('A Valid Transaction could not be initialized.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
931 | - } |
|
932 | - return $transaction; |
|
933 | - } |
|
934 | - |
|
935 | - |
|
936 | - |
|
937 | - /** |
|
938 | - * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
939 | - * |
|
940 | - * @access private |
|
941 | - * @return mixed EE_Transaction|NULL |
|
942 | - */ |
|
943 | - private function _initialize_transaction() |
|
944 | - { |
|
945 | - try { |
|
946 | - // ensure cart totals have been calculated |
|
947 | - $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes(); |
|
948 | - // grab the cart grand total |
|
949 | - $cart_total = $this->checkout->cart->get_cart_grand_total(); |
|
950 | - // create new TXN |
|
951 | - $transaction = EE_Transaction::new_instance( |
|
952 | - array( |
|
953 | - 'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(), |
|
954 | - 'TXN_total' => $cart_total > 0 ? $cart_total : 0, |
|
955 | - 'TXN_paid' => 0, |
|
956 | - 'STS_ID' => EEM_Transaction::failed_status_code, |
|
957 | - ) |
|
958 | - ); |
|
959 | - // save it so that we have an ID for other objects to use |
|
960 | - $transaction->save(); |
|
961 | - // set cron job for following up on TXNs after their session has expired |
|
962 | - EE_Cron_Tasks::schedule_expired_transaction_check( |
|
963 | - EE_Registry::instance()->SSN->expiration() + 1, |
|
964 | - $transaction->ID() |
|
965 | - ); |
|
966 | - return $transaction; |
|
967 | - } catch (Exception $e) { |
|
968 | - EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
969 | - } |
|
970 | - return null; |
|
971 | - } |
|
972 | - |
|
973 | - |
|
974 | - |
|
975 | - /** |
|
976 | - * _get_registrations |
|
977 | - * |
|
978 | - * @access private |
|
979 | - * @param EE_Transaction $transaction |
|
980 | - * @return void |
|
981 | - * @throws \EventEspresso\core\exceptions\InvalidEntityException |
|
982 | - * @throws \EE_Error |
|
983 | - */ |
|
984 | - private function _get_registrations(EE_Transaction $transaction) |
|
985 | - { |
|
986 | - // first step: grab the registrants { : o |
|
987 | - $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true); |
|
988 | - // verify registrations have been set |
|
989 | - if (empty($registrations)) { |
|
990 | - // if no cached registrations, then check the db |
|
991 | - $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
992 | - // still nothing ? well as long as this isn't a revisit |
|
993 | - if (empty($registrations) && ! $this->checkout->revisit) { |
|
994 | - // generate new registrations from scratch |
|
995 | - $registrations = $this->_initialize_registrations($transaction); |
|
996 | - } |
|
997 | - } |
|
998 | - // sort by their original registration order |
|
999 | - usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count')); |
|
1000 | - // then loop thru the array |
|
1001 | - foreach ($registrations as $registration) { |
|
1002 | - // verify each registration |
|
1003 | - if ($registration instanceof EE_Registration) { |
|
1004 | - // we display all attendee info for the primary registrant |
|
1005 | - if ($this->checkout->reg_url_link === $registration->reg_url_link() |
|
1006 | - && $registration->is_primary_registrant() |
|
1007 | - ) { |
|
1008 | - $this->checkout->primary_revisit = true; |
|
1009 | - break; |
|
1010 | - } else if ($this->checkout->revisit |
|
1011 | - && $this->checkout->reg_url_link !== $registration->reg_url_link() |
|
1012 | - ) { |
|
1013 | - // but hide info if it doesn't belong to you |
|
1014 | - $transaction->clear_cache('Registration', $registration->ID()); |
|
1015 | - } |
|
1016 | - $this->checkout->set_reg_status_updated($registration->ID(), false); |
|
1017 | - } |
|
1018 | - } |
|
1019 | - } |
|
1020 | - |
|
1021 | - |
|
1022 | - |
|
1023 | - /** |
|
1024 | - * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object |
|
1025 | - * |
|
1026 | - * @access private |
|
1027 | - * @param EE_Transaction $transaction |
|
1028 | - * @return array |
|
1029 | - * @throws \EventEspresso\core\exceptions\InvalidEntityException |
|
1030 | - * @throws \EE_Error |
|
1031 | - */ |
|
1032 | - private function _initialize_registrations(EE_Transaction $transaction) |
|
1033 | - { |
|
1034 | - $att_nmbr = 0; |
|
1035 | - $registrations = array(); |
|
1036 | - if ($transaction instanceof EE_Transaction) { |
|
1037 | - /** @type EE_Registration_Processor $registration_processor */ |
|
1038 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
1039 | - $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count(); |
|
1040 | - // now let's add the cart items to the $transaction |
|
1041 | - foreach ($this->checkout->cart->get_tickets() as $line_item) { |
|
1042 | - //do the following for each ticket of this type they selected |
|
1043 | - for ($x = 1; $x <= $line_item->quantity(); $x++) { |
|
1044 | - $att_nmbr++; |
|
1045 | - /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */ |
|
1046 | - $CreateRegistrationCommand = EE_Registry::instance() |
|
1047 | - ->create( |
|
1048 | - 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand', |
|
1049 | - array( |
|
1050 | - $transaction, |
|
1051 | - $line_item, |
|
1052 | - $att_nmbr, |
|
1053 | - $this->checkout->total_ticket_count, |
|
1054 | - ) |
|
1055 | - ); |
|
1056 | - // override capabilities for frontend registrations |
|
1057 | - if ( ! is_admin()) { |
|
1058 | - $CreateRegistrationCommand->setCapCheck( |
|
1059 | - new PublicCapabilities('', 'create_new_registration') |
|
1060 | - ); |
|
1061 | - } |
|
1062 | - $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand); |
|
1063 | - if ( ! $registration instanceof EE_Registration) { |
|
1064 | - throw new InvalidEntityException($registration, 'EE_Registration'); |
|
1065 | - } |
|
1066 | - $registrations[ $registration->ID() ] = $registration; |
|
1067 | - } |
|
1068 | - } |
|
1069 | - $registration_processor->fix_reg_final_price_rounding_issue($transaction); |
|
1070 | - } |
|
1071 | - return $registrations; |
|
1072 | - } |
|
1073 | - |
|
1074 | - |
|
1075 | - |
|
1076 | - /** |
|
1077 | - * sorts registrations by REG_count |
|
1078 | - * |
|
1079 | - * @access public |
|
1080 | - * @param EE_Registration $reg_A |
|
1081 | - * @param EE_Registration $reg_B |
|
1082 | - * @return int |
|
1083 | - */ |
|
1084 | - public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B) |
|
1085 | - { |
|
1086 | - // this shouldn't ever happen within the same TXN, but oh well |
|
1087 | - if ($reg_A->count() === $reg_B->count()) { |
|
1088 | - return 0; |
|
1089 | - } |
|
1090 | - return ($reg_A->count() > $reg_B->count()) ? 1 : -1; |
|
1091 | - } |
|
1092 | - |
|
1093 | - |
|
1094 | - |
|
1095 | - /** |
|
1096 | - * _final_verifications |
|
1097 | - * just makes sure that everything is set up correctly before proceeding |
|
1098 | - * |
|
1099 | - * @access private |
|
1100 | - * @return bool |
|
1101 | - * @throws \EE_Error |
|
1102 | - */ |
|
1103 | - private function _final_verifications() |
|
1104 | - { |
|
1105 | - // filter checkout |
|
1106 | - $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout); |
|
1107 | - //verify that current step is still set correctly |
|
1108 | - if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) { |
|
1109 | - EE_Error::add_error( |
|
1110 | - __('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'), |
|
1111 | - __FILE__, |
|
1112 | - __FUNCTION__, |
|
1113 | - __LINE__ |
|
1114 | - ); |
|
1115 | - return false; |
|
1116 | - } |
|
1117 | - // if returning to SPCO, then verify that primary registrant is set |
|
1118 | - if ( ! empty($this->checkout->reg_url_link)) { |
|
1119 | - $valid_registrant = $this->checkout->transaction->primary_registration(); |
|
1120 | - if ( ! $valid_registrant instanceof EE_Registration) { |
|
1121 | - EE_Error::add_error( |
|
1122 | - __('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'), |
|
1123 | - __FILE__, |
|
1124 | - __FUNCTION__, |
|
1125 | - __LINE__ |
|
1126 | - ); |
|
1127 | - return false; |
|
1128 | - } |
|
1129 | - $valid_registrant = null; |
|
1130 | - foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) { |
|
1131 | - if ( |
|
1132 | - $registration instanceof EE_Registration |
|
1133 | - && $registration->reg_url_link() === $this->checkout->reg_url_link |
|
1134 | - ) { |
|
1135 | - $valid_registrant = $registration; |
|
1136 | - } |
|
1137 | - } |
|
1138 | - if ( ! $valid_registrant instanceof EE_Registration) { |
|
1139 | - // hmmm... maybe we have the wrong session because the user is opening multiple tabs ? |
|
1140 | - if (EED_Single_Page_Checkout::$_checkout_verified) { |
|
1141 | - // clear the session, mark the checkout as unverified, and try again |
|
1142 | - EE_Registry::instance()->SSN->clear_session(); |
|
1143 | - EED_Single_Page_Checkout::$_initialized = false; |
|
1144 | - EED_Single_Page_Checkout::$_checkout_verified = false; |
|
1145 | - $this->_initialize(); |
|
1146 | - EE_Error::reset_notices(); |
|
1147 | - return false; |
|
1148 | - } |
|
1149 | - EE_Error::add_error( |
|
1150 | - __('We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.', 'event_espresso'), |
|
1151 | - __FILE__, |
|
1152 | - __FUNCTION__, |
|
1153 | - __LINE__ |
|
1154 | - ); |
|
1155 | - return false; |
|
1156 | - } |
|
1157 | - } |
|
1158 | - // now that things have been kinda sufficiently verified, |
|
1159 | - // let's add the checkout to the session so that's available other systems |
|
1160 | - EE_Registry::instance()->SSN->set_checkout($this->checkout); |
|
1161 | - return true; |
|
1162 | - } |
|
1163 | - |
|
1164 | - |
|
1165 | - |
|
1166 | - /** |
|
1167 | - * _initialize_reg_steps |
|
1168 | - * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required |
|
1169 | - * then loops thru all of the active reg steps and calls the initialize_reg_step() method |
|
1170 | - * |
|
1171 | - * @access private |
|
1172 | - * @param bool $reinitializing |
|
1173 | - * @throws \EE_Error |
|
1174 | - */ |
|
1175 | - private function _initialize_reg_steps($reinitializing = false) |
|
1176 | - { |
|
1177 | - $this->checkout->set_reg_step_initiated($this->checkout->current_step); |
|
1178 | - // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS |
|
1179 | - foreach ($this->checkout->reg_steps as $reg_step) { |
|
1180 | - if ( ! $reg_step->initialize_reg_step()) { |
|
1181 | - // if not initialized then maybe this step is being removed... |
|
1182 | - if ( ! $reinitializing && $reg_step->is_current_step()) { |
|
1183 | - // if it was the current step, then we need to start over here |
|
1184 | - $this->_initialize_reg_steps(true); |
|
1185 | - return; |
|
1186 | - } |
|
1187 | - continue; |
|
1188 | - } |
|
1189 | - // add css and JS for current step |
|
1190 | - $reg_step->enqueue_styles_and_scripts(); |
|
1191 | - // i18n |
|
1192 | - $reg_step->translate_js_strings(); |
|
1193 | - if ($reg_step->is_current_step()) { |
|
1194 | - // the text that appears on the reg step form submit button |
|
1195 | - $reg_step->set_submit_button_text(); |
|
1196 | - } |
|
1197 | - } |
|
1198 | - // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information |
|
1199 | - do_action("AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", $this->checkout->current_step); |
|
1200 | - } |
|
1201 | - |
|
1202 | - |
|
1203 | - |
|
1204 | - /** |
|
1205 | - * _check_form_submission |
|
1206 | - * |
|
1207 | - * @access private |
|
1208 | - * @return boolean |
|
1209 | - */ |
|
1210 | - private function _check_form_submission() |
|
1211 | - { |
|
1212 | - //does this request require the reg form to be generated ? |
|
1213 | - if ($this->checkout->generate_reg_form) { |
|
1214 | - // ever heard that song by Blue Rodeo ? |
|
1215 | - try { |
|
1216 | - $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form(); |
|
1217 | - // if not displaying a form, then check for form submission |
|
1218 | - if ( |
|
1219 | - $this->checkout->process_form_submission |
|
1220 | - && $this->checkout->current_step->reg_form->was_submitted() |
|
1221 | - ) { |
|
1222 | - // clear out any old data in case this step is being run again |
|
1223 | - $this->checkout->current_step->set_valid_data(array()); |
|
1224 | - // capture submitted form data |
|
1225 | - $this->checkout->current_step->reg_form->receive_form_submission( |
|
1226 | - apply_filters('FHEE__Single_Page_Checkout___check_form_submission__request_params', EE_Registry::instance()->REQ->params(), $this->checkout) |
|
1227 | - ); |
|
1228 | - // validate submitted form data |
|
1229 | - if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) { |
|
1230 | - // thou shall not pass !!! |
|
1231 | - $this->checkout->continue_reg = false; |
|
1232 | - // any form validation errors? |
|
1233 | - if ($this->checkout->current_step->reg_form->submission_error_message() !== '') { |
|
1234 | - $submission_error_messages = array(); |
|
1235 | - // bad, bad, bad registrant |
|
1236 | - foreach ($this->checkout->current_step->reg_form->get_validation_errors_accumulated() as $validation_error) { |
|
1237 | - if ($validation_error instanceof EE_Validation_Error) { |
|
1238 | - $submission_error_messages[] = sprintf( |
|
1239 | - __('%s : %s', 'event_espresso'), |
|
1240 | - $validation_error->get_form_section()->html_label_text(), |
|
1241 | - $validation_error->getMessage() |
|
1242 | - ); |
|
1243 | - } |
|
1244 | - } |
|
1245 | - EE_Error::add_error(implode('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__); |
|
1246 | - } |
|
1247 | - // well not really... what will happen is we'll just get redirected back to redo the current step |
|
1248 | - $this->go_to_next_step(); |
|
1249 | - return false; |
|
1250 | - } |
|
1251 | - } |
|
1252 | - } catch (EE_Error $e) { |
|
1253 | - $e->get_error(); |
|
1254 | - } |
|
1255 | - } |
|
1256 | - return true; |
|
1257 | - } |
|
1258 | - |
|
1259 | - |
|
1260 | - |
|
1261 | - /** |
|
1262 | - * _process_action |
|
1263 | - * |
|
1264 | - * @access private |
|
1265 | - * @return void |
|
1266 | - * @throws \EE_Error |
|
1267 | - */ |
|
1268 | - private function _process_form_action() |
|
1269 | - { |
|
1270 | - // what cha wanna do? |
|
1271 | - switch ($this->checkout->action) { |
|
1272 | - // AJAX next step reg form |
|
1273 | - case 'display_spco_reg_step' : |
|
1274 | - $this->checkout->redirect = false; |
|
1275 | - if (EE_Registry::instance()->REQ->ajax) { |
|
1276 | - $this->checkout->json_response->set_reg_step_html($this->checkout->current_step->display_reg_form()); |
|
1277 | - } |
|
1278 | - break; |
|
1279 | - default : |
|
1280 | - // meh... do one of those other steps first |
|
1281 | - if ( ! empty($this->checkout->action) && is_callable(array($this->checkout->current_step, $this->checkout->action))) { |
|
1282 | - // dynamically creates hook point like: AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step |
|
1283 | - do_action("AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step); |
|
1284 | - // call action on current step |
|
1285 | - if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) { |
|
1286 | - // good registrant, you get to proceed |
|
1287 | - if ( |
|
1288 | - $this->checkout->current_step->success_message() !== '' |
|
1289 | - && apply_filters( |
|
1290 | - 'FHEE__Single_Page_Checkout___process_form_action__display_success', |
|
1291 | - false |
|
1292 | - ) |
|
1293 | - ) { |
|
1294 | - EE_Error::add_success( |
|
1295 | - $this->checkout->current_step->success_message() |
|
1296 | - . '<br />' . $this->checkout->next_step->_instructions() |
|
1297 | - ); |
|
1298 | - } |
|
1299 | - // pack it up, pack it in... |
|
1300 | - $this->_setup_redirect(); |
|
1301 | - } |
|
1302 | - // dynamically creates hook point like: AHEE__Single_Page_Checkout__after_payment_options__process_reg_step |
|
1303 | - do_action("AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step); |
|
1304 | - } else { |
|
1305 | - EE_Error::add_error( |
|
1306 | - sprintf( |
|
1307 | - __('The requested form action "%s" does not exist for the current "%s" registration step.', 'event_espresso'), |
|
1308 | - $this->checkout->action, |
|
1309 | - $this->checkout->current_step->name() |
|
1310 | - ), |
|
1311 | - __FILE__, |
|
1312 | - __FUNCTION__, |
|
1313 | - __LINE__ |
|
1314 | - ); |
|
1315 | - } |
|
1316 | - // end default |
|
1317 | - } |
|
1318 | - // store our progress so far |
|
1319 | - $this->checkout->stash_transaction_and_checkout(); |
|
1320 | - // advance to the next step! If you pass GO, collect $200 |
|
1321 | - $this->go_to_next_step(); |
|
1322 | - } |
|
1323 | - |
|
1324 | - |
|
1325 | - |
|
1326 | - /** |
|
1327 | - * add_styles_and_scripts |
|
1328 | - * |
|
1329 | - * @access public |
|
1330 | - * @return void |
|
1331 | - */ |
|
1332 | - public function add_styles_and_scripts() |
|
1333 | - { |
|
1334 | - // i18n |
|
1335 | - $this->translate_js_strings(); |
|
1336 | - if ($this->checkout->admin_request) { |
|
1337 | - add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10); |
|
1338 | - } else { |
|
1339 | - add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10); |
|
1340 | - } |
|
1341 | - } |
|
1342 | - |
|
1343 | - |
|
1344 | - |
|
1345 | - /** |
|
1346 | - * translate_js_strings |
|
1347 | - * |
|
1348 | - * @access public |
|
1349 | - * @return void |
|
1350 | - */ |
|
1351 | - public function translate_js_strings() |
|
1352 | - { |
|
1353 | - EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit; |
|
1354 | - EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link; |
|
1355 | - EE_Registry::$i18n_js_strings['server_error'] = __('An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso'); |
|
1356 | - EE_Registry::$i18n_js_strings['invalid_json_response'] = __('An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso'); |
|
1357 | - EE_Registry::$i18n_js_strings['validation_error'] = __('There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', 'event_espresso'); |
|
1358 | - EE_Registry::$i18n_js_strings['invalid_payment_method'] = __('There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', 'event_espresso'); |
|
1359 | - EE_Registry::$i18n_js_strings['reg_step_error'] = __('This registration step could not be completed. Please refresh the page and try again.', 'event_espresso'); |
|
1360 | - EE_Registry::$i18n_js_strings['invalid_coupon'] = __('We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', 'event_espresso'); |
|
1361 | - EE_Registry::$i18n_js_strings['process_registration'] = sprintf( |
|
1362 | - __('Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', 'event_espresso'), |
|
1363 | - '<br/>', |
|
1364 | - '<br/>' |
|
1365 | - ); |
|
1366 | - EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language'); |
|
1367 | - EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id(); |
|
1368 | - EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency; |
|
1369 | - EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20'; |
|
1370 | - EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso'); |
|
1371 | - EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso'); |
|
1372 | - EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso'); |
|
1373 | - EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso'); |
|
1374 | - EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso'); |
|
1375 | - EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso'); |
|
1376 | - EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso'); |
|
1377 | - EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso'); |
|
1378 | - EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso'); |
|
1379 | - EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso'); |
|
1380 | - EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso'); |
|
1381 | - EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso'); |
|
1382 | - EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso'); |
|
1383 | - EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso'); |
|
1384 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf( |
|
1385 | - __( |
|
1386 | - '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s', |
|
1387 | - 'event_espresso' |
|
1388 | - ), |
|
1389 | - '<h4 class="important-notice">', |
|
1390 | - '</h4>', |
|
1391 | - '<br />', |
|
1392 | - '<p>', |
|
1393 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1394 | - '">', |
|
1395 | - '</a>', |
|
1396 | - '</p>' |
|
1397 | - ); |
|
1398 | - EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters('FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', true); |
|
1399 | - EE_Registry::$i18n_js_strings['session_extension'] = absint( |
|
1400 | - apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS) |
|
1401 | - ); |
|
1402 | - EE_Registry::$i18n_js_strings['session_expiration'] = gmdate( |
|
1403 | - 'M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
1404 | - ); |
|
1405 | - } |
|
1406 | - |
|
1407 | - |
|
1408 | - |
|
1409 | - /** |
|
1410 | - * enqueue_styles_and_scripts |
|
1411 | - * |
|
1412 | - * @access public |
|
1413 | - * @return void |
|
1414 | - * @throws \EE_Error |
|
1415 | - */ |
|
1416 | - public function enqueue_styles_and_scripts() |
|
1417 | - { |
|
1418 | - // load css |
|
1419 | - wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION); |
|
1420 | - wp_enqueue_style('single_page_checkout'); |
|
1421 | - // load JS |
|
1422 | - wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery .plugin.min.js', array('jquery'), '1.0.1', true); |
|
1423 | - wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery .countdown.min.js', array('jquery_plugin'), '2.0.2', true); |
|
1424 | - wp_register_script('single_page_checkout', SPCO_JS_URL . 'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true); |
|
1425 | - if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) { |
|
1426 | - $this->checkout->registration_form->enqueue_js(); |
|
1427 | - } |
|
1428 | - if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) { |
|
1429 | - $this->checkout->current_step->reg_form->enqueue_js(); |
|
1430 | - } |
|
1431 | - wp_enqueue_script('single_page_checkout'); |
|
1432 | - /** |
|
1433 | - * global action hook for enqueueing styles and scripts with |
|
1434 | - * spco calls. |
|
1435 | - */ |
|
1436 | - do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this); |
|
1437 | - /** |
|
1438 | - * dynamic action hook for enqueueing styles and scripts with spco calls. |
|
1439 | - * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information |
|
1440 | - */ |
|
1441 | - do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this); |
|
1442 | - } |
|
1443 | - |
|
1444 | - |
|
1445 | - |
|
1446 | - /** |
|
1447 | - * display the Registration Single Page Checkout Form |
|
1448 | - * |
|
1449 | - * @access private |
|
1450 | - * @return void |
|
1451 | - * @throws \EE_Error |
|
1452 | - */ |
|
1453 | - private function _display_spco_reg_form() |
|
1454 | - { |
|
1455 | - // if registering via the admin, just display the reg form for the current step |
|
1456 | - if ($this->checkout->admin_request) { |
|
1457 | - EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form()); |
|
1458 | - } else { |
|
1459 | - // add powered by EE msg |
|
1460 | - add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer')); |
|
1461 | - $empty_cart = count($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)) < 1 |
|
1462 | - ? true |
|
1463 | - : false; |
|
1464 | - EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart; |
|
1465 | - $cookies_not_set_msg = ''; |
|
1466 | - if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) { |
|
1467 | - $cookies_not_set_msg = apply_filters( |
|
1468 | - 'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg', |
|
1469 | - sprintf( |
|
1470 | - __( |
|
1471 | - '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s', |
|
1472 | - 'event_espresso' |
|
1473 | - ), |
|
1474 | - '<div class="ee-attention">', |
|
1475 | - '</div>', |
|
1476 | - '<h6 class="important-notice">', |
|
1477 | - '</h6>', |
|
1478 | - '<p>', |
|
1479 | - '</p>', |
|
1480 | - '<br />', |
|
1481 | - '<a href="http://www.whatarecookies.com/enable.asp" target="_blank">', |
|
1482 | - '</a>' |
|
1483 | - ) |
|
1484 | - ); |
|
1485 | - } |
|
1486 | - $this->checkout->registration_form = new EE_Form_Section_Proper( |
|
1487 | - array( |
|
1488 | - 'name' => 'single-page-checkout', |
|
1489 | - 'html_id' => 'ee-single-page-checkout-dv', |
|
1490 | - 'layout_strategy' => |
|
1491 | - new EE_Template_Layout( |
|
1492 | - array( |
|
1493 | - 'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php', |
|
1494 | - 'template_args' => array( |
|
1495 | - 'empty_cart' => $empty_cart, |
|
1496 | - 'revisit' => $this->checkout->revisit, |
|
1497 | - 'reg_steps' => $this->checkout->reg_steps, |
|
1498 | - 'next_step' => $this->checkout->next_step instanceof EE_SPCO_Reg_Step |
|
1499 | - ? $this->checkout->next_step->slug() |
|
1500 | - : '', |
|
1501 | - 'cancel_page_url' => $this->checkout->cancel_page_url, |
|
1502 | - 'empty_msg' => apply_filters( |
|
1503 | - 'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg', |
|
1504 | - sprintf( |
|
1505 | - __('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', |
|
1506 | - 'event_espresso'), |
|
1507 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1508 | - '">', |
|
1509 | - '</a>' |
|
1510 | - ) |
|
1511 | - ), |
|
1512 | - 'cookies_not_set_msg' => $cookies_not_set_msg, |
|
1513 | - 'registration_time_limit' => $this->checkout->get_registration_time_limit(), |
|
1514 | - 'session_expiration' => |
|
1515 | - date('M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)), |
|
1516 | - ), |
|
1517 | - ) |
|
1518 | - ), |
|
1519 | - ) |
|
1520 | - ); |
|
1521 | - // load template and add to output sent that gets filtered into the_content() |
|
1522 | - EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html()); |
|
1523 | - } |
|
1524 | - } |
|
1525 | - |
|
1526 | - |
|
1527 | - |
|
1528 | - /** |
|
1529 | - * add_extra_finalize_registration_inputs |
|
1530 | - * |
|
1531 | - * @access public |
|
1532 | - * @param $next_step |
|
1533 | - * @internal param string $label |
|
1534 | - * @return void |
|
1535 | - */ |
|
1536 | - public function add_extra_finalize_registration_inputs($next_step) |
|
1537 | - { |
|
1538 | - if ($next_step === 'finalize_registration') { |
|
1539 | - echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>'; |
|
1540 | - } |
|
1541 | - } |
|
1542 | - |
|
1543 | - |
|
1544 | - |
|
1545 | - /** |
|
1546 | - * display_registration_footer |
|
1547 | - * |
|
1548 | - * @access public |
|
1549 | - * @return string |
|
1550 | - */ |
|
1551 | - public static function display_registration_footer() |
|
1552 | - { |
|
1553 | - if ( |
|
1554 | - apply_filters( |
|
1555 | - 'FHEE__EE_Front__Controller__show_reg_footer', |
|
1556 | - EE_Registry::instance()->CFG->admin->show_reg_footer |
|
1557 | - ) |
|
1558 | - ) { |
|
1559 | - add_filter( |
|
1560 | - 'FHEE__EEH_Template__powered_by_event_espresso__url', |
|
1561 | - function ($url) { |
|
1562 | - return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url); |
|
1563 | - } |
|
1564 | - ); |
|
1565 | - echo apply_filters( |
|
1566 | - 'FHEE__EE_Front_Controller__display_registration_footer', |
|
1567 | - \EEH_Template::powered_by_event_espresso( |
|
1568 | - '', |
|
1569 | - 'espresso-registration-footer-dv', |
|
1570 | - array('utm_content' => 'registration_checkout') |
|
1571 | - ) |
|
1572 | - ); |
|
1573 | - } |
|
1574 | - return ''; |
|
1575 | - } |
|
1576 | - |
|
1577 | - |
|
1578 | - |
|
1579 | - /** |
|
1580 | - * unlock_transaction |
|
1581 | - * |
|
1582 | - * @access public |
|
1583 | - * @return void |
|
1584 | - * @throws \EE_Error |
|
1585 | - */ |
|
1586 | - public function unlock_transaction() |
|
1587 | - { |
|
1588 | - if ($this->checkout->transaction instanceof EE_Transaction) { |
|
1589 | - $this->checkout->transaction->unlock(); |
|
1590 | - } |
|
1591 | - } |
|
1592 | - |
|
1593 | - |
|
1594 | - |
|
1595 | - /** |
|
1596 | - * _setup_redirect |
|
1597 | - * |
|
1598 | - * @access private |
|
1599 | - * @return void |
|
1600 | - */ |
|
1601 | - private function _setup_redirect() |
|
1602 | - { |
|
1603 | - if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) { |
|
1604 | - $this->checkout->redirect = true; |
|
1605 | - if (empty($this->checkout->redirect_url)) { |
|
1606 | - $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url(); |
|
1607 | - } |
|
1608 | - $this->checkout->redirect_url = apply_filters( |
|
1609 | - 'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url', |
|
1610 | - $this->checkout->redirect_url, |
|
1611 | - $this->checkout |
|
1612 | - ); |
|
1613 | - } |
|
1614 | - } |
|
1615 | - |
|
1616 | - |
|
1617 | - |
|
1618 | - /** |
|
1619 | - * handle ajax message responses and redirects |
|
1620 | - * |
|
1621 | - * @access public |
|
1622 | - * @return void |
|
1623 | - * @throws \EE_Error |
|
1624 | - */ |
|
1625 | - public function go_to_next_step() |
|
1626 | - { |
|
1627 | - if (EE_Registry::instance()->REQ->ajax) { |
|
1628 | - // capture contents of output buffer we started earlier in the request, and insert into JSON response |
|
1629 | - $this->checkout->json_response->set_unexpected_errors(ob_get_clean()); |
|
1630 | - } |
|
1631 | - $this->unlock_transaction(); |
|
1632 | - // just return for these conditions |
|
1633 | - if ( |
|
1634 | - $this->checkout->admin_request |
|
1635 | - || $this->checkout->action === 'redirect_form' |
|
1636 | - || $this->checkout->action === 'update_checkout' |
|
1637 | - ) { |
|
1638 | - return; |
|
1639 | - } |
|
1640 | - // AJAX response |
|
1641 | - $this->_handle_json_response(); |
|
1642 | - // redirect to next step or the Thank You page |
|
1643 | - $this->_handle_html_redirects(); |
|
1644 | - // hmmm... must be something wrong, so let's just display the form again ! |
|
1645 | - $this->_display_spco_reg_form(); |
|
1646 | - } |
|
1647 | - |
|
1648 | - |
|
1649 | - |
|
1650 | - /** |
|
1651 | - * _handle_json_response |
|
1652 | - * |
|
1653 | - * @access protected |
|
1654 | - * @return void |
|
1655 | - */ |
|
1656 | - protected function _handle_json_response() |
|
1657 | - { |
|
1658 | - // if this is an ajax request |
|
1659 | - if (EE_Registry::instance()->REQ->ajax) { |
|
1660 | - // DEBUG LOG |
|
1661 | - //$this->checkout->log( |
|
1662 | - // __CLASS__, __FUNCTION__, __LINE__, |
|
1663 | - // array( |
|
1664 | - // 'json_response_redirect_url' => $this->checkout->json_response->redirect_url(), |
|
1665 | - // 'redirect' => $this->checkout->redirect, |
|
1666 | - // 'continue_reg' => $this->checkout->continue_reg, |
|
1667 | - // ) |
|
1668 | - //); |
|
1669 | - $this->checkout->json_response->set_registration_time_limit( |
|
1670 | - $this->checkout->get_registration_time_limit() |
|
1671 | - ); |
|
1672 | - $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing); |
|
1673 | - // just send the ajax ( |
|
1674 | - $json_response = apply_filters( |
|
1675 | - 'FHEE__EE_Single_Page_Checkout__JSON_response', |
|
1676 | - $this->checkout->json_response |
|
1677 | - ); |
|
1678 | - echo $json_response; |
|
1679 | - exit(); |
|
1680 | - } |
|
1681 | - } |
|
1682 | - |
|
1683 | - |
|
1684 | - |
|
1685 | - /** |
|
1686 | - * _handle_redirects |
|
1687 | - * |
|
1688 | - * @access protected |
|
1689 | - * @return void |
|
1690 | - */ |
|
1691 | - protected function _handle_html_redirects() |
|
1692 | - { |
|
1693 | - // going somewhere ? |
|
1694 | - if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) { |
|
1695 | - // store notices in a transient |
|
1696 | - EE_Error::get_notices(false, true, true); |
|
1697 | - // DEBUG LOG |
|
1698 | - //$this->checkout->log( |
|
1699 | - // __CLASS__, __FUNCTION__, __LINE__, |
|
1700 | - // array( |
|
1701 | - // 'headers_sent' => headers_sent(), |
|
1702 | - // 'redirect_url' => $this->checkout->redirect_url, |
|
1703 | - // 'headers_list' => headers_list(), |
|
1704 | - // ) |
|
1705 | - //); |
|
1706 | - wp_safe_redirect($this->checkout->redirect_url); |
|
1707 | - exit(); |
|
1708 | - } |
|
1709 | - } |
|
1710 | - |
|
1711 | - |
|
1712 | - |
|
1713 | - /** |
|
1714 | - * set_checkout_anchor |
|
1715 | - * |
|
1716 | - * @access public |
|
1717 | - * @return void |
|
1718 | - */ |
|
1719 | - public function set_checkout_anchor() |
|
1720 | - { |
|
1721 | - echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>'; |
|
1722 | - } |
|
20 | + /** |
|
21 | + * $_initialized - has the SPCO controller already been initialized ? |
|
22 | + * |
|
23 | + * @access private |
|
24 | + * @var bool $_initialized |
|
25 | + */ |
|
26 | + private static $_initialized = false; |
|
27 | + |
|
28 | + |
|
29 | + /** |
|
30 | + * $_checkout_verified - is the EE_Checkout verified as correct for this request ? |
|
31 | + * |
|
32 | + * @access private |
|
33 | + * @var bool $_valid_checkout |
|
34 | + */ |
|
35 | + private static $_checkout_verified = true; |
|
36 | + |
|
37 | + /** |
|
38 | + * $_reg_steps_array - holds initial array of reg steps |
|
39 | + * |
|
40 | + * @access private |
|
41 | + * @var array $_reg_steps_array |
|
42 | + */ |
|
43 | + private static $_reg_steps_array = array(); |
|
44 | + |
|
45 | + /** |
|
46 | + * $checkout - EE_Checkout object for handling the properties of the current checkout process |
|
47 | + * |
|
48 | + * @access public |
|
49 | + * @var EE_Checkout $checkout |
|
50 | + */ |
|
51 | + public $checkout; |
|
52 | + |
|
53 | + |
|
54 | + |
|
55 | + /** |
|
56 | + * @return EED_Single_Page_Checkout |
|
57 | + */ |
|
58 | + public static function instance() |
|
59 | + { |
|
60 | + add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true'); |
|
61 | + return parent::get_instance(__CLASS__); |
|
62 | + } |
|
63 | + |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * @return EE_CART |
|
68 | + */ |
|
69 | + public function cart() |
|
70 | + { |
|
71 | + return $this->checkout->cart; |
|
72 | + } |
|
73 | + |
|
74 | + |
|
75 | + |
|
76 | + /** |
|
77 | + * @return EE_Transaction |
|
78 | + */ |
|
79 | + public function transaction() |
|
80 | + { |
|
81 | + return $this->checkout->transaction; |
|
82 | + } |
|
83 | + |
|
84 | + |
|
85 | + |
|
86 | + /** |
|
87 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
88 | + * |
|
89 | + * @access public |
|
90 | + * @return void |
|
91 | + * @throws \EE_Error |
|
92 | + */ |
|
93 | + public static function set_hooks() |
|
94 | + { |
|
95 | + EED_Single_Page_Checkout::set_definitions(); |
|
96 | + } |
|
97 | + |
|
98 | + |
|
99 | + |
|
100 | + /** |
|
101 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
102 | + * |
|
103 | + * @access public |
|
104 | + * @return void |
|
105 | + * @throws \EE_Error |
|
106 | + */ |
|
107 | + public static function set_hooks_admin() |
|
108 | + { |
|
109 | + EED_Single_Page_Checkout::set_definitions(); |
|
110 | + if ( ! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
111 | + // hook into the top of pre_get_posts to set the reg step routing, which gives other modules or plugins a chance to modify the reg steps, but just before the routes get called |
|
112 | + add_action('pre_get_posts', array('EED_Single_Page_Checkout', 'load_reg_steps'), 1); |
|
113 | + return; |
|
114 | + } |
|
115 | + // going to start an output buffer in case anything gets accidentally output that might disrupt our JSON response |
|
116 | + ob_start(); |
|
117 | + EED_Single_Page_Checkout::load_request_handler(); |
|
118 | + EED_Single_Page_Checkout::load_reg_steps(); |
|
119 | + // set ajax hooks |
|
120 | + add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
121 | + add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
122 | + add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
123 | + add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
124 | + add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
125 | + add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
126 | + } |
|
127 | + |
|
128 | + |
|
129 | + |
|
130 | + /** |
|
131 | + * process ajax request |
|
132 | + * |
|
133 | + * @param string $ajax_action |
|
134 | + * @throws \EE_Error |
|
135 | + */ |
|
136 | + public static function process_ajax_request($ajax_action) |
|
137 | + { |
|
138 | + EE_Registry::instance()->REQ->set('action', $ajax_action); |
|
139 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
140 | + } |
|
141 | + |
|
142 | + |
|
143 | + |
|
144 | + /** |
|
145 | + * ajax display registration step |
|
146 | + * |
|
147 | + * @throws \EE_Error |
|
148 | + */ |
|
149 | + public static function display_reg_step() |
|
150 | + { |
|
151 | + EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step'); |
|
152 | + } |
|
153 | + |
|
154 | + |
|
155 | + |
|
156 | + /** |
|
157 | + * ajax process registration step |
|
158 | + * |
|
159 | + * @throws \EE_Error |
|
160 | + */ |
|
161 | + public static function process_reg_step() |
|
162 | + { |
|
163 | + EED_Single_Page_Checkout::process_ajax_request('process_reg_step'); |
|
164 | + } |
|
165 | + |
|
166 | + |
|
167 | + |
|
168 | + /** |
|
169 | + * ajax process registration step |
|
170 | + * |
|
171 | + * @throws \EE_Error |
|
172 | + */ |
|
173 | + public static function update_reg_step() |
|
174 | + { |
|
175 | + EED_Single_Page_Checkout::process_ajax_request('update_reg_step'); |
|
176 | + } |
|
177 | + |
|
178 | + |
|
179 | + |
|
180 | + /** |
|
181 | + * update_checkout |
|
182 | + * |
|
183 | + * @access public |
|
184 | + * @return void |
|
185 | + * @throws \EE_Error |
|
186 | + */ |
|
187 | + public static function update_checkout() |
|
188 | + { |
|
189 | + EED_Single_Page_Checkout::process_ajax_request('update_checkout'); |
|
190 | + } |
|
191 | + |
|
192 | + |
|
193 | + |
|
194 | + /** |
|
195 | + * load_request_handler |
|
196 | + * |
|
197 | + * @access public |
|
198 | + * @return void |
|
199 | + */ |
|
200 | + public static function load_request_handler() |
|
201 | + { |
|
202 | + // load core Request_Handler class |
|
203 | + if ( ! isset(EE_Registry::instance()->REQ)) { |
|
204 | + EE_Registry::instance()->load_core('Request_Handler'); |
|
205 | + } |
|
206 | + } |
|
207 | + |
|
208 | + |
|
209 | + |
|
210 | + /** |
|
211 | + * set_definitions |
|
212 | + * |
|
213 | + * @access public |
|
214 | + * @return void |
|
215 | + * @throws \EE_Error |
|
216 | + */ |
|
217 | + public static function set_definitions() |
|
218 | + { |
|
219 | + define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS); |
|
220 | + define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS); |
|
221 | + define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS); |
|
222 | + define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS); |
|
223 | + define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS); |
|
224 | + define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS); |
|
225 | + define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS); |
|
226 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true); |
|
227 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf( |
|
228 | + __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s', |
|
229 | + 'event_espresso'), |
|
230 | + '<h4 class="important-notice">', |
|
231 | + '</h4>', |
|
232 | + '<br />', |
|
233 | + '<p>', |
|
234 | + '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
235 | + '">', |
|
236 | + '</a>', |
|
237 | + '</p>' |
|
238 | + ); |
|
239 | + } |
|
240 | + |
|
241 | + |
|
242 | + |
|
243 | + /** |
|
244 | + * load_reg_steps |
|
245 | + * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array |
|
246 | + * |
|
247 | + * @access private |
|
248 | + * @throws EE_Error |
|
249 | + * @return void |
|
250 | + */ |
|
251 | + public static function load_reg_steps() |
|
252 | + { |
|
253 | + static $reg_steps_loaded = false; |
|
254 | + if ($reg_steps_loaded) { |
|
255 | + return; |
|
256 | + } |
|
257 | + // filter list of reg_steps |
|
258 | + $reg_steps_to_load = (array)apply_filters( |
|
259 | + 'AHEE__SPCO__load_reg_steps__reg_steps_to_load', |
|
260 | + EED_Single_Page_Checkout::get_reg_steps() |
|
261 | + ); |
|
262 | + // sort by key (order) |
|
263 | + ksort($reg_steps_to_load); |
|
264 | + // loop through folders |
|
265 | + foreach ($reg_steps_to_load as $order => $reg_step) { |
|
266 | + // we need a |
|
267 | + if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
268 | + // copy over to the reg_steps_array |
|
269 | + EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step; |
|
270 | + // register custom key route for each reg step |
|
271 | + // ie: step=>"slug" - this is the entire reason we load the reg steps array now |
|
272 | + EE_Config::register_route($reg_step['slug'], 'EED_Single_Page_Checkout', 'run', 'step'); |
|
273 | + // add AJAX or other hooks |
|
274 | + if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) { |
|
275 | + // setup autoloaders if necessary |
|
276 | + if ( ! class_exists($reg_step['class_name'])) { |
|
277 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder($reg_step['file_path'], true); |
|
278 | + } |
|
279 | + if (is_callable($reg_step['class_name'], 'set_hooks')) { |
|
280 | + call_user_func(array($reg_step['class_name'], 'set_hooks')); |
|
281 | + } |
|
282 | + } |
|
283 | + } |
|
284 | + } |
|
285 | + $reg_steps_loaded = true; |
|
286 | + } |
|
287 | + |
|
288 | + |
|
289 | + |
|
290 | + /** |
|
291 | + * get_reg_steps |
|
292 | + * |
|
293 | + * @access public |
|
294 | + * @return array |
|
295 | + */ |
|
296 | + public static function get_reg_steps() |
|
297 | + { |
|
298 | + $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps; |
|
299 | + if (empty($reg_steps)) { |
|
300 | + $reg_steps = array( |
|
301 | + 10 => array( |
|
302 | + 'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information', |
|
303 | + 'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information', |
|
304 | + 'slug' => 'attendee_information', |
|
305 | + 'has_hooks' => false, |
|
306 | + ), |
|
307 | + 20 => array( |
|
308 | + 'file_path' => SPCO_REG_STEPS_PATH . 'registration_confirmation', |
|
309 | + 'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation', |
|
310 | + 'slug' => 'registration_confirmation', |
|
311 | + 'has_hooks' => false, |
|
312 | + ), |
|
313 | + 30 => array( |
|
314 | + 'file_path' => SPCO_REG_STEPS_PATH . 'payment_options', |
|
315 | + 'class_name' => 'EE_SPCO_Reg_Step_Payment_Options', |
|
316 | + 'slug' => 'payment_options', |
|
317 | + 'has_hooks' => true, |
|
318 | + ), |
|
319 | + 999 => array( |
|
320 | + 'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration', |
|
321 | + 'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration', |
|
322 | + 'slug' => 'finalize_registration', |
|
323 | + 'has_hooks' => false, |
|
324 | + ), |
|
325 | + ); |
|
326 | + } |
|
327 | + return $reg_steps; |
|
328 | + } |
|
329 | + |
|
330 | + |
|
331 | + |
|
332 | + /** |
|
333 | + * registration_checkout_for_admin |
|
334 | + * |
|
335 | + * @access public |
|
336 | + * @return string |
|
337 | + * @throws \EE_Error |
|
338 | + */ |
|
339 | + public static function registration_checkout_for_admin() |
|
340 | + { |
|
341 | + EED_Single_Page_Checkout::load_reg_steps(); |
|
342 | + EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
343 | + EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step'); |
|
344 | + EE_Registry::instance()->REQ->set('process_form_submission', false); |
|
345 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
346 | + EED_Single_Page_Checkout::instance()->_display_spco_reg_form(); |
|
347 | + return EE_Registry::instance()->REQ->get_output(); |
|
348 | + } |
|
349 | + |
|
350 | + |
|
351 | + |
|
352 | + /** |
|
353 | + * process_registration_from_admin |
|
354 | + * |
|
355 | + * @access public |
|
356 | + * @return \EE_Transaction |
|
357 | + * @throws \EE_Error |
|
358 | + */ |
|
359 | + public static function process_registration_from_admin() |
|
360 | + { |
|
361 | + EED_Single_Page_Checkout::load_reg_steps(); |
|
362 | + EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
363 | + EE_Registry::instance()->REQ->set('action', 'process_reg_step'); |
|
364 | + EE_Registry::instance()->REQ->set('process_form_submission', true); |
|
365 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
366 | + if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) { |
|
367 | + $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps); |
|
368 | + if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) { |
|
369 | + EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step); |
|
370 | + if ($final_reg_step->process_reg_step()) { |
|
371 | + $final_reg_step->set_completed(); |
|
372 | + EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array(); |
|
373 | + return EED_Single_Page_Checkout::instance()->checkout->transaction; |
|
374 | + } |
|
375 | + } |
|
376 | + } |
|
377 | + return null; |
|
378 | + } |
|
379 | + |
|
380 | + |
|
381 | + |
|
382 | + /** |
|
383 | + * run |
|
384 | + * |
|
385 | + * @access public |
|
386 | + * @param WP_Query $WP_Query |
|
387 | + * @return void |
|
388 | + * @throws \EE_Error |
|
389 | + */ |
|
390 | + public function run($WP_Query) |
|
391 | + { |
|
392 | + if ( |
|
393 | + $WP_Query instanceof WP_Query |
|
394 | + && $WP_Query->is_main_query() |
|
395 | + && apply_filters('FHEE__EED_Single_Page_Checkout__run', true) |
|
396 | + && $this->_is_reg_checkout() |
|
397 | + ) { |
|
398 | + $this->_initialize(); |
|
399 | + } |
|
400 | + } |
|
401 | + |
|
402 | + |
|
403 | + |
|
404 | + /** |
|
405 | + * determines whether current url matches reg page url |
|
406 | + * |
|
407 | + * @return bool |
|
408 | + */ |
|
409 | + protected function _is_reg_checkout() |
|
410 | + { |
|
411 | + // get current permalink for reg page without any extra query args |
|
412 | + $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id); |
|
413 | + // get request URI for current request, but without the scheme or host |
|
414 | + $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI'); |
|
415 | + $current_request_uri = html_entity_decode($current_request_uri); |
|
416 | + // get array of query args from the current request URI |
|
417 | + $query_args = \EEH_URL::get_query_string($current_request_uri); |
|
418 | + // grab page id if it is set |
|
419 | + $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0; |
|
420 | + // and remove the page id from the query args (we will re-add it later) |
|
421 | + unset($query_args['page_id']); |
|
422 | + // now strip all query args from current request URI |
|
423 | + $current_request_uri = remove_query_arg(array_flip($query_args), $current_request_uri); |
|
424 | + // and re-add the page id if it was set |
|
425 | + if ($page_id) { |
|
426 | + $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri); |
|
427 | + } |
|
428 | + // remove slashes and ? |
|
429 | + $current_request_uri = trim($current_request_uri, '?/'); |
|
430 | + // is current request URI part of the known full reg page URL ? |
|
431 | + return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false; |
|
432 | + } |
|
433 | + |
|
434 | + |
|
435 | + |
|
436 | + /** |
|
437 | + * run |
|
438 | + * |
|
439 | + * @access public |
|
440 | + * @param WP_Query $WP_Query |
|
441 | + * @return void |
|
442 | + * @throws \EE_Error |
|
443 | + */ |
|
444 | + public static function init($WP_Query) |
|
445 | + { |
|
446 | + EED_Single_Page_Checkout::instance()->run($WP_Query); |
|
447 | + } |
|
448 | + |
|
449 | + |
|
450 | + |
|
451 | + /** |
|
452 | + * _initialize - initial module setup |
|
453 | + * |
|
454 | + * @access private |
|
455 | + * @throws EE_Error |
|
456 | + * @return void |
|
457 | + */ |
|
458 | + private function _initialize() |
|
459 | + { |
|
460 | + // ensure SPCO doesn't run twice |
|
461 | + if (EED_Single_Page_Checkout::$_initialized) { |
|
462 | + return; |
|
463 | + } |
|
464 | + try { |
|
465 | + $this->_verify_session(); |
|
466 | + // setup the EE_Checkout object |
|
467 | + $this->checkout = $this->_initialize_checkout(); |
|
468 | + // filter checkout |
|
469 | + $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout); |
|
470 | + // get the $_GET |
|
471 | + $this->_get_request_vars(); |
|
472 | + if ($this->_block_bots()) { |
|
473 | + return; |
|
474 | + } |
|
475 | + // filter continue_reg |
|
476 | + $this->checkout->continue_reg = apply_filters('FHEE__EED_Single_Page_Checkout__init___continue_reg', true, $this->checkout); |
|
477 | + // load the reg steps array |
|
478 | + if ( ! $this->_load_and_instantiate_reg_steps()) { |
|
479 | + EED_Single_Page_Checkout::$_initialized = true; |
|
480 | + return; |
|
481 | + } |
|
482 | + // set the current step |
|
483 | + $this->checkout->set_current_step($this->checkout->step); |
|
484 | + // and the next step |
|
485 | + $this->checkout->set_next_step(); |
|
486 | + // verify that everything has been setup correctly |
|
487 | + if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) { |
|
488 | + EED_Single_Page_Checkout::$_initialized = true; |
|
489 | + return; |
|
490 | + } |
|
491 | + // lock the transaction |
|
492 | + $this->checkout->transaction->lock(); |
|
493 | + // make sure all of our cached objects are added to their respective model entity mappers |
|
494 | + $this->checkout->refresh_all_entities(); |
|
495 | + // set amount owing |
|
496 | + $this->checkout->amount_owing = $this->checkout->transaction->remaining(); |
|
497 | + // initialize each reg step, which gives them the chance to potentially alter the process |
|
498 | + $this->_initialize_reg_steps(); |
|
499 | + // DEBUG LOG |
|
500 | + //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
501 | + // get reg form |
|
502 | + if( ! $this->_check_form_submission()) { |
|
503 | + EED_Single_Page_Checkout::$_initialized = true; |
|
504 | + return; |
|
505 | + } |
|
506 | + // checkout the action!!! |
|
507 | + $this->_process_form_action(); |
|
508 | + // add some style and make it dance |
|
509 | + $this->add_styles_and_scripts(); |
|
510 | + // kk... SPCO has successfully run |
|
511 | + EED_Single_Page_Checkout::$_initialized = true; |
|
512 | + // set no cache headers and constants |
|
513 | + EE_System::do_not_cache(); |
|
514 | + // add anchor |
|
515 | + add_action('loop_start', array($this, 'set_checkout_anchor'), 1); |
|
516 | + // remove transaction lock |
|
517 | + add_action('shutdown', array($this, 'unlock_transaction'), 1); |
|
518 | + } catch (Exception $e) { |
|
519 | + EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
520 | + } |
|
521 | + } |
|
522 | + |
|
523 | + |
|
524 | + |
|
525 | + /** |
|
526 | + * _verify_session |
|
527 | + * checks that the session is valid and not expired |
|
528 | + * |
|
529 | + * @access private |
|
530 | + * @throws EE_Error |
|
531 | + */ |
|
532 | + private function _verify_session() |
|
533 | + { |
|
534 | + if ( ! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
535 | + throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso')); |
|
536 | + } |
|
537 | + // is session still valid ? |
|
538 | + if (EE_Registry::instance()->SSN->expired() && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '') { |
|
539 | + $this->checkout = new EE_Checkout(); |
|
540 | + EE_Registry::instance()->SSN->reset_cart(); |
|
541 | + EE_Registry::instance()->SSN->reset_checkout(); |
|
542 | + EE_Registry::instance()->SSN->reset_transaction(); |
|
543 | + EE_Error::add_attention(EE_Registry::$i18n_js_strings['registration_expiration_notice'], __FILE__, |
|
544 | + __FUNCTION__, __LINE__); |
|
545 | + EE_Registry::instance()->SSN->reset_expired(); |
|
546 | + } |
|
547 | + } |
|
548 | + |
|
549 | + |
|
550 | + |
|
551 | + /** |
|
552 | + * _initialize_checkout |
|
553 | + * loads and instantiates EE_Checkout |
|
554 | + * |
|
555 | + * @access private |
|
556 | + * @throws EE_Error |
|
557 | + * @return EE_Checkout |
|
558 | + */ |
|
559 | + private function _initialize_checkout() |
|
560 | + { |
|
561 | + // look in session for existing checkout |
|
562 | + /** @type EE_Checkout $checkout */ |
|
563 | + $checkout = EE_Registry::instance()->SSN->checkout(); |
|
564 | + // verify |
|
565 | + if ( ! $checkout instanceof EE_Checkout) { |
|
566 | + // instantiate EE_Checkout object for handling the properties of the current checkout process |
|
567 | + $checkout = EE_Registry::instance()->load_file(SPCO_INC_PATH, 'EE_Checkout', 'class', array(), false); |
|
568 | + } else { |
|
569 | + if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) { |
|
570 | + $this->unlock_transaction(); |
|
571 | + wp_safe_redirect($checkout->redirect_url); |
|
572 | + exit(); |
|
573 | + } |
|
574 | + } |
|
575 | + $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout); |
|
576 | + // verify again |
|
577 | + if ( ! $checkout instanceof EE_Checkout) { |
|
578 | + throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso')); |
|
579 | + } |
|
580 | + // reset anything that needs a clean slate for each request |
|
581 | + $checkout->reset_for_current_request(); |
|
582 | + return $checkout; |
|
583 | + } |
|
584 | + |
|
585 | + |
|
586 | + |
|
587 | + /** |
|
588 | + * _get_request_vars |
|
589 | + * |
|
590 | + * @access private |
|
591 | + * @return void |
|
592 | + * @throws \EE_Error |
|
593 | + */ |
|
594 | + private function _get_request_vars() |
|
595 | + { |
|
596 | + // load classes |
|
597 | + EED_Single_Page_Checkout::load_request_handler(); |
|
598 | + //make sure this request is marked as belonging to EE |
|
599 | + EE_Registry::instance()->REQ->set_espresso_page(true); |
|
600 | + // which step is being requested ? |
|
601 | + $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step()); |
|
602 | + // which step is being edited ? |
|
603 | + $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', ''); |
|
604 | + // and what we're doing on the current step |
|
605 | + $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step'); |
|
606 | + // timestamp |
|
607 | + $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0); |
|
608 | + // returning to edit ? |
|
609 | + $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', ''); |
|
610 | + // or some other kind of revisit ? |
|
611 | + $this->checkout->revisit = filter_var( |
|
612 | + EE_Registry::instance()->REQ->get('revisit', false), |
|
613 | + FILTER_VALIDATE_BOOLEAN |
|
614 | + ); |
|
615 | + // and whether or not to generate a reg form for this request |
|
616 | + $this->checkout->generate_reg_form = filter_var( |
|
617 | + EE_Registry::instance()->REQ->get('generate_reg_form', true), |
|
618 | + FILTER_VALIDATE_BOOLEAN |
|
619 | + ); |
|
620 | + // and whether or not to process a reg form submission for this request |
|
621 | + $this->checkout->process_form_submission = filter_var( |
|
622 | + EE_Registry::instance()->REQ->get( |
|
623 | + 'process_form_submission', |
|
624 | + $this->checkout->action === 'process_reg_step' |
|
625 | + ), |
|
626 | + FILTER_VALIDATE_BOOLEAN |
|
627 | + ); |
|
628 | + $this->checkout->process_form_submission = filter_var( |
|
629 | + $this->checkout->action !== 'display_spco_reg_step' |
|
630 | + ? $this->checkout->process_form_submission |
|
631 | + : false, |
|
632 | + FILTER_VALIDATE_BOOLEAN |
|
633 | + ); |
|
634 | + // $this->_display_request_vars(); |
|
635 | + } |
|
636 | + |
|
637 | + |
|
638 | + |
|
639 | + /** |
|
640 | + * _display_request_vars |
|
641 | + * |
|
642 | + * @access protected |
|
643 | + * @return void |
|
644 | + */ |
|
645 | + protected function _display_request_vars() |
|
646 | + { |
|
647 | + if ( ! WP_DEBUG) { |
|
648 | + return; |
|
649 | + } |
|
650 | + EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__); |
|
651 | + EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__); |
|
652 | + EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__); |
|
653 | + EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__); |
|
654 | + EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__); |
|
655 | + EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__); |
|
656 | + EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__); |
|
657 | + EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__); |
|
658 | + } |
|
659 | + |
|
660 | + |
|
661 | + |
|
662 | + /** |
|
663 | + * _block_bots |
|
664 | + * checks that the incoming request has either of the following set: |
|
665 | + * a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector |
|
666 | + * a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN |
|
667 | + * so if you're not coming from the Ticket Selector nor returning for a valid IP... |
|
668 | + * then where you coming from man? |
|
669 | + * |
|
670 | + * @return boolean |
|
671 | + */ |
|
672 | + private function _block_bots() |
|
673 | + { |
|
674 | + $invalid_checkout_access = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
675 | + if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) { |
|
676 | + return true; |
|
677 | + } |
|
678 | + return false; |
|
679 | + } |
|
680 | + |
|
681 | + |
|
682 | + |
|
683 | + /** |
|
684 | + * _get_first_step |
|
685 | + * gets slug for first step in $_reg_steps_array |
|
686 | + * |
|
687 | + * @access private |
|
688 | + * @throws EE_Error |
|
689 | + * @return string |
|
690 | + */ |
|
691 | + private function _get_first_step() |
|
692 | + { |
|
693 | + $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array); |
|
694 | + return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information'; |
|
695 | + } |
|
696 | + |
|
697 | + |
|
698 | + |
|
699 | + /** |
|
700 | + * _load_and_instantiate_reg_steps |
|
701 | + * instantiates each reg step based on the loaded reg_steps array |
|
702 | + * |
|
703 | + * @access private |
|
704 | + * @throws EE_Error |
|
705 | + * @return bool |
|
706 | + */ |
|
707 | + private function _load_and_instantiate_reg_steps() |
|
708 | + { |
|
709 | + // have reg_steps already been instantiated ? |
|
710 | + if ( |
|
711 | + empty($this->checkout->reg_steps) |
|
712 | + || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout) |
|
713 | + ) { |
|
714 | + // if not, then loop through raw reg steps array |
|
715 | + foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) { |
|
716 | + if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) { |
|
717 | + return false; |
|
718 | + } |
|
719 | + } |
|
720 | + EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true; |
|
721 | + EE_Registry::instance()->CFG->registration->reg_confirmation_last = true; |
|
722 | + // skip the registration_confirmation page ? |
|
723 | + if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) { |
|
724 | + // just remove it from the reg steps array |
|
725 | + $this->checkout->remove_reg_step('registration_confirmation', false); |
|
726 | + } else if ( |
|
727 | + isset($this->checkout->reg_steps['registration_confirmation']) |
|
728 | + && EE_Registry::instance()->CFG->registration->reg_confirmation_last |
|
729 | + ) { |
|
730 | + // set the order to something big like 100 |
|
731 | + $this->checkout->set_reg_step_order('registration_confirmation', 100); |
|
732 | + } |
|
733 | + // filter the array for good luck |
|
734 | + $this->checkout->reg_steps = apply_filters( |
|
735 | + 'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps', |
|
736 | + $this->checkout->reg_steps |
|
737 | + ); |
|
738 | + // finally re-sort based on the reg step class order properties |
|
739 | + $this->checkout->sort_reg_steps(); |
|
740 | + } else { |
|
741 | + foreach ($this->checkout->reg_steps as $reg_step) { |
|
742 | + // set all current step stati to FALSE |
|
743 | + $reg_step->set_is_current_step(false); |
|
744 | + } |
|
745 | + } |
|
746 | + if (empty($this->checkout->reg_steps)) { |
|
747 | + EE_Error::add_error(__('No Reg Steps were loaded..', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
748 | + return false; |
|
749 | + } |
|
750 | + // make reg step details available to JS |
|
751 | + $this->checkout->set_reg_step_JSON_info(); |
|
752 | + return true; |
|
753 | + } |
|
754 | + |
|
755 | + |
|
756 | + |
|
757 | + /** |
|
758 | + * _load_and_instantiate_reg_step |
|
759 | + * |
|
760 | + * @access private |
|
761 | + * @param array $reg_step |
|
762 | + * @param int $order |
|
763 | + * @return bool |
|
764 | + */ |
|
765 | + private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0) |
|
766 | + { |
|
767 | + // we need a file_path, class_name, and slug to add a reg step |
|
768 | + if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
769 | + // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step) |
|
770 | + if ( |
|
771 | + $this->checkout->reg_url_link |
|
772 | + && $this->checkout->step !== $reg_step['slug'] |
|
773 | + && $reg_step['slug'] !== 'finalize_registration' |
|
774 | + ) { |
|
775 | + return true; |
|
776 | + } |
|
777 | + // instantiate step class using file path and class name |
|
778 | + $reg_step_obj = EE_Registry::instance()->load_file( |
|
779 | + $reg_step['file_path'], |
|
780 | + $reg_step['class_name'], |
|
781 | + 'class', |
|
782 | + $this->checkout, |
|
783 | + false |
|
784 | + ); |
|
785 | + // did we gets the goods ? |
|
786 | + if ($reg_step_obj instanceof EE_SPCO_Reg_Step) { |
|
787 | + // set reg step order based on config |
|
788 | + $reg_step_obj->set_order($order); |
|
789 | + // add instantiated reg step object to the master reg steps array |
|
790 | + $this->checkout->add_reg_step($reg_step_obj); |
|
791 | + } else { |
|
792 | + EE_Error::add_error( |
|
793 | + __('The current step could not be set.', 'event_espresso'), |
|
794 | + __FILE__, __FUNCTION__, __LINE__ |
|
795 | + ); |
|
796 | + return false; |
|
797 | + } |
|
798 | + } else { |
|
799 | + if (WP_DEBUG) { |
|
800 | + EE_Error::add_error( |
|
801 | + sprintf( |
|
802 | + __('A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s', 'event_espresso'), |
|
803 | + isset($reg_step['file_path']) ? $reg_step['file_path'] : '', |
|
804 | + isset($reg_step['class_name']) ? $reg_step['class_name'] : '', |
|
805 | + isset($reg_step['slug']) ? $reg_step['slug'] : '', |
|
806 | + '<ul>', |
|
807 | + '<li>', |
|
808 | + '</li>', |
|
809 | + '</ul>' |
|
810 | + ), |
|
811 | + __FILE__, __FUNCTION__, __LINE__ |
|
812 | + ); |
|
813 | + } |
|
814 | + return false; |
|
815 | + } |
|
816 | + return true; |
|
817 | + } |
|
818 | + |
|
819 | + |
|
820 | + |
|
821 | + /** |
|
822 | + * _verify_transaction_and_get_registrations |
|
823 | + * |
|
824 | + * @access private |
|
825 | + * @return bool |
|
826 | + */ |
|
827 | + private function _verify_transaction_and_get_registrations() |
|
828 | + { |
|
829 | + // was there already a valid transaction in the checkout from the session ? |
|
830 | + if ( ! $this->checkout->transaction instanceof EE_Transaction) { |
|
831 | + // get transaction from db or session |
|
832 | + $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin() |
|
833 | + ? $this->_get_transaction_and_cart_for_previous_visit() |
|
834 | + : $this->_get_cart_for_current_session_and_setup_new_transaction(); |
|
835 | + if ( ! $this->checkout->transaction instanceof EE_Transaction) { |
|
836 | + EE_Error::add_error( |
|
837 | + __('Your Registration and Transaction information could not be retrieved from the db.', |
|
838 | + 'event_espresso'), |
|
839 | + __FILE__, __FUNCTION__, __LINE__ |
|
840 | + ); |
|
841 | + $this->checkout->transaction = EE_Transaction::new_instance(); |
|
842 | + // add some style and make it dance |
|
843 | + $this->add_styles_and_scripts(); |
|
844 | + EED_Single_Page_Checkout::$_initialized = true; |
|
845 | + return false; |
|
846 | + } |
|
847 | + // and the registrations for the transaction |
|
848 | + $this->_get_registrations($this->checkout->transaction); |
|
849 | + } |
|
850 | + return true; |
|
851 | + } |
|
852 | + |
|
853 | + |
|
854 | + |
|
855 | + /** |
|
856 | + * _get_transaction_and_cart_for_previous_visit |
|
857 | + * |
|
858 | + * @access private |
|
859 | + * @return mixed EE_Transaction|NULL |
|
860 | + */ |
|
861 | + private function _get_transaction_and_cart_for_previous_visit() |
|
862 | + { |
|
863 | + /** @var $TXN_model EEM_Transaction */ |
|
864 | + $TXN_model = EE_Registry::instance()->load_model('Transaction'); |
|
865 | + // because the reg_url_link is present in the request, this is a return visit to SPCO, so we'll get the transaction data from the db |
|
866 | + $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link); |
|
867 | + // verify transaction |
|
868 | + if ($transaction instanceof EE_Transaction) { |
|
869 | + // and get the cart that was used for that transaction |
|
870 | + $this->checkout->cart = $this->_get_cart_for_transaction($transaction); |
|
871 | + return $transaction; |
|
872 | + } else { |
|
873 | + EE_Error::add_error(__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
874 | + return null; |
|
875 | + } |
|
876 | + } |
|
877 | + |
|
878 | + |
|
879 | + |
|
880 | + /** |
|
881 | + * _get_cart_for_transaction |
|
882 | + * |
|
883 | + * @access private |
|
884 | + * @param EE_Transaction $transaction |
|
885 | + * @return EE_Cart |
|
886 | + */ |
|
887 | + private function _get_cart_for_transaction($transaction) |
|
888 | + { |
|
889 | + return $this->checkout->get_cart_for_transaction($transaction); |
|
890 | + } |
|
891 | + |
|
892 | + |
|
893 | + |
|
894 | + /** |
|
895 | + * get_cart_for_transaction |
|
896 | + * |
|
897 | + * @access public |
|
898 | + * @param EE_Transaction $transaction |
|
899 | + * @return EE_Cart |
|
900 | + */ |
|
901 | + public function get_cart_for_transaction(EE_Transaction $transaction) |
|
902 | + { |
|
903 | + return $this->checkout->get_cart_for_transaction($transaction); |
|
904 | + } |
|
905 | + |
|
906 | + |
|
907 | + |
|
908 | + /** |
|
909 | + * _get_transaction_and_cart_for_current_session |
|
910 | + * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
911 | + * |
|
912 | + * @access private |
|
913 | + * @return EE_Transaction |
|
914 | + * @throws \EE_Error |
|
915 | + */ |
|
916 | + private function _get_cart_for_current_session_and_setup_new_transaction() |
|
917 | + { |
|
918 | + // if there's no transaction, then this is the FIRST visit to SPCO |
|
919 | + // so load up the cart ( passing nothing for the TXN because it doesn't exist yet ) |
|
920 | + $this->checkout->cart = $this->_get_cart_for_transaction(null); |
|
921 | + // and then create a new transaction |
|
922 | + $transaction = $this->_initialize_transaction(); |
|
923 | + // verify transaction |
|
924 | + if ($transaction instanceof EE_Transaction) { |
|
925 | + // save it so that we have an ID for other objects to use |
|
926 | + $transaction->save(); |
|
927 | + // and save TXN data to the cart |
|
928 | + $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID()); |
|
929 | + } else { |
|
930 | + EE_Error::add_error(__('A Valid Transaction could not be initialized.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
931 | + } |
|
932 | + return $transaction; |
|
933 | + } |
|
934 | + |
|
935 | + |
|
936 | + |
|
937 | + /** |
|
938 | + * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
939 | + * |
|
940 | + * @access private |
|
941 | + * @return mixed EE_Transaction|NULL |
|
942 | + */ |
|
943 | + private function _initialize_transaction() |
|
944 | + { |
|
945 | + try { |
|
946 | + // ensure cart totals have been calculated |
|
947 | + $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes(); |
|
948 | + // grab the cart grand total |
|
949 | + $cart_total = $this->checkout->cart->get_cart_grand_total(); |
|
950 | + // create new TXN |
|
951 | + $transaction = EE_Transaction::new_instance( |
|
952 | + array( |
|
953 | + 'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(), |
|
954 | + 'TXN_total' => $cart_total > 0 ? $cart_total : 0, |
|
955 | + 'TXN_paid' => 0, |
|
956 | + 'STS_ID' => EEM_Transaction::failed_status_code, |
|
957 | + ) |
|
958 | + ); |
|
959 | + // save it so that we have an ID for other objects to use |
|
960 | + $transaction->save(); |
|
961 | + // set cron job for following up on TXNs after their session has expired |
|
962 | + EE_Cron_Tasks::schedule_expired_transaction_check( |
|
963 | + EE_Registry::instance()->SSN->expiration() + 1, |
|
964 | + $transaction->ID() |
|
965 | + ); |
|
966 | + return $transaction; |
|
967 | + } catch (Exception $e) { |
|
968 | + EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
969 | + } |
|
970 | + return null; |
|
971 | + } |
|
972 | + |
|
973 | + |
|
974 | + |
|
975 | + /** |
|
976 | + * _get_registrations |
|
977 | + * |
|
978 | + * @access private |
|
979 | + * @param EE_Transaction $transaction |
|
980 | + * @return void |
|
981 | + * @throws \EventEspresso\core\exceptions\InvalidEntityException |
|
982 | + * @throws \EE_Error |
|
983 | + */ |
|
984 | + private function _get_registrations(EE_Transaction $transaction) |
|
985 | + { |
|
986 | + // first step: grab the registrants { : o |
|
987 | + $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true); |
|
988 | + // verify registrations have been set |
|
989 | + if (empty($registrations)) { |
|
990 | + // if no cached registrations, then check the db |
|
991 | + $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
992 | + // still nothing ? well as long as this isn't a revisit |
|
993 | + if (empty($registrations) && ! $this->checkout->revisit) { |
|
994 | + // generate new registrations from scratch |
|
995 | + $registrations = $this->_initialize_registrations($transaction); |
|
996 | + } |
|
997 | + } |
|
998 | + // sort by their original registration order |
|
999 | + usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count')); |
|
1000 | + // then loop thru the array |
|
1001 | + foreach ($registrations as $registration) { |
|
1002 | + // verify each registration |
|
1003 | + if ($registration instanceof EE_Registration) { |
|
1004 | + // we display all attendee info for the primary registrant |
|
1005 | + if ($this->checkout->reg_url_link === $registration->reg_url_link() |
|
1006 | + && $registration->is_primary_registrant() |
|
1007 | + ) { |
|
1008 | + $this->checkout->primary_revisit = true; |
|
1009 | + break; |
|
1010 | + } else if ($this->checkout->revisit |
|
1011 | + && $this->checkout->reg_url_link !== $registration->reg_url_link() |
|
1012 | + ) { |
|
1013 | + // but hide info if it doesn't belong to you |
|
1014 | + $transaction->clear_cache('Registration', $registration->ID()); |
|
1015 | + } |
|
1016 | + $this->checkout->set_reg_status_updated($registration->ID(), false); |
|
1017 | + } |
|
1018 | + } |
|
1019 | + } |
|
1020 | + |
|
1021 | + |
|
1022 | + |
|
1023 | + /** |
|
1024 | + * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object |
|
1025 | + * |
|
1026 | + * @access private |
|
1027 | + * @param EE_Transaction $transaction |
|
1028 | + * @return array |
|
1029 | + * @throws \EventEspresso\core\exceptions\InvalidEntityException |
|
1030 | + * @throws \EE_Error |
|
1031 | + */ |
|
1032 | + private function _initialize_registrations(EE_Transaction $transaction) |
|
1033 | + { |
|
1034 | + $att_nmbr = 0; |
|
1035 | + $registrations = array(); |
|
1036 | + if ($transaction instanceof EE_Transaction) { |
|
1037 | + /** @type EE_Registration_Processor $registration_processor */ |
|
1038 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
1039 | + $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count(); |
|
1040 | + // now let's add the cart items to the $transaction |
|
1041 | + foreach ($this->checkout->cart->get_tickets() as $line_item) { |
|
1042 | + //do the following for each ticket of this type they selected |
|
1043 | + for ($x = 1; $x <= $line_item->quantity(); $x++) { |
|
1044 | + $att_nmbr++; |
|
1045 | + /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */ |
|
1046 | + $CreateRegistrationCommand = EE_Registry::instance() |
|
1047 | + ->create( |
|
1048 | + 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand', |
|
1049 | + array( |
|
1050 | + $transaction, |
|
1051 | + $line_item, |
|
1052 | + $att_nmbr, |
|
1053 | + $this->checkout->total_ticket_count, |
|
1054 | + ) |
|
1055 | + ); |
|
1056 | + // override capabilities for frontend registrations |
|
1057 | + if ( ! is_admin()) { |
|
1058 | + $CreateRegistrationCommand->setCapCheck( |
|
1059 | + new PublicCapabilities('', 'create_new_registration') |
|
1060 | + ); |
|
1061 | + } |
|
1062 | + $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand); |
|
1063 | + if ( ! $registration instanceof EE_Registration) { |
|
1064 | + throw new InvalidEntityException($registration, 'EE_Registration'); |
|
1065 | + } |
|
1066 | + $registrations[ $registration->ID() ] = $registration; |
|
1067 | + } |
|
1068 | + } |
|
1069 | + $registration_processor->fix_reg_final_price_rounding_issue($transaction); |
|
1070 | + } |
|
1071 | + return $registrations; |
|
1072 | + } |
|
1073 | + |
|
1074 | + |
|
1075 | + |
|
1076 | + /** |
|
1077 | + * sorts registrations by REG_count |
|
1078 | + * |
|
1079 | + * @access public |
|
1080 | + * @param EE_Registration $reg_A |
|
1081 | + * @param EE_Registration $reg_B |
|
1082 | + * @return int |
|
1083 | + */ |
|
1084 | + public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B) |
|
1085 | + { |
|
1086 | + // this shouldn't ever happen within the same TXN, but oh well |
|
1087 | + if ($reg_A->count() === $reg_B->count()) { |
|
1088 | + return 0; |
|
1089 | + } |
|
1090 | + return ($reg_A->count() > $reg_B->count()) ? 1 : -1; |
|
1091 | + } |
|
1092 | + |
|
1093 | + |
|
1094 | + |
|
1095 | + /** |
|
1096 | + * _final_verifications |
|
1097 | + * just makes sure that everything is set up correctly before proceeding |
|
1098 | + * |
|
1099 | + * @access private |
|
1100 | + * @return bool |
|
1101 | + * @throws \EE_Error |
|
1102 | + */ |
|
1103 | + private function _final_verifications() |
|
1104 | + { |
|
1105 | + // filter checkout |
|
1106 | + $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout); |
|
1107 | + //verify that current step is still set correctly |
|
1108 | + if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) { |
|
1109 | + EE_Error::add_error( |
|
1110 | + __('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'), |
|
1111 | + __FILE__, |
|
1112 | + __FUNCTION__, |
|
1113 | + __LINE__ |
|
1114 | + ); |
|
1115 | + return false; |
|
1116 | + } |
|
1117 | + // if returning to SPCO, then verify that primary registrant is set |
|
1118 | + if ( ! empty($this->checkout->reg_url_link)) { |
|
1119 | + $valid_registrant = $this->checkout->transaction->primary_registration(); |
|
1120 | + if ( ! $valid_registrant instanceof EE_Registration) { |
|
1121 | + EE_Error::add_error( |
|
1122 | + __('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'), |
|
1123 | + __FILE__, |
|
1124 | + __FUNCTION__, |
|
1125 | + __LINE__ |
|
1126 | + ); |
|
1127 | + return false; |
|
1128 | + } |
|
1129 | + $valid_registrant = null; |
|
1130 | + foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) { |
|
1131 | + if ( |
|
1132 | + $registration instanceof EE_Registration |
|
1133 | + && $registration->reg_url_link() === $this->checkout->reg_url_link |
|
1134 | + ) { |
|
1135 | + $valid_registrant = $registration; |
|
1136 | + } |
|
1137 | + } |
|
1138 | + if ( ! $valid_registrant instanceof EE_Registration) { |
|
1139 | + // hmmm... maybe we have the wrong session because the user is opening multiple tabs ? |
|
1140 | + if (EED_Single_Page_Checkout::$_checkout_verified) { |
|
1141 | + // clear the session, mark the checkout as unverified, and try again |
|
1142 | + EE_Registry::instance()->SSN->clear_session(); |
|
1143 | + EED_Single_Page_Checkout::$_initialized = false; |
|
1144 | + EED_Single_Page_Checkout::$_checkout_verified = false; |
|
1145 | + $this->_initialize(); |
|
1146 | + EE_Error::reset_notices(); |
|
1147 | + return false; |
|
1148 | + } |
|
1149 | + EE_Error::add_error( |
|
1150 | + __('We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.', 'event_espresso'), |
|
1151 | + __FILE__, |
|
1152 | + __FUNCTION__, |
|
1153 | + __LINE__ |
|
1154 | + ); |
|
1155 | + return false; |
|
1156 | + } |
|
1157 | + } |
|
1158 | + // now that things have been kinda sufficiently verified, |
|
1159 | + // let's add the checkout to the session so that's available other systems |
|
1160 | + EE_Registry::instance()->SSN->set_checkout($this->checkout); |
|
1161 | + return true; |
|
1162 | + } |
|
1163 | + |
|
1164 | + |
|
1165 | + |
|
1166 | + /** |
|
1167 | + * _initialize_reg_steps |
|
1168 | + * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required |
|
1169 | + * then loops thru all of the active reg steps and calls the initialize_reg_step() method |
|
1170 | + * |
|
1171 | + * @access private |
|
1172 | + * @param bool $reinitializing |
|
1173 | + * @throws \EE_Error |
|
1174 | + */ |
|
1175 | + private function _initialize_reg_steps($reinitializing = false) |
|
1176 | + { |
|
1177 | + $this->checkout->set_reg_step_initiated($this->checkout->current_step); |
|
1178 | + // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS |
|
1179 | + foreach ($this->checkout->reg_steps as $reg_step) { |
|
1180 | + if ( ! $reg_step->initialize_reg_step()) { |
|
1181 | + // if not initialized then maybe this step is being removed... |
|
1182 | + if ( ! $reinitializing && $reg_step->is_current_step()) { |
|
1183 | + // if it was the current step, then we need to start over here |
|
1184 | + $this->_initialize_reg_steps(true); |
|
1185 | + return; |
|
1186 | + } |
|
1187 | + continue; |
|
1188 | + } |
|
1189 | + // add css and JS for current step |
|
1190 | + $reg_step->enqueue_styles_and_scripts(); |
|
1191 | + // i18n |
|
1192 | + $reg_step->translate_js_strings(); |
|
1193 | + if ($reg_step->is_current_step()) { |
|
1194 | + // the text that appears on the reg step form submit button |
|
1195 | + $reg_step->set_submit_button_text(); |
|
1196 | + } |
|
1197 | + } |
|
1198 | + // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information |
|
1199 | + do_action("AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", $this->checkout->current_step); |
|
1200 | + } |
|
1201 | + |
|
1202 | + |
|
1203 | + |
|
1204 | + /** |
|
1205 | + * _check_form_submission |
|
1206 | + * |
|
1207 | + * @access private |
|
1208 | + * @return boolean |
|
1209 | + */ |
|
1210 | + private function _check_form_submission() |
|
1211 | + { |
|
1212 | + //does this request require the reg form to be generated ? |
|
1213 | + if ($this->checkout->generate_reg_form) { |
|
1214 | + // ever heard that song by Blue Rodeo ? |
|
1215 | + try { |
|
1216 | + $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form(); |
|
1217 | + // if not displaying a form, then check for form submission |
|
1218 | + if ( |
|
1219 | + $this->checkout->process_form_submission |
|
1220 | + && $this->checkout->current_step->reg_form->was_submitted() |
|
1221 | + ) { |
|
1222 | + // clear out any old data in case this step is being run again |
|
1223 | + $this->checkout->current_step->set_valid_data(array()); |
|
1224 | + // capture submitted form data |
|
1225 | + $this->checkout->current_step->reg_form->receive_form_submission( |
|
1226 | + apply_filters('FHEE__Single_Page_Checkout___check_form_submission__request_params', EE_Registry::instance()->REQ->params(), $this->checkout) |
|
1227 | + ); |
|
1228 | + // validate submitted form data |
|
1229 | + if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) { |
|
1230 | + // thou shall not pass !!! |
|
1231 | + $this->checkout->continue_reg = false; |
|
1232 | + // any form validation errors? |
|
1233 | + if ($this->checkout->current_step->reg_form->submission_error_message() !== '') { |
|
1234 | + $submission_error_messages = array(); |
|
1235 | + // bad, bad, bad registrant |
|
1236 | + foreach ($this->checkout->current_step->reg_form->get_validation_errors_accumulated() as $validation_error) { |
|
1237 | + if ($validation_error instanceof EE_Validation_Error) { |
|
1238 | + $submission_error_messages[] = sprintf( |
|
1239 | + __('%s : %s', 'event_espresso'), |
|
1240 | + $validation_error->get_form_section()->html_label_text(), |
|
1241 | + $validation_error->getMessage() |
|
1242 | + ); |
|
1243 | + } |
|
1244 | + } |
|
1245 | + EE_Error::add_error(implode('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__); |
|
1246 | + } |
|
1247 | + // well not really... what will happen is we'll just get redirected back to redo the current step |
|
1248 | + $this->go_to_next_step(); |
|
1249 | + return false; |
|
1250 | + } |
|
1251 | + } |
|
1252 | + } catch (EE_Error $e) { |
|
1253 | + $e->get_error(); |
|
1254 | + } |
|
1255 | + } |
|
1256 | + return true; |
|
1257 | + } |
|
1258 | + |
|
1259 | + |
|
1260 | + |
|
1261 | + /** |
|
1262 | + * _process_action |
|
1263 | + * |
|
1264 | + * @access private |
|
1265 | + * @return void |
|
1266 | + * @throws \EE_Error |
|
1267 | + */ |
|
1268 | + private function _process_form_action() |
|
1269 | + { |
|
1270 | + // what cha wanna do? |
|
1271 | + switch ($this->checkout->action) { |
|
1272 | + // AJAX next step reg form |
|
1273 | + case 'display_spco_reg_step' : |
|
1274 | + $this->checkout->redirect = false; |
|
1275 | + if (EE_Registry::instance()->REQ->ajax) { |
|
1276 | + $this->checkout->json_response->set_reg_step_html($this->checkout->current_step->display_reg_form()); |
|
1277 | + } |
|
1278 | + break; |
|
1279 | + default : |
|
1280 | + // meh... do one of those other steps first |
|
1281 | + if ( ! empty($this->checkout->action) && is_callable(array($this->checkout->current_step, $this->checkout->action))) { |
|
1282 | + // dynamically creates hook point like: AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step |
|
1283 | + do_action("AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step); |
|
1284 | + // call action on current step |
|
1285 | + if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) { |
|
1286 | + // good registrant, you get to proceed |
|
1287 | + if ( |
|
1288 | + $this->checkout->current_step->success_message() !== '' |
|
1289 | + && apply_filters( |
|
1290 | + 'FHEE__Single_Page_Checkout___process_form_action__display_success', |
|
1291 | + false |
|
1292 | + ) |
|
1293 | + ) { |
|
1294 | + EE_Error::add_success( |
|
1295 | + $this->checkout->current_step->success_message() |
|
1296 | + . '<br />' . $this->checkout->next_step->_instructions() |
|
1297 | + ); |
|
1298 | + } |
|
1299 | + // pack it up, pack it in... |
|
1300 | + $this->_setup_redirect(); |
|
1301 | + } |
|
1302 | + // dynamically creates hook point like: AHEE__Single_Page_Checkout__after_payment_options__process_reg_step |
|
1303 | + do_action("AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step); |
|
1304 | + } else { |
|
1305 | + EE_Error::add_error( |
|
1306 | + sprintf( |
|
1307 | + __('The requested form action "%s" does not exist for the current "%s" registration step.', 'event_espresso'), |
|
1308 | + $this->checkout->action, |
|
1309 | + $this->checkout->current_step->name() |
|
1310 | + ), |
|
1311 | + __FILE__, |
|
1312 | + __FUNCTION__, |
|
1313 | + __LINE__ |
|
1314 | + ); |
|
1315 | + } |
|
1316 | + // end default |
|
1317 | + } |
|
1318 | + // store our progress so far |
|
1319 | + $this->checkout->stash_transaction_and_checkout(); |
|
1320 | + // advance to the next step! If you pass GO, collect $200 |
|
1321 | + $this->go_to_next_step(); |
|
1322 | + } |
|
1323 | + |
|
1324 | + |
|
1325 | + |
|
1326 | + /** |
|
1327 | + * add_styles_and_scripts |
|
1328 | + * |
|
1329 | + * @access public |
|
1330 | + * @return void |
|
1331 | + */ |
|
1332 | + public function add_styles_and_scripts() |
|
1333 | + { |
|
1334 | + // i18n |
|
1335 | + $this->translate_js_strings(); |
|
1336 | + if ($this->checkout->admin_request) { |
|
1337 | + add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10); |
|
1338 | + } else { |
|
1339 | + add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10); |
|
1340 | + } |
|
1341 | + } |
|
1342 | + |
|
1343 | + |
|
1344 | + |
|
1345 | + /** |
|
1346 | + * translate_js_strings |
|
1347 | + * |
|
1348 | + * @access public |
|
1349 | + * @return void |
|
1350 | + */ |
|
1351 | + public function translate_js_strings() |
|
1352 | + { |
|
1353 | + EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit; |
|
1354 | + EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link; |
|
1355 | + EE_Registry::$i18n_js_strings['server_error'] = __('An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso'); |
|
1356 | + EE_Registry::$i18n_js_strings['invalid_json_response'] = __('An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso'); |
|
1357 | + EE_Registry::$i18n_js_strings['validation_error'] = __('There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', 'event_espresso'); |
|
1358 | + EE_Registry::$i18n_js_strings['invalid_payment_method'] = __('There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', 'event_espresso'); |
|
1359 | + EE_Registry::$i18n_js_strings['reg_step_error'] = __('This registration step could not be completed. Please refresh the page and try again.', 'event_espresso'); |
|
1360 | + EE_Registry::$i18n_js_strings['invalid_coupon'] = __('We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', 'event_espresso'); |
|
1361 | + EE_Registry::$i18n_js_strings['process_registration'] = sprintf( |
|
1362 | + __('Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', 'event_espresso'), |
|
1363 | + '<br/>', |
|
1364 | + '<br/>' |
|
1365 | + ); |
|
1366 | + EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language'); |
|
1367 | + EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id(); |
|
1368 | + EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency; |
|
1369 | + EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20'; |
|
1370 | + EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso'); |
|
1371 | + EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso'); |
|
1372 | + EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso'); |
|
1373 | + EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso'); |
|
1374 | + EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso'); |
|
1375 | + EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso'); |
|
1376 | + EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso'); |
|
1377 | + EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso'); |
|
1378 | + EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso'); |
|
1379 | + EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso'); |
|
1380 | + EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso'); |
|
1381 | + EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso'); |
|
1382 | + EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso'); |
|
1383 | + EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso'); |
|
1384 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf( |
|
1385 | + __( |
|
1386 | + '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s', |
|
1387 | + 'event_espresso' |
|
1388 | + ), |
|
1389 | + '<h4 class="important-notice">', |
|
1390 | + '</h4>', |
|
1391 | + '<br />', |
|
1392 | + '<p>', |
|
1393 | + '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1394 | + '">', |
|
1395 | + '</a>', |
|
1396 | + '</p>' |
|
1397 | + ); |
|
1398 | + EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters('FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', true); |
|
1399 | + EE_Registry::$i18n_js_strings['session_extension'] = absint( |
|
1400 | + apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS) |
|
1401 | + ); |
|
1402 | + EE_Registry::$i18n_js_strings['session_expiration'] = gmdate( |
|
1403 | + 'M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
1404 | + ); |
|
1405 | + } |
|
1406 | + |
|
1407 | + |
|
1408 | + |
|
1409 | + /** |
|
1410 | + * enqueue_styles_and_scripts |
|
1411 | + * |
|
1412 | + * @access public |
|
1413 | + * @return void |
|
1414 | + * @throws \EE_Error |
|
1415 | + */ |
|
1416 | + public function enqueue_styles_and_scripts() |
|
1417 | + { |
|
1418 | + // load css |
|
1419 | + wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION); |
|
1420 | + wp_enqueue_style('single_page_checkout'); |
|
1421 | + // load JS |
|
1422 | + wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery .plugin.min.js', array('jquery'), '1.0.1', true); |
|
1423 | + wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery .countdown.min.js', array('jquery_plugin'), '2.0.2', true); |
|
1424 | + wp_register_script('single_page_checkout', SPCO_JS_URL . 'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true); |
|
1425 | + if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) { |
|
1426 | + $this->checkout->registration_form->enqueue_js(); |
|
1427 | + } |
|
1428 | + if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) { |
|
1429 | + $this->checkout->current_step->reg_form->enqueue_js(); |
|
1430 | + } |
|
1431 | + wp_enqueue_script('single_page_checkout'); |
|
1432 | + /** |
|
1433 | + * global action hook for enqueueing styles and scripts with |
|
1434 | + * spco calls. |
|
1435 | + */ |
|
1436 | + do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this); |
|
1437 | + /** |
|
1438 | + * dynamic action hook for enqueueing styles and scripts with spco calls. |
|
1439 | + * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information |
|
1440 | + */ |
|
1441 | + do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this); |
|
1442 | + } |
|
1443 | + |
|
1444 | + |
|
1445 | + |
|
1446 | + /** |
|
1447 | + * display the Registration Single Page Checkout Form |
|
1448 | + * |
|
1449 | + * @access private |
|
1450 | + * @return void |
|
1451 | + * @throws \EE_Error |
|
1452 | + */ |
|
1453 | + private function _display_spco_reg_form() |
|
1454 | + { |
|
1455 | + // if registering via the admin, just display the reg form for the current step |
|
1456 | + if ($this->checkout->admin_request) { |
|
1457 | + EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form()); |
|
1458 | + } else { |
|
1459 | + // add powered by EE msg |
|
1460 | + add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer')); |
|
1461 | + $empty_cart = count($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)) < 1 |
|
1462 | + ? true |
|
1463 | + : false; |
|
1464 | + EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart; |
|
1465 | + $cookies_not_set_msg = ''; |
|
1466 | + if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) { |
|
1467 | + $cookies_not_set_msg = apply_filters( |
|
1468 | + 'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg', |
|
1469 | + sprintf( |
|
1470 | + __( |
|
1471 | + '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s', |
|
1472 | + 'event_espresso' |
|
1473 | + ), |
|
1474 | + '<div class="ee-attention">', |
|
1475 | + '</div>', |
|
1476 | + '<h6 class="important-notice">', |
|
1477 | + '</h6>', |
|
1478 | + '<p>', |
|
1479 | + '</p>', |
|
1480 | + '<br />', |
|
1481 | + '<a href="http://www.whatarecookies.com/enable.asp" target="_blank">', |
|
1482 | + '</a>' |
|
1483 | + ) |
|
1484 | + ); |
|
1485 | + } |
|
1486 | + $this->checkout->registration_form = new EE_Form_Section_Proper( |
|
1487 | + array( |
|
1488 | + 'name' => 'single-page-checkout', |
|
1489 | + 'html_id' => 'ee-single-page-checkout-dv', |
|
1490 | + 'layout_strategy' => |
|
1491 | + new EE_Template_Layout( |
|
1492 | + array( |
|
1493 | + 'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php', |
|
1494 | + 'template_args' => array( |
|
1495 | + 'empty_cart' => $empty_cart, |
|
1496 | + 'revisit' => $this->checkout->revisit, |
|
1497 | + 'reg_steps' => $this->checkout->reg_steps, |
|
1498 | + 'next_step' => $this->checkout->next_step instanceof EE_SPCO_Reg_Step |
|
1499 | + ? $this->checkout->next_step->slug() |
|
1500 | + : '', |
|
1501 | + 'cancel_page_url' => $this->checkout->cancel_page_url, |
|
1502 | + 'empty_msg' => apply_filters( |
|
1503 | + 'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg', |
|
1504 | + sprintf( |
|
1505 | + __('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', |
|
1506 | + 'event_espresso'), |
|
1507 | + '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1508 | + '">', |
|
1509 | + '</a>' |
|
1510 | + ) |
|
1511 | + ), |
|
1512 | + 'cookies_not_set_msg' => $cookies_not_set_msg, |
|
1513 | + 'registration_time_limit' => $this->checkout->get_registration_time_limit(), |
|
1514 | + 'session_expiration' => |
|
1515 | + date('M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)), |
|
1516 | + ), |
|
1517 | + ) |
|
1518 | + ), |
|
1519 | + ) |
|
1520 | + ); |
|
1521 | + // load template and add to output sent that gets filtered into the_content() |
|
1522 | + EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html()); |
|
1523 | + } |
|
1524 | + } |
|
1525 | + |
|
1526 | + |
|
1527 | + |
|
1528 | + /** |
|
1529 | + * add_extra_finalize_registration_inputs |
|
1530 | + * |
|
1531 | + * @access public |
|
1532 | + * @param $next_step |
|
1533 | + * @internal param string $label |
|
1534 | + * @return void |
|
1535 | + */ |
|
1536 | + public function add_extra_finalize_registration_inputs($next_step) |
|
1537 | + { |
|
1538 | + if ($next_step === 'finalize_registration') { |
|
1539 | + echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>'; |
|
1540 | + } |
|
1541 | + } |
|
1542 | + |
|
1543 | + |
|
1544 | + |
|
1545 | + /** |
|
1546 | + * display_registration_footer |
|
1547 | + * |
|
1548 | + * @access public |
|
1549 | + * @return string |
|
1550 | + */ |
|
1551 | + public static function display_registration_footer() |
|
1552 | + { |
|
1553 | + if ( |
|
1554 | + apply_filters( |
|
1555 | + 'FHEE__EE_Front__Controller__show_reg_footer', |
|
1556 | + EE_Registry::instance()->CFG->admin->show_reg_footer |
|
1557 | + ) |
|
1558 | + ) { |
|
1559 | + add_filter( |
|
1560 | + 'FHEE__EEH_Template__powered_by_event_espresso__url', |
|
1561 | + function ($url) { |
|
1562 | + return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url); |
|
1563 | + } |
|
1564 | + ); |
|
1565 | + echo apply_filters( |
|
1566 | + 'FHEE__EE_Front_Controller__display_registration_footer', |
|
1567 | + \EEH_Template::powered_by_event_espresso( |
|
1568 | + '', |
|
1569 | + 'espresso-registration-footer-dv', |
|
1570 | + array('utm_content' => 'registration_checkout') |
|
1571 | + ) |
|
1572 | + ); |
|
1573 | + } |
|
1574 | + return ''; |
|
1575 | + } |
|
1576 | + |
|
1577 | + |
|
1578 | + |
|
1579 | + /** |
|
1580 | + * unlock_transaction |
|
1581 | + * |
|
1582 | + * @access public |
|
1583 | + * @return void |
|
1584 | + * @throws \EE_Error |
|
1585 | + */ |
|
1586 | + public function unlock_transaction() |
|
1587 | + { |
|
1588 | + if ($this->checkout->transaction instanceof EE_Transaction) { |
|
1589 | + $this->checkout->transaction->unlock(); |
|
1590 | + } |
|
1591 | + } |
|
1592 | + |
|
1593 | + |
|
1594 | + |
|
1595 | + /** |
|
1596 | + * _setup_redirect |
|
1597 | + * |
|
1598 | + * @access private |
|
1599 | + * @return void |
|
1600 | + */ |
|
1601 | + private function _setup_redirect() |
|
1602 | + { |
|
1603 | + if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) { |
|
1604 | + $this->checkout->redirect = true; |
|
1605 | + if (empty($this->checkout->redirect_url)) { |
|
1606 | + $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url(); |
|
1607 | + } |
|
1608 | + $this->checkout->redirect_url = apply_filters( |
|
1609 | + 'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url', |
|
1610 | + $this->checkout->redirect_url, |
|
1611 | + $this->checkout |
|
1612 | + ); |
|
1613 | + } |
|
1614 | + } |
|
1615 | + |
|
1616 | + |
|
1617 | + |
|
1618 | + /** |
|
1619 | + * handle ajax message responses and redirects |
|
1620 | + * |
|
1621 | + * @access public |
|
1622 | + * @return void |
|
1623 | + * @throws \EE_Error |
|
1624 | + */ |
|
1625 | + public function go_to_next_step() |
|
1626 | + { |
|
1627 | + if (EE_Registry::instance()->REQ->ajax) { |
|
1628 | + // capture contents of output buffer we started earlier in the request, and insert into JSON response |
|
1629 | + $this->checkout->json_response->set_unexpected_errors(ob_get_clean()); |
|
1630 | + } |
|
1631 | + $this->unlock_transaction(); |
|
1632 | + // just return for these conditions |
|
1633 | + if ( |
|
1634 | + $this->checkout->admin_request |
|
1635 | + || $this->checkout->action === 'redirect_form' |
|
1636 | + || $this->checkout->action === 'update_checkout' |
|
1637 | + ) { |
|
1638 | + return; |
|
1639 | + } |
|
1640 | + // AJAX response |
|
1641 | + $this->_handle_json_response(); |
|
1642 | + // redirect to next step or the Thank You page |
|
1643 | + $this->_handle_html_redirects(); |
|
1644 | + // hmmm... must be something wrong, so let's just display the form again ! |
|
1645 | + $this->_display_spco_reg_form(); |
|
1646 | + } |
|
1647 | + |
|
1648 | + |
|
1649 | + |
|
1650 | + /** |
|
1651 | + * _handle_json_response |
|
1652 | + * |
|
1653 | + * @access protected |
|
1654 | + * @return void |
|
1655 | + */ |
|
1656 | + protected function _handle_json_response() |
|
1657 | + { |
|
1658 | + // if this is an ajax request |
|
1659 | + if (EE_Registry::instance()->REQ->ajax) { |
|
1660 | + // DEBUG LOG |
|
1661 | + //$this->checkout->log( |
|
1662 | + // __CLASS__, __FUNCTION__, __LINE__, |
|
1663 | + // array( |
|
1664 | + // 'json_response_redirect_url' => $this->checkout->json_response->redirect_url(), |
|
1665 | + // 'redirect' => $this->checkout->redirect, |
|
1666 | + // 'continue_reg' => $this->checkout->continue_reg, |
|
1667 | + // ) |
|
1668 | + //); |
|
1669 | + $this->checkout->json_response->set_registration_time_limit( |
|
1670 | + $this->checkout->get_registration_time_limit() |
|
1671 | + ); |
|
1672 | + $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing); |
|
1673 | + // just send the ajax ( |
|
1674 | + $json_response = apply_filters( |
|
1675 | + 'FHEE__EE_Single_Page_Checkout__JSON_response', |
|
1676 | + $this->checkout->json_response |
|
1677 | + ); |
|
1678 | + echo $json_response; |
|
1679 | + exit(); |
|
1680 | + } |
|
1681 | + } |
|
1682 | + |
|
1683 | + |
|
1684 | + |
|
1685 | + /** |
|
1686 | + * _handle_redirects |
|
1687 | + * |
|
1688 | + * @access protected |
|
1689 | + * @return void |
|
1690 | + */ |
|
1691 | + protected function _handle_html_redirects() |
|
1692 | + { |
|
1693 | + // going somewhere ? |
|
1694 | + if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) { |
|
1695 | + // store notices in a transient |
|
1696 | + EE_Error::get_notices(false, true, true); |
|
1697 | + // DEBUG LOG |
|
1698 | + //$this->checkout->log( |
|
1699 | + // __CLASS__, __FUNCTION__, __LINE__, |
|
1700 | + // array( |
|
1701 | + // 'headers_sent' => headers_sent(), |
|
1702 | + // 'redirect_url' => $this->checkout->redirect_url, |
|
1703 | + // 'headers_list' => headers_list(), |
|
1704 | + // ) |
|
1705 | + //); |
|
1706 | + wp_safe_redirect($this->checkout->redirect_url); |
|
1707 | + exit(); |
|
1708 | + } |
|
1709 | + } |
|
1710 | + |
|
1711 | + |
|
1712 | + |
|
1713 | + /** |
|
1714 | + * set_checkout_anchor |
|
1715 | + * |
|
1716 | + * @access public |
|
1717 | + * @return void |
|
1718 | + */ |
|
1719 | + public function set_checkout_anchor() |
|
1720 | + { |
|
1721 | + echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>'; |
|
1722 | + } |
|
1723 | 1723 | |
1724 | 1724 | |
1725 | 1725 |
@@ -216,13 +216,13 @@ discard block |
||
216 | 216 | */ |
217 | 217 | public static function set_definitions() |
218 | 218 | { |
219 | - define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS); |
|
220 | - define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS); |
|
221 | - define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS); |
|
222 | - define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS); |
|
223 | - define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS); |
|
224 | - define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS); |
|
225 | - define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS); |
|
219 | + define('SPCO_BASE_PATH', rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS).DS); |
|
220 | + define('SPCO_CSS_URL', plugin_dir_url(__FILE__).'css'.DS); |
|
221 | + define('SPCO_IMG_URL', plugin_dir_url(__FILE__).'img'.DS); |
|
222 | + define('SPCO_JS_URL', plugin_dir_url(__FILE__).'js'.DS); |
|
223 | + define('SPCO_INC_PATH', SPCO_BASE_PATH.'inc'.DS); |
|
224 | + define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH.'reg_steps'.DS); |
|
225 | + define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH.'templates'.DS); |
|
226 | 226 | EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true); |
227 | 227 | EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf( |
228 | 228 | __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s', |
@@ -231,7 +231,7 @@ discard block |
||
231 | 231 | '</h4>', |
232 | 232 | '<br />', |
233 | 233 | '<p>', |
234 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
234 | + '<a href="'.get_post_type_archive_link('espresso_events').'" title="', |
|
235 | 235 | '">', |
236 | 236 | '</a>', |
237 | 237 | '</p>' |
@@ -255,7 +255,7 @@ discard block |
||
255 | 255 | return; |
256 | 256 | } |
257 | 257 | // filter list of reg_steps |
258 | - $reg_steps_to_load = (array)apply_filters( |
|
258 | + $reg_steps_to_load = (array) apply_filters( |
|
259 | 259 | 'AHEE__SPCO__load_reg_steps__reg_steps_to_load', |
260 | 260 | EED_Single_Page_Checkout::get_reg_steps() |
261 | 261 | ); |
@@ -299,25 +299,25 @@ discard block |
||
299 | 299 | if (empty($reg_steps)) { |
300 | 300 | $reg_steps = array( |
301 | 301 | 10 => array( |
302 | - 'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information', |
|
302 | + 'file_path' => SPCO_REG_STEPS_PATH.'attendee_information', |
|
303 | 303 | 'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information', |
304 | 304 | 'slug' => 'attendee_information', |
305 | 305 | 'has_hooks' => false, |
306 | 306 | ), |
307 | 307 | 20 => array( |
308 | - 'file_path' => SPCO_REG_STEPS_PATH . 'registration_confirmation', |
|
308 | + 'file_path' => SPCO_REG_STEPS_PATH.'registration_confirmation', |
|
309 | 309 | 'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation', |
310 | 310 | 'slug' => 'registration_confirmation', |
311 | 311 | 'has_hooks' => false, |
312 | 312 | ), |
313 | 313 | 30 => array( |
314 | - 'file_path' => SPCO_REG_STEPS_PATH . 'payment_options', |
|
314 | + 'file_path' => SPCO_REG_STEPS_PATH.'payment_options', |
|
315 | 315 | 'class_name' => 'EE_SPCO_Reg_Step_Payment_Options', |
316 | 316 | 'slug' => 'payment_options', |
317 | 317 | 'has_hooks' => true, |
318 | 318 | ), |
319 | 319 | 999 => array( |
320 | - 'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration', |
|
320 | + 'file_path' => SPCO_REG_STEPS_PATH.'finalize_registration', |
|
321 | 321 | 'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration', |
322 | 322 | 'slug' => 'finalize_registration', |
323 | 323 | 'has_hooks' => false, |
@@ -499,7 +499,7 @@ discard block |
||
499 | 499 | // DEBUG LOG |
500 | 500 | //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
501 | 501 | // get reg form |
502 | - if( ! $this->_check_form_submission()) { |
|
502 | + if ( ! $this->_check_form_submission()) { |
|
503 | 503 | EED_Single_Page_Checkout::$_initialized = true; |
504 | 504 | return; |
505 | 505 | } |
@@ -1063,7 +1063,7 @@ discard block |
||
1063 | 1063 | if ( ! $registration instanceof EE_Registration) { |
1064 | 1064 | throw new InvalidEntityException($registration, 'EE_Registration'); |
1065 | 1065 | } |
1066 | - $registrations[ $registration->ID() ] = $registration; |
|
1066 | + $registrations[$registration->ID()] = $registration; |
|
1067 | 1067 | } |
1068 | 1068 | } |
1069 | 1069 | $registration_processor->fix_reg_final_price_rounding_issue($transaction); |
@@ -1293,7 +1293,7 @@ discard block |
||
1293 | 1293 | ) { |
1294 | 1294 | EE_Error::add_success( |
1295 | 1295 | $this->checkout->current_step->success_message() |
1296 | - . '<br />' . $this->checkout->next_step->_instructions() |
|
1296 | + . '<br />'.$this->checkout->next_step->_instructions() |
|
1297 | 1297 | ); |
1298 | 1298 | } |
1299 | 1299 | // pack it up, pack it in... |
@@ -1390,7 +1390,7 @@ discard block |
||
1390 | 1390 | '</h4>', |
1391 | 1391 | '<br />', |
1392 | 1392 | '<p>', |
1393 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1393 | + '<a href="'.get_post_type_archive_link('espresso_events').'" title="', |
|
1394 | 1394 | '">', |
1395 | 1395 | '</a>', |
1396 | 1396 | '</p>' |
@@ -1416,12 +1416,12 @@ discard block |
||
1416 | 1416 | public function enqueue_styles_and_scripts() |
1417 | 1417 | { |
1418 | 1418 | // load css |
1419 | - wp_register_style('single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION); |
|
1419 | + wp_register_style('single_page_checkout', SPCO_CSS_URL.'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION); |
|
1420 | 1420 | wp_enqueue_style('single_page_checkout'); |
1421 | 1421 | // load JS |
1422 | - wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL . 'jquery .plugin.min.js', array('jquery'), '1.0.1', true); |
|
1423 | - wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL . 'jquery .countdown.min.js', array('jquery_plugin'), '2.0.2', true); |
|
1424 | - wp_register_script('single_page_checkout', SPCO_JS_URL . 'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true); |
|
1422 | + wp_register_script('jquery_plugin', EE_THIRD_PARTY_URL.'jquery .plugin.min.js', array('jquery'), '1.0.1', true); |
|
1423 | + wp_register_script('jquery_countdown', EE_THIRD_PARTY_URL.'jquery .countdown.min.js', array('jquery_plugin'), '2.0.2', true); |
|
1424 | + wp_register_script('single_page_checkout', SPCO_JS_URL.'single_page_checkout.js', array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'), EVENT_ESPRESSO_VERSION, true); |
|
1425 | 1425 | if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) { |
1426 | 1426 | $this->checkout->registration_form->enqueue_js(); |
1427 | 1427 | } |
@@ -1438,7 +1438,7 @@ discard block |
||
1438 | 1438 | * dynamic action hook for enqueueing styles and scripts with spco calls. |
1439 | 1439 | * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information |
1440 | 1440 | */ |
1441 | - do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this); |
|
1441 | + do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__'.$this->checkout->current_step->slug(), $this); |
|
1442 | 1442 | } |
1443 | 1443 | |
1444 | 1444 | |
@@ -1490,7 +1490,7 @@ discard block |
||
1490 | 1490 | 'layout_strategy' => |
1491 | 1491 | new EE_Template_Layout( |
1492 | 1492 | array( |
1493 | - 'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php', |
|
1493 | + 'layout_template_file' => SPCO_TEMPLATES_PATH.'registration_page_wrapper.template.php', |
|
1494 | 1494 | 'template_args' => array( |
1495 | 1495 | 'empty_cart' => $empty_cart, |
1496 | 1496 | 'revisit' => $this->checkout->revisit, |
@@ -1504,7 +1504,7 @@ discard block |
||
1504 | 1504 | sprintf( |
1505 | 1505 | __('You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', |
1506 | 1506 | 'event_espresso'), |
1507 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1507 | + '<a href="'.get_post_type_archive_link('espresso_events').'" title="', |
|
1508 | 1508 | '">', |
1509 | 1509 | '</a>' |
1510 | 1510 | ) |
@@ -1558,7 +1558,7 @@ discard block |
||
1558 | 1558 | ) { |
1559 | 1559 | add_filter( |
1560 | 1560 | 'FHEE__EEH_Template__powered_by_event_espresso__url', |
1561 | - function ($url) { |
|
1561 | + function($url) { |
|
1562 | 1562 | return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url); |
1563 | 1563 | } |
1564 | 1564 | ); |
@@ -187,7 +187,7 @@ discard block |
||
187 | 187 | * process_ticket_selections |
188 | 188 | * |
189 | 189 | * @access public |
190 | - * @return array or FALSE |
|
190 | + * @return boolean|null or FALSE |
|
191 | 191 | * @throws \EE_Error |
192 | 192 | */ |
193 | 193 | public function process_ticket_selections() { |
@@ -201,7 +201,7 @@ discard block |
||
201 | 201 | * cancel_ticket_selections |
202 | 202 | * |
203 | 203 | * @access public |
204 | - * @return array or FALSE |
|
204 | + * @return false|null or FALSE |
|
205 | 205 | * @throws \EE_Error |
206 | 206 | */ |
207 | 207 | public function cancel_ticket_selections() { |
@@ -22,15 +22,15 @@ discard block |
||
22 | 22 | */ |
23 | 23 | class EED_Ticket_Selector extends EED_Module { |
24 | 24 | |
25 | - /** |
|
26 | - * @var EventEspresso\modules\ticket_selector\DisplayTicketSelector $ticket_selector |
|
27 | - */ |
|
28 | - private static $ticket_selector; |
|
25 | + /** |
|
26 | + * @var EventEspresso\modules\ticket_selector\DisplayTicketSelector $ticket_selector |
|
27 | + */ |
|
28 | + private static $ticket_selector; |
|
29 | 29 | |
30 | - /** |
|
31 | - * @var EventEspresso\modules\ticket_selector\TicketSelectorIframeEmbedButton $iframe_embed_button |
|
32 | - */ |
|
33 | - private static $iframe_embed_button; |
|
30 | + /** |
|
31 | + * @var EventEspresso\modules\ticket_selector\TicketSelectorIframeEmbedButton $iframe_embed_button |
|
32 | + */ |
|
33 | + private static $iframe_embed_button; |
|
34 | 34 | |
35 | 35 | |
36 | 36 | |
@@ -61,8 +61,8 @@ discard block |
||
61 | 61 | // routing |
62 | 62 | EE_Config::register_route( 'iframe', 'EED_Ticket_Selector', 'ticket_selector_iframe', 'ticket_selector' ); |
63 | 63 | EE_Config::register_route( 'process_ticket_selections', 'EED_Ticket_Selector', 'process_ticket_selections' ); |
64 | - EE_Config::register_route('cancel_ticket_selections', 'EED_Ticket_Selector', 'cancel_ticket_selections'); |
|
65 | - add_action( 'wp_loaded', array( 'EED_Ticket_Selector', 'set_definitions' ), 2 ); |
|
64 | + EE_Config::register_route('cancel_ticket_selections', 'EED_Ticket_Selector', 'cancel_ticket_selections'); |
|
65 | + add_action( 'wp_loaded', array( 'EED_Ticket_Selector', 'set_definitions' ), 2 ); |
|
66 | 66 | add_action( 'AHEE_event_details_header_bottom', array( 'EED_Ticket_Selector', 'display_ticket_selector' ), 10, 1 ); |
67 | 67 | add_action( 'wp_enqueue_scripts', array( 'EED_Ticket_Selector', 'load_tckt_slctr_assets' ), 10 ); |
68 | 68 | } |
@@ -83,7 +83,7 @@ discard block |
||
83 | 83 | array( 'EED_Ticket_Selector', 'ticket_selector_iframe_embed_button' ), |
84 | 84 | 10 |
85 | 85 | ); |
86 | - } |
|
86 | + } |
|
87 | 87 | |
88 | 88 | |
89 | 89 | |
@@ -99,23 +99,23 @@ discard block |
||
99 | 99 | |
100 | 100 | //if config is not set, initialize |
101 | 101 | if ( ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config ) { |
102 | - \EED_Ticket_Selector::instance()->set_config(); |
|
103 | - \EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector = \EED_Ticket_Selector::instance()->config(); |
|
102 | + \EED_Ticket_Selector::instance()->set_config(); |
|
103 | + \EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector = \EED_Ticket_Selector::instance()->config(); |
|
104 | 104 | } |
105 | 105 | } |
106 | 106 | |
107 | 107 | |
108 | 108 | |
109 | 109 | /** |
110 | - * @return \EventEspresso\modules\ticket_selector\DisplayTicketSelector |
|
111 | - */ |
|
112 | - public static function ticketSelector() |
|
113 | - { |
|
114 | - if ( ! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) { |
|
115 | - EED_Ticket_Selector::$ticket_selector = new DisplayTicketSelector(); |
|
116 | - } |
|
117 | - return EED_Ticket_Selector::$ticket_selector; |
|
118 | - } |
|
110 | + * @return \EventEspresso\modules\ticket_selector\DisplayTicketSelector |
|
111 | + */ |
|
112 | + public static function ticketSelector() |
|
113 | + { |
|
114 | + if ( ! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) { |
|
115 | + EED_Ticket_Selector::$ticket_selector = new DisplayTicketSelector(); |
|
116 | + } |
|
117 | + return EED_Ticket_Selector::$ticket_selector; |
|
118 | + } |
|
119 | 119 | |
120 | 120 | |
121 | 121 | /** |
@@ -168,15 +168,15 @@ discard block |
||
168 | 168 | |
169 | 169 | |
170 | 170 | |
171 | - /** |
|
172 | - * creates buttons for selecting number of attendees for an event |
|
173 | - * |
|
174 | - * @access public |
|
175 | - * @param WP_Post|int $event |
|
176 | - * @param bool $view_details |
|
177 | - * @return string |
|
178 | - * @throws \EE_Error |
|
179 | - */ |
|
171 | + /** |
|
172 | + * creates buttons for selecting number of attendees for an event |
|
173 | + * |
|
174 | + * @access public |
|
175 | + * @param WP_Post|int $event |
|
176 | + * @param bool $view_details |
|
177 | + * @return string |
|
178 | + * @throws \EE_Error |
|
179 | + */ |
|
180 | 180 | public static function display_ticket_selector( $event = NULL, $view_details = FALSE ) { |
181 | 181 | return EED_Ticket_Selector::ticketSelector()->display( $event, $view_details ); |
182 | 182 | } |
@@ -198,9 +198,9 @@ discard block |
||
198 | 198 | |
199 | 199 | |
200 | 200 | /** |
201 | - * cancel_ticket_selections |
|
202 | - * |
|
203 | - * @access public |
|
201 | + * cancel_ticket_selections |
|
202 | + * |
|
203 | + * @access public |
|
204 | 204 | * @return array or FALSE |
205 | 205 | * @throws \EE_Error |
206 | 206 | */ |
@@ -212,11 +212,11 @@ discard block |
||
212 | 212 | |
213 | 213 | |
214 | 214 | /** |
215 | - * load js |
|
216 | - * |
|
217 | - * @access public |
|
218 | - * @return void |
|
219 | - */ |
|
215 | + * load js |
|
216 | + * |
|
217 | + * @access public |
|
218 | + * @return void |
|
219 | + */ |
|
220 | 220 | public static function load_tckt_slctr_assets() { |
221 | 221 | if ( apply_filters( 'FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', FALSE ) ) { |
222 | 222 | // add some style |
@@ -225,9 +225,9 @@ discard block |
||
225 | 225 | // make it dance |
226 | 226 | wp_register_script('ticket_selector', TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js', array('espresso_core'), '', TRUE); |
227 | 227 | wp_enqueue_script('ticket_selector'); |
228 | - require_once( EE_LIBRARIES.'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php'); |
|
229 | - \EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts(); |
|
230 | - } |
|
228 | + require_once( EE_LIBRARIES.'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php'); |
|
229 | + \EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts(); |
|
230 | + } |
|
231 | 231 | } |
232 | 232 | |
233 | 233 | |
@@ -236,129 +236,129 @@ discard block |
||
236 | 236 | |
237 | 237 | |
238 | 238 | |
239 | - /** |
|
240 | - * @deprecated |
|
241 | - * @return string |
|
242 | - * @throws \EE_Error |
|
243 | - */ |
|
244 | - public static function display_view_details_btn() |
|
245 | - { |
|
246 | - // todo add doing_it_wrong() notice during next major version |
|
247 | - return EED_Ticket_Selector::ticketSelector()->displayViewDetailsButton(); |
|
248 | - } |
|
249 | - |
|
250 | - |
|
251 | - |
|
252 | - /** |
|
253 | - * @deprecated |
|
254 | - * @return string |
|
255 | - * @throws \EE_Error |
|
256 | - */ |
|
257 | - public static function display_ticket_selector_submit() |
|
258 | - { |
|
259 | - // todo add doing_it_wrong() notice during next major version |
|
260 | - return EED_Ticket_Selector::ticketSelector()->displaySubmitButton(); |
|
261 | - } |
|
262 | - |
|
263 | - |
|
264 | - |
|
265 | - /** |
|
266 | - * @deprecated |
|
267 | - * @param string $permalink_string |
|
268 | - * @param int $id |
|
269 | - * @param string $new_title |
|
270 | - * @param string $new_slug |
|
271 | - * @return string |
|
272 | - */ |
|
273 | - public static function iframe_code_button($permalink_string, $id, $new_title = '', $new_slug = '') |
|
274 | - { |
|
275 | - // todo add doing_it_wrong() notice during next major version |
|
276 | - if ( |
|
277 | - \EE_Registry::instance()->REQ->get('page') === 'espresso_events' |
|
278 | - && \EE_Registry::instance()->REQ->get('action') === 'edit' |
|
279 | - ) { |
|
280 | - $iframe_embed_button = \EED_Ticket_Selector::getIframeEmbedButton(); |
|
281 | - $iframe_embed_button->addEventEditorIframeEmbedButton(); |
|
282 | - } |
|
283 | - return ''; |
|
284 | - } |
|
285 | - |
|
286 | - |
|
287 | - |
|
288 | - /** |
|
289 | - * @deprecated |
|
290 | - * @param int $ID |
|
291 | - * @param string $external_url |
|
292 | - * @return string |
|
293 | - */ |
|
294 | - public static function ticket_selector_form_open($ID = 0, $external_url = '') |
|
295 | - { |
|
296 | - // todo add doing_it_wrong() notice during next major version |
|
297 | - return EED_Ticket_Selector::ticketSelector()->formOpen($ID, $external_url); |
|
298 | - } |
|
299 | - |
|
300 | - |
|
301 | - |
|
302 | - /** |
|
303 | - * @deprecated |
|
304 | - * @return string |
|
305 | - */ |
|
306 | - public static function ticket_selector_form_close() |
|
307 | - { |
|
308 | - // todo add doing_it_wrong() notice during next major version |
|
309 | - return EED_Ticket_Selector::ticketSelector()->formClose(); |
|
310 | - } |
|
311 | - |
|
312 | - |
|
313 | - |
|
314 | - /** |
|
315 | - * @deprecated |
|
316 | - * @return string |
|
317 | - */ |
|
318 | - public static function no_tkt_slctr_end_dv() |
|
319 | - { |
|
320 | - // todo add doing_it_wrong() notice during next major version |
|
321 | - return EED_Ticket_Selector::ticketSelector()->ticketSelectorEndDiv(); |
|
322 | - } |
|
323 | - |
|
324 | - |
|
325 | - |
|
326 | - /** |
|
327 | - * @deprecated 4.9.13 |
|
328 | - * @return string |
|
329 | - */ |
|
330 | - public static function tkt_slctr_end_dv() |
|
331 | - { |
|
332 | - return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
333 | - } |
|
334 | - |
|
335 | - |
|
336 | - |
|
337 | - /** |
|
338 | - * @deprecated |
|
339 | - * @return string |
|
340 | - */ |
|
341 | - public static function clear_tkt_slctr() |
|
342 | - { |
|
343 | - return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
344 | - } |
|
345 | - |
|
346 | - |
|
347 | - |
|
348 | - /** |
|
349 | - * @deprecated |
|
350 | - */ |
|
351 | - public static function load_tckt_slctr_assets_admin() |
|
352 | - { |
|
353 | - // todo add doing_it_wrong() notice during next major version |
|
354 | - if ( |
|
355 | - \EE_Registry::instance()->REQ->get( 'page' ) === 'espresso_events' |
|
356 | - && \EE_Registry::instance()->REQ->get( 'action' ) === 'edit' |
|
357 | - ) { |
|
358 | - $iframe_embed_button = \EED_Ticket_Selector::getIframeEmbedButton(); |
|
359 | - $iframe_embed_button->embedButtonAssets(); |
|
360 | - } |
|
361 | - } |
|
239 | + /** |
|
240 | + * @deprecated |
|
241 | + * @return string |
|
242 | + * @throws \EE_Error |
|
243 | + */ |
|
244 | + public static function display_view_details_btn() |
|
245 | + { |
|
246 | + // todo add doing_it_wrong() notice during next major version |
|
247 | + return EED_Ticket_Selector::ticketSelector()->displayViewDetailsButton(); |
|
248 | + } |
|
249 | + |
|
250 | + |
|
251 | + |
|
252 | + /** |
|
253 | + * @deprecated |
|
254 | + * @return string |
|
255 | + * @throws \EE_Error |
|
256 | + */ |
|
257 | + public static function display_ticket_selector_submit() |
|
258 | + { |
|
259 | + // todo add doing_it_wrong() notice during next major version |
|
260 | + return EED_Ticket_Selector::ticketSelector()->displaySubmitButton(); |
|
261 | + } |
|
262 | + |
|
263 | + |
|
264 | + |
|
265 | + /** |
|
266 | + * @deprecated |
|
267 | + * @param string $permalink_string |
|
268 | + * @param int $id |
|
269 | + * @param string $new_title |
|
270 | + * @param string $new_slug |
|
271 | + * @return string |
|
272 | + */ |
|
273 | + public static function iframe_code_button($permalink_string, $id, $new_title = '', $new_slug = '') |
|
274 | + { |
|
275 | + // todo add doing_it_wrong() notice during next major version |
|
276 | + if ( |
|
277 | + \EE_Registry::instance()->REQ->get('page') === 'espresso_events' |
|
278 | + && \EE_Registry::instance()->REQ->get('action') === 'edit' |
|
279 | + ) { |
|
280 | + $iframe_embed_button = \EED_Ticket_Selector::getIframeEmbedButton(); |
|
281 | + $iframe_embed_button->addEventEditorIframeEmbedButton(); |
|
282 | + } |
|
283 | + return ''; |
|
284 | + } |
|
285 | + |
|
286 | + |
|
287 | + |
|
288 | + /** |
|
289 | + * @deprecated |
|
290 | + * @param int $ID |
|
291 | + * @param string $external_url |
|
292 | + * @return string |
|
293 | + */ |
|
294 | + public static function ticket_selector_form_open($ID = 0, $external_url = '') |
|
295 | + { |
|
296 | + // todo add doing_it_wrong() notice during next major version |
|
297 | + return EED_Ticket_Selector::ticketSelector()->formOpen($ID, $external_url); |
|
298 | + } |
|
299 | + |
|
300 | + |
|
301 | + |
|
302 | + /** |
|
303 | + * @deprecated |
|
304 | + * @return string |
|
305 | + */ |
|
306 | + public static function ticket_selector_form_close() |
|
307 | + { |
|
308 | + // todo add doing_it_wrong() notice during next major version |
|
309 | + return EED_Ticket_Selector::ticketSelector()->formClose(); |
|
310 | + } |
|
311 | + |
|
312 | + |
|
313 | + |
|
314 | + /** |
|
315 | + * @deprecated |
|
316 | + * @return string |
|
317 | + */ |
|
318 | + public static function no_tkt_slctr_end_dv() |
|
319 | + { |
|
320 | + // todo add doing_it_wrong() notice during next major version |
|
321 | + return EED_Ticket_Selector::ticketSelector()->ticketSelectorEndDiv(); |
|
322 | + } |
|
323 | + |
|
324 | + |
|
325 | + |
|
326 | + /** |
|
327 | + * @deprecated 4.9.13 |
|
328 | + * @return string |
|
329 | + */ |
|
330 | + public static function tkt_slctr_end_dv() |
|
331 | + { |
|
332 | + return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
333 | + } |
|
334 | + |
|
335 | + |
|
336 | + |
|
337 | + /** |
|
338 | + * @deprecated |
|
339 | + * @return string |
|
340 | + */ |
|
341 | + public static function clear_tkt_slctr() |
|
342 | + { |
|
343 | + return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
344 | + } |
|
345 | + |
|
346 | + |
|
347 | + |
|
348 | + /** |
|
349 | + * @deprecated |
|
350 | + */ |
|
351 | + public static function load_tckt_slctr_assets_admin() |
|
352 | + { |
|
353 | + // todo add doing_it_wrong() notice during next major version |
|
354 | + if ( |
|
355 | + \EE_Registry::instance()->REQ->get( 'page' ) === 'espresso_events' |
|
356 | + && \EE_Registry::instance()->REQ->get( 'action' ) === 'edit' |
|
357 | + ) { |
|
358 | + $iframe_embed_button = \EED_Ticket_Selector::getIframeEmbedButton(); |
|
359 | + $iframe_embed_button->embedButtonAssets(); |
|
360 | + } |
|
361 | + } |
|
362 | 362 | |
363 | 363 | |
364 | 364 | } |
@@ -3,8 +3,8 @@ discard block |
||
3 | 3 | use EventEspresso\modules\ticket_selector\TicketSelectorIframe; |
4 | 4 | use EventEspresso\modules\ticket_selector\TicketSelectorIframeEmbedButton; |
5 | 5 | |
6 | -if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) { |
|
7 | - exit( 'No direct script access allowed' ); |
|
6 | +if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
|
7 | + exit('No direct script access allowed'); |
|
8 | 8 | } |
9 | 9 | |
10 | 10 | |
@@ -38,15 +38,15 @@ discard block |
||
38 | 38 | * @return EED_Ticket_Selector |
39 | 39 | */ |
40 | 40 | public static function instance() { |
41 | - return parent::get_instance( __CLASS__ ); |
|
41 | + return parent::get_instance(__CLASS__); |
|
42 | 42 | } |
43 | 43 | |
44 | 44 | |
45 | 45 | |
46 | - protected function set_config(){ |
|
47 | - $this->set_config_section( 'template_settings' ); |
|
48 | - $this->set_config_class( 'EE_Ticket_Selector_Config' ); |
|
49 | - $this->set_config_name( 'EED_Ticket_Selector' ); |
|
46 | + protected function set_config() { |
|
47 | + $this->set_config_section('template_settings'); |
|
48 | + $this->set_config_class('EE_Ticket_Selector_Config'); |
|
49 | + $this->set_config_name('EED_Ticket_Selector'); |
|
50 | 50 | } |
51 | 51 | |
52 | 52 | |
@@ -59,12 +59,12 @@ discard block |
||
59 | 59 | */ |
60 | 60 | public static function set_hooks() { |
61 | 61 | // routing |
62 | - EE_Config::register_route( 'iframe', 'EED_Ticket_Selector', 'ticket_selector_iframe', 'ticket_selector' ); |
|
63 | - EE_Config::register_route( 'process_ticket_selections', 'EED_Ticket_Selector', 'process_ticket_selections' ); |
|
62 | + EE_Config::register_route('iframe', 'EED_Ticket_Selector', 'ticket_selector_iframe', 'ticket_selector'); |
|
63 | + EE_Config::register_route('process_ticket_selections', 'EED_Ticket_Selector', 'process_ticket_selections'); |
|
64 | 64 | EE_Config::register_route('cancel_ticket_selections', 'EED_Ticket_Selector', 'cancel_ticket_selections'); |
65 | - add_action( 'wp_loaded', array( 'EED_Ticket_Selector', 'set_definitions' ), 2 ); |
|
66 | - add_action( 'AHEE_event_details_header_bottom', array( 'EED_Ticket_Selector', 'display_ticket_selector' ), 10, 1 ); |
|
67 | - add_action( 'wp_enqueue_scripts', array( 'EED_Ticket_Selector', 'load_tckt_slctr_assets' ), 10 ); |
|
65 | + add_action('wp_loaded', array('EED_Ticket_Selector', 'set_definitions'), 2); |
|
66 | + add_action('AHEE_event_details_header_bottom', array('EED_Ticket_Selector', 'display_ticket_selector'), 10, 1); |
|
67 | + add_action('wp_enqueue_scripts', array('EED_Ticket_Selector', 'load_tckt_slctr_assets'), 10); |
|
68 | 68 | } |
69 | 69 | |
70 | 70 | |
@@ -80,7 +80,7 @@ discard block |
||
80 | 80 | // to load assets for "espresso_events" page on the "edit" route (action) |
81 | 81 | add_action( |
82 | 82 | 'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_events__edit', |
83 | - array( 'EED_Ticket_Selector', 'ticket_selector_iframe_embed_button' ), |
|
83 | + array('EED_Ticket_Selector', 'ticket_selector_iframe_embed_button'), |
|
84 | 84 | 10 |
85 | 85 | ); |
86 | 86 | } |
@@ -94,11 +94,11 @@ discard block |
||
94 | 94 | * @return void |
95 | 95 | */ |
96 | 96 | public static function set_definitions() { |
97 | - define( 'TICKET_SELECTOR_ASSETS_URL', plugin_dir_url( __FILE__ ) . 'assets' . DS ); |
|
98 | - define( 'TICKET_SELECTOR_TEMPLATES_PATH', str_replace( '\\', DS, plugin_dir_path( __FILE__ )) . 'templates' . DS ); |
|
97 | + define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__).'assets'.DS); |
|
98 | + define('TICKET_SELECTOR_TEMPLATES_PATH', str_replace('\\', DS, plugin_dir_path(__FILE__)).'templates'.DS); |
|
99 | 99 | |
100 | 100 | //if config is not set, initialize |
101 | - if ( ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config ) { |
|
101 | + if ( ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config) { |
|
102 | 102 | \EED_Ticket_Selector::instance()->set_config(); |
103 | 103 | \EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector = \EED_Ticket_Selector::instance()->config(); |
104 | 104 | } |
@@ -125,7 +125,7 @@ discard block |
||
125 | 125 | * @param WP $WP |
126 | 126 | * @return void |
127 | 127 | */ |
128 | - public function run( $WP ) {} |
|
128 | + public function run($WP) {} |
|
129 | 129 | |
130 | 130 | |
131 | 131 | |
@@ -133,7 +133,7 @@ discard block |
||
133 | 133 | * @return \EventEspresso\modules\ticket_selector\TicketSelectorIframeEmbedButton |
134 | 134 | */ |
135 | 135 | public static function getIframeEmbedButton() { |
136 | - if ( ! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton ) { |
|
136 | + if ( ! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) { |
|
137 | 137 | self::$iframe_embed_button = new TicketSelectorIframeEmbedButton(); |
138 | 138 | } |
139 | 139 | return self::$iframe_embed_button; |
@@ -177,8 +177,8 @@ discard block |
||
177 | 177 | * @return string |
178 | 178 | * @throws \EE_Error |
179 | 179 | */ |
180 | - public static function display_ticket_selector( $event = NULL, $view_details = FALSE ) { |
|
181 | - return EED_Ticket_Selector::ticketSelector()->display( $event, $view_details ); |
|
180 | + public static function display_ticket_selector($event = NULL, $view_details = FALSE) { |
|
181 | + return EED_Ticket_Selector::ticketSelector()->display($event, $view_details); |
|
182 | 182 | } |
183 | 183 | |
184 | 184 | |
@@ -218,14 +218,14 @@ discard block |
||
218 | 218 | * @return void |
219 | 219 | */ |
220 | 220 | public static function load_tckt_slctr_assets() { |
221 | - if ( apply_filters( 'FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', FALSE ) ) { |
|
221 | + if (apply_filters('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', FALSE)) { |
|
222 | 222 | // add some style |
223 | - wp_register_style('ticket_selector', TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css'); |
|
223 | + wp_register_style('ticket_selector', TICKET_SELECTOR_ASSETS_URL.'ticket_selector.css'); |
|
224 | 224 | wp_enqueue_style('ticket_selector'); |
225 | 225 | // make it dance |
226 | - wp_register_script('ticket_selector', TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js', array('espresso_core'), '', TRUE); |
|
226 | + wp_register_script('ticket_selector', TICKET_SELECTOR_ASSETS_URL.'ticket_selector.js', array('espresso_core'), '', TRUE); |
|
227 | 227 | wp_enqueue_script('ticket_selector'); |
228 | - require_once( EE_LIBRARIES.'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php'); |
|
228 | + require_once(EE_LIBRARIES.'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php'); |
|
229 | 229 | \EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts(); |
230 | 230 | } |
231 | 231 | } |
@@ -352,8 +352,8 @@ discard block |
||
352 | 352 | { |
353 | 353 | // todo add doing_it_wrong() notice during next major version |
354 | 354 | if ( |
355 | - \EE_Registry::instance()->REQ->get( 'page' ) === 'espresso_events' |
|
356 | - && \EE_Registry::instance()->REQ->get( 'action' ) === 'edit' |
|
355 | + \EE_Registry::instance()->REQ->get('page') === 'espresso_events' |
|
356 | + && \EE_Registry::instance()->REQ->get('action') === 'edit' |
|
357 | 357 | ) { |
358 | 358 | $iframe_embed_button = \EED_Ticket_Selector::getIframeEmbedButton(); |
359 | 359 | $iframe_embed_button->embedButtonAssets(); |
@@ -32,7 +32,7 @@ discard block |
||
32 | 32 | /** |
33 | 33 | * cancelTicketSelections |
34 | 34 | * |
35 | - * @return string |
|
35 | + * @return false|null |
|
36 | 36 | */ |
37 | 37 | public function cancelTicketSelections() |
38 | 38 | { |
@@ -99,7 +99,7 @@ discard block |
||
99 | 99 | /** |
100 | 100 | * process_ticket_selections |
101 | 101 | * |
102 | - * @return array|bool |
|
102 | + * @return boolean|null |
|
103 | 103 | * @throws \EE_Error |
104 | 104 | */ |
105 | 105 | public function processTicketSelections() |
@@ -273,7 +273,7 @@ discard block |
||
273 | 273 | * validate_post_data |
274 | 274 | * |
275 | 275 | * @param int $id |
276 | - * @return array|FALSE |
|
276 | + * @return string |
|
277 | 277 | */ |
278 | 278 | private function validatePostData($id = 0) |
279 | 279 | { |
@@ -390,7 +390,7 @@ discard block |
||
390 | 390 | * |
391 | 391 | * @param \EE_Ticket $ticket |
392 | 392 | * @param int $qty |
393 | - * @return TRUE on success, FALSE on fail |
|
393 | + * @return boolean on success, FALSE on fail |
|
394 | 394 | * @throws \EE_Error |
395 | 395 | */ |
396 | 396 | private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1) |
@@ -2,7 +2,7 @@ discard block |
||
2 | 2 | namespace EventEspresso\modules\ticket_selector; |
3 | 3 | |
4 | 4 | if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
5 | - exit('No direct script access allowed'); |
|
5 | + exit('No direct script access allowed'); |
|
6 | 6 | } |
7 | 7 | |
8 | 8 | |
@@ -19,574 +19,574 @@ discard block |
||
19 | 19 | class ProcessTicketSelector |
20 | 20 | { |
21 | 21 | |
22 | - /** |
|
23 | - * array of datetimes and the spaces available for them |
|
24 | - * |
|
25 | - * @access private |
|
26 | - * @var array |
|
27 | - */ |
|
28 | - private static $_available_spaces = array(); |
|
29 | - |
|
30 | - |
|
31 | - |
|
32 | - /** |
|
33 | - * cancelTicketSelections |
|
34 | - * |
|
35 | - * @return string |
|
36 | - */ |
|
37 | - public function cancelTicketSelections() |
|
38 | - { |
|
39 | - // check nonce |
|
40 | - if ( ! $this->processTicketSelectorNonce('cancel_ticket_selections')) { |
|
41 | - return false; |
|
42 | - } |
|
43 | - \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
44 | - if (\EE_Registry::instance()->REQ->is_set('event_id')) { |
|
45 | - wp_safe_redirect( |
|
46 | - \EEH_Event_View::event_link_url( |
|
47 | - \EE_Registry::instance()->REQ->get('event_id') |
|
48 | - ) |
|
49 | - ); |
|
50 | - } else { |
|
51 | - wp_safe_redirect( |
|
52 | - site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/') |
|
53 | - ); |
|
54 | - } |
|
55 | - exit(); |
|
56 | - } |
|
57 | - |
|
58 | - |
|
59 | - |
|
60 | - /** |
|
61 | - * processTicketSelectorNonce |
|
62 | - * |
|
63 | - * @param string $nonce_name |
|
64 | - * @param string $id |
|
65 | - * @return bool |
|
66 | - */ |
|
67 | - private function processTicketSelectorNonce($nonce_name, $id = '') |
|
68 | - { |
|
69 | - $nonce_name_with_id = ! empty($id) ? "{$nonce_name}_nonce_{$id}" : "{$nonce_name}_nonce"; |
|
70 | - if ( |
|
71 | - ! is_admin() |
|
72 | - && ( |
|
73 | - ! \EE_Registry::instance()->REQ->is_set($nonce_name_with_id) |
|
74 | - || ! wp_verify_nonce( |
|
75 | - \EE_Registry::instance()->REQ->get($nonce_name_with_id), |
|
76 | - $nonce_name |
|
77 | - ) |
|
78 | - ) |
|
79 | - ) { |
|
80 | - \EE_Error::add_error( |
|
81 | - sprintf( |
|
82 | - __( |
|
83 | - 'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.', |
|
84 | - 'event_espresso' |
|
85 | - ), |
|
86 | - '<br/>' |
|
87 | - ), |
|
88 | - __FILE__, |
|
89 | - __FUNCTION__, |
|
90 | - __LINE__ |
|
91 | - ); |
|
92 | - return false; |
|
93 | - } |
|
94 | - return true; |
|
95 | - } |
|
96 | - |
|
97 | - |
|
98 | - |
|
99 | - /** |
|
100 | - * process_ticket_selections |
|
101 | - * |
|
102 | - * @return array|bool |
|
103 | - * @throws \EE_Error |
|
104 | - */ |
|
105 | - public function processTicketSelections() |
|
106 | - { |
|
107 | - do_action('EED_Ticket_Selector__process_ticket_selections__before'); |
|
108 | - // do we have an event id? |
|
109 | - if ( ! \EE_Registry::instance()->REQ->is_set('tkt-slctr-event-id')) { |
|
110 | - // $_POST['tkt-slctr-event-id'] was not set ?!?!?!? |
|
111 | - \EE_Error::add_error( |
|
112 | - sprintf( |
|
113 | - __( |
|
114 | - 'An event id was not provided or was not received.%sPlease click the back button on your browser and try again.', |
|
115 | - 'event_espresso' |
|
116 | - ), |
|
117 | - '<br/>' |
|
118 | - ), |
|
119 | - __FILE__, |
|
120 | - __FUNCTION__, |
|
121 | - __LINE__ |
|
122 | - ); |
|
123 | - } |
|
124 | - //if event id is valid |
|
125 | - $id = absint(\EE_Registry::instance()->REQ->get('tkt-slctr-event-id')); |
|
126 | - // check nonce |
|
127 | - if ( ! $this->processTicketSelectorNonce('process_ticket_selections', $id)) { |
|
128 | - return false; |
|
129 | - } |
|
130 | - // d( \EE_Registry::instance()->REQ ); |
|
131 | - self::$_available_spaces = array( |
|
132 | - 'tickets' => array(), |
|
133 | - 'datetimes' => array(), |
|
134 | - ); |
|
135 | - //we should really only have 1 registration in the works now (ie, no MER) so clear any previous items in the cart. |
|
136 | - // When MER happens this will probably need to be tweaked, possibly wrapped in a conditional checking for some constant defined in MER etc. |
|
137 | - \EE_Registry::instance()->load_core('Session'); |
|
138 | - // unless otherwise requested, clear the session |
|
139 | - if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) { |
|
140 | - \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
141 | - } |
|
142 | - //d( \EE_Registry::instance()->SSN ); |
|
143 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
144 | - // validate/sanitize data |
|
145 | - $valid = $this->validatePostData($id); |
|
146 | - //EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
147 | - //EEH_Debug_Tools::printr( $valid, '$valid', __FILE__, __LINE__ ); |
|
148 | - //EEH_Debug_Tools::printr( $valid[ 'total_tickets' ], 'total_tickets', __FILE__, __LINE__ ); |
|
149 | - //EEH_Debug_Tools::printr( $valid[ 'max_atndz' ], 'max_atndz', __FILE__, __LINE__ ); |
|
150 | - //check total tickets ordered vs max number of attendees that can register |
|
151 | - if ($valid['total_tickets'] > $valid['max_atndz']) { |
|
152 | - // ordering too many tickets !!! |
|
153 | - $total_tickets_string = _n( |
|
154 | - 'You have attempted to purchase %s ticket.', |
|
155 | - 'You have attempted to purchase %s tickets.', |
|
156 | - $valid['total_tickets'], |
|
157 | - 'event_espresso' |
|
158 | - ); |
|
159 | - $limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']); |
|
160 | - // dev only message |
|
161 | - $max_atndz_string = _n( |
|
162 | - 'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
163 | - 'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
164 | - $valid['max_atndz'], |
|
165 | - 'event_espresso' |
|
166 | - ); |
|
167 | - $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']); |
|
168 | - \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__); |
|
169 | - } else { |
|
170 | - // all data appears to be valid |
|
171 | - $tckts_slctd = false; |
|
172 | - $tickets_added = 0; |
|
173 | - $valid = apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data', $valid); |
|
174 | - if ($valid['total_tickets'] > 0) { |
|
175 | - // load cart |
|
176 | - \EE_Registry::instance()->load_core('Cart'); |
|
177 | - // cycle thru the number of data rows sent from the event listing |
|
178 | - for ($x = 0; $x < $valid['rows']; $x++) { |
|
179 | - // does this row actually contain a ticket quantity? |
|
180 | - if (isset($valid['qty'][$x]) && $valid['qty'][$x] > 0) { |
|
181 | - // YES we have a ticket quantity |
|
182 | - $tckts_slctd = true; |
|
183 | - // d( $valid['ticket_obj'][$x] ); |
|
184 | - if ($valid['ticket_obj'][$x] instanceof \EE_Ticket) { |
|
185 | - // then add ticket to cart |
|
186 | - $tickets_added += $this->addTicketToCart( |
|
187 | - $valid['ticket_obj'][$x], |
|
188 | - $valid['qty'][$x] |
|
189 | - ); |
|
190 | - if (\EE_Error::has_error()) { |
|
191 | - break; |
|
192 | - } |
|
193 | - } else { |
|
194 | - // nothing added to cart retrieved |
|
195 | - \EE_Error::add_error( |
|
196 | - sprintf( |
|
197 | - __( |
|
198 | - 'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.', |
|
199 | - 'event_espresso' |
|
200 | - ), |
|
201 | - '<br/>' |
|
202 | - ), |
|
203 | - __FILE__, __FUNCTION__, __LINE__ |
|
204 | - ); |
|
205 | - } |
|
206 | - } |
|
207 | - } |
|
208 | - } |
|
209 | - do_action( |
|
210 | - 'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart', |
|
211 | - \EE_Registry::instance()->CART, |
|
212 | - $this |
|
213 | - ); |
|
214 | - //d( \EE_Registry::instance()->CART ); |
|
215 | - //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE |
|
216 | - if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tckts_slctd)) { |
|
217 | - if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) { |
|
218 | - do_action( |
|
219 | - 'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout', |
|
220 | - \EE_Registry::instance()->CART, |
|
221 | - $this |
|
222 | - ); |
|
223 | - \EE_Registry::instance()->CART->recalculate_all_cart_totals(); |
|
224 | - \EE_Registry::instance()->CART->save_cart(false); |
|
225 | - // exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<< OR HERE TO KILL REDIRECT AFTER CART UPDATE |
|
226 | - // just return TRUE for registrations being made from admin |
|
227 | - if (is_admin()) { |
|
228 | - return true; |
|
229 | - } |
|
230 | - \EE_Error::get_notices(false, true); |
|
231 | - wp_safe_redirect( |
|
232 | - apply_filters( |
|
233 | - 'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url', |
|
234 | - \EE_Registry::instance()->CFG->core->reg_page_url() |
|
235 | - ) |
|
236 | - ); |
|
237 | - exit(); |
|
238 | - } else { |
|
239 | - if ( ! \EE_Error::has_error() && ! \EE_Error::has_error(true, 'attention')) { |
|
240 | - // nothing added to cart |
|
241 | - \EE_Error::add_attention(__('No tickets were added for the event', 'event_espresso'), |
|
242 | - __FILE__, __FUNCTION__, __LINE__); |
|
243 | - } |
|
244 | - } |
|
245 | - } else { |
|
246 | - // no ticket quantities were selected |
|
247 | - \EE_Error::add_error(__('You need to select a ticket quantity before you can proceed.', |
|
248 | - 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
249 | - } |
|
250 | - } |
|
251 | - //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT |
|
252 | - // at this point, just return if registration is being made from admin |
|
253 | - if (is_admin()) { |
|
254 | - return false; |
|
255 | - } |
|
256 | - if ($valid['return_url']) { |
|
257 | - \EE_Error::get_notices(false, true); |
|
258 | - wp_safe_redirect($valid['return_url']); |
|
259 | - exit(); |
|
260 | - } elseif (isset($event_to_add['id'])) { |
|
261 | - \EE_Error::get_notices(false, true); |
|
262 | - wp_safe_redirect(get_permalink($event_to_add['id'])); |
|
263 | - exit(); |
|
264 | - } else { |
|
265 | - echo \EE_Error::get_notices(); |
|
266 | - } |
|
267 | - return false; |
|
268 | - } |
|
269 | - |
|
270 | - |
|
271 | - |
|
272 | - /** |
|
273 | - * validate_post_data |
|
274 | - * |
|
275 | - * @param int $id |
|
276 | - * @return array|FALSE |
|
277 | - */ |
|
278 | - private function validatePostData($id = 0) |
|
279 | - { |
|
280 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
281 | - if ( ! $id) { |
|
282 | - \EE_Error::add_error( |
|
283 | - __('The event id provided was not valid.', 'event_espresso'), |
|
284 | - __FILE__, |
|
285 | - __FUNCTION__, |
|
286 | - __LINE__ |
|
287 | - ); |
|
288 | - return false; |
|
289 | - } |
|
290 | - // start with an empty array() |
|
291 | - $valid_data = array(); |
|
292 | - // grab valid id |
|
293 | - $valid_data['id'] = $id; |
|
294 | - // array of other form names |
|
295 | - $inputs_to_clean = array( |
|
296 | - 'event_id' => 'tkt-slctr-event-id', |
|
297 | - 'max_atndz' => 'tkt-slctr-max-atndz-', |
|
298 | - 'rows' => 'tkt-slctr-rows-', |
|
299 | - 'qty' => 'tkt-slctr-qty-', |
|
300 | - 'ticket_id' => 'tkt-slctr-ticket-id-', |
|
301 | - 'return_url' => 'tkt-slctr-return-url-', |
|
302 | - ); |
|
303 | - // let's track the total number of tickets ordered.' |
|
304 | - $valid_data['total_tickets'] = 0; |
|
305 | - // cycle through $inputs_to_clean array |
|
306 | - foreach ($inputs_to_clean as $what => $input_to_clean) { |
|
307 | - // check for POST data |
|
308 | - if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) { |
|
309 | - // grab value |
|
310 | - $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id); |
|
311 | - switch ($what) { |
|
312 | - // integers |
|
313 | - case 'event_id': |
|
314 | - $valid_data[$what] = absint($input_value); |
|
315 | - // get event via the event id we put in the form |
|
316 | - $valid_data['event'] = \EE_Registry::instance() |
|
317 | - ->load_model('Event') |
|
318 | - ->get_one_by_ID($valid_data['event_id']); |
|
319 | - break; |
|
320 | - case 'rows': |
|
321 | - case 'max_atndz': |
|
322 | - $valid_data[$what] = absint($input_value); |
|
323 | - break; |
|
324 | - // arrays of integers |
|
325 | - case 'qty': |
|
326 | - /** @var array $row_qty */ |
|
327 | - $row_qty = $input_value; |
|
328 | - // if qty is coming from a radio button input, then we need to assemble an array of rows |
|
329 | - if ( ! is_array($row_qty)) { |
|
330 | - // get number of rows |
|
331 | - $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id) |
|
332 | - ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id)) |
|
333 | - : 1; |
|
334 | - // explode ints by the dash |
|
335 | - $row_qty = explode('-', $row_qty); |
|
336 | - $row = isset($row_qty[0]) ? absint($row_qty[0]) : 1; |
|
337 | - $qty = isset($row_qty[1]) ? absint($row_qty[1]) : 0; |
|
338 | - $row_qty = array($row => $qty); |
|
339 | - for ($x = 1; $x <= $rows; $x++) { |
|
340 | - if ( ! isset($row_qty[$x])) { |
|
341 | - $row_qty[$x] = 0; |
|
342 | - } |
|
343 | - } |
|
344 | - } |
|
345 | - ksort($row_qty); |
|
346 | - // cycle thru values |
|
347 | - foreach ($row_qty as $qty) { |
|
348 | - $qty = absint($qty); |
|
349 | - // sanitize as integers |
|
350 | - $valid_data[$what][] = $qty; |
|
351 | - $valid_data['total_tickets'] += $qty; |
|
352 | - } |
|
353 | - break; |
|
354 | - // array of integers |
|
355 | - case 'ticket_id': |
|
356 | - $value_array = array(); |
|
357 | - // cycle thru values |
|
358 | - foreach ((array)$input_value as $key => $value) { |
|
359 | - // allow only numbers, letters, spaces, commas and dashes |
|
360 | - $value_array[$key] = wp_strip_all_tags($value); |
|
361 | - // get ticket via the ticket id we put in the form |
|
362 | - $ticket_obj = \EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($value); |
|
363 | - $valid_data['ticket_obj'][$key] = $ticket_obj; |
|
364 | - } |
|
365 | - $valid_data[$what] = $value_array; |
|
366 | - break; |
|
367 | - case 'return_url' : |
|
368 | - // grab and sanitize return-url |
|
369 | - $input_value = esc_url_raw($input_value); |
|
370 | - // was the request coming from an iframe ? if so, then: |
|
371 | - if (strpos($input_value, 'event_list=iframe')) { |
|
372 | - // get anchor fragment |
|
373 | - $input_value = explode('#', $input_value); |
|
374 | - $input_value = end($input_value); |
|
375 | - // use event list url instead, but append anchor |
|
376 | - $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value; |
|
377 | - } |
|
378 | - $valid_data[$what] = $input_value; |
|
379 | - break; |
|
380 | - } // end switch $what |
|
381 | - } |
|
382 | - } // end foreach $inputs_to_clean |
|
383 | - return $valid_data; |
|
384 | - } |
|
385 | - |
|
386 | - |
|
387 | - |
|
388 | - /** |
|
389 | - * adds a ticket to the cart |
|
390 | - * |
|
391 | - * @param \EE_Ticket $ticket |
|
392 | - * @param int $qty |
|
393 | - * @return TRUE on success, FALSE on fail |
|
394 | - * @throws \EE_Error |
|
395 | - */ |
|
396 | - private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1) |
|
397 | - { |
|
398 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
399 | - // get the number of spaces left for this datetime ticket |
|
400 | - $available_spaces = $this->ticketDatetimeAvailability($ticket); |
|
401 | - // compare available spaces against the number of tickets being purchased |
|
402 | - if ($available_spaces >= $qty) { |
|
403 | - // allow addons to prevent a ticket from being added to cart |
|
404 | - if ( |
|
405 | - ! apply_filters( |
|
406 | - 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart', |
|
407 | - true, |
|
408 | - $ticket, |
|
409 | - $qty, |
|
410 | - $available_spaces |
|
411 | - ) |
|
412 | - ) { |
|
413 | - return false; |
|
414 | - } |
|
415 | - $qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket)); |
|
416 | - // add event to cart |
|
417 | - if (\EE_Registry::instance()->CART->add_ticket_to_cart($ticket, $qty)) { |
|
418 | - $this->recalculateTicketDatetimeAvailability($ticket, $qty); |
|
419 | - return true; |
|
420 | - } |
|
421 | - return false; |
|
422 | - } |
|
423 | - // tickets can not be purchased but let's find the exact number left |
|
424 | - // for the last ticket selected PRIOR to subtracting tickets |
|
425 | - $available_spaces = $this->ticketDatetimeAvailability($ticket, true); |
|
426 | - // greedy greedy greedy eh? |
|
427 | - if ($available_spaces > 0) { |
|
428 | - if ( |
|
429 | - apply_filters( |
|
430 | - 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_display_availability_error', |
|
431 | - true, |
|
432 | - $ticket, |
|
433 | - $qty, |
|
434 | - $available_spaces |
|
435 | - ) |
|
436 | - ) { |
|
437 | - $this->displayAvailabilityError($available_spaces); |
|
438 | - } |
|
439 | - } else { |
|
440 | - \EE_Error::add_error( |
|
441 | - __( |
|
442 | - 'We\'re sorry, but there are no available spaces left for this event at this particular date and time.', |
|
443 | - 'event_espresso' |
|
444 | - ), |
|
445 | - __FILE__, __FUNCTION__, __LINE__ |
|
446 | - ); |
|
447 | - } |
|
448 | - return false; |
|
449 | - } |
|
450 | - |
|
451 | - |
|
452 | - |
|
453 | - /** |
|
454 | - * @param int $available_spaces |
|
455 | - * @throws \EE_Error |
|
456 | - */ |
|
457 | - private function displayAvailabilityError($available_spaces = 1) |
|
458 | - { |
|
459 | - // add error messaging - we're using the _n function that will generate |
|
460 | - // the appropriate singular or plural message based on the number of $available_spaces |
|
461 | - if (\EE_Registry::instance()->CART->all_ticket_quantity_count()) { |
|
462 | - $msg = sprintf( |
|
463 | - _n( |
|
464 | - 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
465 | - 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
466 | - $available_spaces, |
|
467 | - 'event_espresso' |
|
468 | - ), |
|
469 | - $available_spaces, |
|
470 | - '<br />' |
|
471 | - ); |
|
472 | - } else { |
|
473 | - $msg = sprintf( |
|
474 | - _n( |
|
475 | - 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
476 | - 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
477 | - $available_spaces, |
|
478 | - 'event_espresso' |
|
479 | - ), |
|
480 | - $available_spaces, |
|
481 | - '<br />' |
|
482 | - ); |
|
483 | - } |
|
484 | - \EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
485 | - } |
|
486 | - |
|
487 | - |
|
488 | - |
|
489 | - /** |
|
490 | - * ticketDatetimeAvailability |
|
491 | - * creates an array of tickets plus all of the datetimes available to each ticket |
|
492 | - * and tracks the spaces remaining for each of those datetimes |
|
493 | - * |
|
494 | - * @param \EE_Ticket $ticket - selected ticket |
|
495 | - * @param bool $get_original_ticket_spaces |
|
496 | - * @return int |
|
497 | - * @throws \EE_Error |
|
498 | - */ |
|
499 | - private function ticketDatetimeAvailability(\EE_Ticket $ticket, $get_original_ticket_spaces = false) |
|
500 | - { |
|
501 | - // if the $_available_spaces array has not been set up yet... |
|
502 | - if ( ! isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
503 | - $this->setInitialTicketDatetimeAvailability($ticket); |
|
504 | - } |
|
505 | - $available_spaces = $ticket->qty() - $ticket->sold(); |
|
506 | - if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
507 | - // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
508 | - foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
509 | - // if we want the original datetime availability BEFORE we started subtracting tickets ? |
|
510 | - if ($get_original_ticket_spaces) { |
|
511 | - // then grab the available spaces from the "tickets" array |
|
512 | - // and compare with the above to get the lowest number |
|
513 | - $available_spaces = min( |
|
514 | - $available_spaces, |
|
515 | - self::$_available_spaces['tickets'][$ticket->ID()][$DTD_ID] |
|
516 | - ); |
|
517 | - } else { |
|
518 | - // we want the updated ticket availability as stored in the "datetimes" array |
|
519 | - $available_spaces = min($available_spaces, self::$_available_spaces['datetimes'][$DTD_ID]); |
|
520 | - } |
|
521 | - } |
|
522 | - } |
|
523 | - return $available_spaces; |
|
524 | - } |
|
525 | - |
|
526 | - |
|
527 | - |
|
528 | - /** |
|
529 | - * @param \EE_Ticket $ticket |
|
530 | - * @return void |
|
531 | - * @throws \EE_Error |
|
532 | - */ |
|
533 | - private function setInitialTicketDatetimeAvailability(\EE_Ticket $ticket) |
|
534 | - { |
|
535 | - // first, get all of the datetimes that are available to this ticket |
|
536 | - $datetimes = $ticket->get_many_related( |
|
537 | - 'Datetime', |
|
538 | - array( |
|
539 | - array( |
|
540 | - 'DTT_EVT_end' => array( |
|
541 | - '>=', |
|
542 | - \EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
543 | - ), |
|
544 | - ), |
|
545 | - 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
546 | - ) |
|
547 | - ); |
|
548 | - if ( ! empty($datetimes)) { |
|
549 | - // now loop thru all of the datetimes |
|
550 | - foreach ($datetimes as $datetime) { |
|
551 | - if ($datetime instanceof \EE_Datetime) { |
|
552 | - // the number of spaces available for the datetime without considering individual ticket quantities |
|
553 | - $spaces_remaining = $datetime->spaces_remaining(); |
|
554 | - // save the total available spaces ( the lesser of the ticket qty minus the number of tickets sold |
|
555 | - // or the datetime spaces remaining) to this ticket using the datetime ID as the key |
|
556 | - self::$_available_spaces['tickets'][$ticket->ID()][$datetime->ID()] = min( |
|
557 | - $ticket->qty() - $ticket->sold(), |
|
558 | - $spaces_remaining |
|
559 | - ); |
|
560 | - // if the remaining spaces for this datetime is already set, |
|
561 | - // then compare that against the datetime spaces remaining, and take the lowest number, |
|
562 | - // else just take the datetime spaces remaining, and assign to the datetimes array |
|
563 | - self::$_available_spaces['datetimes'][$datetime->ID()] = isset( |
|
564 | - self::$_available_spaces['datetimes'][$datetime->ID()] |
|
565 | - ) |
|
566 | - ? min(self::$_available_spaces['datetimes'][$datetime->ID()], $spaces_remaining) |
|
567 | - : $spaces_remaining; |
|
568 | - } |
|
569 | - } |
|
570 | - } |
|
571 | - } |
|
572 | - |
|
573 | - |
|
574 | - |
|
575 | - /** |
|
576 | - * @param \EE_Ticket $ticket |
|
577 | - * @param int $qty |
|
578 | - * @return void |
|
579 | - */ |
|
580 | - private function recalculateTicketDatetimeAvailability(\EE_Ticket $ticket, $qty = 0) |
|
581 | - { |
|
582 | - if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
583 | - // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
584 | - foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
585 | - // subtract the qty of selected tickets from each datetime's available spaces this ticket has access to, |
|
586 | - self::$_available_spaces['datetimes'][$DTD_ID] -= $qty; |
|
587 | - } |
|
588 | - } |
|
589 | - } |
|
22 | + /** |
|
23 | + * array of datetimes and the spaces available for them |
|
24 | + * |
|
25 | + * @access private |
|
26 | + * @var array |
|
27 | + */ |
|
28 | + private static $_available_spaces = array(); |
|
29 | + |
|
30 | + |
|
31 | + |
|
32 | + /** |
|
33 | + * cancelTicketSelections |
|
34 | + * |
|
35 | + * @return string |
|
36 | + */ |
|
37 | + public function cancelTicketSelections() |
|
38 | + { |
|
39 | + // check nonce |
|
40 | + if ( ! $this->processTicketSelectorNonce('cancel_ticket_selections')) { |
|
41 | + return false; |
|
42 | + } |
|
43 | + \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
44 | + if (\EE_Registry::instance()->REQ->is_set('event_id')) { |
|
45 | + wp_safe_redirect( |
|
46 | + \EEH_Event_View::event_link_url( |
|
47 | + \EE_Registry::instance()->REQ->get('event_id') |
|
48 | + ) |
|
49 | + ); |
|
50 | + } else { |
|
51 | + wp_safe_redirect( |
|
52 | + site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/') |
|
53 | + ); |
|
54 | + } |
|
55 | + exit(); |
|
56 | + } |
|
57 | + |
|
58 | + |
|
59 | + |
|
60 | + /** |
|
61 | + * processTicketSelectorNonce |
|
62 | + * |
|
63 | + * @param string $nonce_name |
|
64 | + * @param string $id |
|
65 | + * @return bool |
|
66 | + */ |
|
67 | + private function processTicketSelectorNonce($nonce_name, $id = '') |
|
68 | + { |
|
69 | + $nonce_name_with_id = ! empty($id) ? "{$nonce_name}_nonce_{$id}" : "{$nonce_name}_nonce"; |
|
70 | + if ( |
|
71 | + ! is_admin() |
|
72 | + && ( |
|
73 | + ! \EE_Registry::instance()->REQ->is_set($nonce_name_with_id) |
|
74 | + || ! wp_verify_nonce( |
|
75 | + \EE_Registry::instance()->REQ->get($nonce_name_with_id), |
|
76 | + $nonce_name |
|
77 | + ) |
|
78 | + ) |
|
79 | + ) { |
|
80 | + \EE_Error::add_error( |
|
81 | + sprintf( |
|
82 | + __( |
|
83 | + 'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.', |
|
84 | + 'event_espresso' |
|
85 | + ), |
|
86 | + '<br/>' |
|
87 | + ), |
|
88 | + __FILE__, |
|
89 | + __FUNCTION__, |
|
90 | + __LINE__ |
|
91 | + ); |
|
92 | + return false; |
|
93 | + } |
|
94 | + return true; |
|
95 | + } |
|
96 | + |
|
97 | + |
|
98 | + |
|
99 | + /** |
|
100 | + * process_ticket_selections |
|
101 | + * |
|
102 | + * @return array|bool |
|
103 | + * @throws \EE_Error |
|
104 | + */ |
|
105 | + public function processTicketSelections() |
|
106 | + { |
|
107 | + do_action('EED_Ticket_Selector__process_ticket_selections__before'); |
|
108 | + // do we have an event id? |
|
109 | + if ( ! \EE_Registry::instance()->REQ->is_set('tkt-slctr-event-id')) { |
|
110 | + // $_POST['tkt-slctr-event-id'] was not set ?!?!?!? |
|
111 | + \EE_Error::add_error( |
|
112 | + sprintf( |
|
113 | + __( |
|
114 | + 'An event id was not provided or was not received.%sPlease click the back button on your browser and try again.', |
|
115 | + 'event_espresso' |
|
116 | + ), |
|
117 | + '<br/>' |
|
118 | + ), |
|
119 | + __FILE__, |
|
120 | + __FUNCTION__, |
|
121 | + __LINE__ |
|
122 | + ); |
|
123 | + } |
|
124 | + //if event id is valid |
|
125 | + $id = absint(\EE_Registry::instance()->REQ->get('tkt-slctr-event-id')); |
|
126 | + // check nonce |
|
127 | + if ( ! $this->processTicketSelectorNonce('process_ticket_selections', $id)) { |
|
128 | + return false; |
|
129 | + } |
|
130 | + // d( \EE_Registry::instance()->REQ ); |
|
131 | + self::$_available_spaces = array( |
|
132 | + 'tickets' => array(), |
|
133 | + 'datetimes' => array(), |
|
134 | + ); |
|
135 | + //we should really only have 1 registration in the works now (ie, no MER) so clear any previous items in the cart. |
|
136 | + // When MER happens this will probably need to be tweaked, possibly wrapped in a conditional checking for some constant defined in MER etc. |
|
137 | + \EE_Registry::instance()->load_core('Session'); |
|
138 | + // unless otherwise requested, clear the session |
|
139 | + if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) { |
|
140 | + \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
141 | + } |
|
142 | + //d( \EE_Registry::instance()->SSN ); |
|
143 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
144 | + // validate/sanitize data |
|
145 | + $valid = $this->validatePostData($id); |
|
146 | + //EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
147 | + //EEH_Debug_Tools::printr( $valid, '$valid', __FILE__, __LINE__ ); |
|
148 | + //EEH_Debug_Tools::printr( $valid[ 'total_tickets' ], 'total_tickets', __FILE__, __LINE__ ); |
|
149 | + //EEH_Debug_Tools::printr( $valid[ 'max_atndz' ], 'max_atndz', __FILE__, __LINE__ ); |
|
150 | + //check total tickets ordered vs max number of attendees that can register |
|
151 | + if ($valid['total_tickets'] > $valid['max_atndz']) { |
|
152 | + // ordering too many tickets !!! |
|
153 | + $total_tickets_string = _n( |
|
154 | + 'You have attempted to purchase %s ticket.', |
|
155 | + 'You have attempted to purchase %s tickets.', |
|
156 | + $valid['total_tickets'], |
|
157 | + 'event_espresso' |
|
158 | + ); |
|
159 | + $limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']); |
|
160 | + // dev only message |
|
161 | + $max_atndz_string = _n( |
|
162 | + 'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
163 | + 'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
164 | + $valid['max_atndz'], |
|
165 | + 'event_espresso' |
|
166 | + ); |
|
167 | + $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']); |
|
168 | + \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__); |
|
169 | + } else { |
|
170 | + // all data appears to be valid |
|
171 | + $tckts_slctd = false; |
|
172 | + $tickets_added = 0; |
|
173 | + $valid = apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data', $valid); |
|
174 | + if ($valid['total_tickets'] > 0) { |
|
175 | + // load cart |
|
176 | + \EE_Registry::instance()->load_core('Cart'); |
|
177 | + // cycle thru the number of data rows sent from the event listing |
|
178 | + for ($x = 0; $x < $valid['rows']; $x++) { |
|
179 | + // does this row actually contain a ticket quantity? |
|
180 | + if (isset($valid['qty'][$x]) && $valid['qty'][$x] > 0) { |
|
181 | + // YES we have a ticket quantity |
|
182 | + $tckts_slctd = true; |
|
183 | + // d( $valid['ticket_obj'][$x] ); |
|
184 | + if ($valid['ticket_obj'][$x] instanceof \EE_Ticket) { |
|
185 | + // then add ticket to cart |
|
186 | + $tickets_added += $this->addTicketToCart( |
|
187 | + $valid['ticket_obj'][$x], |
|
188 | + $valid['qty'][$x] |
|
189 | + ); |
|
190 | + if (\EE_Error::has_error()) { |
|
191 | + break; |
|
192 | + } |
|
193 | + } else { |
|
194 | + // nothing added to cart retrieved |
|
195 | + \EE_Error::add_error( |
|
196 | + sprintf( |
|
197 | + __( |
|
198 | + 'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.', |
|
199 | + 'event_espresso' |
|
200 | + ), |
|
201 | + '<br/>' |
|
202 | + ), |
|
203 | + __FILE__, __FUNCTION__, __LINE__ |
|
204 | + ); |
|
205 | + } |
|
206 | + } |
|
207 | + } |
|
208 | + } |
|
209 | + do_action( |
|
210 | + 'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart', |
|
211 | + \EE_Registry::instance()->CART, |
|
212 | + $this |
|
213 | + ); |
|
214 | + //d( \EE_Registry::instance()->CART ); |
|
215 | + //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE |
|
216 | + if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tckts_slctd)) { |
|
217 | + if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) { |
|
218 | + do_action( |
|
219 | + 'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout', |
|
220 | + \EE_Registry::instance()->CART, |
|
221 | + $this |
|
222 | + ); |
|
223 | + \EE_Registry::instance()->CART->recalculate_all_cart_totals(); |
|
224 | + \EE_Registry::instance()->CART->save_cart(false); |
|
225 | + // exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<< OR HERE TO KILL REDIRECT AFTER CART UPDATE |
|
226 | + // just return TRUE for registrations being made from admin |
|
227 | + if (is_admin()) { |
|
228 | + return true; |
|
229 | + } |
|
230 | + \EE_Error::get_notices(false, true); |
|
231 | + wp_safe_redirect( |
|
232 | + apply_filters( |
|
233 | + 'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url', |
|
234 | + \EE_Registry::instance()->CFG->core->reg_page_url() |
|
235 | + ) |
|
236 | + ); |
|
237 | + exit(); |
|
238 | + } else { |
|
239 | + if ( ! \EE_Error::has_error() && ! \EE_Error::has_error(true, 'attention')) { |
|
240 | + // nothing added to cart |
|
241 | + \EE_Error::add_attention(__('No tickets were added for the event', 'event_espresso'), |
|
242 | + __FILE__, __FUNCTION__, __LINE__); |
|
243 | + } |
|
244 | + } |
|
245 | + } else { |
|
246 | + // no ticket quantities were selected |
|
247 | + \EE_Error::add_error(__('You need to select a ticket quantity before you can proceed.', |
|
248 | + 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
249 | + } |
|
250 | + } |
|
251 | + //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT |
|
252 | + // at this point, just return if registration is being made from admin |
|
253 | + if (is_admin()) { |
|
254 | + return false; |
|
255 | + } |
|
256 | + if ($valid['return_url']) { |
|
257 | + \EE_Error::get_notices(false, true); |
|
258 | + wp_safe_redirect($valid['return_url']); |
|
259 | + exit(); |
|
260 | + } elseif (isset($event_to_add['id'])) { |
|
261 | + \EE_Error::get_notices(false, true); |
|
262 | + wp_safe_redirect(get_permalink($event_to_add['id'])); |
|
263 | + exit(); |
|
264 | + } else { |
|
265 | + echo \EE_Error::get_notices(); |
|
266 | + } |
|
267 | + return false; |
|
268 | + } |
|
269 | + |
|
270 | + |
|
271 | + |
|
272 | + /** |
|
273 | + * validate_post_data |
|
274 | + * |
|
275 | + * @param int $id |
|
276 | + * @return array|FALSE |
|
277 | + */ |
|
278 | + private function validatePostData($id = 0) |
|
279 | + { |
|
280 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
281 | + if ( ! $id) { |
|
282 | + \EE_Error::add_error( |
|
283 | + __('The event id provided was not valid.', 'event_espresso'), |
|
284 | + __FILE__, |
|
285 | + __FUNCTION__, |
|
286 | + __LINE__ |
|
287 | + ); |
|
288 | + return false; |
|
289 | + } |
|
290 | + // start with an empty array() |
|
291 | + $valid_data = array(); |
|
292 | + // grab valid id |
|
293 | + $valid_data['id'] = $id; |
|
294 | + // array of other form names |
|
295 | + $inputs_to_clean = array( |
|
296 | + 'event_id' => 'tkt-slctr-event-id', |
|
297 | + 'max_atndz' => 'tkt-slctr-max-atndz-', |
|
298 | + 'rows' => 'tkt-slctr-rows-', |
|
299 | + 'qty' => 'tkt-slctr-qty-', |
|
300 | + 'ticket_id' => 'tkt-slctr-ticket-id-', |
|
301 | + 'return_url' => 'tkt-slctr-return-url-', |
|
302 | + ); |
|
303 | + // let's track the total number of tickets ordered.' |
|
304 | + $valid_data['total_tickets'] = 0; |
|
305 | + // cycle through $inputs_to_clean array |
|
306 | + foreach ($inputs_to_clean as $what => $input_to_clean) { |
|
307 | + // check for POST data |
|
308 | + if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) { |
|
309 | + // grab value |
|
310 | + $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id); |
|
311 | + switch ($what) { |
|
312 | + // integers |
|
313 | + case 'event_id': |
|
314 | + $valid_data[$what] = absint($input_value); |
|
315 | + // get event via the event id we put in the form |
|
316 | + $valid_data['event'] = \EE_Registry::instance() |
|
317 | + ->load_model('Event') |
|
318 | + ->get_one_by_ID($valid_data['event_id']); |
|
319 | + break; |
|
320 | + case 'rows': |
|
321 | + case 'max_atndz': |
|
322 | + $valid_data[$what] = absint($input_value); |
|
323 | + break; |
|
324 | + // arrays of integers |
|
325 | + case 'qty': |
|
326 | + /** @var array $row_qty */ |
|
327 | + $row_qty = $input_value; |
|
328 | + // if qty is coming from a radio button input, then we need to assemble an array of rows |
|
329 | + if ( ! is_array($row_qty)) { |
|
330 | + // get number of rows |
|
331 | + $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id) |
|
332 | + ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id)) |
|
333 | + : 1; |
|
334 | + // explode ints by the dash |
|
335 | + $row_qty = explode('-', $row_qty); |
|
336 | + $row = isset($row_qty[0]) ? absint($row_qty[0]) : 1; |
|
337 | + $qty = isset($row_qty[1]) ? absint($row_qty[1]) : 0; |
|
338 | + $row_qty = array($row => $qty); |
|
339 | + for ($x = 1; $x <= $rows; $x++) { |
|
340 | + if ( ! isset($row_qty[$x])) { |
|
341 | + $row_qty[$x] = 0; |
|
342 | + } |
|
343 | + } |
|
344 | + } |
|
345 | + ksort($row_qty); |
|
346 | + // cycle thru values |
|
347 | + foreach ($row_qty as $qty) { |
|
348 | + $qty = absint($qty); |
|
349 | + // sanitize as integers |
|
350 | + $valid_data[$what][] = $qty; |
|
351 | + $valid_data['total_tickets'] += $qty; |
|
352 | + } |
|
353 | + break; |
|
354 | + // array of integers |
|
355 | + case 'ticket_id': |
|
356 | + $value_array = array(); |
|
357 | + // cycle thru values |
|
358 | + foreach ((array)$input_value as $key => $value) { |
|
359 | + // allow only numbers, letters, spaces, commas and dashes |
|
360 | + $value_array[$key] = wp_strip_all_tags($value); |
|
361 | + // get ticket via the ticket id we put in the form |
|
362 | + $ticket_obj = \EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($value); |
|
363 | + $valid_data['ticket_obj'][$key] = $ticket_obj; |
|
364 | + } |
|
365 | + $valid_data[$what] = $value_array; |
|
366 | + break; |
|
367 | + case 'return_url' : |
|
368 | + // grab and sanitize return-url |
|
369 | + $input_value = esc_url_raw($input_value); |
|
370 | + // was the request coming from an iframe ? if so, then: |
|
371 | + if (strpos($input_value, 'event_list=iframe')) { |
|
372 | + // get anchor fragment |
|
373 | + $input_value = explode('#', $input_value); |
|
374 | + $input_value = end($input_value); |
|
375 | + // use event list url instead, but append anchor |
|
376 | + $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value; |
|
377 | + } |
|
378 | + $valid_data[$what] = $input_value; |
|
379 | + break; |
|
380 | + } // end switch $what |
|
381 | + } |
|
382 | + } // end foreach $inputs_to_clean |
|
383 | + return $valid_data; |
|
384 | + } |
|
385 | + |
|
386 | + |
|
387 | + |
|
388 | + /** |
|
389 | + * adds a ticket to the cart |
|
390 | + * |
|
391 | + * @param \EE_Ticket $ticket |
|
392 | + * @param int $qty |
|
393 | + * @return TRUE on success, FALSE on fail |
|
394 | + * @throws \EE_Error |
|
395 | + */ |
|
396 | + private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1) |
|
397 | + { |
|
398 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
399 | + // get the number of spaces left for this datetime ticket |
|
400 | + $available_spaces = $this->ticketDatetimeAvailability($ticket); |
|
401 | + // compare available spaces against the number of tickets being purchased |
|
402 | + if ($available_spaces >= $qty) { |
|
403 | + // allow addons to prevent a ticket from being added to cart |
|
404 | + if ( |
|
405 | + ! apply_filters( |
|
406 | + 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart', |
|
407 | + true, |
|
408 | + $ticket, |
|
409 | + $qty, |
|
410 | + $available_spaces |
|
411 | + ) |
|
412 | + ) { |
|
413 | + return false; |
|
414 | + } |
|
415 | + $qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket)); |
|
416 | + // add event to cart |
|
417 | + if (\EE_Registry::instance()->CART->add_ticket_to_cart($ticket, $qty)) { |
|
418 | + $this->recalculateTicketDatetimeAvailability($ticket, $qty); |
|
419 | + return true; |
|
420 | + } |
|
421 | + return false; |
|
422 | + } |
|
423 | + // tickets can not be purchased but let's find the exact number left |
|
424 | + // for the last ticket selected PRIOR to subtracting tickets |
|
425 | + $available_spaces = $this->ticketDatetimeAvailability($ticket, true); |
|
426 | + // greedy greedy greedy eh? |
|
427 | + if ($available_spaces > 0) { |
|
428 | + if ( |
|
429 | + apply_filters( |
|
430 | + 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_display_availability_error', |
|
431 | + true, |
|
432 | + $ticket, |
|
433 | + $qty, |
|
434 | + $available_spaces |
|
435 | + ) |
|
436 | + ) { |
|
437 | + $this->displayAvailabilityError($available_spaces); |
|
438 | + } |
|
439 | + } else { |
|
440 | + \EE_Error::add_error( |
|
441 | + __( |
|
442 | + 'We\'re sorry, but there are no available spaces left for this event at this particular date and time.', |
|
443 | + 'event_espresso' |
|
444 | + ), |
|
445 | + __FILE__, __FUNCTION__, __LINE__ |
|
446 | + ); |
|
447 | + } |
|
448 | + return false; |
|
449 | + } |
|
450 | + |
|
451 | + |
|
452 | + |
|
453 | + /** |
|
454 | + * @param int $available_spaces |
|
455 | + * @throws \EE_Error |
|
456 | + */ |
|
457 | + private function displayAvailabilityError($available_spaces = 1) |
|
458 | + { |
|
459 | + // add error messaging - we're using the _n function that will generate |
|
460 | + // the appropriate singular or plural message based on the number of $available_spaces |
|
461 | + if (\EE_Registry::instance()->CART->all_ticket_quantity_count()) { |
|
462 | + $msg = sprintf( |
|
463 | + _n( |
|
464 | + 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
465 | + 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
466 | + $available_spaces, |
|
467 | + 'event_espresso' |
|
468 | + ), |
|
469 | + $available_spaces, |
|
470 | + '<br />' |
|
471 | + ); |
|
472 | + } else { |
|
473 | + $msg = sprintf( |
|
474 | + _n( |
|
475 | + 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
476 | + 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
477 | + $available_spaces, |
|
478 | + 'event_espresso' |
|
479 | + ), |
|
480 | + $available_spaces, |
|
481 | + '<br />' |
|
482 | + ); |
|
483 | + } |
|
484 | + \EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
485 | + } |
|
486 | + |
|
487 | + |
|
488 | + |
|
489 | + /** |
|
490 | + * ticketDatetimeAvailability |
|
491 | + * creates an array of tickets plus all of the datetimes available to each ticket |
|
492 | + * and tracks the spaces remaining for each of those datetimes |
|
493 | + * |
|
494 | + * @param \EE_Ticket $ticket - selected ticket |
|
495 | + * @param bool $get_original_ticket_spaces |
|
496 | + * @return int |
|
497 | + * @throws \EE_Error |
|
498 | + */ |
|
499 | + private function ticketDatetimeAvailability(\EE_Ticket $ticket, $get_original_ticket_spaces = false) |
|
500 | + { |
|
501 | + // if the $_available_spaces array has not been set up yet... |
|
502 | + if ( ! isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
503 | + $this->setInitialTicketDatetimeAvailability($ticket); |
|
504 | + } |
|
505 | + $available_spaces = $ticket->qty() - $ticket->sold(); |
|
506 | + if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
507 | + // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
508 | + foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
509 | + // if we want the original datetime availability BEFORE we started subtracting tickets ? |
|
510 | + if ($get_original_ticket_spaces) { |
|
511 | + // then grab the available spaces from the "tickets" array |
|
512 | + // and compare with the above to get the lowest number |
|
513 | + $available_spaces = min( |
|
514 | + $available_spaces, |
|
515 | + self::$_available_spaces['tickets'][$ticket->ID()][$DTD_ID] |
|
516 | + ); |
|
517 | + } else { |
|
518 | + // we want the updated ticket availability as stored in the "datetimes" array |
|
519 | + $available_spaces = min($available_spaces, self::$_available_spaces['datetimes'][$DTD_ID]); |
|
520 | + } |
|
521 | + } |
|
522 | + } |
|
523 | + return $available_spaces; |
|
524 | + } |
|
525 | + |
|
526 | + |
|
527 | + |
|
528 | + /** |
|
529 | + * @param \EE_Ticket $ticket |
|
530 | + * @return void |
|
531 | + * @throws \EE_Error |
|
532 | + */ |
|
533 | + private function setInitialTicketDatetimeAvailability(\EE_Ticket $ticket) |
|
534 | + { |
|
535 | + // first, get all of the datetimes that are available to this ticket |
|
536 | + $datetimes = $ticket->get_many_related( |
|
537 | + 'Datetime', |
|
538 | + array( |
|
539 | + array( |
|
540 | + 'DTT_EVT_end' => array( |
|
541 | + '>=', |
|
542 | + \EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
543 | + ), |
|
544 | + ), |
|
545 | + 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
546 | + ) |
|
547 | + ); |
|
548 | + if ( ! empty($datetimes)) { |
|
549 | + // now loop thru all of the datetimes |
|
550 | + foreach ($datetimes as $datetime) { |
|
551 | + if ($datetime instanceof \EE_Datetime) { |
|
552 | + // the number of spaces available for the datetime without considering individual ticket quantities |
|
553 | + $spaces_remaining = $datetime->spaces_remaining(); |
|
554 | + // save the total available spaces ( the lesser of the ticket qty minus the number of tickets sold |
|
555 | + // or the datetime spaces remaining) to this ticket using the datetime ID as the key |
|
556 | + self::$_available_spaces['tickets'][$ticket->ID()][$datetime->ID()] = min( |
|
557 | + $ticket->qty() - $ticket->sold(), |
|
558 | + $spaces_remaining |
|
559 | + ); |
|
560 | + // if the remaining spaces for this datetime is already set, |
|
561 | + // then compare that against the datetime spaces remaining, and take the lowest number, |
|
562 | + // else just take the datetime spaces remaining, and assign to the datetimes array |
|
563 | + self::$_available_spaces['datetimes'][$datetime->ID()] = isset( |
|
564 | + self::$_available_spaces['datetimes'][$datetime->ID()] |
|
565 | + ) |
|
566 | + ? min(self::$_available_spaces['datetimes'][$datetime->ID()], $spaces_remaining) |
|
567 | + : $spaces_remaining; |
|
568 | + } |
|
569 | + } |
|
570 | + } |
|
571 | + } |
|
572 | + |
|
573 | + |
|
574 | + |
|
575 | + /** |
|
576 | + * @param \EE_Ticket $ticket |
|
577 | + * @param int $qty |
|
578 | + * @return void |
|
579 | + */ |
|
580 | + private function recalculateTicketDatetimeAvailability(\EE_Ticket $ticket, $qty = 0) |
|
581 | + { |
|
582 | + if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
583 | + // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
584 | + foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
585 | + // subtract the qty of selected tickets from each datetime's available spaces this ticket has access to, |
|
586 | + self::$_available_spaces['datetimes'][$DTD_ID] -= $qty; |
|
587 | + } |
|
588 | + } |
|
589 | + } |
|
590 | 590 | |
591 | 591 | |
592 | 592 | } |
@@ -49,7 +49,7 @@ discard block |
||
49 | 49 | ); |
50 | 50 | } else { |
51 | 51 | wp_safe_redirect( |
52 | - site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/') |
|
52 | + site_url('/'.\EE_Registry::instance()->CFG->core->event_cpt_slug.'/') |
|
53 | 53 | ); |
54 | 54 | } |
55 | 55 | exit(); |
@@ -165,7 +165,7 @@ discard block |
||
165 | 165 | 'event_espresso' |
166 | 166 | ); |
167 | 167 | $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']); |
168 | - \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__); |
|
168 | + \EE_Error::add_error($limit_error_1.'<br/>'.$limit_error_2, __FILE__, __FUNCTION__, __LINE__); |
|
169 | 169 | } else { |
170 | 170 | // all data appears to be valid |
171 | 171 | $tckts_slctd = false; |
@@ -305,9 +305,9 @@ discard block |
||
305 | 305 | // cycle through $inputs_to_clean array |
306 | 306 | foreach ($inputs_to_clean as $what => $input_to_clean) { |
307 | 307 | // check for POST data |
308 | - if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) { |
|
308 | + if (\EE_Registry::instance()->REQ->is_set($input_to_clean.$id)) { |
|
309 | 309 | // grab value |
310 | - $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id); |
|
310 | + $input_value = \EE_Registry::instance()->REQ->get($input_to_clean.$id); |
|
311 | 311 | switch ($what) { |
312 | 312 | // integers |
313 | 313 | case 'event_id': |
@@ -328,8 +328,8 @@ discard block |
||
328 | 328 | // if qty is coming from a radio button input, then we need to assemble an array of rows |
329 | 329 | if ( ! is_array($row_qty)) { |
330 | 330 | // get number of rows |
331 | - $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id) |
|
332 | - ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id)) |
|
331 | + $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-'.$id) |
|
332 | + ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-'.$id)) |
|
333 | 333 | : 1; |
334 | 334 | // explode ints by the dash |
335 | 335 | $row_qty = explode('-', $row_qty); |
@@ -355,7 +355,7 @@ discard block |
||
355 | 355 | case 'ticket_id': |
356 | 356 | $value_array = array(); |
357 | 357 | // cycle thru values |
358 | - foreach ((array)$input_value as $key => $value) { |
|
358 | + foreach ((array) $input_value as $key => $value) { |
|
359 | 359 | // allow only numbers, letters, spaces, commas and dashes |
360 | 360 | $value_array[$key] = wp_strip_all_tags($value); |
361 | 361 | // get ticket via the ticket id we put in the form |
@@ -373,7 +373,7 @@ discard block |
||
373 | 373 | $input_value = explode('#', $input_value); |
374 | 374 | $input_value = end($input_value); |
375 | 375 | // use event list url instead, but append anchor |
376 | - $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value; |
|
376 | + $input_value = \EEH_Event_View::event_archive_url().'#'.$input_value; |
|
377 | 377 | } |
378 | 378 | $valid_data[$what] = $input_value; |
379 | 379 | break; |