@@ -15,1796 +15,1796 @@ |
||
15 | 15 | class EED_Single_Page_Checkout extends EED_Module |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * $_initialized - has the SPCO controller already been initialized ? |
|
20 | - * |
|
21 | - * @access private |
|
22 | - * @var bool $_initialized |
|
23 | - */ |
|
24 | - private static $_initialized = false; |
|
25 | - |
|
26 | - |
|
27 | - /** |
|
28 | - * $_checkout_verified - is the EE_Checkout verified as correct for this request ? |
|
29 | - * |
|
30 | - * @access private |
|
31 | - * @var bool $_valid_checkout |
|
32 | - */ |
|
33 | - private static $_checkout_verified = true; |
|
34 | - |
|
35 | - /** |
|
36 | - * $_reg_steps_array - holds initial array of reg steps |
|
37 | - * |
|
38 | - * @access private |
|
39 | - * @var array $_reg_steps_array |
|
40 | - */ |
|
41 | - private static $_reg_steps_array = array(); |
|
42 | - |
|
43 | - /** |
|
44 | - * $checkout - EE_Checkout object for handling the properties of the current checkout process |
|
45 | - * |
|
46 | - * @access public |
|
47 | - * @var EE_Checkout $checkout |
|
48 | - */ |
|
49 | - public $checkout; |
|
50 | - |
|
51 | - |
|
52 | - /** |
|
53 | - * @return EED_Module|EED_Single_Page_Checkout |
|
54 | - */ |
|
55 | - public static function instance() |
|
56 | - { |
|
57 | - add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true'); |
|
58 | - return parent::get_instance(__CLASS__); |
|
59 | - } |
|
60 | - |
|
61 | - |
|
62 | - /** |
|
63 | - * @return EE_CART |
|
64 | - */ |
|
65 | - public function cart() |
|
66 | - { |
|
67 | - return $this->checkout->cart; |
|
68 | - } |
|
69 | - |
|
70 | - |
|
71 | - /** |
|
72 | - * @return EE_Transaction |
|
73 | - */ |
|
74 | - public function transaction() |
|
75 | - { |
|
76 | - return $this->checkout->transaction; |
|
77 | - } |
|
78 | - |
|
79 | - |
|
80 | - /** |
|
81 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
82 | - * |
|
83 | - * @access public |
|
84 | - * @return void |
|
85 | - * @throws EE_Error |
|
86 | - */ |
|
87 | - public static function set_hooks() |
|
88 | - { |
|
89 | - EED_Single_Page_Checkout::set_definitions(); |
|
90 | - } |
|
91 | - |
|
92 | - |
|
93 | - /** |
|
94 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
95 | - * |
|
96 | - * @access public |
|
97 | - * @return void |
|
98 | - * @throws EE_Error |
|
99 | - */ |
|
100 | - public static function set_hooks_admin() |
|
101 | - { |
|
102 | - EED_Single_Page_Checkout::set_definitions(); |
|
103 | - if (! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
104 | - return; |
|
105 | - } |
|
106 | - // going to start an output buffer in case anything gets accidentally output |
|
107 | - // that might disrupt our JSON response |
|
108 | - ob_start(); |
|
109 | - EED_Single_Page_Checkout::load_request_handler(); |
|
110 | - EED_Single_Page_Checkout::load_reg_steps(); |
|
111 | - // set ajax hooks |
|
112 | - add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
113 | - add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
114 | - add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
115 | - add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
116 | - add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
117 | - add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
118 | - } |
|
119 | - |
|
120 | - |
|
121 | - /** |
|
122 | - * process ajax request |
|
123 | - * |
|
124 | - * @param string $ajax_action |
|
125 | - * @throws EE_Error |
|
126 | - */ |
|
127 | - public static function process_ajax_request($ajax_action) |
|
128 | - { |
|
129 | - EE_Registry::instance()->REQ->set('action', $ajax_action); |
|
130 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
131 | - } |
|
132 | - |
|
133 | - |
|
134 | - /** |
|
135 | - * ajax display registration step |
|
136 | - * |
|
137 | - * @throws EE_Error |
|
138 | - */ |
|
139 | - public static function display_reg_step() |
|
140 | - { |
|
141 | - EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step'); |
|
142 | - } |
|
143 | - |
|
144 | - |
|
145 | - /** |
|
146 | - * ajax process registration step |
|
147 | - * |
|
148 | - * @throws EE_Error |
|
149 | - */ |
|
150 | - public static function process_reg_step() |
|
151 | - { |
|
152 | - EED_Single_Page_Checkout::process_ajax_request('process_reg_step'); |
|
153 | - } |
|
154 | - |
|
155 | - |
|
156 | - /** |
|
157 | - * ajax process registration step |
|
158 | - * |
|
159 | - * @throws EE_Error |
|
160 | - */ |
|
161 | - public static function update_reg_step() |
|
162 | - { |
|
163 | - EED_Single_Page_Checkout::process_ajax_request('update_reg_step'); |
|
164 | - } |
|
165 | - |
|
166 | - |
|
167 | - /** |
|
168 | - * update_checkout |
|
169 | - * |
|
170 | - * @access public |
|
171 | - * @return void |
|
172 | - * @throws EE_Error |
|
173 | - */ |
|
174 | - public static function update_checkout() |
|
175 | - { |
|
176 | - EED_Single_Page_Checkout::process_ajax_request('update_checkout'); |
|
177 | - } |
|
178 | - |
|
179 | - |
|
180 | - /** |
|
181 | - * load_request_handler |
|
182 | - * |
|
183 | - * @access public |
|
184 | - * @return void |
|
185 | - */ |
|
186 | - public static function load_request_handler() |
|
187 | - { |
|
188 | - // load core Request_Handler class |
|
189 | - if (EE_Registry::instance()->REQ !== null) { |
|
190 | - EE_Registry::instance()->load_core('Request_Handler'); |
|
191 | - } |
|
192 | - } |
|
193 | - |
|
194 | - |
|
195 | - /** |
|
196 | - * set_definitions |
|
197 | - * |
|
198 | - * @access public |
|
199 | - * @return void |
|
200 | - * @throws EE_Error |
|
201 | - */ |
|
202 | - public static function set_definitions() |
|
203 | - { |
|
204 | - if (defined('SPCO_BASE_PATH')) { |
|
205 | - return; |
|
206 | - } |
|
207 | - define( |
|
208 | - 'SPCO_BASE_PATH', |
|
209 | - rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/') . '/' |
|
210 | - ); |
|
211 | - define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css/'); |
|
212 | - define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img/'); |
|
213 | - define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js/'); |
|
214 | - define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc/'); |
|
215 | - define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps/'); |
|
216 | - define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates/'); |
|
217 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true); |
|
218 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
219 | - ); |
|
220 | - } |
|
221 | - |
|
222 | - |
|
223 | - /** |
|
224 | - * load_reg_steps |
|
225 | - * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array |
|
226 | - * |
|
227 | - * @access private |
|
228 | - * @throws EE_Error |
|
229 | - */ |
|
230 | - public static function load_reg_steps() |
|
231 | - { |
|
232 | - static $reg_steps_loaded = false; |
|
233 | - if ($reg_steps_loaded) { |
|
234 | - return; |
|
235 | - } |
|
236 | - // filter list of reg_steps |
|
237 | - $reg_steps_to_load = (array) apply_filters( |
|
238 | - 'AHEE__SPCO__load_reg_steps__reg_steps_to_load', |
|
239 | - EED_Single_Page_Checkout::get_reg_steps() |
|
240 | - ); |
|
241 | - // sort by key (order) |
|
242 | - ksort($reg_steps_to_load); |
|
243 | - // loop through folders |
|
244 | - foreach ($reg_steps_to_load as $order => $reg_step) { |
|
245 | - // we need a |
|
246 | - if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
247 | - // copy over to the reg_steps_array |
|
248 | - EED_Single_Page_Checkout::$_reg_steps_array[ $order ] = $reg_step; |
|
249 | - // register custom key route for each reg step |
|
250 | - // ie: step=>"slug" - this is the entire reason we load the reg steps array now |
|
251 | - EE_Config::register_route( |
|
252 | - $reg_step['slug'], |
|
253 | - 'EED_Single_Page_Checkout', |
|
254 | - 'run', |
|
255 | - 'step' |
|
256 | - ); |
|
257 | - // add AJAX or other hooks |
|
258 | - if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) { |
|
259 | - // setup autoloaders if necessary |
|
260 | - if (! class_exists($reg_step['class_name'])) { |
|
261 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder( |
|
262 | - $reg_step['file_path'], |
|
263 | - true |
|
264 | - ); |
|
265 | - } |
|
266 | - if (is_callable($reg_step['class_name'], 'set_hooks')) { |
|
267 | - call_user_func(array($reg_step['class_name'], 'set_hooks')); |
|
268 | - } |
|
269 | - } |
|
270 | - } |
|
271 | - } |
|
272 | - $reg_steps_loaded = true; |
|
273 | - } |
|
274 | - |
|
275 | - |
|
276 | - /** |
|
277 | - * get_reg_steps |
|
278 | - * |
|
279 | - * @access public |
|
280 | - * @return array |
|
281 | - */ |
|
282 | - public static function get_reg_steps() |
|
283 | - { |
|
284 | - $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps; |
|
285 | - if (empty($reg_steps)) { |
|
286 | - $reg_steps = array( |
|
287 | - 10 => array( |
|
288 | - 'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information', |
|
289 | - 'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information', |
|
290 | - 'slug' => 'attendee_information', |
|
291 | - 'has_hooks' => false, |
|
292 | - ), |
|
293 | - 30 => array( |
|
294 | - 'file_path' => SPCO_REG_STEPS_PATH . 'payment_options', |
|
295 | - 'class_name' => 'EE_SPCO_Reg_Step_Payment_Options', |
|
296 | - 'slug' => 'payment_options', |
|
297 | - 'has_hooks' => true, |
|
298 | - ), |
|
299 | - 999 => array( |
|
300 | - 'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration', |
|
301 | - 'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration', |
|
302 | - 'slug' => 'finalize_registration', |
|
303 | - 'has_hooks' => false, |
|
304 | - ), |
|
305 | - ); |
|
306 | - } |
|
307 | - return $reg_steps; |
|
308 | - } |
|
309 | - |
|
310 | - |
|
311 | - /** |
|
312 | - * registration_checkout_for_admin |
|
313 | - * |
|
314 | - * @access public |
|
315 | - * @return string |
|
316 | - * @throws EE_Error |
|
317 | - */ |
|
318 | - public static function registration_checkout_for_admin() |
|
319 | - { |
|
320 | - EED_Single_Page_Checkout::load_request_handler(); |
|
321 | - EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
322 | - EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step'); |
|
323 | - EE_Registry::instance()->REQ->set('process_form_submission', false); |
|
324 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
325 | - EED_Single_Page_Checkout::instance()->_display_spco_reg_form(); |
|
326 | - return EE_Registry::instance()->REQ->get_output(); |
|
327 | - } |
|
328 | - |
|
329 | - |
|
330 | - /** |
|
331 | - * process_registration_from_admin |
|
332 | - * |
|
333 | - * @access public |
|
334 | - * @return \EE_Transaction |
|
335 | - * @throws EE_Error |
|
336 | - */ |
|
337 | - public static function process_registration_from_admin() |
|
338 | - { |
|
339 | - EED_Single_Page_Checkout::load_request_handler(); |
|
340 | - EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
341 | - EE_Registry::instance()->REQ->set('action', 'process_reg_step'); |
|
342 | - EE_Registry::instance()->REQ->set('process_form_submission', true); |
|
343 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
344 | - if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) { |
|
345 | - $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps); |
|
346 | - if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) { |
|
347 | - EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step); |
|
348 | - if ($final_reg_step->process_reg_step()) { |
|
349 | - $final_reg_step->set_completed(); |
|
350 | - EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array(); |
|
351 | - return EED_Single_Page_Checkout::instance()->checkout->transaction; |
|
352 | - } |
|
353 | - } |
|
354 | - } |
|
355 | - return null; |
|
356 | - } |
|
357 | - |
|
358 | - |
|
359 | - /** |
|
360 | - * run |
|
361 | - * |
|
362 | - * @access public |
|
363 | - * @param WP_Query $WP_Query |
|
364 | - * @return void |
|
365 | - * @throws EE_Error |
|
366 | - */ |
|
367 | - public function run($WP_Query) |
|
368 | - { |
|
369 | - if ($WP_Query instanceof WP_Query |
|
370 | - && $WP_Query->is_main_query() |
|
371 | - && apply_filters('FHEE__EED_Single_Page_Checkout__run', true) |
|
372 | - && $this->_is_reg_checkout() |
|
373 | - ) { |
|
374 | - $this->_initialize(); |
|
375 | - } |
|
376 | - } |
|
377 | - |
|
378 | - |
|
379 | - /** |
|
380 | - * determines whether current url matches reg page url |
|
381 | - * |
|
382 | - * @return bool |
|
383 | - */ |
|
384 | - protected function _is_reg_checkout() |
|
385 | - { |
|
386 | - // get current permalink for reg page without any extra query args |
|
387 | - $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id); |
|
388 | - // get request URI for current request, but without the scheme or host |
|
389 | - $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI'); |
|
390 | - $current_request_uri = html_entity_decode($current_request_uri); |
|
391 | - // get array of query args from the current request URI |
|
392 | - $query_args = \EEH_URL::get_query_string($current_request_uri); |
|
393 | - // grab page id if it is set |
|
394 | - $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0; |
|
395 | - // and remove the page id from the query args (we will re-add it later) |
|
396 | - unset($query_args['page_id']); |
|
397 | - // now strip all query args from current request URI |
|
398 | - $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri); |
|
399 | - // and re-add the page id if it was set |
|
400 | - if ($page_id) { |
|
401 | - $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri); |
|
402 | - } |
|
403 | - // remove slashes and ? |
|
404 | - $current_request_uri = trim($current_request_uri, '?/'); |
|
405 | - // is current request URI part of the known full reg page URL ? |
|
406 | - return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false; |
|
407 | - } |
|
408 | - |
|
409 | - |
|
410 | - /** |
|
411 | - * @param WP_Query $wp_query |
|
412 | - * @return void |
|
413 | - * @throws EE_Error |
|
414 | - */ |
|
415 | - public static function init($wp_query) |
|
416 | - { |
|
417 | - EED_Single_Page_Checkout::instance()->run($wp_query); |
|
418 | - } |
|
419 | - |
|
420 | - |
|
421 | - /** |
|
422 | - * _initialize - initial module setup |
|
423 | - * |
|
424 | - * @access private |
|
425 | - * @throws EE_Error |
|
426 | - * @return void |
|
427 | - */ |
|
428 | - private function _initialize() |
|
429 | - { |
|
430 | - // ensure SPCO doesn't run twice |
|
431 | - if (EED_Single_Page_Checkout::$_initialized) { |
|
432 | - return; |
|
433 | - } |
|
434 | - try { |
|
435 | - EED_Single_Page_Checkout::load_reg_steps(); |
|
436 | - $this->_verify_session(); |
|
437 | - // setup the EE_Checkout object |
|
438 | - $this->checkout = $this->_initialize_checkout(); |
|
439 | - // filter checkout |
|
440 | - $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout); |
|
441 | - // get the $_GET |
|
442 | - $this->_get_request_vars(); |
|
443 | - if ($this->_block_bots()) { |
|
444 | - return; |
|
445 | - } |
|
446 | - // filter continue_reg |
|
447 | - $this->checkout->continue_reg = apply_filters( |
|
448 | - 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
449 | - true, |
|
450 | - $this->checkout |
|
451 | - ); |
|
452 | - // load the reg steps array |
|
453 | - if (! $this->_load_and_instantiate_reg_steps()) { |
|
454 | - EED_Single_Page_Checkout::$_initialized = true; |
|
455 | - return; |
|
456 | - } |
|
457 | - // set the current step |
|
458 | - $this->checkout->set_current_step($this->checkout->step); |
|
459 | - // and the next step |
|
460 | - $this->checkout->set_next_step(); |
|
461 | - // verify that everything has been setup correctly |
|
462 | - if (! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) { |
|
463 | - EED_Single_Page_Checkout::$_initialized = true; |
|
464 | - return; |
|
465 | - } |
|
466 | - // lock the transaction |
|
467 | - $this->checkout->transaction->lock(); |
|
468 | - // make sure all of our cached objects are added to their respective model entity mappers |
|
469 | - $this->checkout->refresh_all_entities(); |
|
470 | - // set amount owing |
|
471 | - $this->checkout->amount_owing = $this->checkout->transaction->remaining(); |
|
472 | - // initialize each reg step, which gives them the chance to potentially alter the process |
|
473 | - $this->_initialize_reg_steps(); |
|
474 | - // DEBUG LOG |
|
475 | - // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
476 | - // get reg form |
|
477 | - if (! $this->_check_form_submission()) { |
|
478 | - EED_Single_Page_Checkout::$_initialized = true; |
|
479 | - return; |
|
480 | - } |
|
481 | - // checkout the action!!! |
|
482 | - $this->_process_form_action(); |
|
483 | - // add some style and make it dance |
|
484 | - $this->add_styles_and_scripts($this); |
|
485 | - // kk... SPCO has successfully run |
|
486 | - EED_Single_Page_Checkout::$_initialized = true; |
|
487 | - // set no cache headers and constants |
|
488 | - EE_System::do_not_cache(); |
|
489 | - // add anchor |
|
490 | - add_action('loop_start', array($this, 'set_checkout_anchor'), 1); |
|
491 | - // remove transaction lock |
|
492 | - add_action('shutdown', array($this, 'unlock_transaction'), 1); |
|
493 | - } catch (Exception $e) { |
|
494 | - EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
495 | - } |
|
496 | - } |
|
497 | - |
|
498 | - |
|
499 | - /** |
|
500 | - * _verify_session |
|
501 | - * checks that the session is valid and not expired |
|
502 | - * |
|
503 | - * @access private |
|
504 | - * @throws EE_Error |
|
505 | - */ |
|
506 | - private function _verify_session() |
|
507 | - { |
|
508 | - if (! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
509 | - throw new EE_Error(esc_html__('The EE_Session class could not be loaded.', 'event_espresso')); |
|
510 | - } |
|
511 | - $clear_session_requested = filter_var( |
|
512 | - EE_Registry::instance()->REQ->get('clear_session', false), |
|
513 | - FILTER_VALIDATE_BOOLEAN |
|
514 | - ); |
|
515 | - // is session still valid ? |
|
516 | - if ($clear_session_requested |
|
517 | - || (EE_Registry::instance()->SSN->expired() |
|
518 | - && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '' |
|
519 | - ) |
|
520 | - ) { |
|
521 | - $this->checkout = new EE_Checkout(); |
|
522 | - EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
523 | - // EE_Registry::instance()->SSN->reset_cart(); |
|
524 | - // EE_Registry::instance()->SSN->reset_checkout(); |
|
525 | - // EE_Registry::instance()->SSN->reset_transaction(); |
|
526 | - if (! $clear_session_requested) { |
|
527 | - EE_Error::add_attention( |
|
528 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'], |
|
529 | - __FILE__, |
|
530 | - __FUNCTION__, |
|
531 | - __LINE__ |
|
532 | - ); |
|
533 | - } |
|
534 | - // EE_Registry::instance()->SSN->reset_expired(); |
|
535 | - } |
|
536 | - } |
|
537 | - |
|
538 | - |
|
539 | - /** |
|
540 | - * _initialize_checkout |
|
541 | - * loads and instantiates EE_Checkout |
|
542 | - * |
|
543 | - * @access private |
|
544 | - * @throws EE_Error |
|
545 | - * @return EE_Checkout |
|
546 | - */ |
|
547 | - private function _initialize_checkout() |
|
548 | - { |
|
549 | - // look in session for existing checkout |
|
550 | - /** @type EE_Checkout $checkout */ |
|
551 | - $checkout = EE_Registry::instance()->SSN->checkout(); |
|
552 | - // verify |
|
553 | - if (! $checkout instanceof EE_Checkout) { |
|
554 | - // instantiate EE_Checkout object for handling the properties of the current checkout process |
|
555 | - $checkout = EE_Registry::instance()->load_file( |
|
556 | - SPCO_INC_PATH, |
|
557 | - 'EE_Checkout', |
|
558 | - 'class', |
|
559 | - array(), |
|
560 | - false |
|
561 | - ); |
|
562 | - } else { |
|
563 | - if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) { |
|
564 | - $this->unlock_transaction(); |
|
565 | - wp_safe_redirect($checkout->redirect_url); |
|
566 | - exit(); |
|
567 | - } |
|
568 | - } |
|
569 | - $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout); |
|
570 | - // verify again |
|
571 | - if (! $checkout instanceof EE_Checkout) { |
|
572 | - throw new EE_Error(esc_html__('The EE_Checkout class could not be loaded.', 'event_espresso')); |
|
573 | - } |
|
574 | - // reset anything that needs a clean slate for each request |
|
575 | - $checkout->reset_for_current_request(); |
|
576 | - return $checkout; |
|
577 | - } |
|
578 | - |
|
579 | - |
|
580 | - /** |
|
581 | - * _get_request_vars |
|
582 | - * |
|
583 | - * @access private |
|
584 | - * @return void |
|
585 | - * @throws EE_Error |
|
586 | - */ |
|
587 | - private function _get_request_vars() |
|
588 | - { |
|
589 | - // load classes |
|
590 | - EED_Single_Page_Checkout::load_request_handler(); |
|
591 | - // make sure this request is marked as belonging to EE |
|
592 | - EE_Registry::instance()->REQ->set_espresso_page(true); |
|
593 | - // which step is being requested ? |
|
594 | - $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step()); |
|
595 | - // which step is being edited ? |
|
596 | - $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', ''); |
|
597 | - // and what we're doing on the current step |
|
598 | - $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step'); |
|
599 | - // timestamp |
|
600 | - $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0); |
|
601 | - // returning to edit ? |
|
602 | - $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', ''); |
|
603 | - // add reg url link to registration query params |
|
604 | - if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) { |
|
605 | - $this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link; |
|
606 | - } |
|
607 | - // or some other kind of revisit ? |
|
608 | - $this->checkout->revisit = filter_var( |
|
609 | - EE_Registry::instance()->REQ->get('revisit', false), |
|
610 | - FILTER_VALIDATE_BOOLEAN |
|
611 | - ); |
|
612 | - // and whether or not to generate a reg form for this request |
|
613 | - $this->checkout->generate_reg_form = filter_var( |
|
614 | - EE_Registry::instance()->REQ->get('generate_reg_form', true), |
|
615 | - FILTER_VALIDATE_BOOLEAN |
|
616 | - ); |
|
617 | - // and whether or not to process a reg form submission for this request |
|
618 | - $this->checkout->process_form_submission = filter_var( |
|
619 | - EE_Registry::instance()->REQ->get( |
|
620 | - 'process_form_submission', |
|
621 | - $this->checkout->action === 'process_reg_step' |
|
622 | - ), |
|
623 | - FILTER_VALIDATE_BOOLEAN |
|
624 | - ); |
|
625 | - $this->checkout->process_form_submission = filter_var( |
|
626 | - $this->checkout->action !== 'display_spco_reg_step' |
|
627 | - ? $this->checkout->process_form_submission |
|
628 | - : false, |
|
629 | - FILTER_VALIDATE_BOOLEAN |
|
630 | - ); |
|
631 | - // $this->_display_request_vars(); |
|
632 | - } |
|
633 | - |
|
634 | - |
|
635 | - /** |
|
636 | - * _display_request_vars |
|
637 | - * |
|
638 | - * @access protected |
|
639 | - * @return void |
|
640 | - */ |
|
641 | - protected function _display_request_vars() |
|
642 | - { |
|
643 | - if (! WP_DEBUG) { |
|
644 | - return; |
|
645 | - } |
|
646 | - EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__); |
|
647 | - EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__); |
|
648 | - EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__); |
|
649 | - EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__); |
|
650 | - EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__); |
|
651 | - EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__); |
|
652 | - EEH_Debug_Tools::printr( |
|
653 | - $this->checkout->generate_reg_form, |
|
654 | - '$this->checkout->generate_reg_form', |
|
655 | - __FILE__, |
|
656 | - __LINE__ |
|
657 | - ); |
|
658 | - EEH_Debug_Tools::printr( |
|
659 | - $this->checkout->process_form_submission, |
|
660 | - '$this->checkout->process_form_submission', |
|
661 | - __FILE__, |
|
662 | - __LINE__ |
|
663 | - ); |
|
664 | - } |
|
665 | - |
|
666 | - |
|
667 | - /** |
|
668 | - * _block_bots |
|
669 | - * checks that the incoming request has either of the following set: |
|
670 | - * a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector |
|
671 | - * a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN |
|
672 | - * so if you're not coming from the Ticket Selector nor returning for a valid IP... |
|
673 | - * then where you coming from man? |
|
674 | - * |
|
675 | - * @return boolean |
|
676 | - */ |
|
677 | - private function _block_bots() |
|
678 | - { |
|
679 | - $invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
680 | - if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) { |
|
681 | - return true; |
|
682 | - } |
|
683 | - return false; |
|
684 | - } |
|
685 | - |
|
686 | - |
|
687 | - /** |
|
688 | - * _get_first_step |
|
689 | - * gets slug for first step in $_reg_steps_array |
|
690 | - * |
|
691 | - * @access private |
|
692 | - * @throws EE_Error |
|
693 | - * @return string |
|
694 | - */ |
|
695 | - private function _get_first_step() |
|
696 | - { |
|
697 | - $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array); |
|
698 | - return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information'; |
|
699 | - } |
|
700 | - |
|
701 | - |
|
702 | - /** |
|
703 | - * instantiates each reg step based on the loaded reg_steps array |
|
704 | - * |
|
705 | - * @return bool |
|
706 | - * @throws EE_Error |
|
707 | - * @throws InvalidArgumentException |
|
708 | - * @throws InvalidDataTypeException |
|
709 | - * @throws InvalidInterfaceException |
|
710 | - */ |
|
711 | - private function _load_and_instantiate_reg_steps() |
|
712 | - { |
|
713 | - do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout); |
|
714 | - // have reg_steps already been instantiated ? |
|
715 | - if (empty($this->checkout->reg_steps) |
|
716 | - || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout) |
|
717 | - ) { |
|
718 | - // if not, then loop through raw reg steps array |
|
719 | - foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) { |
|
720 | - if (! $this->_load_and_instantiate_reg_step($reg_step, $order)) { |
|
721 | - return false; |
|
722 | - } |
|
723 | - } |
|
724 | - if (isset($this->checkout->reg_steps['registration_confirmation'])) { |
|
725 | - // skip the registration_confirmation page ? |
|
726 | - if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) { |
|
727 | - // just remove it from the reg steps array |
|
728 | - $this->checkout->remove_reg_step('registration_confirmation', false); |
|
729 | - } elseif (EE_Registry::instance()->CFG->registration->reg_confirmation_last |
|
730 | - ) { |
|
731 | - // set the order to something big like 100 |
|
732 | - $this->checkout->set_reg_step_order('registration_confirmation', 100); |
|
733 | - } |
|
734 | - } |
|
735 | - // filter the array for good luck |
|
736 | - $this->checkout->reg_steps = apply_filters( |
|
737 | - 'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps', |
|
738 | - $this->checkout->reg_steps |
|
739 | - ); |
|
740 | - // finally re-sort based on the reg step class order properties |
|
741 | - $this->checkout->sort_reg_steps(); |
|
742 | - } else { |
|
743 | - foreach ($this->checkout->reg_steps as $reg_step) { |
|
744 | - // set all current step stati to FALSE |
|
745 | - $reg_step->set_is_current_step(false); |
|
746 | - } |
|
747 | - } |
|
748 | - if (empty($this->checkout->reg_steps)) { |
|
749 | - EE_Error::add_error( |
|
750 | - esc_html__('No Reg Steps were loaded..', 'event_espresso'), |
|
751 | - __FILE__, |
|
752 | - __FUNCTION__, |
|
753 | - __LINE__ |
|
754 | - ); |
|
755 | - return false; |
|
756 | - } |
|
757 | - // make reg step details available to JS |
|
758 | - $this->checkout->set_reg_step_JSON_info(); |
|
759 | - return true; |
|
760 | - } |
|
761 | - |
|
762 | - |
|
763 | - /** |
|
764 | - * _load_and_instantiate_reg_step |
|
765 | - * |
|
766 | - * @access private |
|
767 | - * @param array $reg_step |
|
768 | - * @param int $order |
|
769 | - * @return bool |
|
770 | - */ |
|
771 | - private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0) |
|
772 | - { |
|
773 | - // we need a file_path, class_name, and slug to add a reg step |
|
774 | - if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
775 | - // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step) |
|
776 | - if ($this->checkout->reg_url_link |
|
777 | - && $this->checkout->step !== $reg_step['slug'] |
|
778 | - && $reg_step['slug'] !== 'finalize_registration' |
|
779 | - // normally at this point we would NOT load the reg step, but this filter can change that |
|
780 | - && apply_filters( |
|
781 | - 'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step', |
|
782 | - true, |
|
783 | - $reg_step, |
|
784 | - $this->checkout |
|
785 | - ) |
|
786 | - ) { |
|
787 | - return true; |
|
788 | - } |
|
789 | - // instantiate step class using file path and class name |
|
790 | - $reg_step_obj = EE_Registry::instance()->load_file( |
|
791 | - $reg_step['file_path'], |
|
792 | - $reg_step['class_name'], |
|
793 | - 'class', |
|
794 | - $this->checkout, |
|
795 | - false |
|
796 | - ); |
|
797 | - // did we gets the goods ? |
|
798 | - if ($reg_step_obj instanceof EE_SPCO_Reg_Step) { |
|
799 | - // set reg step order based on config |
|
800 | - $reg_step_obj->set_order($order); |
|
801 | - // add instantiated reg step object to the master reg steps array |
|
802 | - $this->checkout->add_reg_step($reg_step_obj); |
|
803 | - } else { |
|
804 | - EE_Error::add_error( |
|
805 | - esc_html__('The current step could not be set.', 'event_espresso'), |
|
806 | - __FILE__, |
|
807 | - __FUNCTION__, |
|
808 | - __LINE__ |
|
809 | - ); |
|
810 | - return false; |
|
811 | - } |
|
812 | - } else { |
|
813 | - if (WP_DEBUG) { |
|
814 | - EE_Error::add_error( |
|
815 | - sprintf( |
|
816 | - esc_html__( |
|
817 | - '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', |
|
818 | - 'event_espresso' |
|
819 | - ), |
|
820 | - isset($reg_step['file_path']) ? $reg_step['file_path'] : '', |
|
821 | - isset($reg_step['class_name']) ? $reg_step['class_name'] : '', |
|
822 | - isset($reg_step['slug']) ? $reg_step['slug'] : '', |
|
823 | - '<ul>', |
|
824 | - '<li>', |
|
825 | - '</li>', |
|
826 | - '</ul>' |
|
827 | - ), |
|
828 | - __FILE__, |
|
829 | - __FUNCTION__, |
|
830 | - __LINE__ |
|
831 | - ); |
|
832 | - } |
|
833 | - return false; |
|
834 | - } |
|
835 | - return true; |
|
836 | - } |
|
837 | - |
|
838 | - |
|
839 | - /** |
|
840 | - * _verify_transaction_and_get_registrations |
|
841 | - * |
|
842 | - * @access private |
|
843 | - * @return bool |
|
844 | - * @throws InvalidDataTypeException |
|
845 | - * @throws InvalidEntityException |
|
846 | - * @throws EE_Error |
|
847 | - */ |
|
848 | - private function _verify_transaction_and_get_registrations() |
|
849 | - { |
|
850 | - // was there already a valid transaction in the checkout from the session ? |
|
851 | - if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
852 | - // get transaction from db or session |
|
853 | - $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin() |
|
854 | - ? $this->_get_transaction_and_cart_for_previous_visit() |
|
855 | - : $this->_get_cart_for_current_session_and_setup_new_transaction(); |
|
856 | - if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
857 | - EE_Error::add_error( |
|
858 | - esc_html__( |
|
859 | - 'Your Registration and Transaction information could not be retrieved from the db.', |
|
860 | - 'event_espresso' |
|
861 | - ), |
|
862 | - __FILE__, |
|
863 | - __FUNCTION__, |
|
864 | - __LINE__ |
|
865 | - ); |
|
866 | - $this->checkout->transaction = EE_Transaction::new_instance(); |
|
867 | - // add some style and make it dance |
|
868 | - $this->add_styles_and_scripts($this); |
|
869 | - EED_Single_Page_Checkout::$_initialized = true; |
|
870 | - return false; |
|
871 | - } |
|
872 | - // and the registrations for the transaction |
|
873 | - $this->_get_registrations($this->checkout->transaction); |
|
874 | - } |
|
875 | - return true; |
|
876 | - } |
|
877 | - |
|
878 | - |
|
879 | - /** |
|
880 | - * _get_transaction_and_cart_for_previous_visit |
|
881 | - * |
|
882 | - * @access private |
|
883 | - * @return mixed EE_Transaction|NULL |
|
884 | - */ |
|
885 | - private function _get_transaction_and_cart_for_previous_visit() |
|
886 | - { |
|
887 | - /** @var $TXN_model EEM_Transaction */ |
|
888 | - $TXN_model = EE_Registry::instance()->load_model('Transaction'); |
|
889 | - // because the reg_url_link is present in the request, |
|
890 | - // this is a return visit to SPCO, so we'll get the transaction data from the db |
|
891 | - $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link); |
|
892 | - // verify transaction |
|
893 | - if ($transaction instanceof EE_Transaction) { |
|
894 | - // and get the cart that was used for that transaction |
|
895 | - $this->checkout->cart = $this->_get_cart_for_transaction($transaction); |
|
896 | - return $transaction; |
|
897 | - } |
|
898 | - EE_Error::add_error( |
|
899 | - esc_html__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), |
|
900 | - __FILE__, |
|
901 | - __FUNCTION__, |
|
902 | - __LINE__ |
|
903 | - ); |
|
904 | - return null; |
|
905 | - } |
|
906 | - |
|
907 | - |
|
908 | - /** |
|
909 | - * _get_cart_for_transaction |
|
910 | - * |
|
911 | - * @access private |
|
912 | - * @param EE_Transaction $transaction |
|
913 | - * @return EE_Cart |
|
914 | - */ |
|
915 | - private function _get_cart_for_transaction($transaction) |
|
916 | - { |
|
917 | - return $this->checkout->get_cart_for_transaction($transaction); |
|
918 | - } |
|
919 | - |
|
920 | - |
|
921 | - /** |
|
922 | - * get_cart_for_transaction |
|
923 | - * |
|
924 | - * @access public |
|
925 | - * @param EE_Transaction $transaction |
|
926 | - * @return EE_Cart |
|
927 | - */ |
|
928 | - public function get_cart_for_transaction(EE_Transaction $transaction) |
|
929 | - { |
|
930 | - return $this->checkout->get_cart_for_transaction($transaction); |
|
931 | - } |
|
932 | - |
|
933 | - |
|
934 | - /** |
|
935 | - * _get_transaction_and_cart_for_current_session |
|
936 | - * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
937 | - * |
|
938 | - * @access private |
|
939 | - * @return EE_Transaction |
|
940 | - * @throws EE_Error |
|
941 | - */ |
|
942 | - private function _get_cart_for_current_session_and_setup_new_transaction() |
|
943 | - { |
|
944 | - // if there's no transaction, then this is the FIRST visit to SPCO |
|
945 | - // so load up the cart ( passing nothing for the TXN because it doesn't exist yet ) |
|
946 | - $this->checkout->cart = $this->_get_cart_for_transaction(null); |
|
947 | - // and then create a new transaction |
|
948 | - $transaction = $this->_initialize_transaction(); |
|
949 | - // verify transaction |
|
950 | - if ($transaction instanceof EE_Transaction) { |
|
951 | - // save it so that we have an ID for other objects to use |
|
952 | - $transaction->save(); |
|
953 | - // and save TXN data to the cart |
|
954 | - $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID()); |
|
955 | - } else { |
|
956 | - EE_Error::add_error( |
|
957 | - esc_html__('A Valid Transaction could not be initialized.', 'event_espresso'), |
|
958 | - __FILE__, |
|
959 | - __FUNCTION__, |
|
960 | - __LINE__ |
|
961 | - ); |
|
962 | - } |
|
963 | - return $transaction; |
|
964 | - } |
|
965 | - |
|
966 | - |
|
967 | - /** |
|
968 | - * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
969 | - * |
|
970 | - * @access private |
|
971 | - * @return mixed EE_Transaction|NULL |
|
972 | - */ |
|
973 | - private function _initialize_transaction() |
|
974 | - { |
|
975 | - try { |
|
976 | - // ensure cart totals have been calculated |
|
977 | - $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes(); |
|
978 | - // grab the cart grand total |
|
979 | - $cart_total = $this->checkout->cart->get_cart_grand_total(); |
|
980 | - // create new TXN |
|
981 | - $transaction = EE_Transaction::new_instance( |
|
982 | - array( |
|
983 | - 'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(), |
|
984 | - 'TXN_total' => $cart_total > 0 ? $cart_total : 0, |
|
985 | - 'TXN_paid' => 0, |
|
986 | - 'STS_ID' => EEM_Transaction::failed_status_code, |
|
987 | - ) |
|
988 | - ); |
|
989 | - // save it so that we have an ID for other objects to use |
|
990 | - $transaction->save(); |
|
991 | - // set cron job for following up on TXNs after their session has expired |
|
992 | - EE_Cron_Tasks::schedule_expired_transaction_check( |
|
993 | - EE_Registry::instance()->SSN->expiration() + 1, |
|
994 | - $transaction->ID() |
|
995 | - ); |
|
996 | - return $transaction; |
|
997 | - } catch (Exception $e) { |
|
998 | - EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
999 | - } |
|
1000 | - return null; |
|
1001 | - } |
|
1002 | - |
|
1003 | - |
|
1004 | - /** |
|
1005 | - * _get_registrations |
|
1006 | - * |
|
1007 | - * @access private |
|
1008 | - * @param EE_Transaction $transaction |
|
1009 | - * @return void |
|
1010 | - * @throws InvalidDataTypeException |
|
1011 | - * @throws InvalidEntityException |
|
1012 | - * @throws EE_Error |
|
1013 | - */ |
|
1014 | - private function _get_registrations(EE_Transaction $transaction) |
|
1015 | - { |
|
1016 | - // first step: grab the registrants { : o |
|
1017 | - $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
1018 | - $this->checkout->total_ticket_count = count($registrations); |
|
1019 | - // verify registrations have been set |
|
1020 | - if (empty($registrations)) { |
|
1021 | - // if no cached registrations, then check the db |
|
1022 | - $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
1023 | - // still nothing ? well as long as this isn't a revisit |
|
1024 | - if (empty($registrations) && ! $this->checkout->revisit) { |
|
1025 | - // generate new registrations from scratch |
|
1026 | - $registrations = $this->_initialize_registrations($transaction); |
|
1027 | - } |
|
1028 | - } |
|
1029 | - // sort by their original registration order |
|
1030 | - usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count')); |
|
1031 | - // then loop thru the array |
|
1032 | - foreach ($registrations as $registration) { |
|
1033 | - // verify each registration |
|
1034 | - if ($registration instanceof EE_Registration) { |
|
1035 | - // we display all attendee info for the primary registrant |
|
1036 | - if ($this->checkout->reg_url_link === $registration->reg_url_link() |
|
1037 | - && $registration->is_primary_registrant() |
|
1038 | - ) { |
|
1039 | - $this->checkout->primary_revisit = true; |
|
1040 | - break; |
|
1041 | - } |
|
1042 | - if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) { |
|
1043 | - // but hide info if it doesn't belong to you |
|
1044 | - $transaction->clear_cache('Registration', $registration->ID()); |
|
1045 | - $this->checkout->total_ticket_count--; |
|
1046 | - } |
|
1047 | - $this->checkout->set_reg_status_updated($registration->ID(), false); |
|
1048 | - } |
|
1049 | - } |
|
1050 | - } |
|
1051 | - |
|
1052 | - |
|
1053 | - /** |
|
1054 | - * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object |
|
1055 | - * |
|
1056 | - * @access private |
|
1057 | - * @param EE_Transaction $transaction |
|
1058 | - * @return array |
|
1059 | - * @throws InvalidDataTypeException |
|
1060 | - * @throws InvalidEntityException |
|
1061 | - * @throws EE_Error |
|
1062 | - */ |
|
1063 | - private function _initialize_registrations(EE_Transaction $transaction) |
|
1064 | - { |
|
1065 | - $att_nmbr = 0; |
|
1066 | - $registrations = array(); |
|
1067 | - if ($transaction instanceof EE_Transaction) { |
|
1068 | - /** @type EE_Registration_Processor $registration_processor */ |
|
1069 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
1070 | - $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count(); |
|
1071 | - // now let's add the cart items to the $transaction |
|
1072 | - foreach ($this->checkout->cart->get_tickets() as $line_item) { |
|
1073 | - // do the following for each ticket of this type they selected |
|
1074 | - for ($x = 1; $x <= $line_item->quantity(); $x++) { |
|
1075 | - $att_nmbr++; |
|
1076 | - /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */ |
|
1077 | - $CreateRegistrationCommand = EE_Registry::instance()->create( |
|
1078 | - 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand', |
|
1079 | - array( |
|
1080 | - $transaction, |
|
1081 | - $line_item, |
|
1082 | - $att_nmbr, |
|
1083 | - $this->checkout->total_ticket_count, |
|
1084 | - ) |
|
1085 | - ); |
|
1086 | - // override capabilities for frontend registrations |
|
1087 | - if (! is_admin()) { |
|
1088 | - $CreateRegistrationCommand->setCapCheck( |
|
1089 | - new PublicCapabilities('', 'create_new_registration') |
|
1090 | - ); |
|
1091 | - } |
|
1092 | - $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand); |
|
1093 | - if (! $registration instanceof EE_Registration) { |
|
1094 | - throw new InvalidEntityException($registration, 'EE_Registration'); |
|
1095 | - } |
|
1096 | - $registrations[ $registration->ID() ] = $registration; |
|
1097 | - } |
|
1098 | - } |
|
1099 | - $registration_processor->fix_reg_final_price_rounding_issue($transaction); |
|
1100 | - } |
|
1101 | - return $registrations; |
|
1102 | - } |
|
1103 | - |
|
1104 | - |
|
1105 | - /** |
|
1106 | - * sorts registrations by REG_count |
|
1107 | - * |
|
1108 | - * @access public |
|
1109 | - * @param EE_Registration $reg_A |
|
1110 | - * @param EE_Registration $reg_B |
|
1111 | - * @return int |
|
1112 | - */ |
|
1113 | - public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B) |
|
1114 | - { |
|
1115 | - // this shouldn't ever happen within the same TXN, but oh well |
|
1116 | - if ($reg_A->count() === $reg_B->count()) { |
|
1117 | - return 0; |
|
1118 | - } |
|
1119 | - return ($reg_A->count() > $reg_B->count()) ? 1 : -1; |
|
1120 | - } |
|
1121 | - |
|
1122 | - |
|
1123 | - /** |
|
1124 | - * _final_verifications |
|
1125 | - * just makes sure that everything is set up correctly before proceeding |
|
1126 | - * |
|
1127 | - * @access private |
|
1128 | - * @return bool |
|
1129 | - * @throws EE_Error |
|
1130 | - */ |
|
1131 | - private function _final_verifications() |
|
1132 | - { |
|
1133 | - // filter checkout |
|
1134 | - $this->checkout = apply_filters( |
|
1135 | - 'FHEE__EED_Single_Page_Checkout___final_verifications__checkout', |
|
1136 | - $this->checkout |
|
1137 | - ); |
|
1138 | - // verify that current step is still set correctly |
|
1139 | - if (! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) { |
|
1140 | - EE_Error::add_error( |
|
1141 | - esc_html__( |
|
1142 | - '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.', |
|
1143 | - 'event_espresso' |
|
1144 | - ), |
|
1145 | - __FILE__, |
|
1146 | - __FUNCTION__, |
|
1147 | - __LINE__ |
|
1148 | - ); |
|
1149 | - return false; |
|
1150 | - } |
|
1151 | - // if returning to SPCO, then verify that primary registrant is set |
|
1152 | - if (! empty($this->checkout->reg_url_link)) { |
|
1153 | - $valid_registrant = $this->checkout->transaction->primary_registration(); |
|
1154 | - if (! $valid_registrant instanceof EE_Registration) { |
|
1155 | - EE_Error::add_error( |
|
1156 | - esc_html__( |
|
1157 | - '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.', |
|
1158 | - 'event_espresso' |
|
1159 | - ), |
|
1160 | - __FILE__, |
|
1161 | - __FUNCTION__, |
|
1162 | - __LINE__ |
|
1163 | - ); |
|
1164 | - return false; |
|
1165 | - } |
|
1166 | - $valid_registrant = null; |
|
1167 | - foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) { |
|
1168 | - if ($registration instanceof EE_Registration |
|
1169 | - && $registration->reg_url_link() === $this->checkout->reg_url_link |
|
1170 | - ) { |
|
1171 | - $valid_registrant = $registration; |
|
1172 | - } |
|
1173 | - } |
|
1174 | - if (! $valid_registrant instanceof EE_Registration) { |
|
1175 | - // hmmm... maybe we have the wrong session because the user is opening multiple tabs ? |
|
1176 | - if (EED_Single_Page_Checkout::$_checkout_verified) { |
|
1177 | - // clear the session, mark the checkout as unverified, and try again |
|
1178 | - EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
1179 | - EED_Single_Page_Checkout::$_initialized = false; |
|
1180 | - EED_Single_Page_Checkout::$_checkout_verified = false; |
|
1181 | - $this->_initialize(); |
|
1182 | - EE_Error::reset_notices(); |
|
1183 | - return false; |
|
1184 | - } |
|
1185 | - EE_Error::add_error( |
|
1186 | - esc_html__( |
|
1187 | - '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.', |
|
1188 | - 'event_espresso' |
|
1189 | - ), |
|
1190 | - __FILE__, |
|
1191 | - __FUNCTION__, |
|
1192 | - __LINE__ |
|
1193 | - ); |
|
1194 | - return false; |
|
1195 | - } |
|
1196 | - } |
|
1197 | - // now that things have been kinda sufficiently verified, |
|
1198 | - // let's add the checkout to the session so that it's available to other systems |
|
1199 | - EE_Registry::instance()->SSN->set_checkout($this->checkout); |
|
1200 | - return true; |
|
1201 | - } |
|
1202 | - |
|
1203 | - |
|
1204 | - /** |
|
1205 | - * _initialize_reg_steps |
|
1206 | - * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required |
|
1207 | - * then loops thru all of the active reg steps and calls the initialize_reg_step() method |
|
1208 | - * |
|
1209 | - * @access private |
|
1210 | - * @param bool $reinitializing |
|
1211 | - * @throws EE_Error |
|
1212 | - */ |
|
1213 | - private function _initialize_reg_steps($reinitializing = false) |
|
1214 | - { |
|
1215 | - $this->checkout->set_reg_step_initiated($this->checkout->current_step); |
|
1216 | - // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS |
|
1217 | - foreach ($this->checkout->reg_steps as $reg_step) { |
|
1218 | - if (! $reg_step->initialize_reg_step()) { |
|
1219 | - // if not initialized then maybe this step is being removed... |
|
1220 | - if (! $reinitializing && $reg_step->is_current_step()) { |
|
1221 | - // if it was the current step, then we need to start over here |
|
1222 | - $this->_initialize_reg_steps(true); |
|
1223 | - return; |
|
1224 | - } |
|
1225 | - continue; |
|
1226 | - } |
|
1227 | - // add css and JS for current step |
|
1228 | - $this->add_styles_and_scripts($reg_step); |
|
1229 | - if ($reg_step->is_current_step()) { |
|
1230 | - // the text that appears on the reg step form submit button |
|
1231 | - $reg_step->set_submit_button_text(); |
|
1232 | - } |
|
1233 | - } |
|
1234 | - // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information |
|
1235 | - do_action( |
|
1236 | - "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", |
|
1237 | - $this->checkout->current_step |
|
1238 | - ); |
|
1239 | - } |
|
1240 | - |
|
1241 | - |
|
1242 | - /** |
|
1243 | - * _check_form_submission |
|
1244 | - * |
|
1245 | - * @access private |
|
1246 | - * @return boolean |
|
1247 | - */ |
|
1248 | - private function _check_form_submission() |
|
1249 | - { |
|
1250 | - // does this request require the reg form to be generated ? |
|
1251 | - if ($this->checkout->generate_reg_form) { |
|
1252 | - // ever heard that song by Blue Rodeo ? |
|
1253 | - try { |
|
1254 | - $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form(); |
|
1255 | - // if not displaying a form, then check for form submission |
|
1256 | - if ($this->checkout->process_form_submission |
|
1257 | - && $this->checkout->current_step->reg_form->was_submitted() |
|
1258 | - ) { |
|
1259 | - // clear out any old data in case this step is being run again |
|
1260 | - $this->checkout->current_step->set_valid_data(array()); |
|
1261 | - // capture submitted form data |
|
1262 | - $this->checkout->current_step->reg_form->receive_form_submission( |
|
1263 | - apply_filters( |
|
1264 | - 'FHEE__Single_Page_Checkout___check_form_submission__request_params', |
|
1265 | - EE_Registry::instance()->REQ->params(), |
|
1266 | - $this->checkout |
|
1267 | - ) |
|
1268 | - ); |
|
1269 | - // validate submitted form data |
|
1270 | - if (! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) { |
|
1271 | - // thou shall not pass !!! |
|
1272 | - $this->checkout->continue_reg = false; |
|
1273 | - // any form validation errors? |
|
1274 | - if ($this->checkout->current_step->reg_form->submission_error_message() !== '') { |
|
1275 | - EE_Error::add_error( |
|
1276 | - $this->checkout->current_step->reg_form->submission_error_message(), |
|
1277 | - __FILE__, |
|
1278 | - __FUNCTION__, |
|
1279 | - __LINE__ |
|
1280 | - ); |
|
1281 | - } |
|
1282 | - // well not really... what will happen is |
|
1283 | - // we'll just get redirected back to redo the current step |
|
1284 | - $this->go_to_next_step(); |
|
1285 | - return false; |
|
1286 | - } |
|
1287 | - } |
|
1288 | - } catch (EE_Error $e) { |
|
1289 | - $e->get_error(); |
|
1290 | - } |
|
1291 | - } |
|
1292 | - return true; |
|
1293 | - } |
|
1294 | - |
|
1295 | - |
|
1296 | - /** |
|
1297 | - * _process_action |
|
1298 | - * |
|
1299 | - * @access private |
|
1300 | - * @return void |
|
1301 | - * @throws EE_Error |
|
1302 | - */ |
|
1303 | - private function _process_form_action() |
|
1304 | - { |
|
1305 | - // what cha wanna do? |
|
1306 | - switch ($this->checkout->action) { |
|
1307 | - // AJAX next step reg form |
|
1308 | - case 'display_spco_reg_step': |
|
1309 | - $this->checkout->redirect = false; |
|
1310 | - if (EE_Registry::instance()->REQ->ajax) { |
|
1311 | - $this->checkout->json_response->set_reg_step_html( |
|
1312 | - $this->checkout->current_step->display_reg_form() |
|
1313 | - ); |
|
1314 | - } |
|
1315 | - break; |
|
1316 | - default: |
|
1317 | - // meh... do one of those other steps first |
|
1318 | - if (! empty($this->checkout->action) |
|
1319 | - && is_callable(array($this->checkout->current_step, $this->checkout->action)) |
|
1320 | - ) { |
|
1321 | - // dynamically creates hook point like: |
|
1322 | - // AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step |
|
1323 | - do_action( |
|
1324 | - "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
1325 | - $this->checkout->current_step |
|
1326 | - ); |
|
1327 | - // call action on current step |
|
1328 | - if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) { |
|
1329 | - // good registrant, you get to proceed |
|
1330 | - if ($this->checkout->current_step->success_message() !== '' |
|
1331 | - && apply_filters( |
|
1332 | - 'FHEE__Single_Page_Checkout___process_form_action__display_success', |
|
1333 | - false |
|
1334 | - ) |
|
1335 | - ) { |
|
1336 | - EE_Error::add_success( |
|
1337 | - $this->checkout->current_step->success_message() |
|
1338 | - . '<br />' . $this->checkout->next_step->_instructions() |
|
1339 | - ); |
|
1340 | - } |
|
1341 | - // pack it up, pack it in... |
|
1342 | - $this->_setup_redirect(); |
|
1343 | - } |
|
1344 | - // dynamically creates hook point like: |
|
1345 | - // AHEE__Single_Page_Checkout__after_payment_options__process_reg_step |
|
1346 | - do_action( |
|
1347 | - "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
1348 | - $this->checkout->current_step |
|
1349 | - ); |
|
1350 | - } else { |
|
1351 | - EE_Error::add_error( |
|
1352 | - sprintf( |
|
1353 | - esc_html__( |
|
1354 | - 'The requested form action "%s" does not exist for the current "%s" registration step.', |
|
1355 | - 'event_espresso' |
|
1356 | - ), |
|
1357 | - $this->checkout->action, |
|
1358 | - $this->checkout->current_step->name() |
|
1359 | - ), |
|
1360 | - __FILE__, |
|
1361 | - __FUNCTION__, |
|
1362 | - __LINE__ |
|
1363 | - ); |
|
1364 | - } |
|
1365 | - // end default |
|
1366 | - } |
|
1367 | - // store our progress so far |
|
1368 | - $this->checkout->stash_transaction_and_checkout(); |
|
1369 | - // advance to the next step! If you pass GO, collect $200 |
|
1370 | - $this->go_to_next_step(); |
|
1371 | - } |
|
1372 | - |
|
1373 | - |
|
1374 | - /** |
|
1375 | - * @param EED_Single_Page_Checkout|EE_SPCO_Reg_Step $target |
|
1376 | - * @param object $target an object with the method `translate_js_strings` and `enqueue_styles_and_scripts`. |
|
1377 | - * @return void |
|
1378 | - */ |
|
1379 | - public function add_styles_and_scripts($target) |
|
1380 | - { |
|
1381 | - // i18n |
|
1382 | - $target->translate_js_strings(); |
|
1383 | - if ($this->checkout->admin_request) { |
|
1384 | - add_action('admin_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
1385 | - } else { |
|
1386 | - add_action('wp_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
1387 | - } |
|
1388 | - } |
|
1389 | - |
|
1390 | - /** |
|
1391 | - * translate_js_strings |
|
1392 | - * |
|
1393 | - * @access public |
|
1394 | - * @return void |
|
1395 | - */ |
|
1396 | - public function translate_js_strings() |
|
1397 | - { |
|
1398 | - EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit; |
|
1399 | - EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link; |
|
1400 | - EE_Registry::$i18n_js_strings['server_error'] = esc_html__( |
|
1401 | - 'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
1402 | - 'event_espresso' |
|
1403 | - ); |
|
1404 | - EE_Registry::$i18n_js_strings['invalid_json_response'] = esc_html__( |
|
1405 | - 'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
1406 | - 'event_espresso' |
|
1407 | - ); |
|
1408 | - EE_Registry::$i18n_js_strings['validation_error'] = esc_html__( |
|
1409 | - 'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', |
|
1410 | - 'event_espresso' |
|
1411 | - ); |
|
1412 | - EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__( |
|
1413 | - 'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', |
|
1414 | - 'event_espresso' |
|
1415 | - ); |
|
1416 | - EE_Registry::$i18n_js_strings['reg_step_error'] = esc_html__( |
|
1417 | - 'This registration step could not be completed. Please refresh the page and try again.', |
|
1418 | - 'event_espresso' |
|
1419 | - ); |
|
1420 | - EE_Registry::$i18n_js_strings['invalid_coupon'] = esc_html__( |
|
1421 | - 'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', |
|
1422 | - 'event_espresso' |
|
1423 | - ); |
|
1424 | - EE_Registry::$i18n_js_strings['process_registration'] = sprintf( |
|
1425 | - esc_html__( |
|
1426 | - 'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', |
|
1427 | - 'event_espresso' |
|
1428 | - ), |
|
1429 | - '<br/>', |
|
1430 | - '<br/>' |
|
1431 | - ); |
|
1432 | - EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language'); |
|
1433 | - EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id(); |
|
1434 | - EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency; |
|
1435 | - EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20'; |
|
1436 | - EE_Registry::$i18n_js_strings['timer_years'] = esc_html__('years', 'event_espresso'); |
|
1437 | - EE_Registry::$i18n_js_strings['timer_months'] = esc_html__('months', 'event_espresso'); |
|
1438 | - EE_Registry::$i18n_js_strings['timer_weeks'] = esc_html__('weeks', 'event_espresso'); |
|
1439 | - EE_Registry::$i18n_js_strings['timer_days'] = esc_html__('days', 'event_espresso'); |
|
1440 | - EE_Registry::$i18n_js_strings['timer_hours'] = esc_html__('hours', 'event_espresso'); |
|
1441 | - EE_Registry::$i18n_js_strings['timer_minutes'] = esc_html__('minutes', 'event_espresso'); |
|
1442 | - EE_Registry::$i18n_js_strings['timer_seconds'] = esc_html__('seconds', 'event_espresso'); |
|
1443 | - EE_Registry::$i18n_js_strings['timer_year'] = esc_html__('year', 'event_espresso'); |
|
1444 | - EE_Registry::$i18n_js_strings['timer_month'] = esc_html__('month', 'event_espresso'); |
|
1445 | - EE_Registry::$i18n_js_strings['timer_week'] = esc_html__('week', 'event_espresso'); |
|
1446 | - EE_Registry::$i18n_js_strings['timer_day'] = esc_html__('day', 'event_espresso'); |
|
1447 | - EE_Registry::$i18n_js_strings['timer_hour'] = esc_html__('hour', 'event_espresso'); |
|
1448 | - EE_Registry::$i18n_js_strings['timer_minute'] = esc_html__('minute', 'event_espresso'); |
|
1449 | - EE_Registry::$i18n_js_strings['timer_second'] = esc_html__('second', 'event_espresso'); |
|
1450 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
1451 | - ); |
|
1452 | - EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters( |
|
1453 | - 'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', |
|
1454 | - true |
|
1455 | - ); |
|
1456 | - EE_Registry::$i18n_js_strings['session_extension'] = absint( |
|
1457 | - apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS) |
|
1458 | - ); |
|
1459 | - EE_Registry::$i18n_js_strings['session_expiration'] = gmdate( |
|
1460 | - 'M d, Y H:i:s', |
|
1461 | - EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
1462 | - ); |
|
1463 | - } |
|
1464 | - |
|
1465 | - |
|
1466 | - /** |
|
1467 | - * enqueue_styles_and_scripts |
|
1468 | - * |
|
1469 | - * @access public |
|
1470 | - * @return void |
|
1471 | - * @throws EE_Error |
|
1472 | - */ |
|
1473 | - public function enqueue_styles_and_scripts() |
|
1474 | - { |
|
1475 | - // load css |
|
1476 | - wp_register_style( |
|
1477 | - 'single_page_checkout', |
|
1478 | - SPCO_CSS_URL . 'single_page_checkout.css', |
|
1479 | - array('espresso_default'), |
|
1480 | - EVENT_ESPRESSO_VERSION |
|
1481 | - ); |
|
1482 | - wp_enqueue_style('single_page_checkout'); |
|
1483 | - // load JS |
|
1484 | - wp_register_script( |
|
1485 | - 'jquery_plugin', |
|
1486 | - EE_THIRD_PARTY_URL . 'jquery .plugin.min.js', |
|
1487 | - array('jquery'), |
|
1488 | - '1.0.1', |
|
1489 | - true |
|
1490 | - ); |
|
1491 | - wp_register_script( |
|
1492 | - 'jquery_countdown', |
|
1493 | - EE_THIRD_PARTY_URL . 'jquery .countdown.min.js', |
|
1494 | - array('jquery_plugin'), |
|
1495 | - '2.1.0', |
|
1496 | - true |
|
1497 | - ); |
|
1498 | - wp_register_script( |
|
1499 | - 'single_page_checkout', |
|
1500 | - SPCO_JS_URL . 'single_page_checkout.js', |
|
1501 | - array('espresso_core', 'underscore', 'ee_form_section_validation'), |
|
1502 | - EVENT_ESPRESSO_VERSION, |
|
1503 | - true |
|
1504 | - ); |
|
1505 | - if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) { |
|
1506 | - $this->checkout->registration_form->enqueue_js(); |
|
1507 | - } |
|
1508 | - if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) { |
|
1509 | - $this->checkout->current_step->reg_form->enqueue_js(); |
|
1510 | - } |
|
1511 | - wp_enqueue_script('single_page_checkout'); |
|
1512 | - if (apply_filters('FHEE__registration_page_wrapper_template__display_time_limit', false)) { |
|
1513 | - wp_enqueue_script('jquery_countdown'); |
|
1514 | - } |
|
1515 | - /** |
|
1516 | - * global action hook for enqueueing styles and scripts with |
|
1517 | - * spco calls. |
|
1518 | - */ |
|
1519 | - do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this); |
|
1520 | - /** |
|
1521 | - * dynamic action hook for enqueueing styles and scripts with spco calls. |
|
1522 | - * The hook will end up being something like: |
|
1523 | - * AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information |
|
1524 | - */ |
|
1525 | - do_action( |
|
1526 | - 'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), |
|
1527 | - $this |
|
1528 | - ); |
|
1529 | - } |
|
1530 | - |
|
1531 | - |
|
1532 | - /** |
|
1533 | - * display the Registration Single Page Checkout Form |
|
1534 | - * |
|
1535 | - * @access private |
|
1536 | - * @return void |
|
1537 | - * @throws EE_Error |
|
1538 | - */ |
|
1539 | - private function _display_spco_reg_form() |
|
1540 | - { |
|
1541 | - // if registering via the admin, just display the reg form for the current step |
|
1542 | - if ($this->checkout->admin_request) { |
|
1543 | - EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form()); |
|
1544 | - } else { |
|
1545 | - // add powered by EE msg |
|
1546 | - add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer')); |
|
1547 | - $empty_cart = count($this->checkout->transaction |
|
1548 | - ->registrations($this->checkout->reg_cache_where_params)) < 1; |
|
1549 | - EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart; |
|
1550 | - $cookies_not_set_msg = ''; |
|
1551 | - if ($empty_cart) { |
|
1552 | - $cookies_not_set_msg = apply_filters( |
|
1553 | - 'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg', |
|
1554 | - sprintf( |
|
1555 | - esc_html__( |
|
1556 | - '%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', |
|
1557 | - 'event_espresso' |
|
1558 | - ), |
|
1559 | - '<div class="ee-attention hidden" id="ee-cookies-not-set-msg">', |
|
1560 | - '</div>', |
|
1561 | - '<h6 class="important-notice">', |
|
1562 | - '</h6>', |
|
1563 | - '<p>', |
|
1564 | - '</p>', |
|
1565 | - '<br />', |
|
1566 | - '<a href="http://www.whatarecookies.com/enable.asp" target="_blank" rel="noopener noreferrer">', |
|
1567 | - '</a>' |
|
1568 | - ) |
|
1569 | - ); |
|
1570 | - } |
|
1571 | - $this->checkout->registration_form = new EE_Form_Section_Proper( |
|
1572 | - array( |
|
1573 | - 'name' => 'single-page-checkout', |
|
1574 | - 'html_id' => 'ee-single-page-checkout-dv', |
|
1575 | - 'layout_strategy' => |
|
1576 | - new EE_Template_Layout( |
|
1577 | - array( |
|
1578 | - 'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php', |
|
1579 | - 'template_args' => array( |
|
1580 | - 'empty_cart' => $empty_cart, |
|
1581 | - 'revisit' => $this->checkout->revisit, |
|
1582 | - 'reg_steps' => $this->checkout->reg_steps, |
|
1583 | - 'next_step' => $this->checkout->next_step instanceof EE_SPCO_Reg_Step |
|
1584 | - ? $this->checkout->next_step->slug() |
|
1585 | - : '', |
|
1586 | - 'empty_msg' => apply_filters( |
|
1587 | - 'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg', |
|
1588 | - sprintf( |
|
1589 | - esc_html__( |
|
1590 | - 'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', |
|
1591 | - 'event_espresso' |
|
1592 | - ), |
|
1593 | - '<a href="' |
|
1594 | - . get_post_type_archive_link('espresso_events') |
|
1595 | - . '" title="', |
|
1596 | - '">', |
|
1597 | - '</a>' |
|
1598 | - ) |
|
1599 | - ), |
|
1600 | - 'cookies_not_set_msg' => $cookies_not_set_msg, |
|
1601 | - 'registration_time_limit' => $this->checkout->get_registration_time_limit(), |
|
1602 | - 'session_expiration' => gmdate( |
|
1603 | - 'M d, Y H:i:s', |
|
1604 | - EE_Registry::instance()->SSN->expiration() |
|
1605 | - + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
1606 | - ), |
|
1607 | - ), |
|
1608 | - ) |
|
1609 | - ), |
|
1610 | - ) |
|
1611 | - ); |
|
1612 | - // load template and add to output sent that gets filtered into the_content() |
|
1613 | - EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html()); |
|
1614 | - } |
|
1615 | - } |
|
1616 | - |
|
1617 | - |
|
1618 | - /** |
|
1619 | - * add_extra_finalize_registration_inputs |
|
1620 | - * |
|
1621 | - * @access public |
|
1622 | - * @param $next_step |
|
1623 | - * @internal param string $label |
|
1624 | - * @return void |
|
1625 | - */ |
|
1626 | - public function add_extra_finalize_registration_inputs($next_step) |
|
1627 | - { |
|
1628 | - if ($next_step === 'finalize_registration') { |
|
1629 | - echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>'; |
|
1630 | - } |
|
1631 | - } |
|
1632 | - |
|
1633 | - |
|
1634 | - /** |
|
1635 | - * display_registration_footer |
|
1636 | - * |
|
1637 | - * @access public |
|
1638 | - * @return string |
|
1639 | - */ |
|
1640 | - public static function display_registration_footer() |
|
1641 | - { |
|
1642 | - if (apply_filters( |
|
1643 | - 'FHEE__EE_Front__Controller__show_reg_footer', |
|
1644 | - EE_Registry::instance()->CFG->admin->show_reg_footer |
|
1645 | - )) { |
|
1646 | - add_filter( |
|
1647 | - 'FHEE__EEH_Template__powered_by_event_espresso__url', |
|
1648 | - function ($url) { |
|
1649 | - return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url); |
|
1650 | - } |
|
1651 | - ); |
|
1652 | - echo apply_filters( |
|
1653 | - 'FHEE__EE_Front_Controller__display_registration_footer', |
|
1654 | - \EEH_Template::powered_by_event_espresso( |
|
1655 | - '', |
|
1656 | - 'espresso-registration-footer-dv', |
|
1657 | - array('utm_content' => 'registration_checkout') |
|
1658 | - ) |
|
1659 | - ); |
|
1660 | - } |
|
1661 | - return ''; |
|
1662 | - } |
|
1663 | - |
|
1664 | - |
|
1665 | - /** |
|
1666 | - * unlock_transaction |
|
1667 | - * |
|
1668 | - * @access public |
|
1669 | - * @return void |
|
1670 | - * @throws EE_Error |
|
1671 | - */ |
|
1672 | - public function unlock_transaction() |
|
1673 | - { |
|
1674 | - if ($this->checkout->transaction instanceof EE_Transaction) { |
|
1675 | - $this->checkout->transaction->unlock(); |
|
1676 | - } |
|
1677 | - } |
|
1678 | - |
|
1679 | - |
|
1680 | - /** |
|
1681 | - * _setup_redirect |
|
1682 | - * |
|
1683 | - * @access private |
|
1684 | - * @return void |
|
1685 | - */ |
|
1686 | - private function _setup_redirect() |
|
1687 | - { |
|
1688 | - if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) { |
|
1689 | - $this->checkout->redirect = true; |
|
1690 | - if (empty($this->checkout->redirect_url)) { |
|
1691 | - $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url(); |
|
1692 | - } |
|
1693 | - $this->checkout->redirect_url = apply_filters( |
|
1694 | - 'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url', |
|
1695 | - $this->checkout->redirect_url, |
|
1696 | - $this->checkout |
|
1697 | - ); |
|
1698 | - } |
|
1699 | - } |
|
1700 | - |
|
1701 | - |
|
1702 | - /** |
|
1703 | - * handle ajax message responses and redirects |
|
1704 | - * |
|
1705 | - * @access public |
|
1706 | - * @return void |
|
1707 | - * @throws EE_Error |
|
1708 | - */ |
|
1709 | - public function go_to_next_step() |
|
1710 | - { |
|
1711 | - if (EE_Registry::instance()->REQ->ajax) { |
|
1712 | - // capture contents of output buffer we started earlier in the request, and insert into JSON response |
|
1713 | - $this->checkout->json_response->set_unexpected_errors(ob_get_clean()); |
|
1714 | - } |
|
1715 | - $this->unlock_transaction(); |
|
1716 | - // just return for these conditions |
|
1717 | - if ($this->checkout->admin_request |
|
1718 | - || $this->checkout->action === 'redirect_form' |
|
1719 | - || $this->checkout->action === 'update_checkout' |
|
1720 | - ) { |
|
1721 | - return; |
|
1722 | - } |
|
1723 | - // AJAX response |
|
1724 | - $this->_handle_json_response(); |
|
1725 | - // redirect to next step or the Thank You page |
|
1726 | - $this->_handle_html_redirects(); |
|
1727 | - // hmmm... must be something wrong, so let's just display the form again ! |
|
1728 | - $this->_display_spco_reg_form(); |
|
1729 | - } |
|
1730 | - |
|
1731 | - |
|
1732 | - /** |
|
1733 | - * _handle_json_response |
|
1734 | - * |
|
1735 | - * @access protected |
|
1736 | - * @return void |
|
1737 | - */ |
|
1738 | - protected function _handle_json_response() |
|
1739 | - { |
|
1740 | - // if this is an ajax request |
|
1741 | - if (EE_Registry::instance()->REQ->ajax) { |
|
1742 | - $this->checkout->json_response->set_registration_time_limit( |
|
1743 | - $this->checkout->get_registration_time_limit() |
|
1744 | - ); |
|
1745 | - $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing); |
|
1746 | - // just send the ajax ( |
|
1747 | - $json_response = apply_filters( |
|
1748 | - 'FHEE__EE_Single_Page_Checkout__JSON_response', |
|
1749 | - $this->checkout->json_response |
|
1750 | - ); |
|
1751 | - echo $json_response; |
|
1752 | - exit(); |
|
1753 | - } |
|
1754 | - } |
|
1755 | - |
|
1756 | - |
|
1757 | - /** |
|
1758 | - * _handle_redirects |
|
1759 | - * |
|
1760 | - * @access protected |
|
1761 | - * @return void |
|
1762 | - */ |
|
1763 | - protected function _handle_html_redirects() |
|
1764 | - { |
|
1765 | - // going somewhere ? |
|
1766 | - if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) { |
|
1767 | - // store notices in a transient |
|
1768 | - EE_Error::get_notices(false, true, true); |
|
1769 | - wp_safe_redirect($this->checkout->redirect_url); |
|
1770 | - exit(); |
|
1771 | - } |
|
1772 | - } |
|
1773 | - |
|
1774 | - |
|
1775 | - /** |
|
1776 | - * set_checkout_anchor |
|
1777 | - * |
|
1778 | - * @access public |
|
1779 | - * @return void |
|
1780 | - */ |
|
1781 | - public function set_checkout_anchor() |
|
1782 | - { |
|
1783 | - echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>'; |
|
1784 | - } |
|
1785 | - |
|
1786 | - /** |
|
1787 | - * getRegistrationExpirationNotice |
|
1788 | - * |
|
1789 | - * @since 4.9.59.p |
|
1790 | - * @access public |
|
1791 | - * @return string |
|
1792 | - */ |
|
1793 | - public static function getRegistrationExpirationNotice() |
|
1794 | - { |
|
1795 | - return sprintf( |
|
1796 | - esc_html__( |
|
1797 | - '%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 accept our apologies for any inconvenience this may have caused.%8$s', |
|
1798 | - 'event_espresso' |
|
1799 | - ), |
|
1800 | - '<h4 class="important-notice">', |
|
1801 | - '</h4>', |
|
1802 | - '<br />', |
|
1803 | - '<p>', |
|
1804 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1805 | - '">', |
|
1806 | - '</a>', |
|
1807 | - '</p>' |
|
1808 | - ); |
|
1809 | - } |
|
18 | + /** |
|
19 | + * $_initialized - has the SPCO controller already been initialized ? |
|
20 | + * |
|
21 | + * @access private |
|
22 | + * @var bool $_initialized |
|
23 | + */ |
|
24 | + private static $_initialized = false; |
|
25 | + |
|
26 | + |
|
27 | + /** |
|
28 | + * $_checkout_verified - is the EE_Checkout verified as correct for this request ? |
|
29 | + * |
|
30 | + * @access private |
|
31 | + * @var bool $_valid_checkout |
|
32 | + */ |
|
33 | + private static $_checkout_verified = true; |
|
34 | + |
|
35 | + /** |
|
36 | + * $_reg_steps_array - holds initial array of reg steps |
|
37 | + * |
|
38 | + * @access private |
|
39 | + * @var array $_reg_steps_array |
|
40 | + */ |
|
41 | + private static $_reg_steps_array = array(); |
|
42 | + |
|
43 | + /** |
|
44 | + * $checkout - EE_Checkout object for handling the properties of the current checkout process |
|
45 | + * |
|
46 | + * @access public |
|
47 | + * @var EE_Checkout $checkout |
|
48 | + */ |
|
49 | + public $checkout; |
|
50 | + |
|
51 | + |
|
52 | + /** |
|
53 | + * @return EED_Module|EED_Single_Page_Checkout |
|
54 | + */ |
|
55 | + public static function instance() |
|
56 | + { |
|
57 | + add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true'); |
|
58 | + return parent::get_instance(__CLASS__); |
|
59 | + } |
|
60 | + |
|
61 | + |
|
62 | + /** |
|
63 | + * @return EE_CART |
|
64 | + */ |
|
65 | + public function cart() |
|
66 | + { |
|
67 | + return $this->checkout->cart; |
|
68 | + } |
|
69 | + |
|
70 | + |
|
71 | + /** |
|
72 | + * @return EE_Transaction |
|
73 | + */ |
|
74 | + public function transaction() |
|
75 | + { |
|
76 | + return $this->checkout->transaction; |
|
77 | + } |
|
78 | + |
|
79 | + |
|
80 | + /** |
|
81 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
82 | + * |
|
83 | + * @access public |
|
84 | + * @return void |
|
85 | + * @throws EE_Error |
|
86 | + */ |
|
87 | + public static function set_hooks() |
|
88 | + { |
|
89 | + EED_Single_Page_Checkout::set_definitions(); |
|
90 | + } |
|
91 | + |
|
92 | + |
|
93 | + /** |
|
94 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
95 | + * |
|
96 | + * @access public |
|
97 | + * @return void |
|
98 | + * @throws EE_Error |
|
99 | + */ |
|
100 | + public static function set_hooks_admin() |
|
101 | + { |
|
102 | + EED_Single_Page_Checkout::set_definitions(); |
|
103 | + if (! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
104 | + return; |
|
105 | + } |
|
106 | + // going to start an output buffer in case anything gets accidentally output |
|
107 | + // that might disrupt our JSON response |
|
108 | + ob_start(); |
|
109 | + EED_Single_Page_Checkout::load_request_handler(); |
|
110 | + EED_Single_Page_Checkout::load_reg_steps(); |
|
111 | + // set ajax hooks |
|
112 | + add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
113 | + add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
114 | + add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
115 | + add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
116 | + add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
117 | + add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
118 | + } |
|
119 | + |
|
120 | + |
|
121 | + /** |
|
122 | + * process ajax request |
|
123 | + * |
|
124 | + * @param string $ajax_action |
|
125 | + * @throws EE_Error |
|
126 | + */ |
|
127 | + public static function process_ajax_request($ajax_action) |
|
128 | + { |
|
129 | + EE_Registry::instance()->REQ->set('action', $ajax_action); |
|
130 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
131 | + } |
|
132 | + |
|
133 | + |
|
134 | + /** |
|
135 | + * ajax display registration step |
|
136 | + * |
|
137 | + * @throws EE_Error |
|
138 | + */ |
|
139 | + public static function display_reg_step() |
|
140 | + { |
|
141 | + EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step'); |
|
142 | + } |
|
143 | + |
|
144 | + |
|
145 | + /** |
|
146 | + * ajax process registration step |
|
147 | + * |
|
148 | + * @throws EE_Error |
|
149 | + */ |
|
150 | + public static function process_reg_step() |
|
151 | + { |
|
152 | + EED_Single_Page_Checkout::process_ajax_request('process_reg_step'); |
|
153 | + } |
|
154 | + |
|
155 | + |
|
156 | + /** |
|
157 | + * ajax process registration step |
|
158 | + * |
|
159 | + * @throws EE_Error |
|
160 | + */ |
|
161 | + public static function update_reg_step() |
|
162 | + { |
|
163 | + EED_Single_Page_Checkout::process_ajax_request('update_reg_step'); |
|
164 | + } |
|
165 | + |
|
166 | + |
|
167 | + /** |
|
168 | + * update_checkout |
|
169 | + * |
|
170 | + * @access public |
|
171 | + * @return void |
|
172 | + * @throws EE_Error |
|
173 | + */ |
|
174 | + public static function update_checkout() |
|
175 | + { |
|
176 | + EED_Single_Page_Checkout::process_ajax_request('update_checkout'); |
|
177 | + } |
|
178 | + |
|
179 | + |
|
180 | + /** |
|
181 | + * load_request_handler |
|
182 | + * |
|
183 | + * @access public |
|
184 | + * @return void |
|
185 | + */ |
|
186 | + public static function load_request_handler() |
|
187 | + { |
|
188 | + // load core Request_Handler class |
|
189 | + if (EE_Registry::instance()->REQ !== null) { |
|
190 | + EE_Registry::instance()->load_core('Request_Handler'); |
|
191 | + } |
|
192 | + } |
|
193 | + |
|
194 | + |
|
195 | + /** |
|
196 | + * set_definitions |
|
197 | + * |
|
198 | + * @access public |
|
199 | + * @return void |
|
200 | + * @throws EE_Error |
|
201 | + */ |
|
202 | + public static function set_definitions() |
|
203 | + { |
|
204 | + if (defined('SPCO_BASE_PATH')) { |
|
205 | + return; |
|
206 | + } |
|
207 | + define( |
|
208 | + 'SPCO_BASE_PATH', |
|
209 | + rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/') . '/' |
|
210 | + ); |
|
211 | + define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css/'); |
|
212 | + define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img/'); |
|
213 | + define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js/'); |
|
214 | + define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc/'); |
|
215 | + define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps/'); |
|
216 | + define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates/'); |
|
217 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true); |
|
218 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
219 | + ); |
|
220 | + } |
|
221 | + |
|
222 | + |
|
223 | + /** |
|
224 | + * load_reg_steps |
|
225 | + * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array |
|
226 | + * |
|
227 | + * @access private |
|
228 | + * @throws EE_Error |
|
229 | + */ |
|
230 | + public static function load_reg_steps() |
|
231 | + { |
|
232 | + static $reg_steps_loaded = false; |
|
233 | + if ($reg_steps_loaded) { |
|
234 | + return; |
|
235 | + } |
|
236 | + // filter list of reg_steps |
|
237 | + $reg_steps_to_load = (array) apply_filters( |
|
238 | + 'AHEE__SPCO__load_reg_steps__reg_steps_to_load', |
|
239 | + EED_Single_Page_Checkout::get_reg_steps() |
|
240 | + ); |
|
241 | + // sort by key (order) |
|
242 | + ksort($reg_steps_to_load); |
|
243 | + // loop through folders |
|
244 | + foreach ($reg_steps_to_load as $order => $reg_step) { |
|
245 | + // we need a |
|
246 | + if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
247 | + // copy over to the reg_steps_array |
|
248 | + EED_Single_Page_Checkout::$_reg_steps_array[ $order ] = $reg_step; |
|
249 | + // register custom key route for each reg step |
|
250 | + // ie: step=>"slug" - this is the entire reason we load the reg steps array now |
|
251 | + EE_Config::register_route( |
|
252 | + $reg_step['slug'], |
|
253 | + 'EED_Single_Page_Checkout', |
|
254 | + 'run', |
|
255 | + 'step' |
|
256 | + ); |
|
257 | + // add AJAX or other hooks |
|
258 | + if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) { |
|
259 | + // setup autoloaders if necessary |
|
260 | + if (! class_exists($reg_step['class_name'])) { |
|
261 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder( |
|
262 | + $reg_step['file_path'], |
|
263 | + true |
|
264 | + ); |
|
265 | + } |
|
266 | + if (is_callable($reg_step['class_name'], 'set_hooks')) { |
|
267 | + call_user_func(array($reg_step['class_name'], 'set_hooks')); |
|
268 | + } |
|
269 | + } |
|
270 | + } |
|
271 | + } |
|
272 | + $reg_steps_loaded = true; |
|
273 | + } |
|
274 | + |
|
275 | + |
|
276 | + /** |
|
277 | + * get_reg_steps |
|
278 | + * |
|
279 | + * @access public |
|
280 | + * @return array |
|
281 | + */ |
|
282 | + public static function get_reg_steps() |
|
283 | + { |
|
284 | + $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps; |
|
285 | + if (empty($reg_steps)) { |
|
286 | + $reg_steps = array( |
|
287 | + 10 => array( |
|
288 | + 'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information', |
|
289 | + 'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information', |
|
290 | + 'slug' => 'attendee_information', |
|
291 | + 'has_hooks' => false, |
|
292 | + ), |
|
293 | + 30 => array( |
|
294 | + 'file_path' => SPCO_REG_STEPS_PATH . 'payment_options', |
|
295 | + 'class_name' => 'EE_SPCO_Reg_Step_Payment_Options', |
|
296 | + 'slug' => 'payment_options', |
|
297 | + 'has_hooks' => true, |
|
298 | + ), |
|
299 | + 999 => array( |
|
300 | + 'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration', |
|
301 | + 'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration', |
|
302 | + 'slug' => 'finalize_registration', |
|
303 | + 'has_hooks' => false, |
|
304 | + ), |
|
305 | + ); |
|
306 | + } |
|
307 | + return $reg_steps; |
|
308 | + } |
|
309 | + |
|
310 | + |
|
311 | + /** |
|
312 | + * registration_checkout_for_admin |
|
313 | + * |
|
314 | + * @access public |
|
315 | + * @return string |
|
316 | + * @throws EE_Error |
|
317 | + */ |
|
318 | + public static function registration_checkout_for_admin() |
|
319 | + { |
|
320 | + EED_Single_Page_Checkout::load_request_handler(); |
|
321 | + EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
322 | + EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step'); |
|
323 | + EE_Registry::instance()->REQ->set('process_form_submission', false); |
|
324 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
325 | + EED_Single_Page_Checkout::instance()->_display_spco_reg_form(); |
|
326 | + return EE_Registry::instance()->REQ->get_output(); |
|
327 | + } |
|
328 | + |
|
329 | + |
|
330 | + /** |
|
331 | + * process_registration_from_admin |
|
332 | + * |
|
333 | + * @access public |
|
334 | + * @return \EE_Transaction |
|
335 | + * @throws EE_Error |
|
336 | + */ |
|
337 | + public static function process_registration_from_admin() |
|
338 | + { |
|
339 | + EED_Single_Page_Checkout::load_request_handler(); |
|
340 | + EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
341 | + EE_Registry::instance()->REQ->set('action', 'process_reg_step'); |
|
342 | + EE_Registry::instance()->REQ->set('process_form_submission', true); |
|
343 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
344 | + if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) { |
|
345 | + $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps); |
|
346 | + if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) { |
|
347 | + EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step); |
|
348 | + if ($final_reg_step->process_reg_step()) { |
|
349 | + $final_reg_step->set_completed(); |
|
350 | + EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array(); |
|
351 | + return EED_Single_Page_Checkout::instance()->checkout->transaction; |
|
352 | + } |
|
353 | + } |
|
354 | + } |
|
355 | + return null; |
|
356 | + } |
|
357 | + |
|
358 | + |
|
359 | + /** |
|
360 | + * run |
|
361 | + * |
|
362 | + * @access public |
|
363 | + * @param WP_Query $WP_Query |
|
364 | + * @return void |
|
365 | + * @throws EE_Error |
|
366 | + */ |
|
367 | + public function run($WP_Query) |
|
368 | + { |
|
369 | + if ($WP_Query instanceof WP_Query |
|
370 | + && $WP_Query->is_main_query() |
|
371 | + && apply_filters('FHEE__EED_Single_Page_Checkout__run', true) |
|
372 | + && $this->_is_reg_checkout() |
|
373 | + ) { |
|
374 | + $this->_initialize(); |
|
375 | + } |
|
376 | + } |
|
377 | + |
|
378 | + |
|
379 | + /** |
|
380 | + * determines whether current url matches reg page url |
|
381 | + * |
|
382 | + * @return bool |
|
383 | + */ |
|
384 | + protected function _is_reg_checkout() |
|
385 | + { |
|
386 | + // get current permalink for reg page without any extra query args |
|
387 | + $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id); |
|
388 | + // get request URI for current request, but without the scheme or host |
|
389 | + $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI'); |
|
390 | + $current_request_uri = html_entity_decode($current_request_uri); |
|
391 | + // get array of query args from the current request URI |
|
392 | + $query_args = \EEH_URL::get_query_string($current_request_uri); |
|
393 | + // grab page id if it is set |
|
394 | + $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0; |
|
395 | + // and remove the page id from the query args (we will re-add it later) |
|
396 | + unset($query_args['page_id']); |
|
397 | + // now strip all query args from current request URI |
|
398 | + $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri); |
|
399 | + // and re-add the page id if it was set |
|
400 | + if ($page_id) { |
|
401 | + $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri); |
|
402 | + } |
|
403 | + // remove slashes and ? |
|
404 | + $current_request_uri = trim($current_request_uri, '?/'); |
|
405 | + // is current request URI part of the known full reg page URL ? |
|
406 | + return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false; |
|
407 | + } |
|
408 | + |
|
409 | + |
|
410 | + /** |
|
411 | + * @param WP_Query $wp_query |
|
412 | + * @return void |
|
413 | + * @throws EE_Error |
|
414 | + */ |
|
415 | + public static function init($wp_query) |
|
416 | + { |
|
417 | + EED_Single_Page_Checkout::instance()->run($wp_query); |
|
418 | + } |
|
419 | + |
|
420 | + |
|
421 | + /** |
|
422 | + * _initialize - initial module setup |
|
423 | + * |
|
424 | + * @access private |
|
425 | + * @throws EE_Error |
|
426 | + * @return void |
|
427 | + */ |
|
428 | + private function _initialize() |
|
429 | + { |
|
430 | + // ensure SPCO doesn't run twice |
|
431 | + if (EED_Single_Page_Checkout::$_initialized) { |
|
432 | + return; |
|
433 | + } |
|
434 | + try { |
|
435 | + EED_Single_Page_Checkout::load_reg_steps(); |
|
436 | + $this->_verify_session(); |
|
437 | + // setup the EE_Checkout object |
|
438 | + $this->checkout = $this->_initialize_checkout(); |
|
439 | + // filter checkout |
|
440 | + $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout); |
|
441 | + // get the $_GET |
|
442 | + $this->_get_request_vars(); |
|
443 | + if ($this->_block_bots()) { |
|
444 | + return; |
|
445 | + } |
|
446 | + // filter continue_reg |
|
447 | + $this->checkout->continue_reg = apply_filters( |
|
448 | + 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
449 | + true, |
|
450 | + $this->checkout |
|
451 | + ); |
|
452 | + // load the reg steps array |
|
453 | + if (! $this->_load_and_instantiate_reg_steps()) { |
|
454 | + EED_Single_Page_Checkout::$_initialized = true; |
|
455 | + return; |
|
456 | + } |
|
457 | + // set the current step |
|
458 | + $this->checkout->set_current_step($this->checkout->step); |
|
459 | + // and the next step |
|
460 | + $this->checkout->set_next_step(); |
|
461 | + // verify that everything has been setup correctly |
|
462 | + if (! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) { |
|
463 | + EED_Single_Page_Checkout::$_initialized = true; |
|
464 | + return; |
|
465 | + } |
|
466 | + // lock the transaction |
|
467 | + $this->checkout->transaction->lock(); |
|
468 | + // make sure all of our cached objects are added to their respective model entity mappers |
|
469 | + $this->checkout->refresh_all_entities(); |
|
470 | + // set amount owing |
|
471 | + $this->checkout->amount_owing = $this->checkout->transaction->remaining(); |
|
472 | + // initialize each reg step, which gives them the chance to potentially alter the process |
|
473 | + $this->_initialize_reg_steps(); |
|
474 | + // DEBUG LOG |
|
475 | + // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
476 | + // get reg form |
|
477 | + if (! $this->_check_form_submission()) { |
|
478 | + EED_Single_Page_Checkout::$_initialized = true; |
|
479 | + return; |
|
480 | + } |
|
481 | + // checkout the action!!! |
|
482 | + $this->_process_form_action(); |
|
483 | + // add some style and make it dance |
|
484 | + $this->add_styles_and_scripts($this); |
|
485 | + // kk... SPCO has successfully run |
|
486 | + EED_Single_Page_Checkout::$_initialized = true; |
|
487 | + // set no cache headers and constants |
|
488 | + EE_System::do_not_cache(); |
|
489 | + // add anchor |
|
490 | + add_action('loop_start', array($this, 'set_checkout_anchor'), 1); |
|
491 | + // remove transaction lock |
|
492 | + add_action('shutdown', array($this, 'unlock_transaction'), 1); |
|
493 | + } catch (Exception $e) { |
|
494 | + EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
495 | + } |
|
496 | + } |
|
497 | + |
|
498 | + |
|
499 | + /** |
|
500 | + * _verify_session |
|
501 | + * checks that the session is valid and not expired |
|
502 | + * |
|
503 | + * @access private |
|
504 | + * @throws EE_Error |
|
505 | + */ |
|
506 | + private function _verify_session() |
|
507 | + { |
|
508 | + if (! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
509 | + throw new EE_Error(esc_html__('The EE_Session class could not be loaded.', 'event_espresso')); |
|
510 | + } |
|
511 | + $clear_session_requested = filter_var( |
|
512 | + EE_Registry::instance()->REQ->get('clear_session', false), |
|
513 | + FILTER_VALIDATE_BOOLEAN |
|
514 | + ); |
|
515 | + // is session still valid ? |
|
516 | + if ($clear_session_requested |
|
517 | + || (EE_Registry::instance()->SSN->expired() |
|
518 | + && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '' |
|
519 | + ) |
|
520 | + ) { |
|
521 | + $this->checkout = new EE_Checkout(); |
|
522 | + EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
523 | + // EE_Registry::instance()->SSN->reset_cart(); |
|
524 | + // EE_Registry::instance()->SSN->reset_checkout(); |
|
525 | + // EE_Registry::instance()->SSN->reset_transaction(); |
|
526 | + if (! $clear_session_requested) { |
|
527 | + EE_Error::add_attention( |
|
528 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'], |
|
529 | + __FILE__, |
|
530 | + __FUNCTION__, |
|
531 | + __LINE__ |
|
532 | + ); |
|
533 | + } |
|
534 | + // EE_Registry::instance()->SSN->reset_expired(); |
|
535 | + } |
|
536 | + } |
|
537 | + |
|
538 | + |
|
539 | + /** |
|
540 | + * _initialize_checkout |
|
541 | + * loads and instantiates EE_Checkout |
|
542 | + * |
|
543 | + * @access private |
|
544 | + * @throws EE_Error |
|
545 | + * @return EE_Checkout |
|
546 | + */ |
|
547 | + private function _initialize_checkout() |
|
548 | + { |
|
549 | + // look in session for existing checkout |
|
550 | + /** @type EE_Checkout $checkout */ |
|
551 | + $checkout = EE_Registry::instance()->SSN->checkout(); |
|
552 | + // verify |
|
553 | + if (! $checkout instanceof EE_Checkout) { |
|
554 | + // instantiate EE_Checkout object for handling the properties of the current checkout process |
|
555 | + $checkout = EE_Registry::instance()->load_file( |
|
556 | + SPCO_INC_PATH, |
|
557 | + 'EE_Checkout', |
|
558 | + 'class', |
|
559 | + array(), |
|
560 | + false |
|
561 | + ); |
|
562 | + } else { |
|
563 | + if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) { |
|
564 | + $this->unlock_transaction(); |
|
565 | + wp_safe_redirect($checkout->redirect_url); |
|
566 | + exit(); |
|
567 | + } |
|
568 | + } |
|
569 | + $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout); |
|
570 | + // verify again |
|
571 | + if (! $checkout instanceof EE_Checkout) { |
|
572 | + throw new EE_Error(esc_html__('The EE_Checkout class could not be loaded.', 'event_espresso')); |
|
573 | + } |
|
574 | + // reset anything that needs a clean slate for each request |
|
575 | + $checkout->reset_for_current_request(); |
|
576 | + return $checkout; |
|
577 | + } |
|
578 | + |
|
579 | + |
|
580 | + /** |
|
581 | + * _get_request_vars |
|
582 | + * |
|
583 | + * @access private |
|
584 | + * @return void |
|
585 | + * @throws EE_Error |
|
586 | + */ |
|
587 | + private function _get_request_vars() |
|
588 | + { |
|
589 | + // load classes |
|
590 | + EED_Single_Page_Checkout::load_request_handler(); |
|
591 | + // make sure this request is marked as belonging to EE |
|
592 | + EE_Registry::instance()->REQ->set_espresso_page(true); |
|
593 | + // which step is being requested ? |
|
594 | + $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step()); |
|
595 | + // which step is being edited ? |
|
596 | + $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', ''); |
|
597 | + // and what we're doing on the current step |
|
598 | + $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step'); |
|
599 | + // timestamp |
|
600 | + $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0); |
|
601 | + // returning to edit ? |
|
602 | + $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', ''); |
|
603 | + // add reg url link to registration query params |
|
604 | + if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) { |
|
605 | + $this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link; |
|
606 | + } |
|
607 | + // or some other kind of revisit ? |
|
608 | + $this->checkout->revisit = filter_var( |
|
609 | + EE_Registry::instance()->REQ->get('revisit', false), |
|
610 | + FILTER_VALIDATE_BOOLEAN |
|
611 | + ); |
|
612 | + // and whether or not to generate a reg form for this request |
|
613 | + $this->checkout->generate_reg_form = filter_var( |
|
614 | + EE_Registry::instance()->REQ->get('generate_reg_form', true), |
|
615 | + FILTER_VALIDATE_BOOLEAN |
|
616 | + ); |
|
617 | + // and whether or not to process a reg form submission for this request |
|
618 | + $this->checkout->process_form_submission = filter_var( |
|
619 | + EE_Registry::instance()->REQ->get( |
|
620 | + 'process_form_submission', |
|
621 | + $this->checkout->action === 'process_reg_step' |
|
622 | + ), |
|
623 | + FILTER_VALIDATE_BOOLEAN |
|
624 | + ); |
|
625 | + $this->checkout->process_form_submission = filter_var( |
|
626 | + $this->checkout->action !== 'display_spco_reg_step' |
|
627 | + ? $this->checkout->process_form_submission |
|
628 | + : false, |
|
629 | + FILTER_VALIDATE_BOOLEAN |
|
630 | + ); |
|
631 | + // $this->_display_request_vars(); |
|
632 | + } |
|
633 | + |
|
634 | + |
|
635 | + /** |
|
636 | + * _display_request_vars |
|
637 | + * |
|
638 | + * @access protected |
|
639 | + * @return void |
|
640 | + */ |
|
641 | + protected function _display_request_vars() |
|
642 | + { |
|
643 | + if (! WP_DEBUG) { |
|
644 | + return; |
|
645 | + } |
|
646 | + EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__); |
|
647 | + EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__); |
|
648 | + EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__); |
|
649 | + EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__); |
|
650 | + EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__); |
|
651 | + EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__); |
|
652 | + EEH_Debug_Tools::printr( |
|
653 | + $this->checkout->generate_reg_form, |
|
654 | + '$this->checkout->generate_reg_form', |
|
655 | + __FILE__, |
|
656 | + __LINE__ |
|
657 | + ); |
|
658 | + EEH_Debug_Tools::printr( |
|
659 | + $this->checkout->process_form_submission, |
|
660 | + '$this->checkout->process_form_submission', |
|
661 | + __FILE__, |
|
662 | + __LINE__ |
|
663 | + ); |
|
664 | + } |
|
665 | + |
|
666 | + |
|
667 | + /** |
|
668 | + * _block_bots |
|
669 | + * checks that the incoming request has either of the following set: |
|
670 | + * a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector |
|
671 | + * a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN |
|
672 | + * so if you're not coming from the Ticket Selector nor returning for a valid IP... |
|
673 | + * then where you coming from man? |
|
674 | + * |
|
675 | + * @return boolean |
|
676 | + */ |
|
677 | + private function _block_bots() |
|
678 | + { |
|
679 | + $invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
680 | + if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) { |
|
681 | + return true; |
|
682 | + } |
|
683 | + return false; |
|
684 | + } |
|
685 | + |
|
686 | + |
|
687 | + /** |
|
688 | + * _get_first_step |
|
689 | + * gets slug for first step in $_reg_steps_array |
|
690 | + * |
|
691 | + * @access private |
|
692 | + * @throws EE_Error |
|
693 | + * @return string |
|
694 | + */ |
|
695 | + private function _get_first_step() |
|
696 | + { |
|
697 | + $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array); |
|
698 | + return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information'; |
|
699 | + } |
|
700 | + |
|
701 | + |
|
702 | + /** |
|
703 | + * instantiates each reg step based on the loaded reg_steps array |
|
704 | + * |
|
705 | + * @return bool |
|
706 | + * @throws EE_Error |
|
707 | + * @throws InvalidArgumentException |
|
708 | + * @throws InvalidDataTypeException |
|
709 | + * @throws InvalidInterfaceException |
|
710 | + */ |
|
711 | + private function _load_and_instantiate_reg_steps() |
|
712 | + { |
|
713 | + do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout); |
|
714 | + // have reg_steps already been instantiated ? |
|
715 | + if (empty($this->checkout->reg_steps) |
|
716 | + || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout) |
|
717 | + ) { |
|
718 | + // if not, then loop through raw reg steps array |
|
719 | + foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) { |
|
720 | + if (! $this->_load_and_instantiate_reg_step($reg_step, $order)) { |
|
721 | + return false; |
|
722 | + } |
|
723 | + } |
|
724 | + if (isset($this->checkout->reg_steps['registration_confirmation'])) { |
|
725 | + // skip the registration_confirmation page ? |
|
726 | + if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) { |
|
727 | + // just remove it from the reg steps array |
|
728 | + $this->checkout->remove_reg_step('registration_confirmation', false); |
|
729 | + } elseif (EE_Registry::instance()->CFG->registration->reg_confirmation_last |
|
730 | + ) { |
|
731 | + // set the order to something big like 100 |
|
732 | + $this->checkout->set_reg_step_order('registration_confirmation', 100); |
|
733 | + } |
|
734 | + } |
|
735 | + // filter the array for good luck |
|
736 | + $this->checkout->reg_steps = apply_filters( |
|
737 | + 'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps', |
|
738 | + $this->checkout->reg_steps |
|
739 | + ); |
|
740 | + // finally re-sort based on the reg step class order properties |
|
741 | + $this->checkout->sort_reg_steps(); |
|
742 | + } else { |
|
743 | + foreach ($this->checkout->reg_steps as $reg_step) { |
|
744 | + // set all current step stati to FALSE |
|
745 | + $reg_step->set_is_current_step(false); |
|
746 | + } |
|
747 | + } |
|
748 | + if (empty($this->checkout->reg_steps)) { |
|
749 | + EE_Error::add_error( |
|
750 | + esc_html__('No Reg Steps were loaded..', 'event_espresso'), |
|
751 | + __FILE__, |
|
752 | + __FUNCTION__, |
|
753 | + __LINE__ |
|
754 | + ); |
|
755 | + return false; |
|
756 | + } |
|
757 | + // make reg step details available to JS |
|
758 | + $this->checkout->set_reg_step_JSON_info(); |
|
759 | + return true; |
|
760 | + } |
|
761 | + |
|
762 | + |
|
763 | + /** |
|
764 | + * _load_and_instantiate_reg_step |
|
765 | + * |
|
766 | + * @access private |
|
767 | + * @param array $reg_step |
|
768 | + * @param int $order |
|
769 | + * @return bool |
|
770 | + */ |
|
771 | + private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0) |
|
772 | + { |
|
773 | + // we need a file_path, class_name, and slug to add a reg step |
|
774 | + if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
775 | + // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step) |
|
776 | + if ($this->checkout->reg_url_link |
|
777 | + && $this->checkout->step !== $reg_step['slug'] |
|
778 | + && $reg_step['slug'] !== 'finalize_registration' |
|
779 | + // normally at this point we would NOT load the reg step, but this filter can change that |
|
780 | + && apply_filters( |
|
781 | + 'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step', |
|
782 | + true, |
|
783 | + $reg_step, |
|
784 | + $this->checkout |
|
785 | + ) |
|
786 | + ) { |
|
787 | + return true; |
|
788 | + } |
|
789 | + // instantiate step class using file path and class name |
|
790 | + $reg_step_obj = EE_Registry::instance()->load_file( |
|
791 | + $reg_step['file_path'], |
|
792 | + $reg_step['class_name'], |
|
793 | + 'class', |
|
794 | + $this->checkout, |
|
795 | + false |
|
796 | + ); |
|
797 | + // did we gets the goods ? |
|
798 | + if ($reg_step_obj instanceof EE_SPCO_Reg_Step) { |
|
799 | + // set reg step order based on config |
|
800 | + $reg_step_obj->set_order($order); |
|
801 | + // add instantiated reg step object to the master reg steps array |
|
802 | + $this->checkout->add_reg_step($reg_step_obj); |
|
803 | + } else { |
|
804 | + EE_Error::add_error( |
|
805 | + esc_html__('The current step could not be set.', 'event_espresso'), |
|
806 | + __FILE__, |
|
807 | + __FUNCTION__, |
|
808 | + __LINE__ |
|
809 | + ); |
|
810 | + return false; |
|
811 | + } |
|
812 | + } else { |
|
813 | + if (WP_DEBUG) { |
|
814 | + EE_Error::add_error( |
|
815 | + sprintf( |
|
816 | + esc_html__( |
|
817 | + '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', |
|
818 | + 'event_espresso' |
|
819 | + ), |
|
820 | + isset($reg_step['file_path']) ? $reg_step['file_path'] : '', |
|
821 | + isset($reg_step['class_name']) ? $reg_step['class_name'] : '', |
|
822 | + isset($reg_step['slug']) ? $reg_step['slug'] : '', |
|
823 | + '<ul>', |
|
824 | + '<li>', |
|
825 | + '</li>', |
|
826 | + '</ul>' |
|
827 | + ), |
|
828 | + __FILE__, |
|
829 | + __FUNCTION__, |
|
830 | + __LINE__ |
|
831 | + ); |
|
832 | + } |
|
833 | + return false; |
|
834 | + } |
|
835 | + return true; |
|
836 | + } |
|
837 | + |
|
838 | + |
|
839 | + /** |
|
840 | + * _verify_transaction_and_get_registrations |
|
841 | + * |
|
842 | + * @access private |
|
843 | + * @return bool |
|
844 | + * @throws InvalidDataTypeException |
|
845 | + * @throws InvalidEntityException |
|
846 | + * @throws EE_Error |
|
847 | + */ |
|
848 | + private function _verify_transaction_and_get_registrations() |
|
849 | + { |
|
850 | + // was there already a valid transaction in the checkout from the session ? |
|
851 | + if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
852 | + // get transaction from db or session |
|
853 | + $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin() |
|
854 | + ? $this->_get_transaction_and_cart_for_previous_visit() |
|
855 | + : $this->_get_cart_for_current_session_and_setup_new_transaction(); |
|
856 | + if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
857 | + EE_Error::add_error( |
|
858 | + esc_html__( |
|
859 | + 'Your Registration and Transaction information could not be retrieved from the db.', |
|
860 | + 'event_espresso' |
|
861 | + ), |
|
862 | + __FILE__, |
|
863 | + __FUNCTION__, |
|
864 | + __LINE__ |
|
865 | + ); |
|
866 | + $this->checkout->transaction = EE_Transaction::new_instance(); |
|
867 | + // add some style and make it dance |
|
868 | + $this->add_styles_and_scripts($this); |
|
869 | + EED_Single_Page_Checkout::$_initialized = true; |
|
870 | + return false; |
|
871 | + } |
|
872 | + // and the registrations for the transaction |
|
873 | + $this->_get_registrations($this->checkout->transaction); |
|
874 | + } |
|
875 | + return true; |
|
876 | + } |
|
877 | + |
|
878 | + |
|
879 | + /** |
|
880 | + * _get_transaction_and_cart_for_previous_visit |
|
881 | + * |
|
882 | + * @access private |
|
883 | + * @return mixed EE_Transaction|NULL |
|
884 | + */ |
|
885 | + private function _get_transaction_and_cart_for_previous_visit() |
|
886 | + { |
|
887 | + /** @var $TXN_model EEM_Transaction */ |
|
888 | + $TXN_model = EE_Registry::instance()->load_model('Transaction'); |
|
889 | + // because the reg_url_link is present in the request, |
|
890 | + // this is a return visit to SPCO, so we'll get the transaction data from the db |
|
891 | + $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link); |
|
892 | + // verify transaction |
|
893 | + if ($transaction instanceof EE_Transaction) { |
|
894 | + // and get the cart that was used for that transaction |
|
895 | + $this->checkout->cart = $this->_get_cart_for_transaction($transaction); |
|
896 | + return $transaction; |
|
897 | + } |
|
898 | + EE_Error::add_error( |
|
899 | + esc_html__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), |
|
900 | + __FILE__, |
|
901 | + __FUNCTION__, |
|
902 | + __LINE__ |
|
903 | + ); |
|
904 | + return null; |
|
905 | + } |
|
906 | + |
|
907 | + |
|
908 | + /** |
|
909 | + * _get_cart_for_transaction |
|
910 | + * |
|
911 | + * @access private |
|
912 | + * @param EE_Transaction $transaction |
|
913 | + * @return EE_Cart |
|
914 | + */ |
|
915 | + private function _get_cart_for_transaction($transaction) |
|
916 | + { |
|
917 | + return $this->checkout->get_cart_for_transaction($transaction); |
|
918 | + } |
|
919 | + |
|
920 | + |
|
921 | + /** |
|
922 | + * get_cart_for_transaction |
|
923 | + * |
|
924 | + * @access public |
|
925 | + * @param EE_Transaction $transaction |
|
926 | + * @return EE_Cart |
|
927 | + */ |
|
928 | + public function get_cart_for_transaction(EE_Transaction $transaction) |
|
929 | + { |
|
930 | + return $this->checkout->get_cart_for_transaction($transaction); |
|
931 | + } |
|
932 | + |
|
933 | + |
|
934 | + /** |
|
935 | + * _get_transaction_and_cart_for_current_session |
|
936 | + * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
937 | + * |
|
938 | + * @access private |
|
939 | + * @return EE_Transaction |
|
940 | + * @throws EE_Error |
|
941 | + */ |
|
942 | + private function _get_cart_for_current_session_and_setup_new_transaction() |
|
943 | + { |
|
944 | + // if there's no transaction, then this is the FIRST visit to SPCO |
|
945 | + // so load up the cart ( passing nothing for the TXN because it doesn't exist yet ) |
|
946 | + $this->checkout->cart = $this->_get_cart_for_transaction(null); |
|
947 | + // and then create a new transaction |
|
948 | + $transaction = $this->_initialize_transaction(); |
|
949 | + // verify transaction |
|
950 | + if ($transaction instanceof EE_Transaction) { |
|
951 | + // save it so that we have an ID for other objects to use |
|
952 | + $transaction->save(); |
|
953 | + // and save TXN data to the cart |
|
954 | + $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID()); |
|
955 | + } else { |
|
956 | + EE_Error::add_error( |
|
957 | + esc_html__('A Valid Transaction could not be initialized.', 'event_espresso'), |
|
958 | + __FILE__, |
|
959 | + __FUNCTION__, |
|
960 | + __LINE__ |
|
961 | + ); |
|
962 | + } |
|
963 | + return $transaction; |
|
964 | + } |
|
965 | + |
|
966 | + |
|
967 | + /** |
|
968 | + * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
969 | + * |
|
970 | + * @access private |
|
971 | + * @return mixed EE_Transaction|NULL |
|
972 | + */ |
|
973 | + private function _initialize_transaction() |
|
974 | + { |
|
975 | + try { |
|
976 | + // ensure cart totals have been calculated |
|
977 | + $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes(); |
|
978 | + // grab the cart grand total |
|
979 | + $cart_total = $this->checkout->cart->get_cart_grand_total(); |
|
980 | + // create new TXN |
|
981 | + $transaction = EE_Transaction::new_instance( |
|
982 | + array( |
|
983 | + 'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(), |
|
984 | + 'TXN_total' => $cart_total > 0 ? $cart_total : 0, |
|
985 | + 'TXN_paid' => 0, |
|
986 | + 'STS_ID' => EEM_Transaction::failed_status_code, |
|
987 | + ) |
|
988 | + ); |
|
989 | + // save it so that we have an ID for other objects to use |
|
990 | + $transaction->save(); |
|
991 | + // set cron job for following up on TXNs after their session has expired |
|
992 | + EE_Cron_Tasks::schedule_expired_transaction_check( |
|
993 | + EE_Registry::instance()->SSN->expiration() + 1, |
|
994 | + $transaction->ID() |
|
995 | + ); |
|
996 | + return $transaction; |
|
997 | + } catch (Exception $e) { |
|
998 | + EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
999 | + } |
|
1000 | + return null; |
|
1001 | + } |
|
1002 | + |
|
1003 | + |
|
1004 | + /** |
|
1005 | + * _get_registrations |
|
1006 | + * |
|
1007 | + * @access private |
|
1008 | + * @param EE_Transaction $transaction |
|
1009 | + * @return void |
|
1010 | + * @throws InvalidDataTypeException |
|
1011 | + * @throws InvalidEntityException |
|
1012 | + * @throws EE_Error |
|
1013 | + */ |
|
1014 | + private function _get_registrations(EE_Transaction $transaction) |
|
1015 | + { |
|
1016 | + // first step: grab the registrants { : o |
|
1017 | + $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
1018 | + $this->checkout->total_ticket_count = count($registrations); |
|
1019 | + // verify registrations have been set |
|
1020 | + if (empty($registrations)) { |
|
1021 | + // if no cached registrations, then check the db |
|
1022 | + $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
1023 | + // still nothing ? well as long as this isn't a revisit |
|
1024 | + if (empty($registrations) && ! $this->checkout->revisit) { |
|
1025 | + // generate new registrations from scratch |
|
1026 | + $registrations = $this->_initialize_registrations($transaction); |
|
1027 | + } |
|
1028 | + } |
|
1029 | + // sort by their original registration order |
|
1030 | + usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count')); |
|
1031 | + // then loop thru the array |
|
1032 | + foreach ($registrations as $registration) { |
|
1033 | + // verify each registration |
|
1034 | + if ($registration instanceof EE_Registration) { |
|
1035 | + // we display all attendee info for the primary registrant |
|
1036 | + if ($this->checkout->reg_url_link === $registration->reg_url_link() |
|
1037 | + && $registration->is_primary_registrant() |
|
1038 | + ) { |
|
1039 | + $this->checkout->primary_revisit = true; |
|
1040 | + break; |
|
1041 | + } |
|
1042 | + if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) { |
|
1043 | + // but hide info if it doesn't belong to you |
|
1044 | + $transaction->clear_cache('Registration', $registration->ID()); |
|
1045 | + $this->checkout->total_ticket_count--; |
|
1046 | + } |
|
1047 | + $this->checkout->set_reg_status_updated($registration->ID(), false); |
|
1048 | + } |
|
1049 | + } |
|
1050 | + } |
|
1051 | + |
|
1052 | + |
|
1053 | + /** |
|
1054 | + * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object |
|
1055 | + * |
|
1056 | + * @access private |
|
1057 | + * @param EE_Transaction $transaction |
|
1058 | + * @return array |
|
1059 | + * @throws InvalidDataTypeException |
|
1060 | + * @throws InvalidEntityException |
|
1061 | + * @throws EE_Error |
|
1062 | + */ |
|
1063 | + private function _initialize_registrations(EE_Transaction $transaction) |
|
1064 | + { |
|
1065 | + $att_nmbr = 0; |
|
1066 | + $registrations = array(); |
|
1067 | + if ($transaction instanceof EE_Transaction) { |
|
1068 | + /** @type EE_Registration_Processor $registration_processor */ |
|
1069 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
1070 | + $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count(); |
|
1071 | + // now let's add the cart items to the $transaction |
|
1072 | + foreach ($this->checkout->cart->get_tickets() as $line_item) { |
|
1073 | + // do the following for each ticket of this type they selected |
|
1074 | + for ($x = 1; $x <= $line_item->quantity(); $x++) { |
|
1075 | + $att_nmbr++; |
|
1076 | + /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */ |
|
1077 | + $CreateRegistrationCommand = EE_Registry::instance()->create( |
|
1078 | + 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand', |
|
1079 | + array( |
|
1080 | + $transaction, |
|
1081 | + $line_item, |
|
1082 | + $att_nmbr, |
|
1083 | + $this->checkout->total_ticket_count, |
|
1084 | + ) |
|
1085 | + ); |
|
1086 | + // override capabilities for frontend registrations |
|
1087 | + if (! is_admin()) { |
|
1088 | + $CreateRegistrationCommand->setCapCheck( |
|
1089 | + new PublicCapabilities('', 'create_new_registration') |
|
1090 | + ); |
|
1091 | + } |
|
1092 | + $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand); |
|
1093 | + if (! $registration instanceof EE_Registration) { |
|
1094 | + throw new InvalidEntityException($registration, 'EE_Registration'); |
|
1095 | + } |
|
1096 | + $registrations[ $registration->ID() ] = $registration; |
|
1097 | + } |
|
1098 | + } |
|
1099 | + $registration_processor->fix_reg_final_price_rounding_issue($transaction); |
|
1100 | + } |
|
1101 | + return $registrations; |
|
1102 | + } |
|
1103 | + |
|
1104 | + |
|
1105 | + /** |
|
1106 | + * sorts registrations by REG_count |
|
1107 | + * |
|
1108 | + * @access public |
|
1109 | + * @param EE_Registration $reg_A |
|
1110 | + * @param EE_Registration $reg_B |
|
1111 | + * @return int |
|
1112 | + */ |
|
1113 | + public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B) |
|
1114 | + { |
|
1115 | + // this shouldn't ever happen within the same TXN, but oh well |
|
1116 | + if ($reg_A->count() === $reg_B->count()) { |
|
1117 | + return 0; |
|
1118 | + } |
|
1119 | + return ($reg_A->count() > $reg_B->count()) ? 1 : -1; |
|
1120 | + } |
|
1121 | + |
|
1122 | + |
|
1123 | + /** |
|
1124 | + * _final_verifications |
|
1125 | + * just makes sure that everything is set up correctly before proceeding |
|
1126 | + * |
|
1127 | + * @access private |
|
1128 | + * @return bool |
|
1129 | + * @throws EE_Error |
|
1130 | + */ |
|
1131 | + private function _final_verifications() |
|
1132 | + { |
|
1133 | + // filter checkout |
|
1134 | + $this->checkout = apply_filters( |
|
1135 | + 'FHEE__EED_Single_Page_Checkout___final_verifications__checkout', |
|
1136 | + $this->checkout |
|
1137 | + ); |
|
1138 | + // verify that current step is still set correctly |
|
1139 | + if (! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) { |
|
1140 | + EE_Error::add_error( |
|
1141 | + esc_html__( |
|
1142 | + '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.', |
|
1143 | + 'event_espresso' |
|
1144 | + ), |
|
1145 | + __FILE__, |
|
1146 | + __FUNCTION__, |
|
1147 | + __LINE__ |
|
1148 | + ); |
|
1149 | + return false; |
|
1150 | + } |
|
1151 | + // if returning to SPCO, then verify that primary registrant is set |
|
1152 | + if (! empty($this->checkout->reg_url_link)) { |
|
1153 | + $valid_registrant = $this->checkout->transaction->primary_registration(); |
|
1154 | + if (! $valid_registrant instanceof EE_Registration) { |
|
1155 | + EE_Error::add_error( |
|
1156 | + esc_html__( |
|
1157 | + '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.', |
|
1158 | + 'event_espresso' |
|
1159 | + ), |
|
1160 | + __FILE__, |
|
1161 | + __FUNCTION__, |
|
1162 | + __LINE__ |
|
1163 | + ); |
|
1164 | + return false; |
|
1165 | + } |
|
1166 | + $valid_registrant = null; |
|
1167 | + foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) { |
|
1168 | + if ($registration instanceof EE_Registration |
|
1169 | + && $registration->reg_url_link() === $this->checkout->reg_url_link |
|
1170 | + ) { |
|
1171 | + $valid_registrant = $registration; |
|
1172 | + } |
|
1173 | + } |
|
1174 | + if (! $valid_registrant instanceof EE_Registration) { |
|
1175 | + // hmmm... maybe we have the wrong session because the user is opening multiple tabs ? |
|
1176 | + if (EED_Single_Page_Checkout::$_checkout_verified) { |
|
1177 | + // clear the session, mark the checkout as unverified, and try again |
|
1178 | + EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
1179 | + EED_Single_Page_Checkout::$_initialized = false; |
|
1180 | + EED_Single_Page_Checkout::$_checkout_verified = false; |
|
1181 | + $this->_initialize(); |
|
1182 | + EE_Error::reset_notices(); |
|
1183 | + return false; |
|
1184 | + } |
|
1185 | + EE_Error::add_error( |
|
1186 | + esc_html__( |
|
1187 | + '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.', |
|
1188 | + 'event_espresso' |
|
1189 | + ), |
|
1190 | + __FILE__, |
|
1191 | + __FUNCTION__, |
|
1192 | + __LINE__ |
|
1193 | + ); |
|
1194 | + return false; |
|
1195 | + } |
|
1196 | + } |
|
1197 | + // now that things have been kinda sufficiently verified, |
|
1198 | + // let's add the checkout to the session so that it's available to other systems |
|
1199 | + EE_Registry::instance()->SSN->set_checkout($this->checkout); |
|
1200 | + return true; |
|
1201 | + } |
|
1202 | + |
|
1203 | + |
|
1204 | + /** |
|
1205 | + * _initialize_reg_steps |
|
1206 | + * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required |
|
1207 | + * then loops thru all of the active reg steps and calls the initialize_reg_step() method |
|
1208 | + * |
|
1209 | + * @access private |
|
1210 | + * @param bool $reinitializing |
|
1211 | + * @throws EE_Error |
|
1212 | + */ |
|
1213 | + private function _initialize_reg_steps($reinitializing = false) |
|
1214 | + { |
|
1215 | + $this->checkout->set_reg_step_initiated($this->checkout->current_step); |
|
1216 | + // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS |
|
1217 | + foreach ($this->checkout->reg_steps as $reg_step) { |
|
1218 | + if (! $reg_step->initialize_reg_step()) { |
|
1219 | + // if not initialized then maybe this step is being removed... |
|
1220 | + if (! $reinitializing && $reg_step->is_current_step()) { |
|
1221 | + // if it was the current step, then we need to start over here |
|
1222 | + $this->_initialize_reg_steps(true); |
|
1223 | + return; |
|
1224 | + } |
|
1225 | + continue; |
|
1226 | + } |
|
1227 | + // add css and JS for current step |
|
1228 | + $this->add_styles_and_scripts($reg_step); |
|
1229 | + if ($reg_step->is_current_step()) { |
|
1230 | + // the text that appears on the reg step form submit button |
|
1231 | + $reg_step->set_submit_button_text(); |
|
1232 | + } |
|
1233 | + } |
|
1234 | + // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information |
|
1235 | + do_action( |
|
1236 | + "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", |
|
1237 | + $this->checkout->current_step |
|
1238 | + ); |
|
1239 | + } |
|
1240 | + |
|
1241 | + |
|
1242 | + /** |
|
1243 | + * _check_form_submission |
|
1244 | + * |
|
1245 | + * @access private |
|
1246 | + * @return boolean |
|
1247 | + */ |
|
1248 | + private function _check_form_submission() |
|
1249 | + { |
|
1250 | + // does this request require the reg form to be generated ? |
|
1251 | + if ($this->checkout->generate_reg_form) { |
|
1252 | + // ever heard that song by Blue Rodeo ? |
|
1253 | + try { |
|
1254 | + $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form(); |
|
1255 | + // if not displaying a form, then check for form submission |
|
1256 | + if ($this->checkout->process_form_submission |
|
1257 | + && $this->checkout->current_step->reg_form->was_submitted() |
|
1258 | + ) { |
|
1259 | + // clear out any old data in case this step is being run again |
|
1260 | + $this->checkout->current_step->set_valid_data(array()); |
|
1261 | + // capture submitted form data |
|
1262 | + $this->checkout->current_step->reg_form->receive_form_submission( |
|
1263 | + apply_filters( |
|
1264 | + 'FHEE__Single_Page_Checkout___check_form_submission__request_params', |
|
1265 | + EE_Registry::instance()->REQ->params(), |
|
1266 | + $this->checkout |
|
1267 | + ) |
|
1268 | + ); |
|
1269 | + // validate submitted form data |
|
1270 | + if (! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) { |
|
1271 | + // thou shall not pass !!! |
|
1272 | + $this->checkout->continue_reg = false; |
|
1273 | + // any form validation errors? |
|
1274 | + if ($this->checkout->current_step->reg_form->submission_error_message() !== '') { |
|
1275 | + EE_Error::add_error( |
|
1276 | + $this->checkout->current_step->reg_form->submission_error_message(), |
|
1277 | + __FILE__, |
|
1278 | + __FUNCTION__, |
|
1279 | + __LINE__ |
|
1280 | + ); |
|
1281 | + } |
|
1282 | + // well not really... what will happen is |
|
1283 | + // we'll just get redirected back to redo the current step |
|
1284 | + $this->go_to_next_step(); |
|
1285 | + return false; |
|
1286 | + } |
|
1287 | + } |
|
1288 | + } catch (EE_Error $e) { |
|
1289 | + $e->get_error(); |
|
1290 | + } |
|
1291 | + } |
|
1292 | + return true; |
|
1293 | + } |
|
1294 | + |
|
1295 | + |
|
1296 | + /** |
|
1297 | + * _process_action |
|
1298 | + * |
|
1299 | + * @access private |
|
1300 | + * @return void |
|
1301 | + * @throws EE_Error |
|
1302 | + */ |
|
1303 | + private function _process_form_action() |
|
1304 | + { |
|
1305 | + // what cha wanna do? |
|
1306 | + switch ($this->checkout->action) { |
|
1307 | + // AJAX next step reg form |
|
1308 | + case 'display_spco_reg_step': |
|
1309 | + $this->checkout->redirect = false; |
|
1310 | + if (EE_Registry::instance()->REQ->ajax) { |
|
1311 | + $this->checkout->json_response->set_reg_step_html( |
|
1312 | + $this->checkout->current_step->display_reg_form() |
|
1313 | + ); |
|
1314 | + } |
|
1315 | + break; |
|
1316 | + default: |
|
1317 | + // meh... do one of those other steps first |
|
1318 | + if (! empty($this->checkout->action) |
|
1319 | + && is_callable(array($this->checkout->current_step, $this->checkout->action)) |
|
1320 | + ) { |
|
1321 | + // dynamically creates hook point like: |
|
1322 | + // AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step |
|
1323 | + do_action( |
|
1324 | + "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
1325 | + $this->checkout->current_step |
|
1326 | + ); |
|
1327 | + // call action on current step |
|
1328 | + if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) { |
|
1329 | + // good registrant, you get to proceed |
|
1330 | + if ($this->checkout->current_step->success_message() !== '' |
|
1331 | + && apply_filters( |
|
1332 | + 'FHEE__Single_Page_Checkout___process_form_action__display_success', |
|
1333 | + false |
|
1334 | + ) |
|
1335 | + ) { |
|
1336 | + EE_Error::add_success( |
|
1337 | + $this->checkout->current_step->success_message() |
|
1338 | + . '<br />' . $this->checkout->next_step->_instructions() |
|
1339 | + ); |
|
1340 | + } |
|
1341 | + // pack it up, pack it in... |
|
1342 | + $this->_setup_redirect(); |
|
1343 | + } |
|
1344 | + // dynamically creates hook point like: |
|
1345 | + // AHEE__Single_Page_Checkout__after_payment_options__process_reg_step |
|
1346 | + do_action( |
|
1347 | + "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
1348 | + $this->checkout->current_step |
|
1349 | + ); |
|
1350 | + } else { |
|
1351 | + EE_Error::add_error( |
|
1352 | + sprintf( |
|
1353 | + esc_html__( |
|
1354 | + 'The requested form action "%s" does not exist for the current "%s" registration step.', |
|
1355 | + 'event_espresso' |
|
1356 | + ), |
|
1357 | + $this->checkout->action, |
|
1358 | + $this->checkout->current_step->name() |
|
1359 | + ), |
|
1360 | + __FILE__, |
|
1361 | + __FUNCTION__, |
|
1362 | + __LINE__ |
|
1363 | + ); |
|
1364 | + } |
|
1365 | + // end default |
|
1366 | + } |
|
1367 | + // store our progress so far |
|
1368 | + $this->checkout->stash_transaction_and_checkout(); |
|
1369 | + // advance to the next step! If you pass GO, collect $200 |
|
1370 | + $this->go_to_next_step(); |
|
1371 | + } |
|
1372 | + |
|
1373 | + |
|
1374 | + /** |
|
1375 | + * @param EED_Single_Page_Checkout|EE_SPCO_Reg_Step $target |
|
1376 | + * @param object $target an object with the method `translate_js_strings` and `enqueue_styles_and_scripts`. |
|
1377 | + * @return void |
|
1378 | + */ |
|
1379 | + public function add_styles_and_scripts($target) |
|
1380 | + { |
|
1381 | + // i18n |
|
1382 | + $target->translate_js_strings(); |
|
1383 | + if ($this->checkout->admin_request) { |
|
1384 | + add_action('admin_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
1385 | + } else { |
|
1386 | + add_action('wp_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
1387 | + } |
|
1388 | + } |
|
1389 | + |
|
1390 | + /** |
|
1391 | + * translate_js_strings |
|
1392 | + * |
|
1393 | + * @access public |
|
1394 | + * @return void |
|
1395 | + */ |
|
1396 | + public function translate_js_strings() |
|
1397 | + { |
|
1398 | + EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit; |
|
1399 | + EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link; |
|
1400 | + EE_Registry::$i18n_js_strings['server_error'] = esc_html__( |
|
1401 | + 'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
1402 | + 'event_espresso' |
|
1403 | + ); |
|
1404 | + EE_Registry::$i18n_js_strings['invalid_json_response'] = esc_html__( |
|
1405 | + 'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
1406 | + 'event_espresso' |
|
1407 | + ); |
|
1408 | + EE_Registry::$i18n_js_strings['validation_error'] = esc_html__( |
|
1409 | + 'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', |
|
1410 | + 'event_espresso' |
|
1411 | + ); |
|
1412 | + EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__( |
|
1413 | + 'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', |
|
1414 | + 'event_espresso' |
|
1415 | + ); |
|
1416 | + EE_Registry::$i18n_js_strings['reg_step_error'] = esc_html__( |
|
1417 | + 'This registration step could not be completed. Please refresh the page and try again.', |
|
1418 | + 'event_espresso' |
|
1419 | + ); |
|
1420 | + EE_Registry::$i18n_js_strings['invalid_coupon'] = esc_html__( |
|
1421 | + 'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', |
|
1422 | + 'event_espresso' |
|
1423 | + ); |
|
1424 | + EE_Registry::$i18n_js_strings['process_registration'] = sprintf( |
|
1425 | + esc_html__( |
|
1426 | + 'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', |
|
1427 | + 'event_espresso' |
|
1428 | + ), |
|
1429 | + '<br/>', |
|
1430 | + '<br/>' |
|
1431 | + ); |
|
1432 | + EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language'); |
|
1433 | + EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id(); |
|
1434 | + EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency; |
|
1435 | + EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20'; |
|
1436 | + EE_Registry::$i18n_js_strings['timer_years'] = esc_html__('years', 'event_espresso'); |
|
1437 | + EE_Registry::$i18n_js_strings['timer_months'] = esc_html__('months', 'event_espresso'); |
|
1438 | + EE_Registry::$i18n_js_strings['timer_weeks'] = esc_html__('weeks', 'event_espresso'); |
|
1439 | + EE_Registry::$i18n_js_strings['timer_days'] = esc_html__('days', 'event_espresso'); |
|
1440 | + EE_Registry::$i18n_js_strings['timer_hours'] = esc_html__('hours', 'event_espresso'); |
|
1441 | + EE_Registry::$i18n_js_strings['timer_minutes'] = esc_html__('minutes', 'event_espresso'); |
|
1442 | + EE_Registry::$i18n_js_strings['timer_seconds'] = esc_html__('seconds', 'event_espresso'); |
|
1443 | + EE_Registry::$i18n_js_strings['timer_year'] = esc_html__('year', 'event_espresso'); |
|
1444 | + EE_Registry::$i18n_js_strings['timer_month'] = esc_html__('month', 'event_espresso'); |
|
1445 | + EE_Registry::$i18n_js_strings['timer_week'] = esc_html__('week', 'event_espresso'); |
|
1446 | + EE_Registry::$i18n_js_strings['timer_day'] = esc_html__('day', 'event_espresso'); |
|
1447 | + EE_Registry::$i18n_js_strings['timer_hour'] = esc_html__('hour', 'event_espresso'); |
|
1448 | + EE_Registry::$i18n_js_strings['timer_minute'] = esc_html__('minute', 'event_espresso'); |
|
1449 | + EE_Registry::$i18n_js_strings['timer_second'] = esc_html__('second', 'event_espresso'); |
|
1450 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
1451 | + ); |
|
1452 | + EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters( |
|
1453 | + 'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', |
|
1454 | + true |
|
1455 | + ); |
|
1456 | + EE_Registry::$i18n_js_strings['session_extension'] = absint( |
|
1457 | + apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS) |
|
1458 | + ); |
|
1459 | + EE_Registry::$i18n_js_strings['session_expiration'] = gmdate( |
|
1460 | + 'M d, Y H:i:s', |
|
1461 | + EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
1462 | + ); |
|
1463 | + } |
|
1464 | + |
|
1465 | + |
|
1466 | + /** |
|
1467 | + * enqueue_styles_and_scripts |
|
1468 | + * |
|
1469 | + * @access public |
|
1470 | + * @return void |
|
1471 | + * @throws EE_Error |
|
1472 | + */ |
|
1473 | + public function enqueue_styles_and_scripts() |
|
1474 | + { |
|
1475 | + // load css |
|
1476 | + wp_register_style( |
|
1477 | + 'single_page_checkout', |
|
1478 | + SPCO_CSS_URL . 'single_page_checkout.css', |
|
1479 | + array('espresso_default'), |
|
1480 | + EVENT_ESPRESSO_VERSION |
|
1481 | + ); |
|
1482 | + wp_enqueue_style('single_page_checkout'); |
|
1483 | + // load JS |
|
1484 | + wp_register_script( |
|
1485 | + 'jquery_plugin', |
|
1486 | + EE_THIRD_PARTY_URL . 'jquery .plugin.min.js', |
|
1487 | + array('jquery'), |
|
1488 | + '1.0.1', |
|
1489 | + true |
|
1490 | + ); |
|
1491 | + wp_register_script( |
|
1492 | + 'jquery_countdown', |
|
1493 | + EE_THIRD_PARTY_URL . 'jquery .countdown.min.js', |
|
1494 | + array('jquery_plugin'), |
|
1495 | + '2.1.0', |
|
1496 | + true |
|
1497 | + ); |
|
1498 | + wp_register_script( |
|
1499 | + 'single_page_checkout', |
|
1500 | + SPCO_JS_URL . 'single_page_checkout.js', |
|
1501 | + array('espresso_core', 'underscore', 'ee_form_section_validation'), |
|
1502 | + EVENT_ESPRESSO_VERSION, |
|
1503 | + true |
|
1504 | + ); |
|
1505 | + if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) { |
|
1506 | + $this->checkout->registration_form->enqueue_js(); |
|
1507 | + } |
|
1508 | + if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) { |
|
1509 | + $this->checkout->current_step->reg_form->enqueue_js(); |
|
1510 | + } |
|
1511 | + wp_enqueue_script('single_page_checkout'); |
|
1512 | + if (apply_filters('FHEE__registration_page_wrapper_template__display_time_limit', false)) { |
|
1513 | + wp_enqueue_script('jquery_countdown'); |
|
1514 | + } |
|
1515 | + /** |
|
1516 | + * global action hook for enqueueing styles and scripts with |
|
1517 | + * spco calls. |
|
1518 | + */ |
|
1519 | + do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this); |
|
1520 | + /** |
|
1521 | + * dynamic action hook for enqueueing styles and scripts with spco calls. |
|
1522 | + * The hook will end up being something like: |
|
1523 | + * AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information |
|
1524 | + */ |
|
1525 | + do_action( |
|
1526 | + 'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), |
|
1527 | + $this |
|
1528 | + ); |
|
1529 | + } |
|
1530 | + |
|
1531 | + |
|
1532 | + /** |
|
1533 | + * display the Registration Single Page Checkout Form |
|
1534 | + * |
|
1535 | + * @access private |
|
1536 | + * @return void |
|
1537 | + * @throws EE_Error |
|
1538 | + */ |
|
1539 | + private function _display_spco_reg_form() |
|
1540 | + { |
|
1541 | + // if registering via the admin, just display the reg form for the current step |
|
1542 | + if ($this->checkout->admin_request) { |
|
1543 | + EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form()); |
|
1544 | + } else { |
|
1545 | + // add powered by EE msg |
|
1546 | + add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer')); |
|
1547 | + $empty_cart = count($this->checkout->transaction |
|
1548 | + ->registrations($this->checkout->reg_cache_where_params)) < 1; |
|
1549 | + EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart; |
|
1550 | + $cookies_not_set_msg = ''; |
|
1551 | + if ($empty_cart) { |
|
1552 | + $cookies_not_set_msg = apply_filters( |
|
1553 | + 'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg', |
|
1554 | + sprintf( |
|
1555 | + esc_html__( |
|
1556 | + '%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', |
|
1557 | + 'event_espresso' |
|
1558 | + ), |
|
1559 | + '<div class="ee-attention hidden" id="ee-cookies-not-set-msg">', |
|
1560 | + '</div>', |
|
1561 | + '<h6 class="important-notice">', |
|
1562 | + '</h6>', |
|
1563 | + '<p>', |
|
1564 | + '</p>', |
|
1565 | + '<br />', |
|
1566 | + '<a href="http://www.whatarecookies.com/enable.asp" target="_blank" rel="noopener noreferrer">', |
|
1567 | + '</a>' |
|
1568 | + ) |
|
1569 | + ); |
|
1570 | + } |
|
1571 | + $this->checkout->registration_form = new EE_Form_Section_Proper( |
|
1572 | + array( |
|
1573 | + 'name' => 'single-page-checkout', |
|
1574 | + 'html_id' => 'ee-single-page-checkout-dv', |
|
1575 | + 'layout_strategy' => |
|
1576 | + new EE_Template_Layout( |
|
1577 | + array( |
|
1578 | + 'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php', |
|
1579 | + 'template_args' => array( |
|
1580 | + 'empty_cart' => $empty_cart, |
|
1581 | + 'revisit' => $this->checkout->revisit, |
|
1582 | + 'reg_steps' => $this->checkout->reg_steps, |
|
1583 | + 'next_step' => $this->checkout->next_step instanceof EE_SPCO_Reg_Step |
|
1584 | + ? $this->checkout->next_step->slug() |
|
1585 | + : '', |
|
1586 | + 'empty_msg' => apply_filters( |
|
1587 | + 'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg', |
|
1588 | + sprintf( |
|
1589 | + esc_html__( |
|
1590 | + 'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', |
|
1591 | + 'event_espresso' |
|
1592 | + ), |
|
1593 | + '<a href="' |
|
1594 | + . get_post_type_archive_link('espresso_events') |
|
1595 | + . '" title="', |
|
1596 | + '">', |
|
1597 | + '</a>' |
|
1598 | + ) |
|
1599 | + ), |
|
1600 | + 'cookies_not_set_msg' => $cookies_not_set_msg, |
|
1601 | + 'registration_time_limit' => $this->checkout->get_registration_time_limit(), |
|
1602 | + 'session_expiration' => gmdate( |
|
1603 | + 'M d, Y H:i:s', |
|
1604 | + EE_Registry::instance()->SSN->expiration() |
|
1605 | + + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
1606 | + ), |
|
1607 | + ), |
|
1608 | + ) |
|
1609 | + ), |
|
1610 | + ) |
|
1611 | + ); |
|
1612 | + // load template and add to output sent that gets filtered into the_content() |
|
1613 | + EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html()); |
|
1614 | + } |
|
1615 | + } |
|
1616 | + |
|
1617 | + |
|
1618 | + /** |
|
1619 | + * add_extra_finalize_registration_inputs |
|
1620 | + * |
|
1621 | + * @access public |
|
1622 | + * @param $next_step |
|
1623 | + * @internal param string $label |
|
1624 | + * @return void |
|
1625 | + */ |
|
1626 | + public function add_extra_finalize_registration_inputs($next_step) |
|
1627 | + { |
|
1628 | + if ($next_step === 'finalize_registration') { |
|
1629 | + echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>'; |
|
1630 | + } |
|
1631 | + } |
|
1632 | + |
|
1633 | + |
|
1634 | + /** |
|
1635 | + * display_registration_footer |
|
1636 | + * |
|
1637 | + * @access public |
|
1638 | + * @return string |
|
1639 | + */ |
|
1640 | + public static function display_registration_footer() |
|
1641 | + { |
|
1642 | + if (apply_filters( |
|
1643 | + 'FHEE__EE_Front__Controller__show_reg_footer', |
|
1644 | + EE_Registry::instance()->CFG->admin->show_reg_footer |
|
1645 | + )) { |
|
1646 | + add_filter( |
|
1647 | + 'FHEE__EEH_Template__powered_by_event_espresso__url', |
|
1648 | + function ($url) { |
|
1649 | + return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url); |
|
1650 | + } |
|
1651 | + ); |
|
1652 | + echo apply_filters( |
|
1653 | + 'FHEE__EE_Front_Controller__display_registration_footer', |
|
1654 | + \EEH_Template::powered_by_event_espresso( |
|
1655 | + '', |
|
1656 | + 'espresso-registration-footer-dv', |
|
1657 | + array('utm_content' => 'registration_checkout') |
|
1658 | + ) |
|
1659 | + ); |
|
1660 | + } |
|
1661 | + return ''; |
|
1662 | + } |
|
1663 | + |
|
1664 | + |
|
1665 | + /** |
|
1666 | + * unlock_transaction |
|
1667 | + * |
|
1668 | + * @access public |
|
1669 | + * @return void |
|
1670 | + * @throws EE_Error |
|
1671 | + */ |
|
1672 | + public function unlock_transaction() |
|
1673 | + { |
|
1674 | + if ($this->checkout->transaction instanceof EE_Transaction) { |
|
1675 | + $this->checkout->transaction->unlock(); |
|
1676 | + } |
|
1677 | + } |
|
1678 | + |
|
1679 | + |
|
1680 | + /** |
|
1681 | + * _setup_redirect |
|
1682 | + * |
|
1683 | + * @access private |
|
1684 | + * @return void |
|
1685 | + */ |
|
1686 | + private function _setup_redirect() |
|
1687 | + { |
|
1688 | + if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) { |
|
1689 | + $this->checkout->redirect = true; |
|
1690 | + if (empty($this->checkout->redirect_url)) { |
|
1691 | + $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url(); |
|
1692 | + } |
|
1693 | + $this->checkout->redirect_url = apply_filters( |
|
1694 | + 'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url', |
|
1695 | + $this->checkout->redirect_url, |
|
1696 | + $this->checkout |
|
1697 | + ); |
|
1698 | + } |
|
1699 | + } |
|
1700 | + |
|
1701 | + |
|
1702 | + /** |
|
1703 | + * handle ajax message responses and redirects |
|
1704 | + * |
|
1705 | + * @access public |
|
1706 | + * @return void |
|
1707 | + * @throws EE_Error |
|
1708 | + */ |
|
1709 | + public function go_to_next_step() |
|
1710 | + { |
|
1711 | + if (EE_Registry::instance()->REQ->ajax) { |
|
1712 | + // capture contents of output buffer we started earlier in the request, and insert into JSON response |
|
1713 | + $this->checkout->json_response->set_unexpected_errors(ob_get_clean()); |
|
1714 | + } |
|
1715 | + $this->unlock_transaction(); |
|
1716 | + // just return for these conditions |
|
1717 | + if ($this->checkout->admin_request |
|
1718 | + || $this->checkout->action === 'redirect_form' |
|
1719 | + || $this->checkout->action === 'update_checkout' |
|
1720 | + ) { |
|
1721 | + return; |
|
1722 | + } |
|
1723 | + // AJAX response |
|
1724 | + $this->_handle_json_response(); |
|
1725 | + // redirect to next step or the Thank You page |
|
1726 | + $this->_handle_html_redirects(); |
|
1727 | + // hmmm... must be something wrong, so let's just display the form again ! |
|
1728 | + $this->_display_spco_reg_form(); |
|
1729 | + } |
|
1730 | + |
|
1731 | + |
|
1732 | + /** |
|
1733 | + * _handle_json_response |
|
1734 | + * |
|
1735 | + * @access protected |
|
1736 | + * @return void |
|
1737 | + */ |
|
1738 | + protected function _handle_json_response() |
|
1739 | + { |
|
1740 | + // if this is an ajax request |
|
1741 | + if (EE_Registry::instance()->REQ->ajax) { |
|
1742 | + $this->checkout->json_response->set_registration_time_limit( |
|
1743 | + $this->checkout->get_registration_time_limit() |
|
1744 | + ); |
|
1745 | + $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing); |
|
1746 | + // just send the ajax ( |
|
1747 | + $json_response = apply_filters( |
|
1748 | + 'FHEE__EE_Single_Page_Checkout__JSON_response', |
|
1749 | + $this->checkout->json_response |
|
1750 | + ); |
|
1751 | + echo $json_response; |
|
1752 | + exit(); |
|
1753 | + } |
|
1754 | + } |
|
1755 | + |
|
1756 | + |
|
1757 | + /** |
|
1758 | + * _handle_redirects |
|
1759 | + * |
|
1760 | + * @access protected |
|
1761 | + * @return void |
|
1762 | + */ |
|
1763 | + protected function _handle_html_redirects() |
|
1764 | + { |
|
1765 | + // going somewhere ? |
|
1766 | + if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) { |
|
1767 | + // store notices in a transient |
|
1768 | + EE_Error::get_notices(false, true, true); |
|
1769 | + wp_safe_redirect($this->checkout->redirect_url); |
|
1770 | + exit(); |
|
1771 | + } |
|
1772 | + } |
|
1773 | + |
|
1774 | + |
|
1775 | + /** |
|
1776 | + * set_checkout_anchor |
|
1777 | + * |
|
1778 | + * @access public |
|
1779 | + * @return void |
|
1780 | + */ |
|
1781 | + public function set_checkout_anchor() |
|
1782 | + { |
|
1783 | + echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>'; |
|
1784 | + } |
|
1785 | + |
|
1786 | + /** |
|
1787 | + * getRegistrationExpirationNotice |
|
1788 | + * |
|
1789 | + * @since 4.9.59.p |
|
1790 | + * @access public |
|
1791 | + * @return string |
|
1792 | + */ |
|
1793 | + public static function getRegistrationExpirationNotice() |
|
1794 | + { |
|
1795 | + return sprintf( |
|
1796 | + esc_html__( |
|
1797 | + '%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 accept our apologies for any inconvenience this may have caused.%8$s', |
|
1798 | + 'event_espresso' |
|
1799 | + ), |
|
1800 | + '<h4 class="important-notice">', |
|
1801 | + '</h4>', |
|
1802 | + '<br />', |
|
1803 | + '<p>', |
|
1804 | + '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
1805 | + '">', |
|
1806 | + '</a>', |
|
1807 | + '</p>' |
|
1808 | + ); |
|
1809 | + } |
|
1810 | 1810 | } |
@@ -28,602 +28,602 @@ |
||
28 | 28 | class EEM_Line_Item extends EEM_Base |
29 | 29 | { |
30 | 30 | |
31 | - /** |
|
32 | - * Tax sub-total is just the total of all the taxes, which should be children |
|
33 | - * of this line item. There should only ever be one tax sub-total, and it should |
|
34 | - * be a direct child of. Its quantity and LIN_unit_price = 1. |
|
35 | - */ |
|
36 | - const type_tax_sub_total = 'tax-sub-total'; |
|
37 | - |
|
38 | - /** |
|
39 | - * Tax line items indicate a tax applied to all the taxable line items. |
|
40 | - * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal |
|
41 | - * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1. |
|
42 | - */ |
|
43 | - const type_tax = 'tax'; |
|
44 | - |
|
45 | - /** |
|
46 | - * Indicating individual items purchased, or discounts or surcharges. |
|
47 | - * The sum of all the regular line items plus the tax items should equal the grand total. |
|
48 | - * Possible children are sub-line-items and cancellations. |
|
49 | - * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children |
|
50 | - * LIN_totals. Its LIN_percent = 0. |
|
51 | - * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1). |
|
52 | - * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1. |
|
53 | - */ |
|
54 | - const type_line_item = 'line-item'; |
|
55 | - |
|
56 | - /** |
|
57 | - * Line item indicating all the factors that make a single line item. |
|
58 | - * Sub-line items should have NO children line items. |
|
59 | - * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's |
|
60 | - * contribution towards the price of ONE of their parent items, and its LIN_total should be |
|
61 | - * = LIN_quantity * LIN_unit_price. Its LIN_percent = 0. |
|
62 | - * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should |
|
63 | - * = LIN_percent / 100 * sum of lower-priority sibling line items.. |
|
64 | - */ |
|
65 | - const type_sub_line_item = 'sub-item'; |
|
66 | - |
|
67 | - /** |
|
68 | - * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal). |
|
69 | - * Direct children should be event subtotals. |
|
70 | - * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals. |
|
71 | - */ |
|
72 | - const type_sub_total = 'sub-total'; |
|
73 | - |
|
74 | - /** |
|
75 | - * Line item for the grand total of an order. |
|
76 | - * Its direct children should be tax subtotals and (pre-tax) subtotals, |
|
77 | - * and possibly a regular line item indicating a transaction-wide discount/surcharge. |
|
78 | - * Should have a quantity of 1, a LIN_total and LIN_unit_price of the entire order's amount. |
|
79 | - */ |
|
80 | - const type_total = 'total'; |
|
81 | - |
|
82 | - /** |
|
83 | - * When a line item is cancelled, a sub-line-item of type 'cancellation' |
|
84 | - * should be created, indicating the quantity that were cancelled |
|
85 | - * (because a line item could have a quantity of 1, and its cancellation item |
|
86 | - * could be for 3, indicating that originally 4 were purchased, but 3 have been |
|
87 | - * cancelled, and only one remains). |
|
88 | - * When items are refunded, a cancellation line item should be made, which points |
|
89 | - * to teh payment model object which actually refunded the payment. |
|
90 | - * Cancellations should NOT have any children line items; the should NOT affect |
|
91 | - * any calculations, and are only meant as a record that cancellations have occurred. |
|
92 | - * Their LIN_percent should be 0. |
|
93 | - */ |
|
94 | - const type_cancellation = 'cancellation'; |
|
95 | - |
|
96 | - // various line item object types |
|
97 | - const OBJ_TYPE_EVENT = 'Event'; |
|
98 | - |
|
99 | - const OBJ_TYPE_PRICE = 'Price'; |
|
100 | - |
|
101 | - const OBJ_TYPE_PROMOTION = 'Promotion'; |
|
102 | - |
|
103 | - const OBJ_TYPE_TICKET = 'Ticket'; |
|
104 | - |
|
105 | - const OBJ_TYPE_TRANSACTION = 'Transaction'; |
|
106 | - |
|
107 | - /** |
|
108 | - * @var EEM_Line_Item $_instance |
|
109 | - */ |
|
110 | - protected static $_instance; |
|
111 | - |
|
112 | - |
|
113 | - /** |
|
114 | - * private constructor to prevent direct creation |
|
115 | - * |
|
116 | - * @Constructor |
|
117 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
118 | - * (and any incoming timezone data that gets saved). |
|
119 | - * Note this just sends the timezone info to the date time model field objects. |
|
120 | - * Default is NULL |
|
121 | - * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
122 | - * @throws EE_Error |
|
123 | - * @throws InvalidArgumentException |
|
124 | - */ |
|
125 | - protected function __construct($timezone) |
|
126 | - { |
|
127 | - $this->singular_item = esc_html__('Line Item', 'event_espresso'); |
|
128 | - $this->plural_item = esc_html__('Line Items', 'event_espresso'); |
|
129 | - |
|
130 | - $this->_tables = array( |
|
131 | - 'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID'), |
|
132 | - ); |
|
133 | - $line_items_can_be_for = apply_filters( |
|
134 | - 'FHEE__EEM_Line_Item__line_items_can_be_for', |
|
135 | - array('Ticket', 'Price', 'Event') |
|
136 | - ); |
|
137 | - $this->_fields = array( |
|
138 | - 'Line_Item' => array( |
|
139 | - 'LIN_ID' => new EE_Primary_Key_Int_Field( |
|
140 | - 'LIN_ID', |
|
141 | - esc_html__('ID', 'event_espresso') |
|
142 | - ), |
|
143 | - 'LIN_code' => new EE_Slug_Field( |
|
144 | - 'LIN_code', |
|
145 | - esc_html__('Code for index into Cart', 'event_espresso'), |
|
146 | - true |
|
147 | - ), |
|
148 | - 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
149 | - 'TXN_ID', |
|
150 | - esc_html__('Transaction ID', 'event_espresso'), |
|
151 | - true, |
|
152 | - null, |
|
153 | - 'Transaction' |
|
154 | - ), |
|
155 | - 'LIN_name' => new EE_Full_HTML_Field( |
|
156 | - 'LIN_name', |
|
157 | - esc_html__('Line Item Name', 'event_espresso'), |
|
158 | - false, |
|
159 | - '' |
|
160 | - ), |
|
161 | - 'LIN_desc' => new EE_Full_HTML_Field( |
|
162 | - 'LIN_desc', |
|
163 | - esc_html__('Line Item Description', 'event_espresso'), |
|
164 | - true |
|
165 | - ), |
|
166 | - 'LIN_unit_price' => new EE_Money_Field( |
|
167 | - 'LIN_unit_price', |
|
168 | - esc_html__('Unit Price', 'event_espresso'), |
|
169 | - false, |
|
170 | - 0 |
|
171 | - ), |
|
172 | - 'LIN_percent' => new EE_Float_Field( |
|
173 | - 'LIN_percent', |
|
174 | - esc_html__('Percent', 'event_espresso'), |
|
175 | - false, |
|
176 | - 0 |
|
177 | - ), |
|
178 | - 'LIN_is_taxable' => new EE_Boolean_Field( |
|
179 | - 'LIN_is_taxable', |
|
180 | - esc_html__('Taxable', 'event_espresso'), |
|
181 | - false, |
|
182 | - false |
|
183 | - ), |
|
184 | - 'LIN_order' => new EE_Integer_Field( |
|
185 | - 'LIN_order', |
|
186 | - esc_html__('Order of Application towards total of parent', 'event_espresso'), |
|
187 | - false, |
|
188 | - 1 |
|
189 | - ), |
|
190 | - 'LIN_total' => new EE_Money_Field( |
|
191 | - 'LIN_total', |
|
192 | - esc_html__('Total (unit price x quantity)', 'event_espresso'), |
|
193 | - false, |
|
194 | - 0 |
|
195 | - ), |
|
196 | - 'LIN_quantity' => new EE_Integer_Field( |
|
197 | - 'LIN_quantity', |
|
198 | - esc_html__('Quantity', 'event_espresso'), |
|
199 | - true, |
|
200 | - 1 |
|
201 | - ), |
|
202 | - 'LIN_parent' => new EE_Integer_Field( |
|
203 | - 'LIN_parent', |
|
204 | - esc_html__("Parent ID (this item goes towards that Line Item's total)", 'event_espresso'), |
|
205 | - true, |
|
206 | - null |
|
207 | - ), |
|
208 | - 'LIN_type' => new EE_Enum_Text_Field( |
|
209 | - 'LIN_type', |
|
210 | - esc_html__('Type', 'event_espresso'), |
|
211 | - false, |
|
212 | - 'line-item', |
|
213 | - array( |
|
214 | - self::type_line_item => esc_html__('Line Item', 'event_espresso'), |
|
215 | - self::type_sub_line_item => esc_html__('Sub-Item', 'event_espresso'), |
|
216 | - self::type_sub_total => esc_html__('Subtotal', 'event_espresso'), |
|
217 | - self::type_tax_sub_total => esc_html__('Tax Subtotal', 'event_espresso'), |
|
218 | - self::type_tax => esc_html__('Tax', 'event_espresso'), |
|
219 | - self::type_total => esc_html__('Total', 'event_espresso'), |
|
220 | - self::type_cancellation => esc_html__('Cancellation', 'event_espresso'), |
|
221 | - ) |
|
222 | - ), |
|
223 | - 'OBJ_ID' => new EE_Foreign_Key_Int_Field( |
|
224 | - 'OBJ_ID', |
|
225 | - esc_html__('ID of Item purchased.', 'event_espresso'), |
|
226 | - true, |
|
227 | - null, |
|
228 | - $line_items_can_be_for |
|
229 | - ), |
|
230 | - 'OBJ_type' => new EE_Any_Foreign_Model_Name_Field( |
|
231 | - 'OBJ_type', |
|
232 | - esc_html__('Model Name this Line Item is for', 'event_espresso'), |
|
233 | - true, |
|
234 | - null, |
|
235 | - $line_items_can_be_for |
|
236 | - ), |
|
237 | - 'LIN_timestamp' => new EE_Datetime_Field( |
|
238 | - 'LIN_timestamp', |
|
239 | - esc_html__('When the line item was created', 'event_espresso'), |
|
240 | - false, |
|
241 | - EE_Datetime_Field::now, |
|
242 | - $timezone |
|
243 | - ), |
|
244 | - ), |
|
245 | - ); |
|
246 | - $this->_model_relations = array( |
|
247 | - 'Transaction' => new EE_Belongs_To_Relation(), |
|
248 | - 'Ticket' => new EE_Belongs_To_Any_Relation(), |
|
249 | - 'Price' => new EE_Belongs_To_Any_Relation(), |
|
250 | - 'Event' => new EE_Belongs_To_Any_Relation(), |
|
251 | - ); |
|
252 | - $this->_model_chain_to_wp_user = 'Transaction.Registration.Event'; |
|
253 | - $this->_caps_slug = 'transactions'; |
|
254 | - parent::__construct($timezone); |
|
255 | - } |
|
256 | - |
|
257 | - |
|
258 | - /** |
|
259 | - * Gets all the line items for this transaction of the given type |
|
260 | - * |
|
261 | - * @param string $line_item_type like one of EEM_Line_Item::type_* |
|
262 | - * @param EE_Transaction|int $transaction |
|
263 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
264 | - * @throws EE_Error |
|
265 | - * @throws InvalidArgumentException |
|
266 | - * @throws InvalidDataTypeException |
|
267 | - * @throws InvalidInterfaceException |
|
268 | - */ |
|
269 | - public function get_all_of_type_for_transaction($line_item_type, $transaction) |
|
270 | - { |
|
271 | - $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
272 | - return $this->get_all(array( |
|
273 | - array( |
|
274 | - 'LIN_type' => $line_item_type, |
|
275 | - 'TXN_ID' => $transaction, |
|
276 | - ), |
|
277 | - )); |
|
278 | - } |
|
279 | - |
|
280 | - |
|
281 | - /** |
|
282 | - * Gets all line items unrelated to tickets that are normal line items |
|
283 | - * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category) |
|
284 | - * |
|
285 | - * @param EE_Transaction|int $transaction |
|
286 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
287 | - * @throws EE_Error |
|
288 | - * @throws InvalidArgumentException |
|
289 | - * @throws InvalidDataTypeException |
|
290 | - * @throws InvalidInterfaceException |
|
291 | - */ |
|
292 | - public function get_all_non_ticket_line_items_for_transaction($transaction) |
|
293 | - { |
|
294 | - $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
295 | - return $this->get_all(array( |
|
296 | - array( |
|
297 | - 'LIN_type' => self::type_line_item, |
|
298 | - 'TXN_ID' => $transaction, |
|
299 | - 'OR' => array( |
|
300 | - 'OBJ_type*notticket' => array('!=', EEM_Line_Item::OBJ_TYPE_TICKET), |
|
301 | - 'OBJ_type*null' => array('IS_NULL'), |
|
302 | - ), |
|
303 | - ), |
|
304 | - )); |
|
305 | - } |
|
306 | - |
|
307 | - |
|
308 | - /** |
|
309 | - * Deletes line items with no transaction who have passed the transaction cutoff time. |
|
310 | - * This needs to be very efficient |
|
311 | - * because if there are spam bots afoot there will be LOTS of line items. Also MySQL doesn't allow a limit when |
|
312 | - * deleting and joining tables like this. |
|
313 | - * |
|
314 | - * @return int count of how many deleted |
|
315 | - * @throws EE_Error |
|
316 | - * @throws InvalidArgumentException |
|
317 | - * @throws InvalidDataTypeException |
|
318 | - * @throws InvalidInterfaceException |
|
319 | - */ |
|
320 | - public function delete_line_items_with_no_transaction() |
|
321 | - { |
|
322 | - /** @type WPDB $wpdb */ |
|
323 | - global $wpdb; |
|
324 | - $time_to_leave_alone = apply_filters( |
|
325 | - 'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', |
|
326 | - WEEK_IN_SECONDS |
|
327 | - ); |
|
328 | - $query = $wpdb->prepare( |
|
329 | - 'DELETE li |
|
31 | + /** |
|
32 | + * Tax sub-total is just the total of all the taxes, which should be children |
|
33 | + * of this line item. There should only ever be one tax sub-total, and it should |
|
34 | + * be a direct child of. Its quantity and LIN_unit_price = 1. |
|
35 | + */ |
|
36 | + const type_tax_sub_total = 'tax-sub-total'; |
|
37 | + |
|
38 | + /** |
|
39 | + * Tax line items indicate a tax applied to all the taxable line items. |
|
40 | + * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal |
|
41 | + * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1. |
|
42 | + */ |
|
43 | + const type_tax = 'tax'; |
|
44 | + |
|
45 | + /** |
|
46 | + * Indicating individual items purchased, or discounts or surcharges. |
|
47 | + * The sum of all the regular line items plus the tax items should equal the grand total. |
|
48 | + * Possible children are sub-line-items and cancellations. |
|
49 | + * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children |
|
50 | + * LIN_totals. Its LIN_percent = 0. |
|
51 | + * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1). |
|
52 | + * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1. |
|
53 | + */ |
|
54 | + const type_line_item = 'line-item'; |
|
55 | + |
|
56 | + /** |
|
57 | + * Line item indicating all the factors that make a single line item. |
|
58 | + * Sub-line items should have NO children line items. |
|
59 | + * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's |
|
60 | + * contribution towards the price of ONE of their parent items, and its LIN_total should be |
|
61 | + * = LIN_quantity * LIN_unit_price. Its LIN_percent = 0. |
|
62 | + * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should |
|
63 | + * = LIN_percent / 100 * sum of lower-priority sibling line items.. |
|
64 | + */ |
|
65 | + const type_sub_line_item = 'sub-item'; |
|
66 | + |
|
67 | + /** |
|
68 | + * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal). |
|
69 | + * Direct children should be event subtotals. |
|
70 | + * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals. |
|
71 | + */ |
|
72 | + const type_sub_total = 'sub-total'; |
|
73 | + |
|
74 | + /** |
|
75 | + * Line item for the grand total of an order. |
|
76 | + * Its direct children should be tax subtotals and (pre-tax) subtotals, |
|
77 | + * and possibly a regular line item indicating a transaction-wide discount/surcharge. |
|
78 | + * Should have a quantity of 1, a LIN_total and LIN_unit_price of the entire order's amount. |
|
79 | + */ |
|
80 | + const type_total = 'total'; |
|
81 | + |
|
82 | + /** |
|
83 | + * When a line item is cancelled, a sub-line-item of type 'cancellation' |
|
84 | + * should be created, indicating the quantity that were cancelled |
|
85 | + * (because a line item could have a quantity of 1, and its cancellation item |
|
86 | + * could be for 3, indicating that originally 4 were purchased, but 3 have been |
|
87 | + * cancelled, and only one remains). |
|
88 | + * When items are refunded, a cancellation line item should be made, which points |
|
89 | + * to teh payment model object which actually refunded the payment. |
|
90 | + * Cancellations should NOT have any children line items; the should NOT affect |
|
91 | + * any calculations, and are only meant as a record that cancellations have occurred. |
|
92 | + * Their LIN_percent should be 0. |
|
93 | + */ |
|
94 | + const type_cancellation = 'cancellation'; |
|
95 | + |
|
96 | + // various line item object types |
|
97 | + const OBJ_TYPE_EVENT = 'Event'; |
|
98 | + |
|
99 | + const OBJ_TYPE_PRICE = 'Price'; |
|
100 | + |
|
101 | + const OBJ_TYPE_PROMOTION = 'Promotion'; |
|
102 | + |
|
103 | + const OBJ_TYPE_TICKET = 'Ticket'; |
|
104 | + |
|
105 | + const OBJ_TYPE_TRANSACTION = 'Transaction'; |
|
106 | + |
|
107 | + /** |
|
108 | + * @var EEM_Line_Item $_instance |
|
109 | + */ |
|
110 | + protected static $_instance; |
|
111 | + |
|
112 | + |
|
113 | + /** |
|
114 | + * private constructor to prevent direct creation |
|
115 | + * |
|
116 | + * @Constructor |
|
117 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
118 | + * (and any incoming timezone data that gets saved). |
|
119 | + * Note this just sends the timezone info to the date time model field objects. |
|
120 | + * Default is NULL |
|
121 | + * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
122 | + * @throws EE_Error |
|
123 | + * @throws InvalidArgumentException |
|
124 | + */ |
|
125 | + protected function __construct($timezone) |
|
126 | + { |
|
127 | + $this->singular_item = esc_html__('Line Item', 'event_espresso'); |
|
128 | + $this->plural_item = esc_html__('Line Items', 'event_espresso'); |
|
129 | + |
|
130 | + $this->_tables = array( |
|
131 | + 'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID'), |
|
132 | + ); |
|
133 | + $line_items_can_be_for = apply_filters( |
|
134 | + 'FHEE__EEM_Line_Item__line_items_can_be_for', |
|
135 | + array('Ticket', 'Price', 'Event') |
|
136 | + ); |
|
137 | + $this->_fields = array( |
|
138 | + 'Line_Item' => array( |
|
139 | + 'LIN_ID' => new EE_Primary_Key_Int_Field( |
|
140 | + 'LIN_ID', |
|
141 | + esc_html__('ID', 'event_espresso') |
|
142 | + ), |
|
143 | + 'LIN_code' => new EE_Slug_Field( |
|
144 | + 'LIN_code', |
|
145 | + esc_html__('Code for index into Cart', 'event_espresso'), |
|
146 | + true |
|
147 | + ), |
|
148 | + 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
149 | + 'TXN_ID', |
|
150 | + esc_html__('Transaction ID', 'event_espresso'), |
|
151 | + true, |
|
152 | + null, |
|
153 | + 'Transaction' |
|
154 | + ), |
|
155 | + 'LIN_name' => new EE_Full_HTML_Field( |
|
156 | + 'LIN_name', |
|
157 | + esc_html__('Line Item Name', 'event_espresso'), |
|
158 | + false, |
|
159 | + '' |
|
160 | + ), |
|
161 | + 'LIN_desc' => new EE_Full_HTML_Field( |
|
162 | + 'LIN_desc', |
|
163 | + esc_html__('Line Item Description', 'event_espresso'), |
|
164 | + true |
|
165 | + ), |
|
166 | + 'LIN_unit_price' => new EE_Money_Field( |
|
167 | + 'LIN_unit_price', |
|
168 | + esc_html__('Unit Price', 'event_espresso'), |
|
169 | + false, |
|
170 | + 0 |
|
171 | + ), |
|
172 | + 'LIN_percent' => new EE_Float_Field( |
|
173 | + 'LIN_percent', |
|
174 | + esc_html__('Percent', 'event_espresso'), |
|
175 | + false, |
|
176 | + 0 |
|
177 | + ), |
|
178 | + 'LIN_is_taxable' => new EE_Boolean_Field( |
|
179 | + 'LIN_is_taxable', |
|
180 | + esc_html__('Taxable', 'event_espresso'), |
|
181 | + false, |
|
182 | + false |
|
183 | + ), |
|
184 | + 'LIN_order' => new EE_Integer_Field( |
|
185 | + 'LIN_order', |
|
186 | + esc_html__('Order of Application towards total of parent', 'event_espresso'), |
|
187 | + false, |
|
188 | + 1 |
|
189 | + ), |
|
190 | + 'LIN_total' => new EE_Money_Field( |
|
191 | + 'LIN_total', |
|
192 | + esc_html__('Total (unit price x quantity)', 'event_espresso'), |
|
193 | + false, |
|
194 | + 0 |
|
195 | + ), |
|
196 | + 'LIN_quantity' => new EE_Integer_Field( |
|
197 | + 'LIN_quantity', |
|
198 | + esc_html__('Quantity', 'event_espresso'), |
|
199 | + true, |
|
200 | + 1 |
|
201 | + ), |
|
202 | + 'LIN_parent' => new EE_Integer_Field( |
|
203 | + 'LIN_parent', |
|
204 | + esc_html__("Parent ID (this item goes towards that Line Item's total)", 'event_espresso'), |
|
205 | + true, |
|
206 | + null |
|
207 | + ), |
|
208 | + 'LIN_type' => new EE_Enum_Text_Field( |
|
209 | + 'LIN_type', |
|
210 | + esc_html__('Type', 'event_espresso'), |
|
211 | + false, |
|
212 | + 'line-item', |
|
213 | + array( |
|
214 | + self::type_line_item => esc_html__('Line Item', 'event_espresso'), |
|
215 | + self::type_sub_line_item => esc_html__('Sub-Item', 'event_espresso'), |
|
216 | + self::type_sub_total => esc_html__('Subtotal', 'event_espresso'), |
|
217 | + self::type_tax_sub_total => esc_html__('Tax Subtotal', 'event_espresso'), |
|
218 | + self::type_tax => esc_html__('Tax', 'event_espresso'), |
|
219 | + self::type_total => esc_html__('Total', 'event_espresso'), |
|
220 | + self::type_cancellation => esc_html__('Cancellation', 'event_espresso'), |
|
221 | + ) |
|
222 | + ), |
|
223 | + 'OBJ_ID' => new EE_Foreign_Key_Int_Field( |
|
224 | + 'OBJ_ID', |
|
225 | + esc_html__('ID of Item purchased.', 'event_espresso'), |
|
226 | + true, |
|
227 | + null, |
|
228 | + $line_items_can_be_for |
|
229 | + ), |
|
230 | + 'OBJ_type' => new EE_Any_Foreign_Model_Name_Field( |
|
231 | + 'OBJ_type', |
|
232 | + esc_html__('Model Name this Line Item is for', 'event_espresso'), |
|
233 | + true, |
|
234 | + null, |
|
235 | + $line_items_can_be_for |
|
236 | + ), |
|
237 | + 'LIN_timestamp' => new EE_Datetime_Field( |
|
238 | + 'LIN_timestamp', |
|
239 | + esc_html__('When the line item was created', 'event_espresso'), |
|
240 | + false, |
|
241 | + EE_Datetime_Field::now, |
|
242 | + $timezone |
|
243 | + ), |
|
244 | + ), |
|
245 | + ); |
|
246 | + $this->_model_relations = array( |
|
247 | + 'Transaction' => new EE_Belongs_To_Relation(), |
|
248 | + 'Ticket' => new EE_Belongs_To_Any_Relation(), |
|
249 | + 'Price' => new EE_Belongs_To_Any_Relation(), |
|
250 | + 'Event' => new EE_Belongs_To_Any_Relation(), |
|
251 | + ); |
|
252 | + $this->_model_chain_to_wp_user = 'Transaction.Registration.Event'; |
|
253 | + $this->_caps_slug = 'transactions'; |
|
254 | + parent::__construct($timezone); |
|
255 | + } |
|
256 | + |
|
257 | + |
|
258 | + /** |
|
259 | + * Gets all the line items for this transaction of the given type |
|
260 | + * |
|
261 | + * @param string $line_item_type like one of EEM_Line_Item::type_* |
|
262 | + * @param EE_Transaction|int $transaction |
|
263 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
264 | + * @throws EE_Error |
|
265 | + * @throws InvalidArgumentException |
|
266 | + * @throws InvalidDataTypeException |
|
267 | + * @throws InvalidInterfaceException |
|
268 | + */ |
|
269 | + public function get_all_of_type_for_transaction($line_item_type, $transaction) |
|
270 | + { |
|
271 | + $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
272 | + return $this->get_all(array( |
|
273 | + array( |
|
274 | + 'LIN_type' => $line_item_type, |
|
275 | + 'TXN_ID' => $transaction, |
|
276 | + ), |
|
277 | + )); |
|
278 | + } |
|
279 | + |
|
280 | + |
|
281 | + /** |
|
282 | + * Gets all line items unrelated to tickets that are normal line items |
|
283 | + * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category) |
|
284 | + * |
|
285 | + * @param EE_Transaction|int $transaction |
|
286 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
287 | + * @throws EE_Error |
|
288 | + * @throws InvalidArgumentException |
|
289 | + * @throws InvalidDataTypeException |
|
290 | + * @throws InvalidInterfaceException |
|
291 | + */ |
|
292 | + public function get_all_non_ticket_line_items_for_transaction($transaction) |
|
293 | + { |
|
294 | + $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
295 | + return $this->get_all(array( |
|
296 | + array( |
|
297 | + 'LIN_type' => self::type_line_item, |
|
298 | + 'TXN_ID' => $transaction, |
|
299 | + 'OR' => array( |
|
300 | + 'OBJ_type*notticket' => array('!=', EEM_Line_Item::OBJ_TYPE_TICKET), |
|
301 | + 'OBJ_type*null' => array('IS_NULL'), |
|
302 | + ), |
|
303 | + ), |
|
304 | + )); |
|
305 | + } |
|
306 | + |
|
307 | + |
|
308 | + /** |
|
309 | + * Deletes line items with no transaction who have passed the transaction cutoff time. |
|
310 | + * This needs to be very efficient |
|
311 | + * because if there are spam bots afoot there will be LOTS of line items. Also MySQL doesn't allow a limit when |
|
312 | + * deleting and joining tables like this. |
|
313 | + * |
|
314 | + * @return int count of how many deleted |
|
315 | + * @throws EE_Error |
|
316 | + * @throws InvalidArgumentException |
|
317 | + * @throws InvalidDataTypeException |
|
318 | + * @throws InvalidInterfaceException |
|
319 | + */ |
|
320 | + public function delete_line_items_with_no_transaction() |
|
321 | + { |
|
322 | + /** @type WPDB $wpdb */ |
|
323 | + global $wpdb; |
|
324 | + $time_to_leave_alone = apply_filters( |
|
325 | + 'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', |
|
326 | + WEEK_IN_SECONDS |
|
327 | + ); |
|
328 | + $query = $wpdb->prepare( |
|
329 | + 'DELETE li |
|
330 | 330 | FROM ' . $this->table() . ' li |
331 | 331 | LEFT JOIN ' . EEM_Transaction::instance()->table() . ' t ON li.TXN_ID = t.TXN_ID |
332 | 332 | WHERE t.TXN_ID IS NULL AND li.LIN_timestamp < %s', |
333 | - // use GMT time because that's what TXN_timestamps are in |
|
334 | - date('Y-m-d H:i:s', time() - $time_to_leave_alone) |
|
335 | - ); |
|
336 | - return $wpdb->query($query); |
|
337 | - } |
|
338 | - |
|
339 | - |
|
340 | - /** |
|
341 | - * get_line_item_for_transaction_object |
|
342 | - * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket |
|
343 | - * |
|
344 | - * @param int $TXN_ID |
|
345 | - * @param EE_Base_Class $object |
|
346 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
347 | - * @throws EE_Error |
|
348 | - * @throws InvalidArgumentException |
|
349 | - * @throws InvalidDataTypeException |
|
350 | - * @throws InvalidInterfaceException |
|
351 | - * @throws ReflectionException |
|
352 | - */ |
|
353 | - public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object) |
|
354 | - { |
|
355 | - return $this->get_all(array( |
|
356 | - array( |
|
357 | - 'TXN_ID' => $TXN_ID, |
|
358 | - 'OBJ_type' => str_replace('EE_', '', get_class($object)), |
|
359 | - 'OBJ_ID' => $object->ID(), |
|
360 | - ), |
|
361 | - )); |
|
362 | - } |
|
363 | - |
|
364 | - |
|
365 | - /** |
|
366 | - * get_object_line_items_for_transaction |
|
367 | - * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs |
|
368 | - * |
|
369 | - * @param int $TXN_ID |
|
370 | - * @param string $OBJ_type |
|
371 | - * @param array $OBJ_IDs |
|
372 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
373 | - * @throws EE_Error |
|
374 | - */ |
|
375 | - public function get_object_line_items_for_transaction( |
|
376 | - $TXN_ID, |
|
377 | - $OBJ_type = EEM_Line_Item::OBJ_TYPE_EVENT, |
|
378 | - $OBJ_IDs = array() |
|
379 | - ) { |
|
380 | - $query_params = array( |
|
381 | - 'OBJ_type' => $OBJ_type, |
|
382 | - // if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query |
|
383 | - 'OBJ_ID' => is_array($OBJ_IDs) && ! isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs, |
|
384 | - ); |
|
385 | - if ($TXN_ID) { |
|
386 | - $query_params['TXN_ID'] = $TXN_ID; |
|
387 | - } |
|
388 | - return $this->get_all(array($query_params)); |
|
389 | - } |
|
390 | - |
|
391 | - |
|
392 | - /** |
|
393 | - * get_all_ticket_line_items_for_transaction |
|
394 | - * |
|
395 | - * @param EE_Transaction $transaction |
|
396 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
397 | - * @throws EE_Error |
|
398 | - * @throws InvalidArgumentException |
|
399 | - * @throws InvalidDataTypeException |
|
400 | - * @throws InvalidInterfaceException |
|
401 | - * @throws ReflectionException |
|
402 | - */ |
|
403 | - public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction) |
|
404 | - { |
|
405 | - return $this->get_all(array( |
|
406 | - array( |
|
407 | - 'TXN_ID' => $transaction->ID(), |
|
408 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
409 | - ), |
|
410 | - )); |
|
411 | - } |
|
412 | - |
|
413 | - |
|
414 | - /** |
|
415 | - * get_ticket_line_item_for_transaction |
|
416 | - * |
|
417 | - * @param int $TXN_ID |
|
418 | - * @param int $TKT_ID |
|
419 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
420 | - * @throws EE_Error |
|
421 | - * @throws InvalidArgumentException |
|
422 | - * @throws InvalidDataTypeException |
|
423 | - * @throws InvalidInterfaceException |
|
424 | - */ |
|
425 | - public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID) |
|
426 | - { |
|
427 | - return $this->get_one(array( |
|
428 | - array( |
|
429 | - 'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID), |
|
430 | - 'OBJ_ID' => $TKT_ID, |
|
431 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
432 | - ), |
|
433 | - )); |
|
434 | - } |
|
435 | - |
|
436 | - |
|
437 | - /** |
|
438 | - * get_existing_promotion_line_item |
|
439 | - * searches the cart for existing line items for the specified promotion |
|
440 | - * |
|
441 | - * @since 1.0.0 |
|
442 | - * @param EE_Line_Item $parent_line_item |
|
443 | - * @param EE_Promotion $promotion |
|
444 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
445 | - * @throws EE_Error |
|
446 | - * @throws InvalidArgumentException |
|
447 | - * @throws InvalidDataTypeException |
|
448 | - * @throws InvalidInterfaceException |
|
449 | - * @throws ReflectionException |
|
450 | - */ |
|
451 | - public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion) |
|
452 | - { |
|
453 | - return $this->get_one(array( |
|
454 | - array( |
|
455 | - 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
456 | - 'LIN_parent' => $parent_line_item->ID(), |
|
457 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
458 | - 'OBJ_ID' => $promotion->ID(), |
|
459 | - ), |
|
460 | - )); |
|
461 | - } |
|
462 | - |
|
463 | - |
|
464 | - /** |
|
465 | - * get_all_promotion_line_items |
|
466 | - * searches the cart for any and all existing promotion line items |
|
467 | - * |
|
468 | - * @since 1.0.0 |
|
469 | - * @param EE_Line_Item $parent_line_item |
|
470 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
471 | - * @throws EE_Error |
|
472 | - * @throws InvalidArgumentException |
|
473 | - * @throws InvalidDataTypeException |
|
474 | - * @throws InvalidInterfaceException |
|
475 | - * @throws ReflectionException |
|
476 | - */ |
|
477 | - public function get_all_promotion_line_items(EE_Line_Item $parent_line_item) |
|
478 | - { |
|
479 | - return $this->get_all(array( |
|
480 | - array( |
|
481 | - 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
482 | - 'LIN_parent' => $parent_line_item->ID(), |
|
483 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
484 | - ), |
|
485 | - )); |
|
486 | - } |
|
487 | - |
|
488 | - |
|
489 | - /** |
|
490 | - * Gets the registration's corresponding line item. |
|
491 | - * Note: basically does NOT support having multiple line items for a single ticket, |
|
492 | - * which would happen if some of the registrations had a price modifier while others didn't. |
|
493 | - * In order to support that, we'd probably need a LIN_ID on registrations or something. |
|
494 | - * |
|
495 | - * @param EE_Registration $registration |
|
496 | - * @return EE_Base_Class|EE_Line_ITem|EE_Soft_Delete_Base_Class|NULL |
|
497 | - * @throws EE_Error |
|
498 | - */ |
|
499 | - public function get_line_item_for_registration(EE_Registration $registration) |
|
500 | - { |
|
501 | - return $this->get_one($this->line_item_for_registration_query_params($registration)); |
|
502 | - } |
|
503 | - |
|
504 | - |
|
505 | - /** |
|
506 | - * Gets the query params used to retrieve a specific line item for the given registration |
|
507 | - * |
|
508 | - * @param EE_Registration $registration |
|
509 | - * @param array $original_query_params any extra query params you'd like to be merged with |
|
510 | - * @return array @see |
|
511 | - * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
512 | - * @throws EE_Error |
|
513 | - */ |
|
514 | - public function line_item_for_registration_query_params( |
|
515 | - EE_Registration $registration, |
|
516 | - $original_query_params = array() |
|
517 | - ) { |
|
518 | - return array_replace_recursive($original_query_params, array( |
|
519 | - array( |
|
520 | - 'OBJ_ID' => $registration->ticket_ID(), |
|
521 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
522 | - 'TXN_ID' => $registration->transaction_ID(), |
|
523 | - ), |
|
524 | - )); |
|
525 | - } |
|
526 | - |
|
527 | - |
|
528 | - /** |
|
529 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
530 | - * @throws InvalidInterfaceException |
|
531 | - * @throws InvalidDataTypeException |
|
532 | - * @throws EE_Error |
|
533 | - * @throws InvalidArgumentException |
|
534 | - */ |
|
535 | - public function get_total_line_items_with_no_transaction() |
|
536 | - { |
|
537 | - return $this->get_total_line_items_for_carts(); |
|
538 | - } |
|
539 | - |
|
540 | - |
|
541 | - /** |
|
542 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
543 | - * @throws InvalidInterfaceException |
|
544 | - * @throws InvalidDataTypeException |
|
545 | - * @throws EE_Error |
|
546 | - * @throws InvalidArgumentException |
|
547 | - */ |
|
548 | - public function get_total_line_items_for_active_carts() |
|
549 | - { |
|
550 | - return $this->get_total_line_items_for_carts(false); |
|
551 | - } |
|
552 | - |
|
553 | - |
|
554 | - /** |
|
555 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
556 | - * @throws InvalidInterfaceException |
|
557 | - * @throws InvalidDataTypeException |
|
558 | - * @throws EE_Error |
|
559 | - * @throws InvalidArgumentException |
|
560 | - */ |
|
561 | - public function get_total_line_items_for_expired_carts() |
|
562 | - { |
|
563 | - return $this->get_total_line_items_for_carts(true); |
|
564 | - } |
|
565 | - |
|
566 | - |
|
567 | - /** |
|
568 | - * Returns an array of grand total line items where the TXN_ID is 0. |
|
569 | - * If $expired is set to true, then only line items for expired sessions will be returned. |
|
570 | - * If $expired is set to false, then only line items for active sessions will be returned. |
|
571 | - * |
|
572 | - * @param null $expired |
|
573 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
574 | - * @throws EE_Error |
|
575 | - * @throws InvalidArgumentException |
|
576 | - * @throws InvalidDataTypeException |
|
577 | - * @throws InvalidInterfaceException |
|
578 | - */ |
|
579 | - private function get_total_line_items_for_carts($expired = null) |
|
580 | - { |
|
581 | - $where_params = array( |
|
582 | - 'TXN_ID' => 0, |
|
583 | - 'LIN_type' => 'total', |
|
584 | - ); |
|
585 | - if ($expired !== null) { |
|
586 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
587 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
588 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
589 | - ); |
|
590 | - $where_params['LIN_timestamp'] = array( |
|
591 | - $expired ? '<=' : '>', |
|
592 | - $session_lifespan->expiration(), |
|
593 | - ); |
|
594 | - } |
|
595 | - return $this->get_all(array($where_params)); |
|
596 | - } |
|
597 | - |
|
598 | - |
|
599 | - /** |
|
600 | - * Returns an array of ticket total line items where the TXN_ID is 0 |
|
601 | - * AND the timestamp is older than the session lifespan. |
|
602 | - * |
|
603 | - * @param int $timestamp |
|
604 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
605 | - * @throws EE_Error |
|
606 | - * @throws InvalidArgumentException |
|
607 | - * @throws InvalidDataTypeException |
|
608 | - * @throws InvalidInterfaceException |
|
609 | - */ |
|
610 | - public function getTicketLineItemsForExpiredCarts($timestamp = 0) |
|
611 | - { |
|
612 | - if (! absint($timestamp)) { |
|
613 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
614 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
615 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
616 | - ); |
|
617 | - $timestamp = $session_lifespan->expiration(); |
|
618 | - } |
|
619 | - return $this->get_all( |
|
620 | - array( |
|
621 | - array( |
|
622 | - 'TXN_ID' => 0, |
|
623 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
624 | - 'LIN_timestamp' => array('<=', $timestamp), |
|
625 | - ), |
|
626 | - ) |
|
627 | - ); |
|
628 | - } |
|
333 | + // use GMT time because that's what TXN_timestamps are in |
|
334 | + date('Y-m-d H:i:s', time() - $time_to_leave_alone) |
|
335 | + ); |
|
336 | + return $wpdb->query($query); |
|
337 | + } |
|
338 | + |
|
339 | + |
|
340 | + /** |
|
341 | + * get_line_item_for_transaction_object |
|
342 | + * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket |
|
343 | + * |
|
344 | + * @param int $TXN_ID |
|
345 | + * @param EE_Base_Class $object |
|
346 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
347 | + * @throws EE_Error |
|
348 | + * @throws InvalidArgumentException |
|
349 | + * @throws InvalidDataTypeException |
|
350 | + * @throws InvalidInterfaceException |
|
351 | + * @throws ReflectionException |
|
352 | + */ |
|
353 | + public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object) |
|
354 | + { |
|
355 | + return $this->get_all(array( |
|
356 | + array( |
|
357 | + 'TXN_ID' => $TXN_ID, |
|
358 | + 'OBJ_type' => str_replace('EE_', '', get_class($object)), |
|
359 | + 'OBJ_ID' => $object->ID(), |
|
360 | + ), |
|
361 | + )); |
|
362 | + } |
|
363 | + |
|
364 | + |
|
365 | + /** |
|
366 | + * get_object_line_items_for_transaction |
|
367 | + * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs |
|
368 | + * |
|
369 | + * @param int $TXN_ID |
|
370 | + * @param string $OBJ_type |
|
371 | + * @param array $OBJ_IDs |
|
372 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
373 | + * @throws EE_Error |
|
374 | + */ |
|
375 | + public function get_object_line_items_for_transaction( |
|
376 | + $TXN_ID, |
|
377 | + $OBJ_type = EEM_Line_Item::OBJ_TYPE_EVENT, |
|
378 | + $OBJ_IDs = array() |
|
379 | + ) { |
|
380 | + $query_params = array( |
|
381 | + 'OBJ_type' => $OBJ_type, |
|
382 | + // if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query |
|
383 | + 'OBJ_ID' => is_array($OBJ_IDs) && ! isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs, |
|
384 | + ); |
|
385 | + if ($TXN_ID) { |
|
386 | + $query_params['TXN_ID'] = $TXN_ID; |
|
387 | + } |
|
388 | + return $this->get_all(array($query_params)); |
|
389 | + } |
|
390 | + |
|
391 | + |
|
392 | + /** |
|
393 | + * get_all_ticket_line_items_for_transaction |
|
394 | + * |
|
395 | + * @param EE_Transaction $transaction |
|
396 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
397 | + * @throws EE_Error |
|
398 | + * @throws InvalidArgumentException |
|
399 | + * @throws InvalidDataTypeException |
|
400 | + * @throws InvalidInterfaceException |
|
401 | + * @throws ReflectionException |
|
402 | + */ |
|
403 | + public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction) |
|
404 | + { |
|
405 | + return $this->get_all(array( |
|
406 | + array( |
|
407 | + 'TXN_ID' => $transaction->ID(), |
|
408 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
409 | + ), |
|
410 | + )); |
|
411 | + } |
|
412 | + |
|
413 | + |
|
414 | + /** |
|
415 | + * get_ticket_line_item_for_transaction |
|
416 | + * |
|
417 | + * @param int $TXN_ID |
|
418 | + * @param int $TKT_ID |
|
419 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
420 | + * @throws EE_Error |
|
421 | + * @throws InvalidArgumentException |
|
422 | + * @throws InvalidDataTypeException |
|
423 | + * @throws InvalidInterfaceException |
|
424 | + */ |
|
425 | + public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID) |
|
426 | + { |
|
427 | + return $this->get_one(array( |
|
428 | + array( |
|
429 | + 'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID), |
|
430 | + 'OBJ_ID' => $TKT_ID, |
|
431 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
432 | + ), |
|
433 | + )); |
|
434 | + } |
|
435 | + |
|
436 | + |
|
437 | + /** |
|
438 | + * get_existing_promotion_line_item |
|
439 | + * searches the cart for existing line items for the specified promotion |
|
440 | + * |
|
441 | + * @since 1.0.0 |
|
442 | + * @param EE_Line_Item $parent_line_item |
|
443 | + * @param EE_Promotion $promotion |
|
444 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
445 | + * @throws EE_Error |
|
446 | + * @throws InvalidArgumentException |
|
447 | + * @throws InvalidDataTypeException |
|
448 | + * @throws InvalidInterfaceException |
|
449 | + * @throws ReflectionException |
|
450 | + */ |
|
451 | + public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion) |
|
452 | + { |
|
453 | + return $this->get_one(array( |
|
454 | + array( |
|
455 | + 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
456 | + 'LIN_parent' => $parent_line_item->ID(), |
|
457 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
458 | + 'OBJ_ID' => $promotion->ID(), |
|
459 | + ), |
|
460 | + )); |
|
461 | + } |
|
462 | + |
|
463 | + |
|
464 | + /** |
|
465 | + * get_all_promotion_line_items |
|
466 | + * searches the cart for any and all existing promotion line items |
|
467 | + * |
|
468 | + * @since 1.0.0 |
|
469 | + * @param EE_Line_Item $parent_line_item |
|
470 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
471 | + * @throws EE_Error |
|
472 | + * @throws InvalidArgumentException |
|
473 | + * @throws InvalidDataTypeException |
|
474 | + * @throws InvalidInterfaceException |
|
475 | + * @throws ReflectionException |
|
476 | + */ |
|
477 | + public function get_all_promotion_line_items(EE_Line_Item $parent_line_item) |
|
478 | + { |
|
479 | + return $this->get_all(array( |
|
480 | + array( |
|
481 | + 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
482 | + 'LIN_parent' => $parent_line_item->ID(), |
|
483 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
484 | + ), |
|
485 | + )); |
|
486 | + } |
|
487 | + |
|
488 | + |
|
489 | + /** |
|
490 | + * Gets the registration's corresponding line item. |
|
491 | + * Note: basically does NOT support having multiple line items for a single ticket, |
|
492 | + * which would happen if some of the registrations had a price modifier while others didn't. |
|
493 | + * In order to support that, we'd probably need a LIN_ID on registrations or something. |
|
494 | + * |
|
495 | + * @param EE_Registration $registration |
|
496 | + * @return EE_Base_Class|EE_Line_ITem|EE_Soft_Delete_Base_Class|NULL |
|
497 | + * @throws EE_Error |
|
498 | + */ |
|
499 | + public function get_line_item_for_registration(EE_Registration $registration) |
|
500 | + { |
|
501 | + return $this->get_one($this->line_item_for_registration_query_params($registration)); |
|
502 | + } |
|
503 | + |
|
504 | + |
|
505 | + /** |
|
506 | + * Gets the query params used to retrieve a specific line item for the given registration |
|
507 | + * |
|
508 | + * @param EE_Registration $registration |
|
509 | + * @param array $original_query_params any extra query params you'd like to be merged with |
|
510 | + * @return array @see |
|
511 | + * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
512 | + * @throws EE_Error |
|
513 | + */ |
|
514 | + public function line_item_for_registration_query_params( |
|
515 | + EE_Registration $registration, |
|
516 | + $original_query_params = array() |
|
517 | + ) { |
|
518 | + return array_replace_recursive($original_query_params, array( |
|
519 | + array( |
|
520 | + 'OBJ_ID' => $registration->ticket_ID(), |
|
521 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
522 | + 'TXN_ID' => $registration->transaction_ID(), |
|
523 | + ), |
|
524 | + )); |
|
525 | + } |
|
526 | + |
|
527 | + |
|
528 | + /** |
|
529 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
530 | + * @throws InvalidInterfaceException |
|
531 | + * @throws InvalidDataTypeException |
|
532 | + * @throws EE_Error |
|
533 | + * @throws InvalidArgumentException |
|
534 | + */ |
|
535 | + public function get_total_line_items_with_no_transaction() |
|
536 | + { |
|
537 | + return $this->get_total_line_items_for_carts(); |
|
538 | + } |
|
539 | + |
|
540 | + |
|
541 | + /** |
|
542 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
543 | + * @throws InvalidInterfaceException |
|
544 | + * @throws InvalidDataTypeException |
|
545 | + * @throws EE_Error |
|
546 | + * @throws InvalidArgumentException |
|
547 | + */ |
|
548 | + public function get_total_line_items_for_active_carts() |
|
549 | + { |
|
550 | + return $this->get_total_line_items_for_carts(false); |
|
551 | + } |
|
552 | + |
|
553 | + |
|
554 | + /** |
|
555 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
556 | + * @throws InvalidInterfaceException |
|
557 | + * @throws InvalidDataTypeException |
|
558 | + * @throws EE_Error |
|
559 | + * @throws InvalidArgumentException |
|
560 | + */ |
|
561 | + public function get_total_line_items_for_expired_carts() |
|
562 | + { |
|
563 | + return $this->get_total_line_items_for_carts(true); |
|
564 | + } |
|
565 | + |
|
566 | + |
|
567 | + /** |
|
568 | + * Returns an array of grand total line items where the TXN_ID is 0. |
|
569 | + * If $expired is set to true, then only line items for expired sessions will be returned. |
|
570 | + * If $expired is set to false, then only line items for active sessions will be returned. |
|
571 | + * |
|
572 | + * @param null $expired |
|
573 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
574 | + * @throws EE_Error |
|
575 | + * @throws InvalidArgumentException |
|
576 | + * @throws InvalidDataTypeException |
|
577 | + * @throws InvalidInterfaceException |
|
578 | + */ |
|
579 | + private function get_total_line_items_for_carts($expired = null) |
|
580 | + { |
|
581 | + $where_params = array( |
|
582 | + 'TXN_ID' => 0, |
|
583 | + 'LIN_type' => 'total', |
|
584 | + ); |
|
585 | + if ($expired !== null) { |
|
586 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
587 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
588 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
589 | + ); |
|
590 | + $where_params['LIN_timestamp'] = array( |
|
591 | + $expired ? '<=' : '>', |
|
592 | + $session_lifespan->expiration(), |
|
593 | + ); |
|
594 | + } |
|
595 | + return $this->get_all(array($where_params)); |
|
596 | + } |
|
597 | + |
|
598 | + |
|
599 | + /** |
|
600 | + * Returns an array of ticket total line items where the TXN_ID is 0 |
|
601 | + * AND the timestamp is older than the session lifespan. |
|
602 | + * |
|
603 | + * @param int $timestamp |
|
604 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
605 | + * @throws EE_Error |
|
606 | + * @throws InvalidArgumentException |
|
607 | + * @throws InvalidDataTypeException |
|
608 | + * @throws InvalidInterfaceException |
|
609 | + */ |
|
610 | + public function getTicketLineItemsForExpiredCarts($timestamp = 0) |
|
611 | + { |
|
612 | + if (! absint($timestamp)) { |
|
613 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
614 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
615 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
616 | + ); |
|
617 | + $timestamp = $session_lifespan->expiration(); |
|
618 | + } |
|
619 | + return $this->get_all( |
|
620 | + array( |
|
621 | + array( |
|
622 | + 'TXN_ID' => 0, |
|
623 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
624 | + 'LIN_timestamp' => array('<=', $timestamp), |
|
625 | + ), |
|
626 | + ) |
|
627 | + ); |
|
628 | + } |
|
629 | 629 | } |
@@ -13,816 +13,816 @@ discard block |
||
13 | 13 | class EEM_Registration extends EEM_Soft_Delete_Base |
14 | 14 | { |
15 | 15 | |
16 | - /** |
|
17 | - * @var EEM_Registration $_instance |
|
18 | - */ |
|
19 | - protected static $_instance; |
|
20 | - |
|
21 | - /** |
|
22 | - * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values |
|
23 | - * are status codes (eg, approved, cancelled, etc) |
|
24 | - * |
|
25 | - * @var array |
|
26 | - */ |
|
27 | - private static $_reg_status; |
|
28 | - |
|
29 | - /** |
|
30 | - * The value of REG_count for a primary registrant |
|
31 | - */ |
|
32 | - const PRIMARY_REGISTRANT_COUNT = 1; |
|
33 | - |
|
34 | - /** |
|
35 | - * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration. |
|
36 | - * Initial status for registrations when they are first created |
|
37 | - * Payments are NOT allowed. |
|
38 | - * Automatically toggled to whatever the default Event registration status is upon completion of the attendee |
|
39 | - * information reg step NO space reserved. Registration is NOT active |
|
40 | - */ |
|
41 | - const status_id_incomplete = 'RIC'; |
|
42 | - |
|
43 | - /** |
|
44 | - * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration. |
|
45 | - * Payments are NOT allowed. |
|
46 | - * Event Admin must manually toggle STS_ID for it to change |
|
47 | - * No space reserved. |
|
48 | - * Registration is active |
|
49 | - */ |
|
50 | - const status_id_not_approved = 'RNA'; |
|
51 | - |
|
52 | - /** |
|
53 | - * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT . |
|
54 | - * Payments are allowed. |
|
55 | - * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
56 | - * No space reserved. |
|
57 | - * Registration is active |
|
58 | - */ |
|
59 | - const status_id_pending_payment = 'RPP'; |
|
60 | - |
|
61 | - /** |
|
62 | - * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST . |
|
63 | - * Payments are allowed. |
|
64 | - * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
65 | - * No space reserved. |
|
66 | - * Registration is active |
|
67 | - */ |
|
68 | - const status_id_wait_list = 'RWL'; |
|
69 | - |
|
70 | - /** |
|
71 | - * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration. |
|
72 | - * the TXN may or may not be completed ( paid in full ) |
|
73 | - * Payments are allowed. |
|
74 | - * A space IS reserved. |
|
75 | - * Registration is active |
|
76 | - */ |
|
77 | - const status_id_approved = 'RAP'; |
|
78 | - |
|
79 | - /** |
|
80 | - * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee. |
|
81 | - * Payments are NOT allowed. |
|
82 | - * NO space reserved. |
|
83 | - * Registration is NOT active |
|
84 | - */ |
|
85 | - const status_id_cancelled = 'RCN'; |
|
86 | - |
|
87 | - /** |
|
88 | - * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin |
|
89 | - * Payments are NOT allowed. |
|
90 | - * No space reserved. |
|
91 | - * Registration is NOT active |
|
92 | - */ |
|
93 | - const status_id_declined = 'RDC'; |
|
94 | - |
|
95 | - /** |
|
96 | - * @var TableAnalysis $table_analysis |
|
97 | - */ |
|
98 | - protected $_table_analysis; |
|
99 | - |
|
100 | - |
|
101 | - /** |
|
102 | - * private constructor to prevent direct creation |
|
103 | - * |
|
104 | - * @Constructor |
|
105 | - * @access protected |
|
106 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
107 | - * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
108 | - * date time model field objects. Default is NULL (and will be assumed using the set |
|
109 | - * timezone in the 'timezone_string' wp option) |
|
110 | - * @throws EE_Error |
|
111 | - */ |
|
112 | - protected function __construct($timezone = null) |
|
113 | - { |
|
114 | - $this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true); |
|
115 | - $this->singular_item = esc_html__('Registration', 'event_espresso'); |
|
116 | - $this->plural_item = esc_html__('Registrations', 'event_espresso'); |
|
117 | - $this->_tables = array( |
|
118 | - 'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'), |
|
119 | - ); |
|
120 | - $this->_fields = array( |
|
121 | - 'Registration' => array( |
|
122 | - 'REG_ID' => new EE_Primary_Key_Int_Field( |
|
123 | - 'REG_ID', |
|
124 | - esc_html__('Registration ID', 'event_espresso') |
|
125 | - ), |
|
126 | - 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
127 | - 'EVT_ID', |
|
128 | - esc_html__('Event ID', 'event_espresso'), |
|
129 | - false, |
|
130 | - 0, |
|
131 | - 'Event' |
|
132 | - ), |
|
133 | - 'ATT_ID' => new EE_Foreign_Key_Int_Field( |
|
134 | - 'ATT_ID', |
|
135 | - esc_html__('Attendee ID', 'event_espresso'), |
|
136 | - false, |
|
137 | - 0, |
|
138 | - 'Attendee' |
|
139 | - ), |
|
140 | - 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
141 | - 'TXN_ID', |
|
142 | - esc_html__('Transaction ID', 'event_espresso'), |
|
143 | - false, |
|
144 | - 0, |
|
145 | - 'Transaction' |
|
146 | - ), |
|
147 | - 'TKT_ID' => new EE_Foreign_Key_Int_Field( |
|
148 | - 'TKT_ID', |
|
149 | - esc_html__('Ticket ID', 'event_espresso'), |
|
150 | - false, |
|
151 | - 0, |
|
152 | - 'Ticket' |
|
153 | - ), |
|
154 | - 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
155 | - 'STS_ID', |
|
156 | - esc_html__('Status ID', 'event_espresso'), |
|
157 | - false, |
|
158 | - EEM_Registration::status_id_incomplete, |
|
159 | - 'Status' |
|
160 | - ), |
|
161 | - 'REG_date' => new EE_Datetime_Field( |
|
162 | - 'REG_date', |
|
163 | - esc_html__('Time registration occurred', 'event_espresso'), |
|
164 | - false, |
|
165 | - EE_Datetime_Field::now, |
|
166 | - $timezone |
|
167 | - ), |
|
168 | - 'REG_final_price' => new EE_Money_Field( |
|
169 | - 'REG_final_price', |
|
170 | - esc_html__('Registration\'s share of the transaction total', 'event_espresso'), |
|
171 | - false, |
|
172 | - 0 |
|
173 | - ), |
|
174 | - 'REG_paid' => new EE_Money_Field( |
|
175 | - 'REG_paid', |
|
176 | - esc_html__('Amount paid to date towards registration', 'event_espresso'), |
|
177 | - false, |
|
178 | - 0 |
|
179 | - ), |
|
180 | - 'REG_session' => new EE_Plain_Text_Field( |
|
181 | - 'REG_session', |
|
182 | - esc_html__('Session ID of registration', 'event_espresso'), |
|
183 | - false, |
|
184 | - '' |
|
185 | - ), |
|
186 | - 'REG_code' => new EE_Plain_Text_Field( |
|
187 | - 'REG_code', |
|
188 | - esc_html__('Unique Code for this registration', 'event_espresso'), |
|
189 | - false, |
|
190 | - '' |
|
191 | - ), |
|
192 | - 'REG_url_link' => new EE_Plain_Text_Field( |
|
193 | - 'REG_url_link', |
|
194 | - esc_html__('String to be used in URL for identifying registration', 'event_espresso'), |
|
195 | - false, |
|
196 | - '' |
|
197 | - ), |
|
198 | - 'REG_count' => new EE_Integer_Field( |
|
199 | - 'REG_count', |
|
200 | - esc_html__('Count of this registration in the group registration ', 'event_espresso'), |
|
201 | - true, |
|
202 | - 1 |
|
203 | - ), |
|
204 | - 'REG_group_size' => new EE_Integer_Field( |
|
205 | - 'REG_group_size', |
|
206 | - esc_html__('Number of registrations on this group', 'event_espresso'), |
|
207 | - false, |
|
208 | - 1 |
|
209 | - ), |
|
210 | - 'REG_att_is_going' => new EE_Boolean_Field( |
|
211 | - 'REG_att_is_going', |
|
212 | - esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'), |
|
213 | - false, |
|
214 | - false |
|
215 | - ), |
|
216 | - 'REG_deleted' => new EE_Trashed_Flag_Field( |
|
217 | - 'REG_deleted', |
|
218 | - esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'), |
|
219 | - false, |
|
220 | - false |
|
221 | - ), |
|
222 | - ), |
|
223 | - ); |
|
224 | - $this->_model_relations = array( |
|
225 | - 'Event' => new EE_Belongs_To_Relation(), |
|
226 | - 'Attendee' => new EE_Belongs_To_Relation(), |
|
227 | - 'Transaction' => new EE_Belongs_To_Relation(), |
|
228 | - 'Ticket' => new EE_Belongs_To_Relation(), |
|
229 | - 'Status' => new EE_Belongs_To_Relation(), |
|
230 | - 'Answer' => new EE_Has_Many_Relation(), |
|
231 | - 'Checkin' => new EE_Has_Many_Relation(), |
|
232 | - 'Registration_Payment' => new EE_Has_Many_Relation(), |
|
233 | - 'Payment' => new EE_HABTM_Relation('Registration_Payment'), |
|
234 | - 'Message' => new EE_Has_Many_Any_Relation(false) |
|
235 | - // allow deletes even if there are messages in the queue related |
|
236 | - ); |
|
237 | - $this->_model_chain_to_wp_user = 'Event'; |
|
238 | - parent::__construct($timezone); |
|
239 | - } |
|
240 | - |
|
241 | - |
|
242 | - /** |
|
243 | - * a list of ALL valid registration statuses currently in use within the system |
|
244 | - * generated by combining the filterable active and inactive reg status arrays |
|
245 | - * |
|
246 | - * @return array |
|
247 | - */ |
|
248 | - public static function reg_statuses() |
|
249 | - { |
|
250 | - return array_unique( |
|
251 | - array_merge( |
|
252 | - EEM_Registration::active_reg_statuses(), |
|
253 | - EEM_Registration::inactive_reg_statuses() |
|
254 | - ) |
|
255 | - ); |
|
256 | - } |
|
257 | - |
|
258 | - |
|
259 | - /** |
|
260 | - * reg_statuses_that_allow_payment |
|
261 | - * a filterable list of registration statuses that allow a registrant to make a payment |
|
262 | - * |
|
263 | - * @access public |
|
264 | - * @return array |
|
265 | - */ |
|
266 | - public static function reg_statuses_that_allow_payment() |
|
267 | - { |
|
268 | - return apply_filters( |
|
269 | - 'FHEE__EEM_Registration__reg_statuses_that_allow_payment', |
|
270 | - array( |
|
271 | - EEM_Registration::status_id_approved, |
|
272 | - EEM_Registration::status_id_pending_payment, |
|
273 | - ) |
|
274 | - ); |
|
275 | - } |
|
276 | - |
|
277 | - |
|
278 | - /** |
|
279 | - * active_reg_statuses |
|
280 | - * a filterable list of registration statuses that are considered active |
|
281 | - * |
|
282 | - * @access public |
|
283 | - * @return array |
|
284 | - */ |
|
285 | - public static function active_reg_statuses() |
|
286 | - { |
|
287 | - return apply_filters( |
|
288 | - 'FHEE__EEM_Registration__active_reg_statuses', |
|
289 | - array( |
|
290 | - EEM_Registration::status_id_approved, |
|
291 | - EEM_Registration::status_id_pending_payment, |
|
292 | - EEM_Registration::status_id_wait_list, |
|
293 | - EEM_Registration::status_id_not_approved, |
|
294 | - ) |
|
295 | - ); |
|
296 | - } |
|
297 | - |
|
298 | - |
|
299 | - /** |
|
300 | - * inactive_reg_statuses |
|
301 | - * a filterable list of registration statuses that are not considered active |
|
302 | - * |
|
303 | - * @access public |
|
304 | - * @return array |
|
305 | - */ |
|
306 | - public static function inactive_reg_statuses() |
|
307 | - { |
|
308 | - return apply_filters( |
|
309 | - 'FHEE__EEM_Registration__inactive_reg_statuses', |
|
310 | - array( |
|
311 | - EEM_Registration::status_id_incomplete, |
|
312 | - EEM_Registration::status_id_cancelled, |
|
313 | - EEM_Registration::status_id_declined, |
|
314 | - ) |
|
315 | - ); |
|
316 | - } |
|
317 | - |
|
318 | - |
|
319 | - /** |
|
320 | - * closed_reg_statuses |
|
321 | - * a filterable list of registration statuses that are considered "closed" |
|
322 | - * meaning they should not be considered in any calculations involving monies owing |
|
323 | - * |
|
324 | - * @access public |
|
325 | - * @return array |
|
326 | - */ |
|
327 | - public static function closed_reg_statuses() |
|
328 | - { |
|
329 | - return apply_filters( |
|
330 | - 'FHEE__EEM_Registration__closed_reg_statuses', |
|
331 | - array( |
|
332 | - EEM_Registration::status_id_cancelled, |
|
333 | - EEM_Registration::status_id_declined, |
|
334 | - EEM_Registration::status_id_wait_list, |
|
335 | - ) |
|
336 | - ); |
|
337 | - } |
|
338 | - |
|
339 | - |
|
340 | - /** |
|
341 | - * get list of registration statuses |
|
342 | - * |
|
343 | - * @access public |
|
344 | - * @param array $exclude The status ids to exclude from the returned results |
|
345 | - * @param bool $translated If true will return the values as singular localized strings |
|
346 | - * @return array |
|
347 | - * @throws EE_Error |
|
348 | - */ |
|
349 | - public static function reg_status_array($exclude = array(), $translated = false) |
|
350 | - { |
|
351 | - EEM_Registration::instance()->_get_registration_status_array($exclude); |
|
352 | - return $translated |
|
353 | - ? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence') |
|
354 | - : self::$_reg_status; |
|
355 | - } |
|
356 | - |
|
357 | - |
|
358 | - /** |
|
359 | - * get list of registration statuses |
|
360 | - * |
|
361 | - * @access private |
|
362 | - * @param array $exclude |
|
363 | - * @return void |
|
364 | - * @throws EE_Error |
|
365 | - */ |
|
366 | - private function _get_registration_status_array($exclude = array()) |
|
367 | - { |
|
368 | - // in the very rare circumstance that we are deleting a model's table's data |
|
369 | - // and the table hasn't actually been created, this could have an error |
|
370 | - /** @type WPDB $wpdb */ |
|
371 | - global $wpdb; |
|
372 | - if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) { |
|
373 | - $results = $wpdb->get_results( |
|
374 | - "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'" |
|
375 | - ); |
|
376 | - self::$_reg_status = array(); |
|
377 | - foreach ($results as $status) { |
|
378 | - if (!in_array($status->STS_ID, $exclude, true)) { |
|
379 | - self::$_reg_status[ $status->STS_ID ] = $status->STS_code; |
|
380 | - } |
|
381 | - } |
|
382 | - } |
|
383 | - } |
|
384 | - |
|
385 | - |
|
386 | - /** |
|
387 | - * Gets the injected table analyzer, or throws an exception |
|
388 | - * |
|
389 | - * @return TableAnalysis |
|
390 | - * @throws EE_Error |
|
391 | - */ |
|
392 | - protected function _get_table_analysis() |
|
393 | - { |
|
394 | - if ($this->_table_analysis instanceof TableAnalysis) { |
|
395 | - return $this->_table_analysis; |
|
396 | - } |
|
397 | - throw new EE_Error( |
|
398 | - sprintf( |
|
399 | - esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'), |
|
400 | - get_class($this) |
|
401 | - ) |
|
402 | - ); |
|
403 | - } |
|
404 | - |
|
405 | - |
|
406 | - /** |
|
407 | - * This returns a wpdb->results array of all registration date month and years matching the incoming query params |
|
408 | - * and grouped by month and year. |
|
409 | - * |
|
410 | - * @param array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
411 | - * @return array |
|
412 | - * @throws EE_Error |
|
413 | - */ |
|
414 | - public function get_reg_months_and_years($where_params) |
|
415 | - { |
|
416 | - $query_params[0] = $where_params; |
|
417 | - $query_params['group_by'] = array('reg_year', 'reg_month'); |
|
418 | - $query_params['order_by'] = array('REG_date' => 'DESC'); |
|
419 | - $columns_to_select = array( |
|
420 | - 'reg_year' => array('YEAR(REG_date)', '%s'), |
|
421 | - 'reg_month' => array('MONTHNAME(REG_date)', '%s'), |
|
422 | - ); |
|
423 | - return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select); |
|
424 | - } |
|
425 | - |
|
426 | - |
|
427 | - /** |
|
428 | - * retrieve ALL registrations for a particular Attendee from db |
|
429 | - * |
|
430 | - * @param int $ATT_ID |
|
431 | - * @return EE_Base_Class[]|EE_Registration[]|null |
|
432 | - * @throws EE_Error |
|
433 | - */ |
|
434 | - public function get_all_registrations_for_attendee($ATT_ID = 0) |
|
435 | - { |
|
436 | - if (!$ATT_ID) { |
|
437 | - return null; |
|
438 | - } |
|
439 | - return $this->get_all(array(array('ATT_ID' => $ATT_ID))); |
|
440 | - } |
|
441 | - |
|
442 | - |
|
443 | - /** |
|
444 | - * Gets a registration given their REG_url_link. Yes, this should usually |
|
445 | - * be passed via a GET parameter. |
|
446 | - * |
|
447 | - * @param string $REG_url_link |
|
448 | - * @return EE_Base_Class|EE_Registration|null |
|
449 | - * @throws EE_Error |
|
450 | - */ |
|
451 | - public function get_registration_for_reg_url_link($REG_url_link) |
|
452 | - { |
|
453 | - if (!$REG_url_link) { |
|
454 | - return null; |
|
455 | - } |
|
456 | - return $this->get_one(array(array('REG_url_link' => $REG_url_link))); |
|
457 | - } |
|
458 | - |
|
459 | - |
|
460 | - /** |
|
461 | - * retrieve registration for a specific transaction attendee from db |
|
462 | - * |
|
463 | - * @access public |
|
464 | - * @param int $TXN_ID |
|
465 | - * @param int $ATT_ID |
|
466 | - * @param int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the |
|
467 | - * attendee number is required |
|
468 | - * @return mixed array on success, FALSE on fail |
|
469 | - * @throws EE_Error |
|
470 | - */ |
|
471 | - public function get_registration_for_transaction_attendee($TXN_ID = 0, $ATT_ID = 0, $att_nmbr = 0) |
|
472 | - { |
|
473 | - return $this->get_one(array( |
|
474 | - array( |
|
475 | - 'TXN_ID' => $TXN_ID, |
|
476 | - 'ATT_ID' => $ATT_ID, |
|
477 | - ), |
|
478 | - 'limit' => array(min($att_nmbr - 1, 0), 1), |
|
479 | - )); |
|
480 | - } |
|
481 | - |
|
482 | - |
|
483 | - /** |
|
484 | - * get the number of registrations per day for the Registration Admin page Reports Tab. |
|
485 | - * (doesn't utilize models because it's a fairly specialized query) |
|
486 | - * |
|
487 | - * @access public |
|
488 | - * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
489 | - * @return stdClass[] with properties regDate and total |
|
490 | - * @throws EE_Error |
|
491 | - */ |
|
492 | - public function get_registrations_per_day_report($period = '-1 month') |
|
493 | - { |
|
494 | - $sql_date = $this->convert_datetime_for_query( |
|
495 | - 'REG_date', |
|
496 | - date('Y-m-d H:i:s', strtotime($period)), |
|
497 | - 'Y-m-d H:i:s', |
|
498 | - 'UTC' |
|
499 | - ); |
|
500 | - $where = array( |
|
501 | - 'REG_date' => array('>=', $sql_date), |
|
502 | - 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
503 | - ); |
|
504 | - if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) { |
|
505 | - $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
506 | - } |
|
507 | - $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date'); |
|
508 | - $results = $this->_get_all_wpdb_results( |
|
509 | - array( |
|
510 | - $where, |
|
511 | - 'group_by' => 'regDate', |
|
512 | - 'order_by' => array('REG_date' => 'ASC'), |
|
513 | - ), |
|
514 | - OBJECT, |
|
515 | - array( |
|
516 | - 'regDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
517 | - 'total' => array('count(REG_ID)', '%d'), |
|
518 | - ) |
|
519 | - ); |
|
520 | - return $results; |
|
521 | - } |
|
522 | - |
|
523 | - |
|
524 | - /** |
|
525 | - * Get the number of registrations per day including the count of registrations for each Registration Status. |
|
526 | - * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
527 | - * |
|
528 | - * @param string $period |
|
529 | - * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID |
|
530 | - * @throws EE_Error |
|
531 | - * (i.e. RAP) |
|
532 | - */ |
|
533 | - public function get_registrations_per_day_and_per_status_report($period = '-1 month') |
|
534 | - { |
|
535 | - global $wpdb; |
|
536 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
537 | - $event_table = $wpdb->posts; |
|
538 | - $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
539 | - // prepare the query interval for displaying offset |
|
540 | - $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date'); |
|
541 | - // inner date query |
|
542 | - $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} "; |
|
543 | - $inner_where = ' WHERE'; |
|
544 | - // exclude events not authored by user if permissions in effect |
|
545 | - if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
546 | - $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
547 | - $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
548 | - } |
|
549 | - $inner_where .= " REG_date >= '{$sql_date}'"; |
|
550 | - $inner_date_query .= $inner_where; |
|
551 | - // start main query |
|
552 | - $select = "SELECT DATE({$query_interval}) as Registration_REG_date, "; |
|
553 | - $join = ''; |
|
554 | - $join_parts = array(); |
|
555 | - $select_parts = array(); |
|
556 | - // loop through registration stati to do parts for each status. |
|
557 | - foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
558 | - if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
559 | - continue; |
|
560 | - } |
|
561 | - $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
562 | - $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'"; |
|
563 | - } |
|
564 | - // setup the selects |
|
565 | - $select .= implode(', ', $select_parts); |
|
566 | - $select .= " FROM ($inner_date_query) AS dates LEFT JOIN "; |
|
567 | - // setup the joins |
|
568 | - $join .= implode(' LEFT JOIN ', $join_parts); |
|
569 | - // now let's put it all together |
|
570 | - $query = $select . $join . ' GROUP BY Registration_REG_date'; |
|
571 | - // and execute it |
|
572 | - return $wpdb->get_results($query, ARRAY_A); |
|
573 | - } |
|
574 | - |
|
575 | - |
|
576 | - /** |
|
577 | - * get the number of registrations per event for the Registration Admin page Reports Tab |
|
578 | - * |
|
579 | - * @access public |
|
580 | - * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
581 | - * @return stdClass[] each with properties event_name, reg_limit, and total |
|
582 | - * @throws EE_Error |
|
583 | - */ |
|
584 | - public function get_registrations_per_event_report($period = '-1 month') |
|
585 | - { |
|
586 | - $date_sql = $this->convert_datetime_for_query( |
|
587 | - 'REG_date', |
|
588 | - date('Y-m-d H:i:s', strtotime($period)), |
|
589 | - 'Y-m-d H:i:s', |
|
590 | - 'UTC' |
|
591 | - ); |
|
592 | - $where = array( |
|
593 | - 'REG_date' => array('>=', $date_sql), |
|
594 | - 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
595 | - ); |
|
596 | - if (!EE_Registry::instance()->CAP->current_user_can( |
|
597 | - 'ee_read_others_registrations', |
|
598 | - 'reg_per_event_report' |
|
599 | - ) |
|
600 | - ) { |
|
601 | - $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
602 | - } |
|
603 | - $results = $this->_get_all_wpdb_results( |
|
604 | - array( |
|
605 | - $where, |
|
606 | - 'group_by' => 'Event.EVT_name', |
|
607 | - 'order_by' => 'Event.EVT_name', |
|
608 | - 'limit' => array(0, 24), |
|
609 | - ), |
|
610 | - OBJECT, |
|
611 | - array( |
|
612 | - 'event_name' => array('Event_CPT.post_title', '%s'), |
|
613 | - 'total' => array('COUNT(REG_ID)', '%s'), |
|
614 | - ) |
|
615 | - ); |
|
616 | - return $results; |
|
617 | - } |
|
618 | - |
|
619 | - |
|
620 | - /** |
|
621 | - * Get the number of registrations per event grouped by registration status. |
|
622 | - * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
623 | - * |
|
624 | - * @param string $period |
|
625 | - * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID |
|
626 | - * @throws EE_Error |
|
627 | - * (i.e. RAP) |
|
628 | - */ |
|
629 | - public function get_registrations_per_event_and_per_status_report($period = '-1 month') |
|
630 | - { |
|
631 | - global $wpdb; |
|
632 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
633 | - $event_table = $wpdb->posts; |
|
634 | - $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
635 | - // inner date query |
|
636 | - $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table "; |
|
637 | - $inner_where = ' WHERE'; |
|
638 | - // exclude events not authored by user if permissions in effect |
|
639 | - if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
640 | - $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
641 | - $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
642 | - } |
|
643 | - $inner_where .= " REG_date >= '{$sql_date}'"; |
|
644 | - $inner_date_query .= $inner_where; |
|
645 | - // build main query |
|
646 | - $select = 'SELECT Event.post_title as Registration_Event, '; |
|
647 | - $join = ''; |
|
648 | - $join_parts = array(); |
|
649 | - $select_parts = array(); |
|
650 | - // loop through registration stati to do parts for each status. |
|
651 | - foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
652 | - if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
653 | - continue; |
|
654 | - } |
|
655 | - $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
656 | - $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date"; |
|
657 | - } |
|
658 | - // setup the selects |
|
659 | - $select .= implode(', ', $select_parts); |
|
660 | - $select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN "; |
|
661 | - // setup remaining joins |
|
662 | - $join .= implode(' LEFT JOIN ', $join_parts); |
|
663 | - // now put it all together |
|
664 | - $query = $select . $join . ' GROUP BY Registration_Event'; |
|
665 | - // and execute |
|
666 | - return $wpdb->get_results($query, ARRAY_A); |
|
667 | - } |
|
668 | - |
|
669 | - |
|
670 | - /** |
|
671 | - * Returns the EE_Registration of the primary attendee on the transaction id provided |
|
672 | - * |
|
673 | - * @param int $TXN_ID |
|
674 | - * @return EE_Base_Class|EE_Registration|null |
|
675 | - * @throws EE_Error |
|
676 | - */ |
|
677 | - public function get_primary_registration_for_transaction_ID($TXN_ID = 0) |
|
678 | - { |
|
679 | - if (!$TXN_ID) { |
|
680 | - return null; |
|
681 | - } |
|
682 | - return $this->get_one(array( |
|
683 | - array( |
|
684 | - 'TXN_ID' => $TXN_ID, |
|
685 | - 'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT, |
|
686 | - ), |
|
687 | - )); |
|
688 | - } |
|
689 | - |
|
690 | - |
|
691 | - /** |
|
692 | - * get_event_registration_count |
|
693 | - * |
|
694 | - * @access public |
|
695 | - * @param int $EVT_ID |
|
696 | - * @param boolean $for_incomplete_payments |
|
697 | - * @return int |
|
698 | - * @throws EE_Error |
|
699 | - */ |
|
700 | - public function get_event_registration_count($EVT_ID, $for_incomplete_payments = false) |
|
701 | - { |
|
702 | - // we only count approved registrations towards registration limits |
|
703 | - $query_params = array(array('EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved)); |
|
704 | - if ($for_incomplete_payments) { |
|
705 | - $query_params[0]['Transaction.STS_ID'] = array('!=', EEM_Transaction::complete_status_code); |
|
706 | - } |
|
707 | - return $this->count($query_params); |
|
708 | - } |
|
709 | - |
|
710 | - |
|
711 | - /** |
|
712 | - * Deletes all registrations with no transactions. Note that this needs to be very efficient |
|
713 | - * and so it uses wpdb directly. Also, we can't put a limit on this because MySQL doesn't allow a limit on a delete |
|
714 | - * when joining tables like this. |
|
715 | - * |
|
716 | - * @global WPDB $wpdb |
|
717 | - * @return int number deleted |
|
718 | - * @throws EE_Error |
|
719 | - */ |
|
720 | - public function delete_registrations_with_no_transaction() |
|
721 | - { |
|
722 | - /** @type WPDB $wpdb */ |
|
723 | - global $wpdb; |
|
724 | - return $wpdb->query( |
|
725 | - 'DELETE r FROM ' |
|
726 | - . $this->table() |
|
727 | - . ' r LEFT JOIN ' |
|
728 | - . EEM_Transaction::instance()->table() |
|
729 | - . ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL' |
|
730 | - ); |
|
731 | - } |
|
732 | - |
|
733 | - |
|
734 | - /** |
|
735 | - * Count registrations checked into (or out of) a datetime |
|
736 | - * |
|
737 | - * @param int $DTT_ID datetime ID |
|
738 | - * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
739 | - * @return int |
|
740 | - * @throws EE_Error |
|
741 | - */ |
|
742 | - public function count_registrations_checked_into_datetime($DTT_ID, $checked_in = true) |
|
743 | - { |
|
744 | - global $wpdb; |
|
745 | - // subquery to get latest checkin |
|
746 | - $query = $wpdb->prepare( |
|
747 | - 'SELECT ' |
|
748 | - . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
749 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
750 | - . '( SELECT ' |
|
751 | - . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
752 | - . 'REG_ID AS REG_ID ' |
|
753 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' ' |
|
754 | - . 'WHERE DTT_ID=%d ' |
|
755 | - . 'GROUP BY REG_ID' |
|
756 | - . ') AS most_recent_checkin_per_reg ' |
|
757 | - . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
758 | - . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
759 | - . 'WHERE ' |
|
760 | - . 'checkins.CHK_in=%d', |
|
761 | - $DTT_ID, |
|
762 | - $checked_in |
|
763 | - ); |
|
764 | - return (int) $wpdb->get_var($query); |
|
765 | - } |
|
766 | - |
|
767 | - |
|
768 | - /** |
|
769 | - * Count registrations checked into (or out of) an event. |
|
770 | - * |
|
771 | - * @param int $EVT_ID event ID |
|
772 | - * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
773 | - * @return int |
|
774 | - * @throws EE_Error |
|
775 | - */ |
|
776 | - public function count_registrations_checked_into_event($EVT_ID, $checked_in = true) |
|
777 | - { |
|
778 | - global $wpdb; |
|
779 | - // subquery to get latest checkin |
|
780 | - $query = $wpdb->prepare( |
|
781 | - 'SELECT ' |
|
782 | - . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
783 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
784 | - . '( SELECT ' |
|
785 | - . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
786 | - . 'REG_ID AS REG_ID ' |
|
787 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c ' |
|
788 | - . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d ' |
|
789 | - . 'ON c.DTT_ID=d.DTT_ID ' |
|
790 | - . 'WHERE d.EVT_ID=%d ' |
|
791 | - . 'GROUP BY REG_ID' |
|
792 | - . ') AS most_recent_checkin_per_reg ' |
|
793 | - . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
794 | - . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
795 | - . 'WHERE ' |
|
796 | - . 'checkins.CHK_in=%d', |
|
797 | - $EVT_ID, |
|
798 | - $checked_in |
|
799 | - ); |
|
800 | - return (int) $wpdb->get_var($query); |
|
801 | - } |
|
802 | - |
|
803 | - |
|
804 | - /** |
|
805 | - * The purpose of this method is to retrieve an array of |
|
806 | - * EE_Registration objects that represent the latest registration |
|
807 | - * for each ATT_ID given in the function argument. |
|
808 | - * |
|
809 | - * @param array $attendee_ids |
|
810 | - * @return EE_Base_Class[]|EE_Registration[] |
|
811 | - * @throws EE_Error |
|
812 | - */ |
|
813 | - public function get_latest_registration_for_each_of_given_contacts($attendee_ids = array()) |
|
814 | - { |
|
815 | - // first do a native wp_query to get the latest REG_ID's matching these attendees. |
|
816 | - global $wpdb; |
|
817 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
818 | - $attendee_table = $wpdb->posts; |
|
819 | - $attendee_ids = is_array($attendee_ids) |
|
820 | - ? array_map('absint', $attendee_ids) |
|
821 | - : array((int) $attendee_ids); |
|
822 | - $ATT_IDs = implode(',', $attendee_ids); |
|
823 | - // first we do a query to get the registration ids |
|
824 | - // (because a group by before order by causes the order by to be ignored.) |
|
825 | - $registration_id_query = " |
|
16 | + /** |
|
17 | + * @var EEM_Registration $_instance |
|
18 | + */ |
|
19 | + protected static $_instance; |
|
20 | + |
|
21 | + /** |
|
22 | + * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values |
|
23 | + * are status codes (eg, approved, cancelled, etc) |
|
24 | + * |
|
25 | + * @var array |
|
26 | + */ |
|
27 | + private static $_reg_status; |
|
28 | + |
|
29 | + /** |
|
30 | + * The value of REG_count for a primary registrant |
|
31 | + */ |
|
32 | + const PRIMARY_REGISTRANT_COUNT = 1; |
|
33 | + |
|
34 | + /** |
|
35 | + * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration. |
|
36 | + * Initial status for registrations when they are first created |
|
37 | + * Payments are NOT allowed. |
|
38 | + * Automatically toggled to whatever the default Event registration status is upon completion of the attendee |
|
39 | + * information reg step NO space reserved. Registration is NOT active |
|
40 | + */ |
|
41 | + const status_id_incomplete = 'RIC'; |
|
42 | + |
|
43 | + /** |
|
44 | + * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration. |
|
45 | + * Payments are NOT allowed. |
|
46 | + * Event Admin must manually toggle STS_ID for it to change |
|
47 | + * No space reserved. |
|
48 | + * Registration is active |
|
49 | + */ |
|
50 | + const status_id_not_approved = 'RNA'; |
|
51 | + |
|
52 | + /** |
|
53 | + * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT . |
|
54 | + * Payments are allowed. |
|
55 | + * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
56 | + * No space reserved. |
|
57 | + * Registration is active |
|
58 | + */ |
|
59 | + const status_id_pending_payment = 'RPP'; |
|
60 | + |
|
61 | + /** |
|
62 | + * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST . |
|
63 | + * Payments are allowed. |
|
64 | + * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
65 | + * No space reserved. |
|
66 | + * Registration is active |
|
67 | + */ |
|
68 | + const status_id_wait_list = 'RWL'; |
|
69 | + |
|
70 | + /** |
|
71 | + * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration. |
|
72 | + * the TXN may or may not be completed ( paid in full ) |
|
73 | + * Payments are allowed. |
|
74 | + * A space IS reserved. |
|
75 | + * Registration is active |
|
76 | + */ |
|
77 | + const status_id_approved = 'RAP'; |
|
78 | + |
|
79 | + /** |
|
80 | + * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee. |
|
81 | + * Payments are NOT allowed. |
|
82 | + * NO space reserved. |
|
83 | + * Registration is NOT active |
|
84 | + */ |
|
85 | + const status_id_cancelled = 'RCN'; |
|
86 | + |
|
87 | + /** |
|
88 | + * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin |
|
89 | + * Payments are NOT allowed. |
|
90 | + * No space reserved. |
|
91 | + * Registration is NOT active |
|
92 | + */ |
|
93 | + const status_id_declined = 'RDC'; |
|
94 | + |
|
95 | + /** |
|
96 | + * @var TableAnalysis $table_analysis |
|
97 | + */ |
|
98 | + protected $_table_analysis; |
|
99 | + |
|
100 | + |
|
101 | + /** |
|
102 | + * private constructor to prevent direct creation |
|
103 | + * |
|
104 | + * @Constructor |
|
105 | + * @access protected |
|
106 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
107 | + * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
108 | + * date time model field objects. Default is NULL (and will be assumed using the set |
|
109 | + * timezone in the 'timezone_string' wp option) |
|
110 | + * @throws EE_Error |
|
111 | + */ |
|
112 | + protected function __construct($timezone = null) |
|
113 | + { |
|
114 | + $this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true); |
|
115 | + $this->singular_item = esc_html__('Registration', 'event_espresso'); |
|
116 | + $this->plural_item = esc_html__('Registrations', 'event_espresso'); |
|
117 | + $this->_tables = array( |
|
118 | + 'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'), |
|
119 | + ); |
|
120 | + $this->_fields = array( |
|
121 | + 'Registration' => array( |
|
122 | + 'REG_ID' => new EE_Primary_Key_Int_Field( |
|
123 | + 'REG_ID', |
|
124 | + esc_html__('Registration ID', 'event_espresso') |
|
125 | + ), |
|
126 | + 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
127 | + 'EVT_ID', |
|
128 | + esc_html__('Event ID', 'event_espresso'), |
|
129 | + false, |
|
130 | + 0, |
|
131 | + 'Event' |
|
132 | + ), |
|
133 | + 'ATT_ID' => new EE_Foreign_Key_Int_Field( |
|
134 | + 'ATT_ID', |
|
135 | + esc_html__('Attendee ID', 'event_espresso'), |
|
136 | + false, |
|
137 | + 0, |
|
138 | + 'Attendee' |
|
139 | + ), |
|
140 | + 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
141 | + 'TXN_ID', |
|
142 | + esc_html__('Transaction ID', 'event_espresso'), |
|
143 | + false, |
|
144 | + 0, |
|
145 | + 'Transaction' |
|
146 | + ), |
|
147 | + 'TKT_ID' => new EE_Foreign_Key_Int_Field( |
|
148 | + 'TKT_ID', |
|
149 | + esc_html__('Ticket ID', 'event_espresso'), |
|
150 | + false, |
|
151 | + 0, |
|
152 | + 'Ticket' |
|
153 | + ), |
|
154 | + 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
155 | + 'STS_ID', |
|
156 | + esc_html__('Status ID', 'event_espresso'), |
|
157 | + false, |
|
158 | + EEM_Registration::status_id_incomplete, |
|
159 | + 'Status' |
|
160 | + ), |
|
161 | + 'REG_date' => new EE_Datetime_Field( |
|
162 | + 'REG_date', |
|
163 | + esc_html__('Time registration occurred', 'event_espresso'), |
|
164 | + false, |
|
165 | + EE_Datetime_Field::now, |
|
166 | + $timezone |
|
167 | + ), |
|
168 | + 'REG_final_price' => new EE_Money_Field( |
|
169 | + 'REG_final_price', |
|
170 | + esc_html__('Registration\'s share of the transaction total', 'event_espresso'), |
|
171 | + false, |
|
172 | + 0 |
|
173 | + ), |
|
174 | + 'REG_paid' => new EE_Money_Field( |
|
175 | + 'REG_paid', |
|
176 | + esc_html__('Amount paid to date towards registration', 'event_espresso'), |
|
177 | + false, |
|
178 | + 0 |
|
179 | + ), |
|
180 | + 'REG_session' => new EE_Plain_Text_Field( |
|
181 | + 'REG_session', |
|
182 | + esc_html__('Session ID of registration', 'event_espresso'), |
|
183 | + false, |
|
184 | + '' |
|
185 | + ), |
|
186 | + 'REG_code' => new EE_Plain_Text_Field( |
|
187 | + 'REG_code', |
|
188 | + esc_html__('Unique Code for this registration', 'event_espresso'), |
|
189 | + false, |
|
190 | + '' |
|
191 | + ), |
|
192 | + 'REG_url_link' => new EE_Plain_Text_Field( |
|
193 | + 'REG_url_link', |
|
194 | + esc_html__('String to be used in URL for identifying registration', 'event_espresso'), |
|
195 | + false, |
|
196 | + '' |
|
197 | + ), |
|
198 | + 'REG_count' => new EE_Integer_Field( |
|
199 | + 'REG_count', |
|
200 | + esc_html__('Count of this registration in the group registration ', 'event_espresso'), |
|
201 | + true, |
|
202 | + 1 |
|
203 | + ), |
|
204 | + 'REG_group_size' => new EE_Integer_Field( |
|
205 | + 'REG_group_size', |
|
206 | + esc_html__('Number of registrations on this group', 'event_espresso'), |
|
207 | + false, |
|
208 | + 1 |
|
209 | + ), |
|
210 | + 'REG_att_is_going' => new EE_Boolean_Field( |
|
211 | + 'REG_att_is_going', |
|
212 | + esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'), |
|
213 | + false, |
|
214 | + false |
|
215 | + ), |
|
216 | + 'REG_deleted' => new EE_Trashed_Flag_Field( |
|
217 | + 'REG_deleted', |
|
218 | + esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'), |
|
219 | + false, |
|
220 | + false |
|
221 | + ), |
|
222 | + ), |
|
223 | + ); |
|
224 | + $this->_model_relations = array( |
|
225 | + 'Event' => new EE_Belongs_To_Relation(), |
|
226 | + 'Attendee' => new EE_Belongs_To_Relation(), |
|
227 | + 'Transaction' => new EE_Belongs_To_Relation(), |
|
228 | + 'Ticket' => new EE_Belongs_To_Relation(), |
|
229 | + 'Status' => new EE_Belongs_To_Relation(), |
|
230 | + 'Answer' => new EE_Has_Many_Relation(), |
|
231 | + 'Checkin' => new EE_Has_Many_Relation(), |
|
232 | + 'Registration_Payment' => new EE_Has_Many_Relation(), |
|
233 | + 'Payment' => new EE_HABTM_Relation('Registration_Payment'), |
|
234 | + 'Message' => new EE_Has_Many_Any_Relation(false) |
|
235 | + // allow deletes even if there are messages in the queue related |
|
236 | + ); |
|
237 | + $this->_model_chain_to_wp_user = 'Event'; |
|
238 | + parent::__construct($timezone); |
|
239 | + } |
|
240 | + |
|
241 | + |
|
242 | + /** |
|
243 | + * a list of ALL valid registration statuses currently in use within the system |
|
244 | + * generated by combining the filterable active and inactive reg status arrays |
|
245 | + * |
|
246 | + * @return array |
|
247 | + */ |
|
248 | + public static function reg_statuses() |
|
249 | + { |
|
250 | + return array_unique( |
|
251 | + array_merge( |
|
252 | + EEM_Registration::active_reg_statuses(), |
|
253 | + EEM_Registration::inactive_reg_statuses() |
|
254 | + ) |
|
255 | + ); |
|
256 | + } |
|
257 | + |
|
258 | + |
|
259 | + /** |
|
260 | + * reg_statuses_that_allow_payment |
|
261 | + * a filterable list of registration statuses that allow a registrant to make a payment |
|
262 | + * |
|
263 | + * @access public |
|
264 | + * @return array |
|
265 | + */ |
|
266 | + public static function reg_statuses_that_allow_payment() |
|
267 | + { |
|
268 | + return apply_filters( |
|
269 | + 'FHEE__EEM_Registration__reg_statuses_that_allow_payment', |
|
270 | + array( |
|
271 | + EEM_Registration::status_id_approved, |
|
272 | + EEM_Registration::status_id_pending_payment, |
|
273 | + ) |
|
274 | + ); |
|
275 | + } |
|
276 | + |
|
277 | + |
|
278 | + /** |
|
279 | + * active_reg_statuses |
|
280 | + * a filterable list of registration statuses that are considered active |
|
281 | + * |
|
282 | + * @access public |
|
283 | + * @return array |
|
284 | + */ |
|
285 | + public static function active_reg_statuses() |
|
286 | + { |
|
287 | + return apply_filters( |
|
288 | + 'FHEE__EEM_Registration__active_reg_statuses', |
|
289 | + array( |
|
290 | + EEM_Registration::status_id_approved, |
|
291 | + EEM_Registration::status_id_pending_payment, |
|
292 | + EEM_Registration::status_id_wait_list, |
|
293 | + EEM_Registration::status_id_not_approved, |
|
294 | + ) |
|
295 | + ); |
|
296 | + } |
|
297 | + |
|
298 | + |
|
299 | + /** |
|
300 | + * inactive_reg_statuses |
|
301 | + * a filterable list of registration statuses that are not considered active |
|
302 | + * |
|
303 | + * @access public |
|
304 | + * @return array |
|
305 | + */ |
|
306 | + public static function inactive_reg_statuses() |
|
307 | + { |
|
308 | + return apply_filters( |
|
309 | + 'FHEE__EEM_Registration__inactive_reg_statuses', |
|
310 | + array( |
|
311 | + EEM_Registration::status_id_incomplete, |
|
312 | + EEM_Registration::status_id_cancelled, |
|
313 | + EEM_Registration::status_id_declined, |
|
314 | + ) |
|
315 | + ); |
|
316 | + } |
|
317 | + |
|
318 | + |
|
319 | + /** |
|
320 | + * closed_reg_statuses |
|
321 | + * a filterable list of registration statuses that are considered "closed" |
|
322 | + * meaning they should not be considered in any calculations involving monies owing |
|
323 | + * |
|
324 | + * @access public |
|
325 | + * @return array |
|
326 | + */ |
|
327 | + public static function closed_reg_statuses() |
|
328 | + { |
|
329 | + return apply_filters( |
|
330 | + 'FHEE__EEM_Registration__closed_reg_statuses', |
|
331 | + array( |
|
332 | + EEM_Registration::status_id_cancelled, |
|
333 | + EEM_Registration::status_id_declined, |
|
334 | + EEM_Registration::status_id_wait_list, |
|
335 | + ) |
|
336 | + ); |
|
337 | + } |
|
338 | + |
|
339 | + |
|
340 | + /** |
|
341 | + * get list of registration statuses |
|
342 | + * |
|
343 | + * @access public |
|
344 | + * @param array $exclude The status ids to exclude from the returned results |
|
345 | + * @param bool $translated If true will return the values as singular localized strings |
|
346 | + * @return array |
|
347 | + * @throws EE_Error |
|
348 | + */ |
|
349 | + public static function reg_status_array($exclude = array(), $translated = false) |
|
350 | + { |
|
351 | + EEM_Registration::instance()->_get_registration_status_array($exclude); |
|
352 | + return $translated |
|
353 | + ? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence') |
|
354 | + : self::$_reg_status; |
|
355 | + } |
|
356 | + |
|
357 | + |
|
358 | + /** |
|
359 | + * get list of registration statuses |
|
360 | + * |
|
361 | + * @access private |
|
362 | + * @param array $exclude |
|
363 | + * @return void |
|
364 | + * @throws EE_Error |
|
365 | + */ |
|
366 | + private function _get_registration_status_array($exclude = array()) |
|
367 | + { |
|
368 | + // in the very rare circumstance that we are deleting a model's table's data |
|
369 | + // and the table hasn't actually been created, this could have an error |
|
370 | + /** @type WPDB $wpdb */ |
|
371 | + global $wpdb; |
|
372 | + if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) { |
|
373 | + $results = $wpdb->get_results( |
|
374 | + "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'" |
|
375 | + ); |
|
376 | + self::$_reg_status = array(); |
|
377 | + foreach ($results as $status) { |
|
378 | + if (!in_array($status->STS_ID, $exclude, true)) { |
|
379 | + self::$_reg_status[ $status->STS_ID ] = $status->STS_code; |
|
380 | + } |
|
381 | + } |
|
382 | + } |
|
383 | + } |
|
384 | + |
|
385 | + |
|
386 | + /** |
|
387 | + * Gets the injected table analyzer, or throws an exception |
|
388 | + * |
|
389 | + * @return TableAnalysis |
|
390 | + * @throws EE_Error |
|
391 | + */ |
|
392 | + protected function _get_table_analysis() |
|
393 | + { |
|
394 | + if ($this->_table_analysis instanceof TableAnalysis) { |
|
395 | + return $this->_table_analysis; |
|
396 | + } |
|
397 | + throw new EE_Error( |
|
398 | + sprintf( |
|
399 | + esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'), |
|
400 | + get_class($this) |
|
401 | + ) |
|
402 | + ); |
|
403 | + } |
|
404 | + |
|
405 | + |
|
406 | + /** |
|
407 | + * This returns a wpdb->results array of all registration date month and years matching the incoming query params |
|
408 | + * and grouped by month and year. |
|
409 | + * |
|
410 | + * @param array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
411 | + * @return array |
|
412 | + * @throws EE_Error |
|
413 | + */ |
|
414 | + public function get_reg_months_and_years($where_params) |
|
415 | + { |
|
416 | + $query_params[0] = $where_params; |
|
417 | + $query_params['group_by'] = array('reg_year', 'reg_month'); |
|
418 | + $query_params['order_by'] = array('REG_date' => 'DESC'); |
|
419 | + $columns_to_select = array( |
|
420 | + 'reg_year' => array('YEAR(REG_date)', '%s'), |
|
421 | + 'reg_month' => array('MONTHNAME(REG_date)', '%s'), |
|
422 | + ); |
|
423 | + return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select); |
|
424 | + } |
|
425 | + |
|
426 | + |
|
427 | + /** |
|
428 | + * retrieve ALL registrations for a particular Attendee from db |
|
429 | + * |
|
430 | + * @param int $ATT_ID |
|
431 | + * @return EE_Base_Class[]|EE_Registration[]|null |
|
432 | + * @throws EE_Error |
|
433 | + */ |
|
434 | + public function get_all_registrations_for_attendee($ATT_ID = 0) |
|
435 | + { |
|
436 | + if (!$ATT_ID) { |
|
437 | + return null; |
|
438 | + } |
|
439 | + return $this->get_all(array(array('ATT_ID' => $ATT_ID))); |
|
440 | + } |
|
441 | + |
|
442 | + |
|
443 | + /** |
|
444 | + * Gets a registration given their REG_url_link. Yes, this should usually |
|
445 | + * be passed via a GET parameter. |
|
446 | + * |
|
447 | + * @param string $REG_url_link |
|
448 | + * @return EE_Base_Class|EE_Registration|null |
|
449 | + * @throws EE_Error |
|
450 | + */ |
|
451 | + public function get_registration_for_reg_url_link($REG_url_link) |
|
452 | + { |
|
453 | + if (!$REG_url_link) { |
|
454 | + return null; |
|
455 | + } |
|
456 | + return $this->get_one(array(array('REG_url_link' => $REG_url_link))); |
|
457 | + } |
|
458 | + |
|
459 | + |
|
460 | + /** |
|
461 | + * retrieve registration for a specific transaction attendee from db |
|
462 | + * |
|
463 | + * @access public |
|
464 | + * @param int $TXN_ID |
|
465 | + * @param int $ATT_ID |
|
466 | + * @param int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the |
|
467 | + * attendee number is required |
|
468 | + * @return mixed array on success, FALSE on fail |
|
469 | + * @throws EE_Error |
|
470 | + */ |
|
471 | + public function get_registration_for_transaction_attendee($TXN_ID = 0, $ATT_ID = 0, $att_nmbr = 0) |
|
472 | + { |
|
473 | + return $this->get_one(array( |
|
474 | + array( |
|
475 | + 'TXN_ID' => $TXN_ID, |
|
476 | + 'ATT_ID' => $ATT_ID, |
|
477 | + ), |
|
478 | + 'limit' => array(min($att_nmbr - 1, 0), 1), |
|
479 | + )); |
|
480 | + } |
|
481 | + |
|
482 | + |
|
483 | + /** |
|
484 | + * get the number of registrations per day for the Registration Admin page Reports Tab. |
|
485 | + * (doesn't utilize models because it's a fairly specialized query) |
|
486 | + * |
|
487 | + * @access public |
|
488 | + * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
489 | + * @return stdClass[] with properties regDate and total |
|
490 | + * @throws EE_Error |
|
491 | + */ |
|
492 | + public function get_registrations_per_day_report($period = '-1 month') |
|
493 | + { |
|
494 | + $sql_date = $this->convert_datetime_for_query( |
|
495 | + 'REG_date', |
|
496 | + date('Y-m-d H:i:s', strtotime($period)), |
|
497 | + 'Y-m-d H:i:s', |
|
498 | + 'UTC' |
|
499 | + ); |
|
500 | + $where = array( |
|
501 | + 'REG_date' => array('>=', $sql_date), |
|
502 | + 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
503 | + ); |
|
504 | + if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) { |
|
505 | + $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
506 | + } |
|
507 | + $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date'); |
|
508 | + $results = $this->_get_all_wpdb_results( |
|
509 | + array( |
|
510 | + $where, |
|
511 | + 'group_by' => 'regDate', |
|
512 | + 'order_by' => array('REG_date' => 'ASC'), |
|
513 | + ), |
|
514 | + OBJECT, |
|
515 | + array( |
|
516 | + 'regDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
517 | + 'total' => array('count(REG_ID)', '%d'), |
|
518 | + ) |
|
519 | + ); |
|
520 | + return $results; |
|
521 | + } |
|
522 | + |
|
523 | + |
|
524 | + /** |
|
525 | + * Get the number of registrations per day including the count of registrations for each Registration Status. |
|
526 | + * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
527 | + * |
|
528 | + * @param string $period |
|
529 | + * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID |
|
530 | + * @throws EE_Error |
|
531 | + * (i.e. RAP) |
|
532 | + */ |
|
533 | + public function get_registrations_per_day_and_per_status_report($period = '-1 month') |
|
534 | + { |
|
535 | + global $wpdb; |
|
536 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
537 | + $event_table = $wpdb->posts; |
|
538 | + $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
539 | + // prepare the query interval for displaying offset |
|
540 | + $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date'); |
|
541 | + // inner date query |
|
542 | + $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} "; |
|
543 | + $inner_where = ' WHERE'; |
|
544 | + // exclude events not authored by user if permissions in effect |
|
545 | + if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
546 | + $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
547 | + $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
548 | + } |
|
549 | + $inner_where .= " REG_date >= '{$sql_date}'"; |
|
550 | + $inner_date_query .= $inner_where; |
|
551 | + // start main query |
|
552 | + $select = "SELECT DATE({$query_interval}) as Registration_REG_date, "; |
|
553 | + $join = ''; |
|
554 | + $join_parts = array(); |
|
555 | + $select_parts = array(); |
|
556 | + // loop through registration stati to do parts for each status. |
|
557 | + foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
558 | + if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
559 | + continue; |
|
560 | + } |
|
561 | + $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
562 | + $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'"; |
|
563 | + } |
|
564 | + // setup the selects |
|
565 | + $select .= implode(', ', $select_parts); |
|
566 | + $select .= " FROM ($inner_date_query) AS dates LEFT JOIN "; |
|
567 | + // setup the joins |
|
568 | + $join .= implode(' LEFT JOIN ', $join_parts); |
|
569 | + // now let's put it all together |
|
570 | + $query = $select . $join . ' GROUP BY Registration_REG_date'; |
|
571 | + // and execute it |
|
572 | + return $wpdb->get_results($query, ARRAY_A); |
|
573 | + } |
|
574 | + |
|
575 | + |
|
576 | + /** |
|
577 | + * get the number of registrations per event for the Registration Admin page Reports Tab |
|
578 | + * |
|
579 | + * @access public |
|
580 | + * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
581 | + * @return stdClass[] each with properties event_name, reg_limit, and total |
|
582 | + * @throws EE_Error |
|
583 | + */ |
|
584 | + public function get_registrations_per_event_report($period = '-1 month') |
|
585 | + { |
|
586 | + $date_sql = $this->convert_datetime_for_query( |
|
587 | + 'REG_date', |
|
588 | + date('Y-m-d H:i:s', strtotime($period)), |
|
589 | + 'Y-m-d H:i:s', |
|
590 | + 'UTC' |
|
591 | + ); |
|
592 | + $where = array( |
|
593 | + 'REG_date' => array('>=', $date_sql), |
|
594 | + 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
595 | + ); |
|
596 | + if (!EE_Registry::instance()->CAP->current_user_can( |
|
597 | + 'ee_read_others_registrations', |
|
598 | + 'reg_per_event_report' |
|
599 | + ) |
|
600 | + ) { |
|
601 | + $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
602 | + } |
|
603 | + $results = $this->_get_all_wpdb_results( |
|
604 | + array( |
|
605 | + $where, |
|
606 | + 'group_by' => 'Event.EVT_name', |
|
607 | + 'order_by' => 'Event.EVT_name', |
|
608 | + 'limit' => array(0, 24), |
|
609 | + ), |
|
610 | + OBJECT, |
|
611 | + array( |
|
612 | + 'event_name' => array('Event_CPT.post_title', '%s'), |
|
613 | + 'total' => array('COUNT(REG_ID)', '%s'), |
|
614 | + ) |
|
615 | + ); |
|
616 | + return $results; |
|
617 | + } |
|
618 | + |
|
619 | + |
|
620 | + /** |
|
621 | + * Get the number of registrations per event grouped by registration status. |
|
622 | + * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
623 | + * |
|
624 | + * @param string $period |
|
625 | + * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID |
|
626 | + * @throws EE_Error |
|
627 | + * (i.e. RAP) |
|
628 | + */ |
|
629 | + public function get_registrations_per_event_and_per_status_report($period = '-1 month') |
|
630 | + { |
|
631 | + global $wpdb; |
|
632 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
633 | + $event_table = $wpdb->posts; |
|
634 | + $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
635 | + // inner date query |
|
636 | + $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table "; |
|
637 | + $inner_where = ' WHERE'; |
|
638 | + // exclude events not authored by user if permissions in effect |
|
639 | + if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
640 | + $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
641 | + $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
642 | + } |
|
643 | + $inner_where .= " REG_date >= '{$sql_date}'"; |
|
644 | + $inner_date_query .= $inner_where; |
|
645 | + // build main query |
|
646 | + $select = 'SELECT Event.post_title as Registration_Event, '; |
|
647 | + $join = ''; |
|
648 | + $join_parts = array(); |
|
649 | + $select_parts = array(); |
|
650 | + // loop through registration stati to do parts for each status. |
|
651 | + foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
652 | + if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
653 | + continue; |
|
654 | + } |
|
655 | + $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
656 | + $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date"; |
|
657 | + } |
|
658 | + // setup the selects |
|
659 | + $select .= implode(', ', $select_parts); |
|
660 | + $select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN "; |
|
661 | + // setup remaining joins |
|
662 | + $join .= implode(' LEFT JOIN ', $join_parts); |
|
663 | + // now put it all together |
|
664 | + $query = $select . $join . ' GROUP BY Registration_Event'; |
|
665 | + // and execute |
|
666 | + return $wpdb->get_results($query, ARRAY_A); |
|
667 | + } |
|
668 | + |
|
669 | + |
|
670 | + /** |
|
671 | + * Returns the EE_Registration of the primary attendee on the transaction id provided |
|
672 | + * |
|
673 | + * @param int $TXN_ID |
|
674 | + * @return EE_Base_Class|EE_Registration|null |
|
675 | + * @throws EE_Error |
|
676 | + */ |
|
677 | + public function get_primary_registration_for_transaction_ID($TXN_ID = 0) |
|
678 | + { |
|
679 | + if (!$TXN_ID) { |
|
680 | + return null; |
|
681 | + } |
|
682 | + return $this->get_one(array( |
|
683 | + array( |
|
684 | + 'TXN_ID' => $TXN_ID, |
|
685 | + 'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT, |
|
686 | + ), |
|
687 | + )); |
|
688 | + } |
|
689 | + |
|
690 | + |
|
691 | + /** |
|
692 | + * get_event_registration_count |
|
693 | + * |
|
694 | + * @access public |
|
695 | + * @param int $EVT_ID |
|
696 | + * @param boolean $for_incomplete_payments |
|
697 | + * @return int |
|
698 | + * @throws EE_Error |
|
699 | + */ |
|
700 | + public function get_event_registration_count($EVT_ID, $for_incomplete_payments = false) |
|
701 | + { |
|
702 | + // we only count approved registrations towards registration limits |
|
703 | + $query_params = array(array('EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved)); |
|
704 | + if ($for_incomplete_payments) { |
|
705 | + $query_params[0]['Transaction.STS_ID'] = array('!=', EEM_Transaction::complete_status_code); |
|
706 | + } |
|
707 | + return $this->count($query_params); |
|
708 | + } |
|
709 | + |
|
710 | + |
|
711 | + /** |
|
712 | + * Deletes all registrations with no transactions. Note that this needs to be very efficient |
|
713 | + * and so it uses wpdb directly. Also, we can't put a limit on this because MySQL doesn't allow a limit on a delete |
|
714 | + * when joining tables like this. |
|
715 | + * |
|
716 | + * @global WPDB $wpdb |
|
717 | + * @return int number deleted |
|
718 | + * @throws EE_Error |
|
719 | + */ |
|
720 | + public function delete_registrations_with_no_transaction() |
|
721 | + { |
|
722 | + /** @type WPDB $wpdb */ |
|
723 | + global $wpdb; |
|
724 | + return $wpdb->query( |
|
725 | + 'DELETE r FROM ' |
|
726 | + . $this->table() |
|
727 | + . ' r LEFT JOIN ' |
|
728 | + . EEM_Transaction::instance()->table() |
|
729 | + . ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL' |
|
730 | + ); |
|
731 | + } |
|
732 | + |
|
733 | + |
|
734 | + /** |
|
735 | + * Count registrations checked into (or out of) a datetime |
|
736 | + * |
|
737 | + * @param int $DTT_ID datetime ID |
|
738 | + * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
739 | + * @return int |
|
740 | + * @throws EE_Error |
|
741 | + */ |
|
742 | + public function count_registrations_checked_into_datetime($DTT_ID, $checked_in = true) |
|
743 | + { |
|
744 | + global $wpdb; |
|
745 | + // subquery to get latest checkin |
|
746 | + $query = $wpdb->prepare( |
|
747 | + 'SELECT ' |
|
748 | + . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
749 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
750 | + . '( SELECT ' |
|
751 | + . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
752 | + . 'REG_ID AS REG_ID ' |
|
753 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' ' |
|
754 | + . 'WHERE DTT_ID=%d ' |
|
755 | + . 'GROUP BY REG_ID' |
|
756 | + . ') AS most_recent_checkin_per_reg ' |
|
757 | + . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
758 | + . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
759 | + . 'WHERE ' |
|
760 | + . 'checkins.CHK_in=%d', |
|
761 | + $DTT_ID, |
|
762 | + $checked_in |
|
763 | + ); |
|
764 | + return (int) $wpdb->get_var($query); |
|
765 | + } |
|
766 | + |
|
767 | + |
|
768 | + /** |
|
769 | + * Count registrations checked into (or out of) an event. |
|
770 | + * |
|
771 | + * @param int $EVT_ID event ID |
|
772 | + * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
773 | + * @return int |
|
774 | + * @throws EE_Error |
|
775 | + */ |
|
776 | + public function count_registrations_checked_into_event($EVT_ID, $checked_in = true) |
|
777 | + { |
|
778 | + global $wpdb; |
|
779 | + // subquery to get latest checkin |
|
780 | + $query = $wpdb->prepare( |
|
781 | + 'SELECT ' |
|
782 | + . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
783 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
784 | + . '( SELECT ' |
|
785 | + . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
786 | + . 'REG_ID AS REG_ID ' |
|
787 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c ' |
|
788 | + . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d ' |
|
789 | + . 'ON c.DTT_ID=d.DTT_ID ' |
|
790 | + . 'WHERE d.EVT_ID=%d ' |
|
791 | + . 'GROUP BY REG_ID' |
|
792 | + . ') AS most_recent_checkin_per_reg ' |
|
793 | + . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
794 | + . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
795 | + . 'WHERE ' |
|
796 | + . 'checkins.CHK_in=%d', |
|
797 | + $EVT_ID, |
|
798 | + $checked_in |
|
799 | + ); |
|
800 | + return (int) $wpdb->get_var($query); |
|
801 | + } |
|
802 | + |
|
803 | + |
|
804 | + /** |
|
805 | + * The purpose of this method is to retrieve an array of |
|
806 | + * EE_Registration objects that represent the latest registration |
|
807 | + * for each ATT_ID given in the function argument. |
|
808 | + * |
|
809 | + * @param array $attendee_ids |
|
810 | + * @return EE_Base_Class[]|EE_Registration[] |
|
811 | + * @throws EE_Error |
|
812 | + */ |
|
813 | + public function get_latest_registration_for_each_of_given_contacts($attendee_ids = array()) |
|
814 | + { |
|
815 | + // first do a native wp_query to get the latest REG_ID's matching these attendees. |
|
816 | + global $wpdb; |
|
817 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
818 | + $attendee_table = $wpdb->posts; |
|
819 | + $attendee_ids = is_array($attendee_ids) |
|
820 | + ? array_map('absint', $attendee_ids) |
|
821 | + : array((int) $attendee_ids); |
|
822 | + $ATT_IDs = implode(',', $attendee_ids); |
|
823 | + // first we do a query to get the registration ids |
|
824 | + // (because a group by before order by causes the order by to be ignored.) |
|
825 | + $registration_id_query = " |
|
826 | 826 | SELECT registrations.registration_ids as registration_id |
827 | 827 | FROM ( |
828 | 828 | SELECT |
@@ -836,61 +836,61 @@ discard block |
||
836 | 836 | ) AS registrations |
837 | 837 | GROUP BY registrations.attendee_ids |
838 | 838 | "; |
839 | - $registration_ids = $wpdb->get_results($registration_id_query, ARRAY_A); |
|
840 | - if (empty($registration_ids)) { |
|
841 | - return array(); |
|
842 | - } |
|
843 | - $ids_for_model_query = array(); |
|
844 | - // let's flatten the ids so they can be used in the model query. |
|
845 | - foreach ($registration_ids as $registration_id) { |
|
846 | - if (isset($registration_id['registration_id'])) { |
|
847 | - $ids_for_model_query[] = $registration_id['registration_id']; |
|
848 | - } |
|
849 | - } |
|
850 | - // construct query |
|
851 | - $_where = array( |
|
852 | - 'REG_ID' => array('IN', $ids_for_model_query), |
|
853 | - ); |
|
854 | - return $this->get_all(array($_where)); |
|
855 | - } |
|
856 | - |
|
857 | - |
|
858 | - |
|
859 | - /** |
|
860 | - * returns a count of registrations for the supplied event having the status as specified |
|
861 | - * |
|
862 | - * @param int $EVT_ID |
|
863 | - * @param array $statuses |
|
864 | - * @return int |
|
865 | - * @throws InvalidArgumentException |
|
866 | - * @throws InvalidStatusException |
|
867 | - * @throws EE_Error |
|
868 | - */ |
|
869 | - public function event_reg_count_for_statuses($EVT_ID, $statuses = array()) |
|
870 | - { |
|
871 | - $EVT_ID = absint($EVT_ID); |
|
872 | - if (! $EVT_ID) { |
|
873 | - throw new InvalidArgumentException( |
|
874 | - esc_html__('An invalid Event ID was supplied.', 'event_espresso') |
|
875 | - ); |
|
876 | - } |
|
877 | - $statuses = is_array($statuses) ? $statuses : array($statuses); |
|
878 | - $statuses = ! empty($statuses) ? $statuses : array(EEM_Registration::status_id_approved); |
|
879 | - $valid_reg_statuses = EEM_Registration::reg_statuses(); |
|
880 | - foreach ($statuses as $status) { |
|
881 | - if (! in_array($status, $valid_reg_statuses, true)) { |
|
882 | - throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso')); |
|
883 | - } |
|
884 | - } |
|
885 | - return $this->count( |
|
886 | - array( |
|
887 | - array( |
|
888 | - 'EVT_ID' => $EVT_ID, |
|
889 | - 'STS_ID' => array('IN', $statuses), |
|
890 | - ), |
|
891 | - ), |
|
892 | - 'REG_ID', |
|
893 | - true |
|
894 | - ); |
|
895 | - } |
|
839 | + $registration_ids = $wpdb->get_results($registration_id_query, ARRAY_A); |
|
840 | + if (empty($registration_ids)) { |
|
841 | + return array(); |
|
842 | + } |
|
843 | + $ids_for_model_query = array(); |
|
844 | + // let's flatten the ids so they can be used in the model query. |
|
845 | + foreach ($registration_ids as $registration_id) { |
|
846 | + if (isset($registration_id['registration_id'])) { |
|
847 | + $ids_for_model_query[] = $registration_id['registration_id']; |
|
848 | + } |
|
849 | + } |
|
850 | + // construct query |
|
851 | + $_where = array( |
|
852 | + 'REG_ID' => array('IN', $ids_for_model_query), |
|
853 | + ); |
|
854 | + return $this->get_all(array($_where)); |
|
855 | + } |
|
856 | + |
|
857 | + |
|
858 | + |
|
859 | + /** |
|
860 | + * returns a count of registrations for the supplied event having the status as specified |
|
861 | + * |
|
862 | + * @param int $EVT_ID |
|
863 | + * @param array $statuses |
|
864 | + * @return int |
|
865 | + * @throws InvalidArgumentException |
|
866 | + * @throws InvalidStatusException |
|
867 | + * @throws EE_Error |
|
868 | + */ |
|
869 | + public function event_reg_count_for_statuses($EVT_ID, $statuses = array()) |
|
870 | + { |
|
871 | + $EVT_ID = absint($EVT_ID); |
|
872 | + if (! $EVT_ID) { |
|
873 | + throw new InvalidArgumentException( |
|
874 | + esc_html__('An invalid Event ID was supplied.', 'event_espresso') |
|
875 | + ); |
|
876 | + } |
|
877 | + $statuses = is_array($statuses) ? $statuses : array($statuses); |
|
878 | + $statuses = ! empty($statuses) ? $statuses : array(EEM_Registration::status_id_approved); |
|
879 | + $valid_reg_statuses = EEM_Registration::reg_statuses(); |
|
880 | + foreach ($statuses as $status) { |
|
881 | + if (! in_array($status, $valid_reg_statuses, true)) { |
|
882 | + throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso')); |
|
883 | + } |
|
884 | + } |
|
885 | + return $this->count( |
|
886 | + array( |
|
887 | + array( |
|
888 | + 'EVT_ID' => $EVT_ID, |
|
889 | + 'STS_ID' => array('IN', $statuses), |
|
890 | + ), |
|
891 | + ), |
|
892 | + 'REG_ID', |
|
893 | + true |
|
894 | + ); |
|
895 | + } |
|
896 | 896 | } |
@@ -9,628 +9,628 @@ |
||
9 | 9 | class EEM_Message extends EEM_Base implements EEI_Query_Filter |
10 | 10 | { |
11 | 11 | |
12 | - // private instance of the Message object |
|
13 | - protected static $_instance = null; |
|
12 | + // private instance of the Message object |
|
13 | + protected static $_instance = null; |
|
14 | 14 | |
15 | 15 | |
16 | - /** |
|
17 | - * This priority indicates a message should be generated and sent ASAP |
|
18 | - * |
|
19 | - * @type int |
|
20 | - */ |
|
21 | - const priority_high = 10; |
|
22 | - |
|
23 | - |
|
24 | - /** |
|
25 | - * This priority indicates a message should be generated ASAP and queued for sending. |
|
26 | - * |
|
27 | - * @type |
|
28 | - */ |
|
29 | - const priority_medium = 20; |
|
30 | - |
|
31 | - |
|
32 | - /** |
|
33 | - * This priority indicates a message should be queued for generating. |
|
34 | - * |
|
35 | - * @type int |
|
36 | - */ |
|
37 | - const priority_low = 30; |
|
38 | - |
|
39 | - |
|
40 | - /** |
|
41 | - * indicates this message was sent at the time modified |
|
42 | - */ |
|
43 | - const status_sent = 'MSN'; |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * indicates this message is waiting to be sent |
|
48 | - */ |
|
49 | - const status_idle = 'MID'; |
|
50 | - |
|
51 | - |
|
52 | - /** |
|
53 | - * indicates an attempt was a made to send this message |
|
54 | - * at the scheduled time, but it failed at the time modified. This differs from MDO status in that it will ALWAYS |
|
55 | - * appear to the end user. |
|
56 | - */ |
|
57 | - const status_failed = 'MFL'; |
|
58 | - |
|
59 | - |
|
60 | - /** |
|
61 | - * indicates the message has been flagged for resending (at the time modified). |
|
62 | - */ |
|
63 | - const status_resend = 'MRS'; |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * indicates the message has been flagged for generation but has not been generated yet. Messages always start as |
|
68 | - * this status when added to the queue. |
|
69 | - */ |
|
70 | - const status_incomplete = 'MIC'; |
|
71 | - |
|
72 | - |
|
73 | - /** |
|
74 | - * Indicates everything was generated fine for the message, however, the messenger was unable to send. |
|
75 | - * This status means that its possible to retry sending the message. |
|
76 | - */ |
|
77 | - const status_retry = 'MRT'; |
|
78 | - |
|
79 | - |
|
80 | - /** |
|
81 | - * This is used for more informational messages that may not indicate anything is broken but still cannot be |
|
82 | - * generated or sent correctly. An example of a message that would get flagged this way would be when a not |
|
83 | - * approved message was queued for generation, but at time of generation, the attached registration(s) are |
|
84 | - * approved. So the message queued for generation is no longer valid. Messages for this status will only persist |
|
85 | - * in the db and be viewable in the message activity list table when the messages system is in debug mode. |
|
86 | - * |
|
87 | - * @see EEM_Message::debug() |
|
88 | - */ |
|
89 | - const status_debug_only = 'MDO'; |
|
90 | - |
|
91 | - |
|
92 | - /** |
|
93 | - * This status is given to messages it is processed by the messenger send method. |
|
94 | - * Messages with this status should rarely be seen in the Message List table, but if they are, that's usually |
|
95 | - * indicative of a PHP timeout or memory limit issue. |
|
96 | - */ |
|
97 | - const status_messenger_executing = 'MEX'; |
|
98 | - |
|
99 | - |
|
100 | - /** |
|
101 | - * Private constructor to prevent direct creation. |
|
102 | - * |
|
103 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and |
|
104 | - * any incoming timezone data that gets saved). Note this just sends the timezone info to |
|
105 | - * the date time model field objects. Default is null (and will be assumed using the set |
|
106 | - * timezone in the 'timezone_string' wp option) |
|
107 | - * @return EEM_Message |
|
108 | - */ |
|
109 | - protected function __construct($timezone = null) |
|
110 | - { |
|
111 | - $this->singular_item = __('Message', 'event_espresso'); |
|
112 | - $this->plural_item = __('Messages', 'event_espresso'); |
|
113 | - |
|
114 | - // used for token generator |
|
115 | - EE_Registry::instance()->load_helper('URL'); |
|
116 | - |
|
117 | - $this->_tables = array( |
|
118 | - 'Message' => new EE_Primary_Table('esp_message', 'MSG_ID'), |
|
119 | - ); |
|
120 | - |
|
121 | - $allowed_priority = array( |
|
122 | - self::priority_high => __('high', 'event_espresso'), |
|
123 | - self::priority_medium => __('medium', 'event_espresso'), |
|
124 | - self::priority_low => __('low', 'event_espresso'), |
|
125 | - ); |
|
126 | - |
|
127 | - $this->_fields = array( |
|
128 | - 'Message' => array( |
|
129 | - 'MSG_ID' => new EE_Primary_Key_Int_Field('MSG_ID', __('Message ID', 'event_espresso')), |
|
130 | - 'MSG_token' => new EE_Plain_Text_Field( |
|
131 | - 'MSG_token', |
|
132 | - __( |
|
133 | - 'Unique Token used to represent this row in publicly viewable contexts (eg. a url).', |
|
134 | - 'event_espresso' |
|
135 | - ), |
|
136 | - false, |
|
137 | - EEH_URL::generate_unique_token() |
|
138 | - ), |
|
139 | - 'GRP_ID' => new EE_Foreign_Key_Int_Field( |
|
140 | - 'GRP_ID', |
|
141 | - __('Foreign key to the EEM_Message_Template_Group table.', 'event_espresso'), |
|
142 | - true, |
|
143 | - 0, |
|
144 | - 'Message_Template_Group' |
|
145 | - ), |
|
146 | - 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
147 | - 'TXN_ID', |
|
148 | - __( |
|
149 | - 'Foreign key to the related EE_Transaction. This is required to give context for regenerating the specific message', |
|
150 | - 'event_espresso' |
|
151 | - ), |
|
152 | - true, |
|
153 | - 0, |
|
154 | - 'Transaction' |
|
155 | - ), |
|
156 | - 'MSG_messenger' => new EE_Plain_Text_Field( |
|
157 | - 'MSG_messenger', |
|
158 | - __( |
|
159 | - 'Corresponds to the EE_messenger::name used to send this message. This will also be used to attempt any resending of the message.', |
|
160 | - 'event_espresso' |
|
161 | - ), |
|
162 | - false, |
|
163 | - 'email' |
|
164 | - ), |
|
165 | - 'MSG_message_type' => new EE_Plain_Text_Field( |
|
166 | - 'MSG_message_type', |
|
167 | - __('Corresponds to the EE_message_type::name used to generate this message.', 'event_espresso'), |
|
168 | - false, |
|
169 | - 'receipt' |
|
170 | - ), |
|
171 | - 'MSG_context' => new EE_Plain_Text_Field('MSG_context', __('Context', 'event_espresso'), false), |
|
172 | - 'MSG_recipient_ID' => new EE_Foreign_Key_Int_Field( |
|
173 | - 'MSG_recipient_ID', |
|
174 | - __('Recipient ID', 'event_espresso'), |
|
175 | - true, |
|
176 | - null, |
|
177 | - array('Registration', 'Attendee', 'WP_User') |
|
178 | - ), |
|
179 | - 'MSG_recipient_type' => new EE_Any_Foreign_Model_Name_Field( |
|
180 | - 'MSG_recipient_type', |
|
181 | - __('Recipient Type', 'event_espresso'), |
|
182 | - true, |
|
183 | - null, |
|
184 | - array('Registration', 'Attendee', 'WP_User') |
|
185 | - ), |
|
186 | - 'MSG_content' => new EE_Maybe_Serialized_Text_Field( |
|
187 | - 'MSG_content', |
|
188 | - __('Content', 'event_espresso'), |
|
189 | - true, |
|
190 | - '' |
|
191 | - ), |
|
192 | - 'MSG_to' => new EE_Maybe_Serialized_Text_Field( |
|
193 | - 'MSG_to', |
|
194 | - __('Address To', 'event_espresso'), |
|
195 | - true |
|
196 | - ), |
|
197 | - 'MSG_from' => new EE_Maybe_Serialized_Text_Field( |
|
198 | - 'MSG_from', |
|
199 | - __('Address From', 'event_espresso'), |
|
200 | - true |
|
201 | - ), |
|
202 | - 'MSG_subject' => new EE_Maybe_Serialized_Text_Field( |
|
203 | - 'MSG_subject', |
|
204 | - __('Subject', 'event_espresso'), |
|
205 | - true, |
|
206 | - '' |
|
207 | - ), |
|
208 | - 'MSG_priority' => new EE_Enum_Integer_Field( |
|
209 | - 'MSG_priority', |
|
210 | - __('Priority', 'event_espresso'), |
|
211 | - false, |
|
212 | - self::priority_low, |
|
213 | - $allowed_priority |
|
214 | - ), |
|
215 | - 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
216 | - 'STS_ID', |
|
217 | - __('Status', 'event_espresso'), |
|
218 | - false, |
|
219 | - self::status_incomplete, |
|
220 | - 'Status' |
|
221 | - ), |
|
222 | - 'MSG_created' => new EE_Datetime_Field( |
|
223 | - 'MSG_created', |
|
224 | - __('Created', 'event_espresso'), |
|
225 | - false, |
|
226 | - EE_Datetime_Field::now |
|
227 | - ), |
|
228 | - 'MSG_modified' => new EE_Datetime_Field( |
|
229 | - 'MSG_modified', |
|
230 | - __('Modified', 'event_espresso'), |
|
231 | - true, |
|
232 | - EE_Datetime_Field::now |
|
233 | - ), |
|
234 | - ), |
|
235 | - ); |
|
236 | - $this->_model_relations = array( |
|
237 | - 'Attendee' => new EE_Belongs_To_Any_Relation(), |
|
238 | - 'Registration' => new EE_Belongs_To_Any_Relation(), |
|
239 | - 'WP_User' => new EE_Belongs_To_Any_Relation(), |
|
240 | - 'Message_Template_Group' => new EE_Belongs_To_Relation(), |
|
241 | - 'Transaction' => new EE_Belongs_To_Relation(), |
|
242 | - ); |
|
243 | - parent::__construct($timezone); |
|
244 | - } |
|
245 | - |
|
246 | - |
|
247 | - /** |
|
248 | - * @return \EE_Message |
|
249 | - */ |
|
250 | - public function create_default_object() |
|
251 | - { |
|
252 | - /** @type EE_Message $message */ |
|
253 | - $message = parent::create_default_object(); |
|
254 | - if ($message instanceof EE_Message) { |
|
255 | - return EE_Message_Factory::set_messenger_and_message_type($message); |
|
256 | - } |
|
257 | - return null; |
|
258 | - } |
|
259 | - |
|
260 | - |
|
261 | - /** |
|
262 | - * @param mixed $cols_n_values |
|
263 | - * @return \EE_Message |
|
264 | - */ |
|
265 | - public function instantiate_class_from_array_or_object($cols_n_values) |
|
266 | - { |
|
267 | - /** @type EE_Message $message */ |
|
268 | - $message = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
269 | - if ($message instanceof EE_Message) { |
|
270 | - return EE_Message_Factory::set_messenger_and_message_type($message); |
|
271 | - } |
|
272 | - return null; |
|
273 | - } |
|
274 | - |
|
275 | - |
|
276 | - /** |
|
277 | - * Returns whether or not a message of that type was sent for a given attendee. |
|
278 | - * |
|
279 | - * @param EE_Attendee|int $attendee |
|
280 | - * @param string $message_type the message type slug |
|
281 | - * @return boolean |
|
282 | - */ |
|
283 | - public function message_sent_for_attendee($attendee, $message_type) |
|
284 | - { |
|
285 | - $attendee_ID = EEM_Attendee::instance()->ensure_is_ID($attendee); |
|
286 | - return $this->exists(array( |
|
287 | - array( |
|
288 | - 'Attendee.ATT_ID' => $attendee_ID, |
|
289 | - 'MSG_message_type' => $message_type, |
|
290 | - 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
291 | - ), |
|
292 | - )); |
|
293 | - } |
|
294 | - |
|
295 | - |
|
296 | - /** |
|
297 | - * Returns whether or not a message of that type was sent for a given registration |
|
298 | - * |
|
299 | - * @param EE_Registration|int $registration |
|
300 | - * @param string $message_type the message type slug |
|
301 | - * @return boolean |
|
302 | - */ |
|
303 | - public function message_sent_for_registration($registration, $message_type) |
|
304 | - { |
|
305 | - $registrationID = EEM_Registration::instance()->ensure_is_ID($registration); |
|
306 | - return $this->exists(array( |
|
307 | - array( |
|
308 | - 'Registration.REG_ID' => $registrationID, |
|
309 | - 'MSG_message_type' => $message_type, |
|
310 | - 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
311 | - ), |
|
312 | - )); |
|
313 | - } |
|
314 | - |
|
315 | - |
|
316 | - /** |
|
317 | - * This retrieves an EE_Message object from the db matching the given token string. |
|
318 | - * |
|
319 | - * @param string $token |
|
320 | - * @return EE_Message |
|
321 | - */ |
|
322 | - public function get_one_by_token($token) |
|
323 | - { |
|
324 | - return $this->get_one(array( |
|
325 | - array( |
|
326 | - 'MSG_token' => $token, |
|
327 | - ), |
|
328 | - )); |
|
329 | - } |
|
330 | - |
|
331 | - |
|
332 | - /** |
|
333 | - * Returns stati that indicate the message HAS been sent |
|
334 | - * |
|
335 | - * @return array of strings for possible stati |
|
336 | - */ |
|
337 | - public function stati_indicating_sent() |
|
338 | - { |
|
339 | - return apply_filters('FHEE__EEM_Message__stati_indicating_sent', array(self::status_sent)); |
|
340 | - } |
|
341 | - |
|
342 | - |
|
343 | - /** |
|
344 | - * Returns stati that indicate the message is waiting to be sent. |
|
345 | - * |
|
346 | - * @return array of strings for possible stati. |
|
347 | - */ |
|
348 | - public function stati_indicating_to_send() |
|
349 | - { |
|
350 | - return apply_filters( |
|
351 | - 'FHEE__EEM_Message__stati_indicating_to_send', |
|
352 | - array(self::status_idle, self::status_resend) |
|
353 | - ); |
|
354 | - } |
|
355 | - |
|
356 | - |
|
357 | - /** |
|
358 | - * Returns stati that indicate the message has failed sending |
|
359 | - * |
|
360 | - * @return array array of strings for possible stati. |
|
361 | - */ |
|
362 | - public function stati_indicating_failed_sending() |
|
363 | - { |
|
364 | - $failed_stati = array( |
|
365 | - self::status_failed, |
|
366 | - self::status_retry, |
|
367 | - self::status_messenger_executing, |
|
368 | - ); |
|
369 | - // if WP_DEBUG is set, then let's include debug_only fails |
|
370 | - if (WP_DEBUG) { |
|
371 | - $failed_stati[] = self::status_debug_only; |
|
372 | - } |
|
373 | - return apply_filters('FHEE__EEM_Message__stati_indicating_failed_sending', $failed_stati); |
|
374 | - } |
|
375 | - |
|
376 | - |
|
377 | - /** |
|
378 | - * Returns filterable array of all EEM_Message statuses. |
|
379 | - * |
|
380 | - * @return array |
|
381 | - */ |
|
382 | - public function all_statuses() |
|
383 | - { |
|
384 | - return apply_filters( |
|
385 | - 'FHEE__EEM_Message__all_statuses', |
|
386 | - array( |
|
387 | - EEM_Message::status_sent, |
|
388 | - EEM_Message::status_incomplete, |
|
389 | - EEM_Message::status_idle, |
|
390 | - EEM_Message::status_resend, |
|
391 | - EEM_Message::status_retry, |
|
392 | - EEM_Message::status_failed, |
|
393 | - EEM_Message::status_messenger_executing, |
|
394 | - EEM_Message::status_debug_only, |
|
395 | - ) |
|
396 | - ); |
|
397 | - } |
|
398 | - |
|
399 | - /** |
|
400 | - * Detects any specific query variables in the request and uses those to setup appropriate |
|
401 | - * filter for any queries. |
|
402 | - * |
|
403 | - * @return array |
|
404 | - */ |
|
405 | - public function filter_by_query_params() |
|
406 | - { |
|
407 | - // expected possible query_vars, the key in this array matches an expected key in the request, |
|
408 | - // the value, matches the corresponding EEM_Base child reference. |
|
409 | - $expected_vars = $this->_expected_vars_for_query_inject(); |
|
410 | - $query_params[0] = array(); |
|
411 | - foreach ($expected_vars as $request_key => $model_name) { |
|
412 | - $request_value = EE_Registry::instance()->REQ->get($request_key); |
|
413 | - if ($request_value) { |
|
414 | - // special case |
|
415 | - switch ($request_key) { |
|
416 | - case '_REG_ID': |
|
417 | - $query_params[0]['AND**filter_by']['OR**filter_by_REG_ID'] = array( |
|
418 | - 'Transaction.Registration.REG_ID' => $request_value, |
|
419 | - ); |
|
420 | - break; |
|
421 | - case 'EVT_ID': |
|
422 | - $query_params[0]['AND**filter_by']['OR**filter_by_EVT_ID'] = array( |
|
423 | - 'Transaction.Registration.EVT_ID' => $request_value, |
|
424 | - ); |
|
425 | - break; |
|
426 | - default: |
|
427 | - $query_params[0]['AND**filter_by'][ 'OR**filter_by_' . $request_key ][ $model_name . '.' . $request_key ] = $request_value; |
|
428 | - break; |
|
429 | - } |
|
430 | - } |
|
431 | - } |
|
432 | - return $query_params; |
|
433 | - } |
|
434 | - |
|
435 | - |
|
436 | - /** |
|
437 | - * @return string |
|
438 | - */ |
|
439 | - public function get_pretty_label_for_results() |
|
440 | - { |
|
441 | - $expected_vars = $this->_expected_vars_for_query_inject(); |
|
442 | - $pretty_label = ''; |
|
443 | - $label_parts = array(); |
|
444 | - foreach ($expected_vars as $request_key => $model_name) { |
|
445 | - $model = EE_Registry::instance()->load_model($model_name); |
|
446 | - if ($model_field_value = EE_Registry::instance()->REQ->get($request_key)) { |
|
447 | - switch ($request_key) { |
|
448 | - case '_REG_ID': |
|
449 | - $label_parts[] = sprintf( |
|
450 | - esc_html__('Registration with the ID: %s', 'event_espresso'), |
|
451 | - $model_field_value |
|
452 | - ); |
|
453 | - break; |
|
454 | - case 'ATT_ID': |
|
455 | - /** @var EE_Attendee $attendee */ |
|
456 | - $attendee = $model->get_one_by_ID($model_field_value); |
|
457 | - $label_parts[] = $attendee instanceof EE_Attendee |
|
458 | - ? sprintf(esc_html__('Attendee %s', 'event_espresso'), $attendee->full_name()) |
|
459 | - : sprintf(esc_html__('Attendee ID: %s', 'event_espresso'), $model_field_value); |
|
460 | - break; |
|
461 | - case 'ID': |
|
462 | - /** @var EE_WP_User $wpUser */ |
|
463 | - $wpUser = $model->get_one_by_ID($model_field_value); |
|
464 | - $label_parts[] = $wpUser instanceof EE_WP_User |
|
465 | - ? sprintf(esc_html__('WP User: %s', 'event_espresso'), $wpUser->name()) |
|
466 | - : sprintf(esc_html__('WP User ID: %s', 'event_espresso'), $model_field_value); |
|
467 | - break; |
|
468 | - case 'TXN_ID': |
|
469 | - $label_parts[] = sprintf( |
|
470 | - esc_html__('Transaction with the ID: %s', 'event_espresso'), |
|
471 | - $model_field_value |
|
472 | - ); |
|
473 | - break; |
|
474 | - case 'EVT_ID': |
|
475 | - /** @var EE_Event $Event */ |
|
476 | - $Event = $model->get_one_by_ID($model_field_value); |
|
477 | - $label_parts[] = $Event instanceof EE_Event |
|
478 | - ? sprintf(esc_html__('for the Event: %s', 'event_espresso'), $Event->name()) |
|
479 | - : sprintf(esc_html__('for the Event with ID: %s', 'event_espresso'), $model_field_value); |
|
480 | - break; |
|
481 | - } |
|
482 | - } |
|
483 | - } |
|
484 | - |
|
485 | - if ($label_parts) { |
|
486 | - // prepend to the last element of $label_parts an "and". |
|
487 | - if (count($label_parts) > 1) { |
|
488 | - $label_parts_index_to_prepend = count($label_parts) - 1; |
|
489 | - $label_parts[ $label_parts_index_to_prepend ] = 'and' . $label_parts[ $label_parts_index_to_prepend ]; |
|
490 | - } |
|
491 | - |
|
492 | - $pretty_label .= sprintf( |
|
493 | - esc_html_x( |
|
494 | - 'Showing messages for %s', |
|
495 | - 'A label for the messages returned in a query that are filtered by items in the query. This could be Transaction, Event, Attendee, Registration, or WP_User.', |
|
496 | - 'event_espresso' |
|
497 | - ), |
|
498 | - implode(', ', $label_parts) |
|
499 | - ); |
|
500 | - } |
|
501 | - return $pretty_label; |
|
502 | - } |
|
503 | - |
|
504 | - |
|
505 | - /** |
|
506 | - * This returns the array of expected variables for the EEI_Query_Filter methods being implemented |
|
507 | - * The array is in the format: |
|
508 | - * array( |
|
509 | - * {$field_name} => {$model_name} |
|
510 | - * ); |
|
511 | - * |
|
512 | - * @since 4.9.0 |
|
513 | - * @return array |
|
514 | - */ |
|
515 | - protected function _expected_vars_for_query_inject() |
|
516 | - { |
|
517 | - return array( |
|
518 | - '_REG_ID' => 'Registration', |
|
519 | - 'ATT_ID' => 'Attendee', |
|
520 | - 'ID' => 'WP_User', |
|
521 | - 'TXN_ID' => 'Transaction', |
|
522 | - 'EVT_ID' => 'Event', |
|
523 | - ); |
|
524 | - } |
|
525 | - |
|
526 | - |
|
527 | - /** |
|
528 | - * This returns whether EEM_Message is in debug mode or not. |
|
529 | - * Currently "debug mode" is used to control the handling of the EEM_Message::debug_only status when |
|
530 | - * generating/sending messages. Debug mode can be set by either: |
|
531 | - * 1. Sending in a value for the $set_debug argument |
|
532 | - * 2. Defining `EE_DEBUG_MESSAGES` constant in wp-config.php |
|
533 | - * 3. Overriding the above via the provided filter. |
|
534 | - * |
|
535 | - * @param bool|null $set_debug If provided, then the debug mode will be set internally until reset via the |
|
536 | - * provided boolean. When no argument is provided (default null) then the debug |
|
537 | - * mode will be returned. |
|
538 | - * @return bool true means Messages is in debug mode. false means messages system is not in debug mode. |
|
539 | - */ |
|
540 | - public static function debug($set_debug = null) |
|
541 | - { |
|
542 | - static $is_debugging = null; |
|
543 | - |
|
544 | - // initialize (use constant if set). |
|
545 | - if (is_null($set_debug) && is_null($is_debugging)) { |
|
546 | - $is_debugging = defined('EE_DEBUG_MESSAGES') && EE_DEBUG_MESSAGES; |
|
547 | - } |
|
548 | - |
|
549 | - if (! is_null($set_debug)) { |
|
550 | - $is_debugging = filter_var($set_debug, FILTER_VALIDATE_BOOLEAN); |
|
551 | - } |
|
552 | - |
|
553 | - // return filtered value |
|
554 | - return apply_filters('FHEE__EEM_Message__debug', $is_debugging); |
|
555 | - } |
|
556 | - |
|
557 | - |
|
558 | - /** |
|
559 | - * Deletes old messages meeting certain criteria for removal from the database. |
|
560 | - * By default, this will delete messages that: |
|
561 | - * - are older than the value of the delete_threshold in months. |
|
562 | - * - have a STS_ID other than EEM_Message::status_idle |
|
563 | - * |
|
564 | - * @param int $delete_threshold This integer will be used to set the boundary for what messages are deleted in months. |
|
565 | - * @return bool|false|int Either the number of records affected or false if there was an error (you can call |
|
566 | - * $wpdb->last_error to find out what the error was. |
|
567 | - */ |
|
568 | - public function delete_old_messages($delete_threshold = 6) |
|
569 | - { |
|
570 | - $number_deleted = 0; |
|
571 | - /** |
|
572 | - * Allows code to change the boundary for what messages are kept. |
|
573 | - * Uses the value of the `delete_threshold` variable by default. |
|
574 | - * |
|
575 | - * @param int $seconds seconds that will be subtracted from the timestamp for now. |
|
576 | - * @return int |
|
577 | - */ |
|
578 | - $time_to_leave_alone = absint( |
|
579 | - apply_filters( |
|
580 | - 'FHEE__EEM_Message__delete_old_messages__time_to_leave_alone', |
|
581 | - ((int) $delete_threshold) * MONTH_IN_SECONDS |
|
582 | - ) |
|
583 | - ); |
|
584 | - |
|
585 | - |
|
586 | - /** |
|
587 | - * Allows code to change what message stati are ignored when deleting. |
|
588 | - * Defaults to only ignore EEM_Message::status_idle messages. |
|
589 | - * |
|
590 | - * @param string $message_stati_to_keep An array of message statuses that will be ignored when deleting. |
|
591 | - */ |
|
592 | - $message_stati_to_keep = (array) apply_filters( |
|
593 | - 'FHEE__EEM_Message__delete_old_messages__message_stati_to_keep', |
|
594 | - array( |
|
595 | - EEM_Message::status_idle |
|
596 | - ) |
|
597 | - ); |
|
598 | - |
|
599 | - // first get all the ids of messages being deleted |
|
600 | - $message_ids_to_delete = EEM_Message::instance()->get_col( |
|
601 | - array( |
|
602 | - 0 => array( |
|
603 | - 'STS_ID' => array('NOT_IN', $message_stati_to_keep), |
|
604 | - 'MSG_modified' => array('<', time() - $time_to_leave_alone) |
|
605 | - ), |
|
606 | - 'limit' => apply_filters( |
|
607 | - 'EEM_Message__delete_old_messages__limit', |
|
608 | - 2000, |
|
609 | - $delete_threshold |
|
610 | - ) |
|
611 | - ) |
|
612 | - ); |
|
613 | - |
|
614 | - if (! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) { |
|
615 | - global $wpdb; |
|
616 | - $number_deleted = $wpdb->query(' |
|
16 | + /** |
|
17 | + * This priority indicates a message should be generated and sent ASAP |
|
18 | + * |
|
19 | + * @type int |
|
20 | + */ |
|
21 | + const priority_high = 10; |
|
22 | + |
|
23 | + |
|
24 | + /** |
|
25 | + * This priority indicates a message should be generated ASAP and queued for sending. |
|
26 | + * |
|
27 | + * @type |
|
28 | + */ |
|
29 | + const priority_medium = 20; |
|
30 | + |
|
31 | + |
|
32 | + /** |
|
33 | + * This priority indicates a message should be queued for generating. |
|
34 | + * |
|
35 | + * @type int |
|
36 | + */ |
|
37 | + const priority_low = 30; |
|
38 | + |
|
39 | + |
|
40 | + /** |
|
41 | + * indicates this message was sent at the time modified |
|
42 | + */ |
|
43 | + const status_sent = 'MSN'; |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * indicates this message is waiting to be sent |
|
48 | + */ |
|
49 | + const status_idle = 'MID'; |
|
50 | + |
|
51 | + |
|
52 | + /** |
|
53 | + * indicates an attempt was a made to send this message |
|
54 | + * at the scheduled time, but it failed at the time modified. This differs from MDO status in that it will ALWAYS |
|
55 | + * appear to the end user. |
|
56 | + */ |
|
57 | + const status_failed = 'MFL'; |
|
58 | + |
|
59 | + |
|
60 | + /** |
|
61 | + * indicates the message has been flagged for resending (at the time modified). |
|
62 | + */ |
|
63 | + const status_resend = 'MRS'; |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * indicates the message has been flagged for generation but has not been generated yet. Messages always start as |
|
68 | + * this status when added to the queue. |
|
69 | + */ |
|
70 | + const status_incomplete = 'MIC'; |
|
71 | + |
|
72 | + |
|
73 | + /** |
|
74 | + * Indicates everything was generated fine for the message, however, the messenger was unable to send. |
|
75 | + * This status means that its possible to retry sending the message. |
|
76 | + */ |
|
77 | + const status_retry = 'MRT'; |
|
78 | + |
|
79 | + |
|
80 | + /** |
|
81 | + * This is used for more informational messages that may not indicate anything is broken but still cannot be |
|
82 | + * generated or sent correctly. An example of a message that would get flagged this way would be when a not |
|
83 | + * approved message was queued for generation, but at time of generation, the attached registration(s) are |
|
84 | + * approved. So the message queued for generation is no longer valid. Messages for this status will only persist |
|
85 | + * in the db and be viewable in the message activity list table when the messages system is in debug mode. |
|
86 | + * |
|
87 | + * @see EEM_Message::debug() |
|
88 | + */ |
|
89 | + const status_debug_only = 'MDO'; |
|
90 | + |
|
91 | + |
|
92 | + /** |
|
93 | + * This status is given to messages it is processed by the messenger send method. |
|
94 | + * Messages with this status should rarely be seen in the Message List table, but if they are, that's usually |
|
95 | + * indicative of a PHP timeout or memory limit issue. |
|
96 | + */ |
|
97 | + const status_messenger_executing = 'MEX'; |
|
98 | + |
|
99 | + |
|
100 | + /** |
|
101 | + * Private constructor to prevent direct creation. |
|
102 | + * |
|
103 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and |
|
104 | + * any incoming timezone data that gets saved). Note this just sends the timezone info to |
|
105 | + * the date time model field objects. Default is null (and will be assumed using the set |
|
106 | + * timezone in the 'timezone_string' wp option) |
|
107 | + * @return EEM_Message |
|
108 | + */ |
|
109 | + protected function __construct($timezone = null) |
|
110 | + { |
|
111 | + $this->singular_item = __('Message', 'event_espresso'); |
|
112 | + $this->plural_item = __('Messages', 'event_espresso'); |
|
113 | + |
|
114 | + // used for token generator |
|
115 | + EE_Registry::instance()->load_helper('URL'); |
|
116 | + |
|
117 | + $this->_tables = array( |
|
118 | + 'Message' => new EE_Primary_Table('esp_message', 'MSG_ID'), |
|
119 | + ); |
|
120 | + |
|
121 | + $allowed_priority = array( |
|
122 | + self::priority_high => __('high', 'event_espresso'), |
|
123 | + self::priority_medium => __('medium', 'event_espresso'), |
|
124 | + self::priority_low => __('low', 'event_espresso'), |
|
125 | + ); |
|
126 | + |
|
127 | + $this->_fields = array( |
|
128 | + 'Message' => array( |
|
129 | + 'MSG_ID' => new EE_Primary_Key_Int_Field('MSG_ID', __('Message ID', 'event_espresso')), |
|
130 | + 'MSG_token' => new EE_Plain_Text_Field( |
|
131 | + 'MSG_token', |
|
132 | + __( |
|
133 | + 'Unique Token used to represent this row in publicly viewable contexts (eg. a url).', |
|
134 | + 'event_espresso' |
|
135 | + ), |
|
136 | + false, |
|
137 | + EEH_URL::generate_unique_token() |
|
138 | + ), |
|
139 | + 'GRP_ID' => new EE_Foreign_Key_Int_Field( |
|
140 | + 'GRP_ID', |
|
141 | + __('Foreign key to the EEM_Message_Template_Group table.', 'event_espresso'), |
|
142 | + true, |
|
143 | + 0, |
|
144 | + 'Message_Template_Group' |
|
145 | + ), |
|
146 | + 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
147 | + 'TXN_ID', |
|
148 | + __( |
|
149 | + 'Foreign key to the related EE_Transaction. This is required to give context for regenerating the specific message', |
|
150 | + 'event_espresso' |
|
151 | + ), |
|
152 | + true, |
|
153 | + 0, |
|
154 | + 'Transaction' |
|
155 | + ), |
|
156 | + 'MSG_messenger' => new EE_Plain_Text_Field( |
|
157 | + 'MSG_messenger', |
|
158 | + __( |
|
159 | + 'Corresponds to the EE_messenger::name used to send this message. This will also be used to attempt any resending of the message.', |
|
160 | + 'event_espresso' |
|
161 | + ), |
|
162 | + false, |
|
163 | + 'email' |
|
164 | + ), |
|
165 | + 'MSG_message_type' => new EE_Plain_Text_Field( |
|
166 | + 'MSG_message_type', |
|
167 | + __('Corresponds to the EE_message_type::name used to generate this message.', 'event_espresso'), |
|
168 | + false, |
|
169 | + 'receipt' |
|
170 | + ), |
|
171 | + 'MSG_context' => new EE_Plain_Text_Field('MSG_context', __('Context', 'event_espresso'), false), |
|
172 | + 'MSG_recipient_ID' => new EE_Foreign_Key_Int_Field( |
|
173 | + 'MSG_recipient_ID', |
|
174 | + __('Recipient ID', 'event_espresso'), |
|
175 | + true, |
|
176 | + null, |
|
177 | + array('Registration', 'Attendee', 'WP_User') |
|
178 | + ), |
|
179 | + 'MSG_recipient_type' => new EE_Any_Foreign_Model_Name_Field( |
|
180 | + 'MSG_recipient_type', |
|
181 | + __('Recipient Type', 'event_espresso'), |
|
182 | + true, |
|
183 | + null, |
|
184 | + array('Registration', 'Attendee', 'WP_User') |
|
185 | + ), |
|
186 | + 'MSG_content' => new EE_Maybe_Serialized_Text_Field( |
|
187 | + 'MSG_content', |
|
188 | + __('Content', 'event_espresso'), |
|
189 | + true, |
|
190 | + '' |
|
191 | + ), |
|
192 | + 'MSG_to' => new EE_Maybe_Serialized_Text_Field( |
|
193 | + 'MSG_to', |
|
194 | + __('Address To', 'event_espresso'), |
|
195 | + true |
|
196 | + ), |
|
197 | + 'MSG_from' => new EE_Maybe_Serialized_Text_Field( |
|
198 | + 'MSG_from', |
|
199 | + __('Address From', 'event_espresso'), |
|
200 | + true |
|
201 | + ), |
|
202 | + 'MSG_subject' => new EE_Maybe_Serialized_Text_Field( |
|
203 | + 'MSG_subject', |
|
204 | + __('Subject', 'event_espresso'), |
|
205 | + true, |
|
206 | + '' |
|
207 | + ), |
|
208 | + 'MSG_priority' => new EE_Enum_Integer_Field( |
|
209 | + 'MSG_priority', |
|
210 | + __('Priority', 'event_espresso'), |
|
211 | + false, |
|
212 | + self::priority_low, |
|
213 | + $allowed_priority |
|
214 | + ), |
|
215 | + 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
216 | + 'STS_ID', |
|
217 | + __('Status', 'event_espresso'), |
|
218 | + false, |
|
219 | + self::status_incomplete, |
|
220 | + 'Status' |
|
221 | + ), |
|
222 | + 'MSG_created' => new EE_Datetime_Field( |
|
223 | + 'MSG_created', |
|
224 | + __('Created', 'event_espresso'), |
|
225 | + false, |
|
226 | + EE_Datetime_Field::now |
|
227 | + ), |
|
228 | + 'MSG_modified' => new EE_Datetime_Field( |
|
229 | + 'MSG_modified', |
|
230 | + __('Modified', 'event_espresso'), |
|
231 | + true, |
|
232 | + EE_Datetime_Field::now |
|
233 | + ), |
|
234 | + ), |
|
235 | + ); |
|
236 | + $this->_model_relations = array( |
|
237 | + 'Attendee' => new EE_Belongs_To_Any_Relation(), |
|
238 | + 'Registration' => new EE_Belongs_To_Any_Relation(), |
|
239 | + 'WP_User' => new EE_Belongs_To_Any_Relation(), |
|
240 | + 'Message_Template_Group' => new EE_Belongs_To_Relation(), |
|
241 | + 'Transaction' => new EE_Belongs_To_Relation(), |
|
242 | + ); |
|
243 | + parent::__construct($timezone); |
|
244 | + } |
|
245 | + |
|
246 | + |
|
247 | + /** |
|
248 | + * @return \EE_Message |
|
249 | + */ |
|
250 | + public function create_default_object() |
|
251 | + { |
|
252 | + /** @type EE_Message $message */ |
|
253 | + $message = parent::create_default_object(); |
|
254 | + if ($message instanceof EE_Message) { |
|
255 | + return EE_Message_Factory::set_messenger_and_message_type($message); |
|
256 | + } |
|
257 | + return null; |
|
258 | + } |
|
259 | + |
|
260 | + |
|
261 | + /** |
|
262 | + * @param mixed $cols_n_values |
|
263 | + * @return \EE_Message |
|
264 | + */ |
|
265 | + public function instantiate_class_from_array_or_object($cols_n_values) |
|
266 | + { |
|
267 | + /** @type EE_Message $message */ |
|
268 | + $message = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
269 | + if ($message instanceof EE_Message) { |
|
270 | + return EE_Message_Factory::set_messenger_and_message_type($message); |
|
271 | + } |
|
272 | + return null; |
|
273 | + } |
|
274 | + |
|
275 | + |
|
276 | + /** |
|
277 | + * Returns whether or not a message of that type was sent for a given attendee. |
|
278 | + * |
|
279 | + * @param EE_Attendee|int $attendee |
|
280 | + * @param string $message_type the message type slug |
|
281 | + * @return boolean |
|
282 | + */ |
|
283 | + public function message_sent_for_attendee($attendee, $message_type) |
|
284 | + { |
|
285 | + $attendee_ID = EEM_Attendee::instance()->ensure_is_ID($attendee); |
|
286 | + return $this->exists(array( |
|
287 | + array( |
|
288 | + 'Attendee.ATT_ID' => $attendee_ID, |
|
289 | + 'MSG_message_type' => $message_type, |
|
290 | + 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
291 | + ), |
|
292 | + )); |
|
293 | + } |
|
294 | + |
|
295 | + |
|
296 | + /** |
|
297 | + * Returns whether or not a message of that type was sent for a given registration |
|
298 | + * |
|
299 | + * @param EE_Registration|int $registration |
|
300 | + * @param string $message_type the message type slug |
|
301 | + * @return boolean |
|
302 | + */ |
|
303 | + public function message_sent_for_registration($registration, $message_type) |
|
304 | + { |
|
305 | + $registrationID = EEM_Registration::instance()->ensure_is_ID($registration); |
|
306 | + return $this->exists(array( |
|
307 | + array( |
|
308 | + 'Registration.REG_ID' => $registrationID, |
|
309 | + 'MSG_message_type' => $message_type, |
|
310 | + 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
311 | + ), |
|
312 | + )); |
|
313 | + } |
|
314 | + |
|
315 | + |
|
316 | + /** |
|
317 | + * This retrieves an EE_Message object from the db matching the given token string. |
|
318 | + * |
|
319 | + * @param string $token |
|
320 | + * @return EE_Message |
|
321 | + */ |
|
322 | + public function get_one_by_token($token) |
|
323 | + { |
|
324 | + return $this->get_one(array( |
|
325 | + array( |
|
326 | + 'MSG_token' => $token, |
|
327 | + ), |
|
328 | + )); |
|
329 | + } |
|
330 | + |
|
331 | + |
|
332 | + /** |
|
333 | + * Returns stati that indicate the message HAS been sent |
|
334 | + * |
|
335 | + * @return array of strings for possible stati |
|
336 | + */ |
|
337 | + public function stati_indicating_sent() |
|
338 | + { |
|
339 | + return apply_filters('FHEE__EEM_Message__stati_indicating_sent', array(self::status_sent)); |
|
340 | + } |
|
341 | + |
|
342 | + |
|
343 | + /** |
|
344 | + * Returns stati that indicate the message is waiting to be sent. |
|
345 | + * |
|
346 | + * @return array of strings for possible stati. |
|
347 | + */ |
|
348 | + public function stati_indicating_to_send() |
|
349 | + { |
|
350 | + return apply_filters( |
|
351 | + 'FHEE__EEM_Message__stati_indicating_to_send', |
|
352 | + array(self::status_idle, self::status_resend) |
|
353 | + ); |
|
354 | + } |
|
355 | + |
|
356 | + |
|
357 | + /** |
|
358 | + * Returns stati that indicate the message has failed sending |
|
359 | + * |
|
360 | + * @return array array of strings for possible stati. |
|
361 | + */ |
|
362 | + public function stati_indicating_failed_sending() |
|
363 | + { |
|
364 | + $failed_stati = array( |
|
365 | + self::status_failed, |
|
366 | + self::status_retry, |
|
367 | + self::status_messenger_executing, |
|
368 | + ); |
|
369 | + // if WP_DEBUG is set, then let's include debug_only fails |
|
370 | + if (WP_DEBUG) { |
|
371 | + $failed_stati[] = self::status_debug_only; |
|
372 | + } |
|
373 | + return apply_filters('FHEE__EEM_Message__stati_indicating_failed_sending', $failed_stati); |
|
374 | + } |
|
375 | + |
|
376 | + |
|
377 | + /** |
|
378 | + * Returns filterable array of all EEM_Message statuses. |
|
379 | + * |
|
380 | + * @return array |
|
381 | + */ |
|
382 | + public function all_statuses() |
|
383 | + { |
|
384 | + return apply_filters( |
|
385 | + 'FHEE__EEM_Message__all_statuses', |
|
386 | + array( |
|
387 | + EEM_Message::status_sent, |
|
388 | + EEM_Message::status_incomplete, |
|
389 | + EEM_Message::status_idle, |
|
390 | + EEM_Message::status_resend, |
|
391 | + EEM_Message::status_retry, |
|
392 | + EEM_Message::status_failed, |
|
393 | + EEM_Message::status_messenger_executing, |
|
394 | + EEM_Message::status_debug_only, |
|
395 | + ) |
|
396 | + ); |
|
397 | + } |
|
398 | + |
|
399 | + /** |
|
400 | + * Detects any specific query variables in the request and uses those to setup appropriate |
|
401 | + * filter for any queries. |
|
402 | + * |
|
403 | + * @return array |
|
404 | + */ |
|
405 | + public function filter_by_query_params() |
|
406 | + { |
|
407 | + // expected possible query_vars, the key in this array matches an expected key in the request, |
|
408 | + // the value, matches the corresponding EEM_Base child reference. |
|
409 | + $expected_vars = $this->_expected_vars_for_query_inject(); |
|
410 | + $query_params[0] = array(); |
|
411 | + foreach ($expected_vars as $request_key => $model_name) { |
|
412 | + $request_value = EE_Registry::instance()->REQ->get($request_key); |
|
413 | + if ($request_value) { |
|
414 | + // special case |
|
415 | + switch ($request_key) { |
|
416 | + case '_REG_ID': |
|
417 | + $query_params[0]['AND**filter_by']['OR**filter_by_REG_ID'] = array( |
|
418 | + 'Transaction.Registration.REG_ID' => $request_value, |
|
419 | + ); |
|
420 | + break; |
|
421 | + case 'EVT_ID': |
|
422 | + $query_params[0]['AND**filter_by']['OR**filter_by_EVT_ID'] = array( |
|
423 | + 'Transaction.Registration.EVT_ID' => $request_value, |
|
424 | + ); |
|
425 | + break; |
|
426 | + default: |
|
427 | + $query_params[0]['AND**filter_by'][ 'OR**filter_by_' . $request_key ][ $model_name . '.' . $request_key ] = $request_value; |
|
428 | + break; |
|
429 | + } |
|
430 | + } |
|
431 | + } |
|
432 | + return $query_params; |
|
433 | + } |
|
434 | + |
|
435 | + |
|
436 | + /** |
|
437 | + * @return string |
|
438 | + */ |
|
439 | + public function get_pretty_label_for_results() |
|
440 | + { |
|
441 | + $expected_vars = $this->_expected_vars_for_query_inject(); |
|
442 | + $pretty_label = ''; |
|
443 | + $label_parts = array(); |
|
444 | + foreach ($expected_vars as $request_key => $model_name) { |
|
445 | + $model = EE_Registry::instance()->load_model($model_name); |
|
446 | + if ($model_field_value = EE_Registry::instance()->REQ->get($request_key)) { |
|
447 | + switch ($request_key) { |
|
448 | + case '_REG_ID': |
|
449 | + $label_parts[] = sprintf( |
|
450 | + esc_html__('Registration with the ID: %s', 'event_espresso'), |
|
451 | + $model_field_value |
|
452 | + ); |
|
453 | + break; |
|
454 | + case 'ATT_ID': |
|
455 | + /** @var EE_Attendee $attendee */ |
|
456 | + $attendee = $model->get_one_by_ID($model_field_value); |
|
457 | + $label_parts[] = $attendee instanceof EE_Attendee |
|
458 | + ? sprintf(esc_html__('Attendee %s', 'event_espresso'), $attendee->full_name()) |
|
459 | + : sprintf(esc_html__('Attendee ID: %s', 'event_espresso'), $model_field_value); |
|
460 | + break; |
|
461 | + case 'ID': |
|
462 | + /** @var EE_WP_User $wpUser */ |
|
463 | + $wpUser = $model->get_one_by_ID($model_field_value); |
|
464 | + $label_parts[] = $wpUser instanceof EE_WP_User |
|
465 | + ? sprintf(esc_html__('WP User: %s', 'event_espresso'), $wpUser->name()) |
|
466 | + : sprintf(esc_html__('WP User ID: %s', 'event_espresso'), $model_field_value); |
|
467 | + break; |
|
468 | + case 'TXN_ID': |
|
469 | + $label_parts[] = sprintf( |
|
470 | + esc_html__('Transaction with the ID: %s', 'event_espresso'), |
|
471 | + $model_field_value |
|
472 | + ); |
|
473 | + break; |
|
474 | + case 'EVT_ID': |
|
475 | + /** @var EE_Event $Event */ |
|
476 | + $Event = $model->get_one_by_ID($model_field_value); |
|
477 | + $label_parts[] = $Event instanceof EE_Event |
|
478 | + ? sprintf(esc_html__('for the Event: %s', 'event_espresso'), $Event->name()) |
|
479 | + : sprintf(esc_html__('for the Event with ID: %s', 'event_espresso'), $model_field_value); |
|
480 | + break; |
|
481 | + } |
|
482 | + } |
|
483 | + } |
|
484 | + |
|
485 | + if ($label_parts) { |
|
486 | + // prepend to the last element of $label_parts an "and". |
|
487 | + if (count($label_parts) > 1) { |
|
488 | + $label_parts_index_to_prepend = count($label_parts) - 1; |
|
489 | + $label_parts[ $label_parts_index_to_prepend ] = 'and' . $label_parts[ $label_parts_index_to_prepend ]; |
|
490 | + } |
|
491 | + |
|
492 | + $pretty_label .= sprintf( |
|
493 | + esc_html_x( |
|
494 | + 'Showing messages for %s', |
|
495 | + 'A label for the messages returned in a query that are filtered by items in the query. This could be Transaction, Event, Attendee, Registration, or WP_User.', |
|
496 | + 'event_espresso' |
|
497 | + ), |
|
498 | + implode(', ', $label_parts) |
|
499 | + ); |
|
500 | + } |
|
501 | + return $pretty_label; |
|
502 | + } |
|
503 | + |
|
504 | + |
|
505 | + /** |
|
506 | + * This returns the array of expected variables for the EEI_Query_Filter methods being implemented |
|
507 | + * The array is in the format: |
|
508 | + * array( |
|
509 | + * {$field_name} => {$model_name} |
|
510 | + * ); |
|
511 | + * |
|
512 | + * @since 4.9.0 |
|
513 | + * @return array |
|
514 | + */ |
|
515 | + protected function _expected_vars_for_query_inject() |
|
516 | + { |
|
517 | + return array( |
|
518 | + '_REG_ID' => 'Registration', |
|
519 | + 'ATT_ID' => 'Attendee', |
|
520 | + 'ID' => 'WP_User', |
|
521 | + 'TXN_ID' => 'Transaction', |
|
522 | + 'EVT_ID' => 'Event', |
|
523 | + ); |
|
524 | + } |
|
525 | + |
|
526 | + |
|
527 | + /** |
|
528 | + * This returns whether EEM_Message is in debug mode or not. |
|
529 | + * Currently "debug mode" is used to control the handling of the EEM_Message::debug_only status when |
|
530 | + * generating/sending messages. Debug mode can be set by either: |
|
531 | + * 1. Sending in a value for the $set_debug argument |
|
532 | + * 2. Defining `EE_DEBUG_MESSAGES` constant in wp-config.php |
|
533 | + * 3. Overriding the above via the provided filter. |
|
534 | + * |
|
535 | + * @param bool|null $set_debug If provided, then the debug mode will be set internally until reset via the |
|
536 | + * provided boolean. When no argument is provided (default null) then the debug |
|
537 | + * mode will be returned. |
|
538 | + * @return bool true means Messages is in debug mode. false means messages system is not in debug mode. |
|
539 | + */ |
|
540 | + public static function debug($set_debug = null) |
|
541 | + { |
|
542 | + static $is_debugging = null; |
|
543 | + |
|
544 | + // initialize (use constant if set). |
|
545 | + if (is_null($set_debug) && is_null($is_debugging)) { |
|
546 | + $is_debugging = defined('EE_DEBUG_MESSAGES') && EE_DEBUG_MESSAGES; |
|
547 | + } |
|
548 | + |
|
549 | + if (! is_null($set_debug)) { |
|
550 | + $is_debugging = filter_var($set_debug, FILTER_VALIDATE_BOOLEAN); |
|
551 | + } |
|
552 | + |
|
553 | + // return filtered value |
|
554 | + return apply_filters('FHEE__EEM_Message__debug', $is_debugging); |
|
555 | + } |
|
556 | + |
|
557 | + |
|
558 | + /** |
|
559 | + * Deletes old messages meeting certain criteria for removal from the database. |
|
560 | + * By default, this will delete messages that: |
|
561 | + * - are older than the value of the delete_threshold in months. |
|
562 | + * - have a STS_ID other than EEM_Message::status_idle |
|
563 | + * |
|
564 | + * @param int $delete_threshold This integer will be used to set the boundary for what messages are deleted in months. |
|
565 | + * @return bool|false|int Either the number of records affected or false if there was an error (you can call |
|
566 | + * $wpdb->last_error to find out what the error was. |
|
567 | + */ |
|
568 | + public function delete_old_messages($delete_threshold = 6) |
|
569 | + { |
|
570 | + $number_deleted = 0; |
|
571 | + /** |
|
572 | + * Allows code to change the boundary for what messages are kept. |
|
573 | + * Uses the value of the `delete_threshold` variable by default. |
|
574 | + * |
|
575 | + * @param int $seconds seconds that will be subtracted from the timestamp for now. |
|
576 | + * @return int |
|
577 | + */ |
|
578 | + $time_to_leave_alone = absint( |
|
579 | + apply_filters( |
|
580 | + 'FHEE__EEM_Message__delete_old_messages__time_to_leave_alone', |
|
581 | + ((int) $delete_threshold) * MONTH_IN_SECONDS |
|
582 | + ) |
|
583 | + ); |
|
584 | + |
|
585 | + |
|
586 | + /** |
|
587 | + * Allows code to change what message stati are ignored when deleting. |
|
588 | + * Defaults to only ignore EEM_Message::status_idle messages. |
|
589 | + * |
|
590 | + * @param string $message_stati_to_keep An array of message statuses that will be ignored when deleting. |
|
591 | + */ |
|
592 | + $message_stati_to_keep = (array) apply_filters( |
|
593 | + 'FHEE__EEM_Message__delete_old_messages__message_stati_to_keep', |
|
594 | + array( |
|
595 | + EEM_Message::status_idle |
|
596 | + ) |
|
597 | + ); |
|
598 | + |
|
599 | + // first get all the ids of messages being deleted |
|
600 | + $message_ids_to_delete = EEM_Message::instance()->get_col( |
|
601 | + array( |
|
602 | + 0 => array( |
|
603 | + 'STS_ID' => array('NOT_IN', $message_stati_to_keep), |
|
604 | + 'MSG_modified' => array('<', time() - $time_to_leave_alone) |
|
605 | + ), |
|
606 | + 'limit' => apply_filters( |
|
607 | + 'EEM_Message__delete_old_messages__limit', |
|
608 | + 2000, |
|
609 | + $delete_threshold |
|
610 | + ) |
|
611 | + ) |
|
612 | + ); |
|
613 | + |
|
614 | + if (! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) { |
|
615 | + global $wpdb; |
|
616 | + $number_deleted = $wpdb->query(' |
|
617 | 617 | DELETE |
618 | 618 | FROM ' . $this->table() . ' |
619 | 619 | WHERE |
620 | 620 | MSG_ID IN (' . implode(",", $message_ids_to_delete) . ') |
621 | 621 | '); |
622 | - } |
|
623 | - |
|
624 | - /** |
|
625 | - * This will get called if the number of records deleted 0 or greater. So a successful deletion is one where |
|
626 | - * there were no errors. An unsuccessful deletion is where there were errors. Keep that in mind for the actions |
|
627 | - * below. |
|
628 | - */ |
|
629 | - if ($number_deleted !== false) { |
|
630 | - do_action('AHEE__EEM_Message__delete_old_messages__after_successful_deletion', $message_ids_to_delete, $number_deleted); |
|
631 | - } else { |
|
632 | - do_action('AHEE__EEM_Message__delete_old_messages__after_deletion_fail', $message_ids_to_delete, $number_deleted); |
|
633 | - } |
|
634 | - return $number_deleted; |
|
635 | - } |
|
622 | + } |
|
623 | + |
|
624 | + /** |
|
625 | + * This will get called if the number of records deleted 0 or greater. So a successful deletion is one where |
|
626 | + * there were no errors. An unsuccessful deletion is where there were errors. Keep that in mind for the actions |
|
627 | + * below. |
|
628 | + */ |
|
629 | + if ($number_deleted !== false) { |
|
630 | + do_action('AHEE__EEM_Message__delete_old_messages__after_successful_deletion', $message_ids_to_delete, $number_deleted); |
|
631 | + } else { |
|
632 | + do_action('AHEE__EEM_Message__delete_old_messages__after_deletion_fail', $message_ids_to_delete, $number_deleted); |
|
633 | + } |
|
634 | + return $number_deleted; |
|
635 | + } |
|
636 | 636 | } |
@@ -16,230 +16,230 @@ discard block |
||
16 | 16 | class EEM_Transaction extends EEM_Base |
17 | 17 | { |
18 | 18 | |
19 | - // private instance of the Transaction object |
|
20 | - protected static $_instance; |
|
21 | - |
|
22 | - /** |
|
23 | - * Status ID(STS_ID on esp_status table) to indicate the transaction is complete, |
|
24 | - * but payment is pending. This is the state for transactions where payment is promised |
|
25 | - * from an offline gateway. |
|
26 | - */ |
|
27 | - // const open_status_code = 'TPN'; |
|
28 | - |
|
29 | - /** |
|
30 | - * Status ID(STS_ID on esp_status table) to indicate the transaction failed, |
|
31 | - * either due to a technical reason (server or computer crash during registration), |
|
32 | - * or some other reason that prevent the collection of any useful contact information from any of the registrants |
|
33 | - */ |
|
34 | - const failed_status_code = 'TFL'; |
|
35 | - |
|
36 | - /** |
|
37 | - * Status ID(STS_ID on esp_status table) to indicate the transaction was abandoned, |
|
38 | - * either due to a technical reason (server or computer crash during registration), |
|
39 | - * or due to an abandoned cart after registrant chose not to complete the registration process |
|
40 | - * HOWEVER... |
|
41 | - * an abandoned TXN differs from a failed TXN in that it was able to capture contact information for at least one |
|
42 | - * registrant |
|
43 | - */ |
|
44 | - const abandoned_status_code = 'TAB'; |
|
45 | - |
|
46 | - /** |
|
47 | - * Status ID(STS_ID on esp_status table) to indicate an incomplete transaction, |
|
48 | - * meaning that monies are still owing: TXN_paid < TXN_total |
|
49 | - */ |
|
50 | - const incomplete_status_code = 'TIN'; |
|
51 | - |
|
52 | - /** |
|
53 | - * Status ID (STS_ID on esp_status table) to indicate a complete transaction. |
|
54 | - * meaning that NO monies are owing: TXN_paid == TXN_total |
|
55 | - */ |
|
56 | - const complete_status_code = 'TCM'; |
|
57 | - |
|
58 | - /** |
|
59 | - * Status ID(STS_ID on esp_status table) to indicate the transaction is overpaid. |
|
60 | - * This is the same as complete, but site admins actually owe clients the moneys! TXN_paid > TXN_total |
|
61 | - */ |
|
62 | - const overpaid_status_code = 'TOP'; |
|
63 | - |
|
64 | - |
|
65 | - /** |
|
66 | - * private constructor to prevent direct creation |
|
67 | - * |
|
68 | - * @Constructor |
|
69 | - * @access protected |
|
70 | - * |
|
71 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
72 | - * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
73 | - * date time model field objects. Default is NULL (and will be assumed using the set |
|
74 | - * timezone in the 'timezone_string' wp option) |
|
75 | - * |
|
76 | - * @return EEM_Transaction |
|
77 | - * @throws \EE_Error |
|
78 | - */ |
|
79 | - protected function __construct($timezone) |
|
80 | - { |
|
81 | - $this->singular_item = __('Transaction', 'event_espresso'); |
|
82 | - $this->plural_item = __('Transactions', 'event_espresso'); |
|
83 | - |
|
84 | - $this->_tables = array( |
|
85 | - 'TransactionTable' => new EE_Primary_Table('esp_transaction', 'TXN_ID') |
|
86 | - ); |
|
87 | - $this->_fields = array( |
|
88 | - 'TransactionTable' => array( |
|
89 | - 'TXN_ID' => new EE_Primary_Key_Int_Field('TXN_ID', __('Transaction ID', 'event_espresso')), |
|
90 | - 'TXN_timestamp' => new EE_Datetime_Field( |
|
91 | - 'TXN_timestamp', |
|
92 | - __('date when transaction was created', 'event_espresso'), |
|
93 | - false, |
|
94 | - EE_Datetime_Field::now, |
|
95 | - $timezone |
|
96 | - ), |
|
97 | - 'TXN_total' => new EE_Money_Field( |
|
98 | - 'TXN_total', |
|
99 | - __('Total value of Transaction', 'event_espresso'), |
|
100 | - false, |
|
101 | - 0 |
|
102 | - ), |
|
103 | - 'TXN_paid' => new EE_Money_Field( |
|
104 | - 'TXN_paid', |
|
105 | - __('Amount paid towards transaction to date', 'event_espresso'), |
|
106 | - false, |
|
107 | - 0 |
|
108 | - ), |
|
109 | - 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
110 | - 'STS_ID', |
|
111 | - __('Status ID', 'event_espresso'), |
|
112 | - false, |
|
113 | - EEM_Transaction::failed_status_code, |
|
114 | - 'Status' |
|
115 | - ), |
|
116 | - 'TXN_session_data' => new EE_Serialized_Text_Field( |
|
117 | - 'TXN_session_data', |
|
118 | - __('Serialized session data', 'event_espresso'), |
|
119 | - true, |
|
120 | - '' |
|
121 | - ), |
|
122 | - 'TXN_hash_salt' => new EE_Plain_Text_Field( |
|
123 | - 'TXN_hash_salt', |
|
124 | - __('Transaction Hash Salt', 'event_espresso'), |
|
125 | - true, |
|
126 | - '' |
|
127 | - ), |
|
128 | - 'PMD_ID' => new EE_Foreign_Key_Int_Field( |
|
129 | - 'PMD_ID', |
|
130 | - __("Last Used Payment Method", 'event_espresso'), |
|
131 | - true, |
|
132 | - null, |
|
133 | - 'Payment_Method' |
|
134 | - ), |
|
135 | - 'TXN_reg_steps' => new EE_Serialized_Text_Field( |
|
136 | - 'TXN_reg_steps', |
|
137 | - __('Registration Steps', 'event_espresso'), |
|
138 | - false, |
|
139 | - array() |
|
140 | - ), |
|
141 | - ) |
|
142 | - ); |
|
143 | - $this->_model_relations = array( |
|
144 | - 'Registration' => new EE_Has_Many_Relation(), |
|
145 | - 'Payment' => new EE_Has_Many_Relation(), |
|
146 | - 'Status' => new EE_Belongs_To_Relation(), |
|
147 | - 'Line_Item' => new EE_Has_Many_Relation(false), |
|
148 | - // you can delete a transaction without needing to delete its line items |
|
149 | - 'Payment_Method' => new EE_Belongs_To_Relation(), |
|
150 | - 'Message' => new EE_Has_Many_Relation() |
|
151 | - ); |
|
152 | - $this->_model_chain_to_wp_user = 'Registration.Event'; |
|
153 | - parent::__construct($timezone); |
|
154 | - } |
|
155 | - |
|
156 | - |
|
157 | - /** |
|
158 | - * txn_status_array |
|
159 | - * get list of transaction statuses |
|
160 | - * |
|
161 | - * @access public |
|
162 | - * @return array |
|
163 | - */ |
|
164 | - public static function txn_status_array() |
|
165 | - { |
|
166 | - return apply_filters( |
|
167 | - 'FHEE__EEM_Transaction__txn_status_array', |
|
168 | - array( |
|
169 | - EEM_Transaction::overpaid_status_code, |
|
170 | - EEM_Transaction::complete_status_code, |
|
171 | - EEM_Transaction::incomplete_status_code, |
|
172 | - EEM_Transaction::abandoned_status_code, |
|
173 | - EEM_Transaction::failed_status_code, |
|
174 | - ) |
|
175 | - ); |
|
176 | - } |
|
177 | - |
|
178 | - /** |
|
179 | - * get the revenue per day for the Transaction Admin page Reports Tab |
|
180 | - * |
|
181 | - * @access public |
|
182 | - * |
|
183 | - * @param string $period |
|
184 | - * |
|
185 | - * @return \stdClass[] |
|
186 | - */ |
|
187 | - public function get_revenue_per_day_report($period = '-1 month') |
|
188 | - { |
|
189 | - $sql_date = $this->convert_datetime_for_query( |
|
190 | - 'TXN_timestamp', |
|
191 | - date('Y-m-d H:i:s', strtotime($period)), |
|
192 | - 'Y-m-d H:i:s', |
|
193 | - 'UTC' |
|
194 | - ); |
|
195 | - |
|
196 | - $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'TXN_timestamp'); |
|
197 | - |
|
198 | - return $this->_get_all_wpdb_results( |
|
199 | - array( |
|
200 | - array( |
|
201 | - 'TXN_timestamp' => array('>=', $sql_date) |
|
202 | - ), |
|
203 | - 'group_by' => 'txnDate', |
|
204 | - 'order_by' => array('TXN_timestamp' => 'ASC') |
|
205 | - ), |
|
206 | - OBJECT, |
|
207 | - array( |
|
208 | - 'txnDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
209 | - 'revenue' => array('SUM(TransactionTable.TXN_paid)', '%d') |
|
210 | - ) |
|
211 | - ); |
|
212 | - } |
|
213 | - |
|
214 | - |
|
215 | - /** |
|
216 | - * get the revenue per event for the Transaction Admin page Reports Tab |
|
217 | - * |
|
218 | - * @access public |
|
219 | - * |
|
220 | - * @param string $period |
|
221 | - * |
|
222 | - * @throws \EE_Error |
|
223 | - * @return mixed |
|
224 | - */ |
|
225 | - public function get_revenue_per_event_report($period = '-1 month') |
|
226 | - { |
|
227 | - global $wpdb; |
|
228 | - $transaction_table = $wpdb->prefix . 'esp_transaction'; |
|
229 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
230 | - $registration_payment_table = $wpdb->prefix . 'esp_registration_payment'; |
|
231 | - $event_table = $wpdb->posts; |
|
232 | - $payment_table = $wpdb->prefix . 'esp_payment'; |
|
233 | - $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
234 | - $approved_payment_status = EEM_Payment::status_id_approved; |
|
235 | - $extra_event_on_join = ''; |
|
236 | - // exclude events not authored by user if permissions in effect |
|
237 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
238 | - $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id(); |
|
239 | - } |
|
240 | - |
|
241 | - return $wpdb->get_results( |
|
242 | - "SELECT |
|
19 | + // private instance of the Transaction object |
|
20 | + protected static $_instance; |
|
21 | + |
|
22 | + /** |
|
23 | + * Status ID(STS_ID on esp_status table) to indicate the transaction is complete, |
|
24 | + * but payment is pending. This is the state for transactions where payment is promised |
|
25 | + * from an offline gateway. |
|
26 | + */ |
|
27 | + // const open_status_code = 'TPN'; |
|
28 | + |
|
29 | + /** |
|
30 | + * Status ID(STS_ID on esp_status table) to indicate the transaction failed, |
|
31 | + * either due to a technical reason (server or computer crash during registration), |
|
32 | + * or some other reason that prevent the collection of any useful contact information from any of the registrants |
|
33 | + */ |
|
34 | + const failed_status_code = 'TFL'; |
|
35 | + |
|
36 | + /** |
|
37 | + * Status ID(STS_ID on esp_status table) to indicate the transaction was abandoned, |
|
38 | + * either due to a technical reason (server or computer crash during registration), |
|
39 | + * or due to an abandoned cart after registrant chose not to complete the registration process |
|
40 | + * HOWEVER... |
|
41 | + * an abandoned TXN differs from a failed TXN in that it was able to capture contact information for at least one |
|
42 | + * registrant |
|
43 | + */ |
|
44 | + const abandoned_status_code = 'TAB'; |
|
45 | + |
|
46 | + /** |
|
47 | + * Status ID(STS_ID on esp_status table) to indicate an incomplete transaction, |
|
48 | + * meaning that monies are still owing: TXN_paid < TXN_total |
|
49 | + */ |
|
50 | + const incomplete_status_code = 'TIN'; |
|
51 | + |
|
52 | + /** |
|
53 | + * Status ID (STS_ID on esp_status table) to indicate a complete transaction. |
|
54 | + * meaning that NO monies are owing: TXN_paid == TXN_total |
|
55 | + */ |
|
56 | + const complete_status_code = 'TCM'; |
|
57 | + |
|
58 | + /** |
|
59 | + * Status ID(STS_ID on esp_status table) to indicate the transaction is overpaid. |
|
60 | + * This is the same as complete, but site admins actually owe clients the moneys! TXN_paid > TXN_total |
|
61 | + */ |
|
62 | + const overpaid_status_code = 'TOP'; |
|
63 | + |
|
64 | + |
|
65 | + /** |
|
66 | + * private constructor to prevent direct creation |
|
67 | + * |
|
68 | + * @Constructor |
|
69 | + * @access protected |
|
70 | + * |
|
71 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
72 | + * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
73 | + * date time model field objects. Default is NULL (and will be assumed using the set |
|
74 | + * timezone in the 'timezone_string' wp option) |
|
75 | + * |
|
76 | + * @return EEM_Transaction |
|
77 | + * @throws \EE_Error |
|
78 | + */ |
|
79 | + protected function __construct($timezone) |
|
80 | + { |
|
81 | + $this->singular_item = __('Transaction', 'event_espresso'); |
|
82 | + $this->plural_item = __('Transactions', 'event_espresso'); |
|
83 | + |
|
84 | + $this->_tables = array( |
|
85 | + 'TransactionTable' => new EE_Primary_Table('esp_transaction', 'TXN_ID') |
|
86 | + ); |
|
87 | + $this->_fields = array( |
|
88 | + 'TransactionTable' => array( |
|
89 | + 'TXN_ID' => new EE_Primary_Key_Int_Field('TXN_ID', __('Transaction ID', 'event_espresso')), |
|
90 | + 'TXN_timestamp' => new EE_Datetime_Field( |
|
91 | + 'TXN_timestamp', |
|
92 | + __('date when transaction was created', 'event_espresso'), |
|
93 | + false, |
|
94 | + EE_Datetime_Field::now, |
|
95 | + $timezone |
|
96 | + ), |
|
97 | + 'TXN_total' => new EE_Money_Field( |
|
98 | + 'TXN_total', |
|
99 | + __('Total value of Transaction', 'event_espresso'), |
|
100 | + false, |
|
101 | + 0 |
|
102 | + ), |
|
103 | + 'TXN_paid' => new EE_Money_Field( |
|
104 | + 'TXN_paid', |
|
105 | + __('Amount paid towards transaction to date', 'event_espresso'), |
|
106 | + false, |
|
107 | + 0 |
|
108 | + ), |
|
109 | + 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
110 | + 'STS_ID', |
|
111 | + __('Status ID', 'event_espresso'), |
|
112 | + false, |
|
113 | + EEM_Transaction::failed_status_code, |
|
114 | + 'Status' |
|
115 | + ), |
|
116 | + 'TXN_session_data' => new EE_Serialized_Text_Field( |
|
117 | + 'TXN_session_data', |
|
118 | + __('Serialized session data', 'event_espresso'), |
|
119 | + true, |
|
120 | + '' |
|
121 | + ), |
|
122 | + 'TXN_hash_salt' => new EE_Plain_Text_Field( |
|
123 | + 'TXN_hash_salt', |
|
124 | + __('Transaction Hash Salt', 'event_espresso'), |
|
125 | + true, |
|
126 | + '' |
|
127 | + ), |
|
128 | + 'PMD_ID' => new EE_Foreign_Key_Int_Field( |
|
129 | + 'PMD_ID', |
|
130 | + __("Last Used Payment Method", 'event_espresso'), |
|
131 | + true, |
|
132 | + null, |
|
133 | + 'Payment_Method' |
|
134 | + ), |
|
135 | + 'TXN_reg_steps' => new EE_Serialized_Text_Field( |
|
136 | + 'TXN_reg_steps', |
|
137 | + __('Registration Steps', 'event_espresso'), |
|
138 | + false, |
|
139 | + array() |
|
140 | + ), |
|
141 | + ) |
|
142 | + ); |
|
143 | + $this->_model_relations = array( |
|
144 | + 'Registration' => new EE_Has_Many_Relation(), |
|
145 | + 'Payment' => new EE_Has_Many_Relation(), |
|
146 | + 'Status' => new EE_Belongs_To_Relation(), |
|
147 | + 'Line_Item' => new EE_Has_Many_Relation(false), |
|
148 | + // you can delete a transaction without needing to delete its line items |
|
149 | + 'Payment_Method' => new EE_Belongs_To_Relation(), |
|
150 | + 'Message' => new EE_Has_Many_Relation() |
|
151 | + ); |
|
152 | + $this->_model_chain_to_wp_user = 'Registration.Event'; |
|
153 | + parent::__construct($timezone); |
|
154 | + } |
|
155 | + |
|
156 | + |
|
157 | + /** |
|
158 | + * txn_status_array |
|
159 | + * get list of transaction statuses |
|
160 | + * |
|
161 | + * @access public |
|
162 | + * @return array |
|
163 | + */ |
|
164 | + public static function txn_status_array() |
|
165 | + { |
|
166 | + return apply_filters( |
|
167 | + 'FHEE__EEM_Transaction__txn_status_array', |
|
168 | + array( |
|
169 | + EEM_Transaction::overpaid_status_code, |
|
170 | + EEM_Transaction::complete_status_code, |
|
171 | + EEM_Transaction::incomplete_status_code, |
|
172 | + EEM_Transaction::abandoned_status_code, |
|
173 | + EEM_Transaction::failed_status_code, |
|
174 | + ) |
|
175 | + ); |
|
176 | + } |
|
177 | + |
|
178 | + /** |
|
179 | + * get the revenue per day for the Transaction Admin page Reports Tab |
|
180 | + * |
|
181 | + * @access public |
|
182 | + * |
|
183 | + * @param string $period |
|
184 | + * |
|
185 | + * @return \stdClass[] |
|
186 | + */ |
|
187 | + public function get_revenue_per_day_report($period = '-1 month') |
|
188 | + { |
|
189 | + $sql_date = $this->convert_datetime_for_query( |
|
190 | + 'TXN_timestamp', |
|
191 | + date('Y-m-d H:i:s', strtotime($period)), |
|
192 | + 'Y-m-d H:i:s', |
|
193 | + 'UTC' |
|
194 | + ); |
|
195 | + |
|
196 | + $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'TXN_timestamp'); |
|
197 | + |
|
198 | + return $this->_get_all_wpdb_results( |
|
199 | + array( |
|
200 | + array( |
|
201 | + 'TXN_timestamp' => array('>=', $sql_date) |
|
202 | + ), |
|
203 | + 'group_by' => 'txnDate', |
|
204 | + 'order_by' => array('TXN_timestamp' => 'ASC') |
|
205 | + ), |
|
206 | + OBJECT, |
|
207 | + array( |
|
208 | + 'txnDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
209 | + 'revenue' => array('SUM(TransactionTable.TXN_paid)', '%d') |
|
210 | + ) |
|
211 | + ); |
|
212 | + } |
|
213 | + |
|
214 | + |
|
215 | + /** |
|
216 | + * get the revenue per event for the Transaction Admin page Reports Tab |
|
217 | + * |
|
218 | + * @access public |
|
219 | + * |
|
220 | + * @param string $period |
|
221 | + * |
|
222 | + * @throws \EE_Error |
|
223 | + * @return mixed |
|
224 | + */ |
|
225 | + public function get_revenue_per_event_report($period = '-1 month') |
|
226 | + { |
|
227 | + global $wpdb; |
|
228 | + $transaction_table = $wpdb->prefix . 'esp_transaction'; |
|
229 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
230 | + $registration_payment_table = $wpdb->prefix . 'esp_registration_payment'; |
|
231 | + $event_table = $wpdb->posts; |
|
232 | + $payment_table = $wpdb->prefix . 'esp_payment'; |
|
233 | + $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
234 | + $approved_payment_status = EEM_Payment::status_id_approved; |
|
235 | + $extra_event_on_join = ''; |
|
236 | + // exclude events not authored by user if permissions in effect |
|
237 | + if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
238 | + $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id(); |
|
239 | + } |
|
240 | + |
|
241 | + return $wpdb->get_results( |
|
242 | + "SELECT |
|
243 | 243 | Transaction_Event.event_name AS event_name, |
244 | 244 | SUM(Transaction_Event.paid) AS revenue |
245 | 245 | FROM |
@@ -267,233 +267,233 @@ discard block |
||
267 | 267 | $extra_event_on_join |
268 | 268 | ) AS Transaction_Event |
269 | 269 | GROUP BY event_name", |
270 | - OBJECT |
|
271 | - ); |
|
272 | - } |
|
273 | - |
|
274 | - |
|
275 | - /** |
|
276 | - * Gets the current transaction given the reg_url_link, or assumes the reg_url_link is in the |
|
277 | - * $_REQUEST global variable. Either way, tries to find the current transaction (through |
|
278 | - * the registration pointed to by reg_url_link), if not returns null |
|
279 | - * |
|
280 | - * @param string $reg_url_link |
|
281 | - * |
|
282 | - * @return EE_Transaction |
|
283 | - */ |
|
284 | - public function get_transaction_from_reg_url_link($reg_url_link = '') |
|
285 | - { |
|
286 | - return $this->get_one(array( |
|
287 | - array( |
|
288 | - 'Registration.REG_url_link' => ! empty($reg_url_link) ? $reg_url_link : EE_Registry::instance()->REQ->get( |
|
289 | - 'e_reg_url_link', |
|
290 | - '' |
|
291 | - ) |
|
292 | - ) |
|
293 | - )); |
|
294 | - } |
|
295 | - |
|
296 | - |
|
297 | - /** |
|
298 | - * Updates the provided EE_Transaction with all the applicable payments |
|
299 | - * (or fetch the EE_Transaction from its ID) |
|
300 | - * |
|
301 | - * @deprecated |
|
302 | - * |
|
303 | - * @param EE_Transaction|int $transaction_obj_or_id |
|
304 | - * @param boolean $save_txn whether or not to save the transaction during this function call |
|
305 | - * |
|
306 | - * @return boolean |
|
307 | - * @throws \EE_Error |
|
308 | - */ |
|
309 | - public function update_based_on_payments($transaction_obj_or_id, $save_txn = true) |
|
310 | - { |
|
311 | - EE_Error::doing_it_wrong( |
|
312 | - __CLASS__ . '::' . __FUNCTION__, |
|
313 | - sprintf( |
|
314 | - __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
315 | - 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
|
316 | - ), |
|
317 | - '4.6.0' |
|
318 | - ); |
|
319 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
320 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
321 | - |
|
322 | - return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
323 | - $this->ensure_is_obj($transaction_obj_or_id) |
|
324 | - ); |
|
325 | - } |
|
326 | - |
|
327 | - /** |
|
328 | - * Deletes "junk" transactions that were probably added by bots. There might be TONS |
|
329 | - * of these, so we are very careful to NOT select (which the models do even when deleting), |
|
330 | - * and so we only use wpdb directly and only do minimal joins. |
|
331 | - * Transactions are considered "junk" if they're failed for longer than a week. |
|
332 | - * Also, there is an extra check for payments related to the transaction, because if a transaction has a payment on |
|
333 | - * it, it's probably not junk (regardless of what status it has). |
|
334 | - * The downside to this approach is that is addons are listening for object deletions |
|
335 | - * on EEM_Base::delete() they won't be notified of this. However, there is an action that plugins can hook into |
|
336 | - * to catch these types of deletions. |
|
337 | - * |
|
338 | - * @global WPDB $wpdb |
|
339 | - * @return mixed |
|
340 | - */ |
|
341 | - public function delete_junk_transactions() |
|
342 | - { |
|
343 | - /** @type WPDB $wpdb */ |
|
344 | - global $wpdb; |
|
345 | - $deleted = false; |
|
346 | - $time_to_leave_alone = apply_filters( |
|
347 | - 'FHEE__EEM_Transaction__delete_junk_transactions__time_to_leave_alone', |
|
348 | - WEEK_IN_SECONDS |
|
349 | - ); |
|
350 | - |
|
351 | - |
|
352 | - /** |
|
353 | - * This allows code to filter the query arguments used for retrieving the transaction IDs to delete. |
|
354 | - * Useful for plugins that want to exclude transactions matching certain query parameters. |
|
355 | - * The query parameters should be in the format accepted by the EEM_Base model queries. |
|
356 | - */ |
|
357 | - $ids_query = apply_filters( |
|
358 | - 'FHEE__EEM_Transaction__delete_junk_transactions__initial_query_args', |
|
359 | - array( |
|
360 | - 0 => array( |
|
361 | - 'STS_ID' => EEM_Transaction::failed_status_code, |
|
362 | - 'Payment.PAY_ID' => array( 'IS NULL' ), |
|
363 | - 'TXN_timestamp' => array('<', time() - $time_to_leave_alone) |
|
364 | - ), |
|
365 | - 'order_by' => ['TXN_timestamp' => 'ASC'], |
|
366 | - 'limit' => 1000 |
|
367 | - ), |
|
368 | - $time_to_leave_alone |
|
369 | - ); |
|
370 | - |
|
371 | - |
|
372 | - /** |
|
373 | - * This filter is for when code needs to filter the list of transaction ids that represent transactions |
|
374 | - * about to be deleted based on some other criteria that isn't easily done via the query args filter. |
|
375 | - */ |
|
376 | - $txn_ids = apply_filters( |
|
377 | - 'FHEE__EEM_Transaction__delete_junk_transactions__transaction_ids_to_delete', |
|
378 | - EEM_Transaction::instance()->get_col($ids_query, 'TXN_ID'), |
|
379 | - $time_to_leave_alone |
|
380 | - ); |
|
381 | - // now that we have the ids to delete |
|
382 | - if (! empty($txn_ids) && is_array($txn_ids)) { |
|
383 | - // first, make sure these TXN's are removed the "ee_locked_transactions" array |
|
384 | - EEM_Transaction::unset_locked_transactions($txn_ids); |
|
385 | - |
|
386 | - // Create IDs placeholder. |
|
387 | - $placeholders = array_fill(0, count($txn_ids), '%d'); |
|
270 | + OBJECT |
|
271 | + ); |
|
272 | + } |
|
273 | + |
|
274 | + |
|
275 | + /** |
|
276 | + * Gets the current transaction given the reg_url_link, or assumes the reg_url_link is in the |
|
277 | + * $_REQUEST global variable. Either way, tries to find the current transaction (through |
|
278 | + * the registration pointed to by reg_url_link), if not returns null |
|
279 | + * |
|
280 | + * @param string $reg_url_link |
|
281 | + * |
|
282 | + * @return EE_Transaction |
|
283 | + */ |
|
284 | + public function get_transaction_from_reg_url_link($reg_url_link = '') |
|
285 | + { |
|
286 | + return $this->get_one(array( |
|
287 | + array( |
|
288 | + 'Registration.REG_url_link' => ! empty($reg_url_link) ? $reg_url_link : EE_Registry::instance()->REQ->get( |
|
289 | + 'e_reg_url_link', |
|
290 | + '' |
|
291 | + ) |
|
292 | + ) |
|
293 | + )); |
|
294 | + } |
|
295 | + |
|
296 | + |
|
297 | + /** |
|
298 | + * Updates the provided EE_Transaction with all the applicable payments |
|
299 | + * (or fetch the EE_Transaction from its ID) |
|
300 | + * |
|
301 | + * @deprecated |
|
302 | + * |
|
303 | + * @param EE_Transaction|int $transaction_obj_or_id |
|
304 | + * @param boolean $save_txn whether or not to save the transaction during this function call |
|
305 | + * |
|
306 | + * @return boolean |
|
307 | + * @throws \EE_Error |
|
308 | + */ |
|
309 | + public function update_based_on_payments($transaction_obj_or_id, $save_txn = true) |
|
310 | + { |
|
311 | + EE_Error::doing_it_wrong( |
|
312 | + __CLASS__ . '::' . __FUNCTION__, |
|
313 | + sprintf( |
|
314 | + __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
315 | + 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
|
316 | + ), |
|
317 | + '4.6.0' |
|
318 | + ); |
|
319 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
320 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
321 | + |
|
322 | + return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
323 | + $this->ensure_is_obj($transaction_obj_or_id) |
|
324 | + ); |
|
325 | + } |
|
326 | + |
|
327 | + /** |
|
328 | + * Deletes "junk" transactions that were probably added by bots. There might be TONS |
|
329 | + * of these, so we are very careful to NOT select (which the models do even when deleting), |
|
330 | + * and so we only use wpdb directly and only do minimal joins. |
|
331 | + * Transactions are considered "junk" if they're failed for longer than a week. |
|
332 | + * Also, there is an extra check for payments related to the transaction, because if a transaction has a payment on |
|
333 | + * it, it's probably not junk (regardless of what status it has). |
|
334 | + * The downside to this approach is that is addons are listening for object deletions |
|
335 | + * on EEM_Base::delete() they won't be notified of this. However, there is an action that plugins can hook into |
|
336 | + * to catch these types of deletions. |
|
337 | + * |
|
338 | + * @global WPDB $wpdb |
|
339 | + * @return mixed |
|
340 | + */ |
|
341 | + public function delete_junk_transactions() |
|
342 | + { |
|
343 | + /** @type WPDB $wpdb */ |
|
344 | + global $wpdb; |
|
345 | + $deleted = false; |
|
346 | + $time_to_leave_alone = apply_filters( |
|
347 | + 'FHEE__EEM_Transaction__delete_junk_transactions__time_to_leave_alone', |
|
348 | + WEEK_IN_SECONDS |
|
349 | + ); |
|
350 | + |
|
351 | + |
|
352 | + /** |
|
353 | + * This allows code to filter the query arguments used for retrieving the transaction IDs to delete. |
|
354 | + * Useful for plugins that want to exclude transactions matching certain query parameters. |
|
355 | + * The query parameters should be in the format accepted by the EEM_Base model queries. |
|
356 | + */ |
|
357 | + $ids_query = apply_filters( |
|
358 | + 'FHEE__EEM_Transaction__delete_junk_transactions__initial_query_args', |
|
359 | + array( |
|
360 | + 0 => array( |
|
361 | + 'STS_ID' => EEM_Transaction::failed_status_code, |
|
362 | + 'Payment.PAY_ID' => array( 'IS NULL' ), |
|
363 | + 'TXN_timestamp' => array('<', time() - $time_to_leave_alone) |
|
364 | + ), |
|
365 | + 'order_by' => ['TXN_timestamp' => 'ASC'], |
|
366 | + 'limit' => 1000 |
|
367 | + ), |
|
368 | + $time_to_leave_alone |
|
369 | + ); |
|
370 | + |
|
371 | + |
|
372 | + /** |
|
373 | + * This filter is for when code needs to filter the list of transaction ids that represent transactions |
|
374 | + * about to be deleted based on some other criteria that isn't easily done via the query args filter. |
|
375 | + */ |
|
376 | + $txn_ids = apply_filters( |
|
377 | + 'FHEE__EEM_Transaction__delete_junk_transactions__transaction_ids_to_delete', |
|
378 | + EEM_Transaction::instance()->get_col($ids_query, 'TXN_ID'), |
|
379 | + $time_to_leave_alone |
|
380 | + ); |
|
381 | + // now that we have the ids to delete |
|
382 | + if (! empty($txn_ids) && is_array($txn_ids)) { |
|
383 | + // first, make sure these TXN's are removed the "ee_locked_transactions" array |
|
384 | + EEM_Transaction::unset_locked_transactions($txn_ids); |
|
385 | + |
|
386 | + // Create IDs placeholder. |
|
387 | + $placeholders = array_fill(0, count($txn_ids), '%d'); |
|
388 | 388 | |
389 | - // Glue it together to use inside $wpdb->prepare. |
|
390 | - $format = implode(', ', $placeholders); |
|
391 | - |
|
392 | - // let's get deletin'... |
|
393 | - // We got the ids from the original query to get them FROM |
|
394 | - // the db (which is sanitized) so no need to prepare them again. |
|
395 | - $query = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids); |
|
396 | - $deleted = $wpdb->query($query); |
|
397 | - } |
|
398 | - if ($deleted) { |
|
399 | - /** |
|
400 | - * Allows code to do something after the transactions have been deleted. |
|
401 | - */ |
|
402 | - do_action('AHEE__EEM_Transaction__delete_junk_transactions__successful_deletion', $txn_ids); |
|
403 | - } |
|
404 | - |
|
405 | - return $deleted; |
|
406 | - } |
|
407 | - |
|
408 | - |
|
409 | - /** |
|
410 | - * @param array $transaction_IDs |
|
411 | - * |
|
412 | - * @return bool |
|
413 | - */ |
|
414 | - public static function unset_locked_transactions(array $transaction_IDs) |
|
415 | - { |
|
416 | - $locked_transactions = get_option('ee_locked_transactions', array()); |
|
417 | - $update = false; |
|
418 | - foreach ($transaction_IDs as $TXN_ID) { |
|
419 | - if (isset($locked_transactions[ $TXN_ID ])) { |
|
420 | - unset($locked_transactions[ $TXN_ID ]); |
|
421 | - $update = true; |
|
422 | - } |
|
423 | - } |
|
424 | - if ($update) { |
|
425 | - update_option('ee_locked_transactions', $locked_transactions); |
|
426 | - } |
|
427 | - |
|
428 | - return $update; |
|
429 | - } |
|
430 | - |
|
431 | - |
|
432 | - |
|
433 | - /** |
|
434 | - * returns an array of EE_Transaction objects whose timestamp is greater than |
|
435 | - * the current time minus the session lifespan, which defaults to 60 minutes |
|
436 | - * |
|
437 | - * @return EE_Base_Class[]|EE_Transaction[] |
|
438 | - * @throws EE_Error |
|
439 | - * @throws InvalidArgumentException |
|
440 | - * @throws InvalidDataTypeException |
|
441 | - * @throws InvalidInterfaceException |
|
442 | - */ |
|
443 | - public function get_transactions_in_progress() |
|
444 | - { |
|
445 | - return $this->_get_transactions_in_progress(); |
|
446 | - } |
|
447 | - |
|
448 | - |
|
449 | - |
|
450 | - /** |
|
451 | - * returns an array of EE_Transaction objects whose timestamp is less than |
|
452 | - * the current time minus the session lifespan, which defaults to 60 minutes |
|
453 | - * |
|
454 | - * @return EE_Base_Class[]|EE_Transaction[] |
|
455 | - * @throws EE_Error |
|
456 | - * @throws InvalidArgumentException |
|
457 | - * @throws InvalidDataTypeException |
|
458 | - * @throws InvalidInterfaceException |
|
459 | - */ |
|
460 | - public function get_transactions_not_in_progress() |
|
461 | - { |
|
462 | - return $this->_get_transactions_in_progress('<='); |
|
463 | - } |
|
464 | - |
|
465 | - |
|
466 | - |
|
467 | - /** |
|
468 | - * @param string $comparison |
|
469 | - * @return EE_Base_Class[]|EE_Transaction[] |
|
470 | - * @throws EE_Error |
|
471 | - * @throws InvalidArgumentException |
|
472 | - * @throws InvalidDataTypeException |
|
473 | - * @throws InvalidInterfaceException |
|
474 | - */ |
|
475 | - private function _get_transactions_in_progress($comparison = '>=') |
|
476 | - { |
|
477 | - $comparison = $comparison === '>=' || $comparison === '<=' |
|
478 | - ? $comparison |
|
479 | - : '>='; |
|
480 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
481 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
482 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
483 | - ); |
|
484 | - return $this->get_all( |
|
485 | - array( |
|
486 | - array( |
|
487 | - 'TXN_timestamp' => array( |
|
488 | - $comparison, |
|
489 | - $session_lifespan->expiration() |
|
490 | - ), |
|
491 | - 'STS_ID' => array( |
|
492 | - '!=', |
|
493 | - EEM_Transaction::complete_status_code |
|
494 | - ), |
|
495 | - ) |
|
496 | - ) |
|
497 | - ); |
|
498 | - } |
|
389 | + // Glue it together to use inside $wpdb->prepare. |
|
390 | + $format = implode(', ', $placeholders); |
|
391 | + |
|
392 | + // let's get deletin'... |
|
393 | + // We got the ids from the original query to get them FROM |
|
394 | + // the db (which is sanitized) so no need to prepare them again. |
|
395 | + $query = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids); |
|
396 | + $deleted = $wpdb->query($query); |
|
397 | + } |
|
398 | + if ($deleted) { |
|
399 | + /** |
|
400 | + * Allows code to do something after the transactions have been deleted. |
|
401 | + */ |
|
402 | + do_action('AHEE__EEM_Transaction__delete_junk_transactions__successful_deletion', $txn_ids); |
|
403 | + } |
|
404 | + |
|
405 | + return $deleted; |
|
406 | + } |
|
407 | + |
|
408 | + |
|
409 | + /** |
|
410 | + * @param array $transaction_IDs |
|
411 | + * |
|
412 | + * @return bool |
|
413 | + */ |
|
414 | + public static function unset_locked_transactions(array $transaction_IDs) |
|
415 | + { |
|
416 | + $locked_transactions = get_option('ee_locked_transactions', array()); |
|
417 | + $update = false; |
|
418 | + foreach ($transaction_IDs as $TXN_ID) { |
|
419 | + if (isset($locked_transactions[ $TXN_ID ])) { |
|
420 | + unset($locked_transactions[ $TXN_ID ]); |
|
421 | + $update = true; |
|
422 | + } |
|
423 | + } |
|
424 | + if ($update) { |
|
425 | + update_option('ee_locked_transactions', $locked_transactions); |
|
426 | + } |
|
427 | + |
|
428 | + return $update; |
|
429 | + } |
|
430 | + |
|
431 | + |
|
432 | + |
|
433 | + /** |
|
434 | + * returns an array of EE_Transaction objects whose timestamp is greater than |
|
435 | + * the current time minus the session lifespan, which defaults to 60 minutes |
|
436 | + * |
|
437 | + * @return EE_Base_Class[]|EE_Transaction[] |
|
438 | + * @throws EE_Error |
|
439 | + * @throws InvalidArgumentException |
|
440 | + * @throws InvalidDataTypeException |
|
441 | + * @throws InvalidInterfaceException |
|
442 | + */ |
|
443 | + public function get_transactions_in_progress() |
|
444 | + { |
|
445 | + return $this->_get_transactions_in_progress(); |
|
446 | + } |
|
447 | + |
|
448 | + |
|
449 | + |
|
450 | + /** |
|
451 | + * returns an array of EE_Transaction objects whose timestamp is less than |
|
452 | + * the current time minus the session lifespan, which defaults to 60 minutes |
|
453 | + * |
|
454 | + * @return EE_Base_Class[]|EE_Transaction[] |
|
455 | + * @throws EE_Error |
|
456 | + * @throws InvalidArgumentException |
|
457 | + * @throws InvalidDataTypeException |
|
458 | + * @throws InvalidInterfaceException |
|
459 | + */ |
|
460 | + public function get_transactions_not_in_progress() |
|
461 | + { |
|
462 | + return $this->_get_transactions_in_progress('<='); |
|
463 | + } |
|
464 | + |
|
465 | + |
|
466 | + |
|
467 | + /** |
|
468 | + * @param string $comparison |
|
469 | + * @return EE_Base_Class[]|EE_Transaction[] |
|
470 | + * @throws EE_Error |
|
471 | + * @throws InvalidArgumentException |
|
472 | + * @throws InvalidDataTypeException |
|
473 | + * @throws InvalidInterfaceException |
|
474 | + */ |
|
475 | + private function _get_transactions_in_progress($comparison = '>=') |
|
476 | + { |
|
477 | + $comparison = $comparison === '>=' || $comparison === '<=' |
|
478 | + ? $comparison |
|
479 | + : '>='; |
|
480 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
481 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
482 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
483 | + ); |
|
484 | + return $this->get_all( |
|
485 | + array( |
|
486 | + array( |
|
487 | + 'TXN_timestamp' => array( |
|
488 | + $comparison, |
|
489 | + $session_lifespan->expiration() |
|
490 | + ), |
|
491 | + 'STS_ID' => array( |
|
492 | + '!=', |
|
493 | + EEM_Transaction::complete_status_code |
|
494 | + ), |
|
495 | + ) |
|
496 | + ) |
|
497 | + ); |
|
498 | + } |
|
499 | 499 | } |
@@ -140,7 +140,7 @@ discard block |
||
140 | 140 | ), |
141 | 141 | ) |
142 | 142 | ); |
143 | - $this->_model_relations = array( |
|
143 | + $this->_model_relations = array( |
|
144 | 144 | 'Registration' => new EE_Has_Many_Relation(), |
145 | 145 | 'Payment' => new EE_Has_Many_Relation(), |
146 | 146 | 'Status' => new EE_Belongs_To_Relation(), |
@@ -205,7 +205,7 @@ discard block |
||
205 | 205 | ), |
206 | 206 | OBJECT, |
207 | 207 | array( |
208 | - 'txnDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
208 | + 'txnDate' => array('DATE('.$query_interval.')', '%s'), |
|
209 | 209 | 'revenue' => array('SUM(TransactionTable.TXN_paid)', '%d') |
210 | 210 | ) |
211 | 211 | ); |
@@ -225,17 +225,17 @@ discard block |
||
225 | 225 | public function get_revenue_per_event_report($period = '-1 month') |
226 | 226 | { |
227 | 227 | global $wpdb; |
228 | - $transaction_table = $wpdb->prefix . 'esp_transaction'; |
|
229 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
230 | - $registration_payment_table = $wpdb->prefix . 'esp_registration_payment'; |
|
228 | + $transaction_table = $wpdb->prefix.'esp_transaction'; |
|
229 | + $registration_table = $wpdb->prefix.'esp_registration'; |
|
230 | + $registration_payment_table = $wpdb->prefix.'esp_registration_payment'; |
|
231 | 231 | $event_table = $wpdb->posts; |
232 | - $payment_table = $wpdb->prefix . 'esp_payment'; |
|
232 | + $payment_table = $wpdb->prefix.'esp_payment'; |
|
233 | 233 | $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
234 | 234 | $approved_payment_status = EEM_Payment::status_id_approved; |
235 | 235 | $extra_event_on_join = ''; |
236 | 236 | // exclude events not authored by user if permissions in effect |
237 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
238 | - $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id(); |
|
237 | + if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
238 | + $extra_event_on_join = ' AND Event.post_author = '.get_current_user_id(); |
|
239 | 239 | } |
240 | 240 | |
241 | 241 | return $wpdb->get_results( |
@@ -309,7 +309,7 @@ discard block |
||
309 | 309 | public function update_based_on_payments($transaction_obj_or_id, $save_txn = true) |
310 | 310 | { |
311 | 311 | EE_Error::doing_it_wrong( |
312 | - __CLASS__ . '::' . __FUNCTION__, |
|
312 | + __CLASS__.'::'.__FUNCTION__, |
|
313 | 313 | sprintf( |
314 | 314 | __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
315 | 315 | 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
@@ -359,7 +359,7 @@ discard block |
||
359 | 359 | array( |
360 | 360 | 0 => array( |
361 | 361 | 'STS_ID' => EEM_Transaction::failed_status_code, |
362 | - 'Payment.PAY_ID' => array( 'IS NULL' ), |
|
362 | + 'Payment.PAY_ID' => array('IS NULL'), |
|
363 | 363 | 'TXN_timestamp' => array('<', time() - $time_to_leave_alone) |
364 | 364 | ), |
365 | 365 | 'order_by' => ['TXN_timestamp' => 'ASC'], |
@@ -379,7 +379,7 @@ discard block |
||
379 | 379 | $time_to_leave_alone |
380 | 380 | ); |
381 | 381 | // now that we have the ids to delete |
382 | - if (! empty($txn_ids) && is_array($txn_ids)) { |
|
382 | + if ( ! empty($txn_ids) && is_array($txn_ids)) { |
|
383 | 383 | // first, make sure these TXN's are removed the "ee_locked_transactions" array |
384 | 384 | EEM_Transaction::unset_locked_transactions($txn_ids); |
385 | 385 | |
@@ -392,7 +392,7 @@ discard block |
||
392 | 392 | // let's get deletin'... |
393 | 393 | // We got the ids from the original query to get them FROM |
394 | 394 | // the db (which is sanitized) so no need to prepare them again. |
395 | - $query = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids); |
|
395 | + $query = $wpdb->prepare("DELETE FROM ".$this->table()." WHERE TXN_ID IN ( $format )", $txn_ids); |
|
396 | 396 | $deleted = $wpdb->query($query); |
397 | 397 | } |
398 | 398 | if ($deleted) { |
@@ -416,8 +416,8 @@ discard block |
||
416 | 416 | $locked_transactions = get_option('ee_locked_transactions', array()); |
417 | 417 | $update = false; |
418 | 418 | foreach ($transaction_IDs as $TXN_ID) { |
419 | - if (isset($locked_transactions[ $TXN_ID ])) { |
|
420 | - unset($locked_transactions[ $TXN_ID ]); |
|
419 | + if (isset($locked_transactions[$TXN_ID])) { |
|
420 | + unset($locked_transactions[$TXN_ID]); |
|
421 | 421 | $update = true; |
422 | 422 | } |
423 | 423 | } |
@@ -16,1267 +16,1267 @@ |
||
16 | 16 | { |
17 | 17 | |
18 | 18 | |
19 | - /** |
|
20 | - * This is used to hold the reports template data which is setup early in the request. |
|
21 | - * |
|
22 | - * @type array |
|
23 | - */ |
|
24 | - protected $_reports_template_data = array(); |
|
19 | + /** |
|
20 | + * This is used to hold the reports template data which is setup early in the request. |
|
21 | + * |
|
22 | + * @type array |
|
23 | + */ |
|
24 | + protected $_reports_template_data = array(); |
|
25 | 25 | |
26 | 26 | |
27 | - /** |
|
28 | - * Extend_Registrations_Admin_Page constructor. |
|
29 | - * |
|
30 | - * @param bool $routing |
|
31 | - */ |
|
32 | - public function __construct($routing = true) |
|
33 | - { |
|
34 | - parent::__construct($routing); |
|
35 | - if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
36 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
37 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
38 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
39 | - } |
|
40 | - } |
|
27 | + /** |
|
28 | + * Extend_Registrations_Admin_Page constructor. |
|
29 | + * |
|
30 | + * @param bool $routing |
|
31 | + */ |
|
32 | + public function __construct($routing = true) |
|
33 | + { |
|
34 | + parent::__construct($routing); |
|
35 | + if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
36 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
37 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
38 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
39 | + } |
|
40 | + } |
|
41 | 41 | |
42 | 42 | |
43 | - /** |
|
44 | - * Extending page configuration. |
|
45 | - */ |
|
46 | - protected function _extend_page_config() |
|
47 | - { |
|
48 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
49 | - $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
50 | - ? $this->_req_data['_REG_ID'] |
|
51 | - : 0; |
|
52 | - $new_page_routes = array( |
|
53 | - 'reports' => array( |
|
54 | - 'func' => '_registration_reports', |
|
55 | - 'capability' => 'ee_read_registrations', |
|
56 | - ), |
|
57 | - 'registration_checkins' => array( |
|
58 | - 'func' => '_registration_checkin_list_table', |
|
59 | - 'capability' => 'ee_read_checkins', |
|
60 | - ), |
|
61 | - 'newsletter_selected_send' => array( |
|
62 | - 'func' => '_newsletter_selected_send', |
|
63 | - 'noheader' => true, |
|
64 | - 'capability' => 'ee_send_message', |
|
65 | - ), |
|
66 | - 'delete_checkin_rows' => array( |
|
67 | - 'func' => '_delete_checkin_rows', |
|
68 | - 'noheader' => true, |
|
69 | - 'capability' => 'ee_delete_checkins', |
|
70 | - ), |
|
71 | - 'delete_checkin_row' => array( |
|
72 | - 'func' => '_delete_checkin_row', |
|
73 | - 'noheader' => true, |
|
74 | - 'capability' => 'ee_delete_checkin', |
|
75 | - 'obj_id' => $reg_id, |
|
76 | - ), |
|
77 | - 'toggle_checkin_status' => array( |
|
78 | - 'func' => '_toggle_checkin_status', |
|
79 | - 'noheader' => true, |
|
80 | - 'capability' => 'ee_edit_checkin', |
|
81 | - 'obj_id' => $reg_id, |
|
82 | - ), |
|
83 | - 'toggle_checkin_status_bulk' => array( |
|
84 | - 'func' => '_toggle_checkin_status', |
|
85 | - 'noheader' => true, |
|
86 | - 'capability' => 'ee_edit_checkins', |
|
87 | - ), |
|
88 | - 'event_registrations' => array( |
|
89 | - 'func' => '_event_registrations_list_table', |
|
90 | - 'capability' => 'ee_read_checkins', |
|
91 | - ), |
|
92 | - 'registrations_checkin_report' => array( |
|
93 | - 'func' => '_registrations_checkin_report', |
|
94 | - 'noheader' => true, |
|
95 | - 'capability' => 'ee_read_registrations', |
|
96 | - ), |
|
97 | - ); |
|
98 | - $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
99 | - $new_page_config = array( |
|
100 | - 'reports' => array( |
|
101 | - 'nav' => array( |
|
102 | - 'label' => esc_html__('Reports', 'event_espresso'), |
|
103 | - 'order' => 30, |
|
104 | - ), |
|
105 | - 'help_tabs' => array( |
|
106 | - 'registrations_reports_help_tab' => array( |
|
107 | - 'title' => esc_html__('Registration Reports', 'event_espresso'), |
|
108 | - 'filename' => 'registrations_reports', |
|
109 | - ), |
|
110 | - ), |
|
111 | - /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
112 | - 'require_nonce' => false, |
|
113 | - ), |
|
114 | - 'event_registrations' => array( |
|
115 | - 'nav' => array( |
|
116 | - 'label' => esc_html__('Event Check-In', 'event_espresso'), |
|
117 | - 'order' => 10, |
|
118 | - 'persistent' => true, |
|
119 | - ), |
|
120 | - 'help_tabs' => array( |
|
121 | - 'registrations_event_checkin_help_tab' => array( |
|
122 | - 'title' => esc_html__('Registrations Event Check-In', 'event_espresso'), |
|
123 | - 'filename' => 'registrations_event_checkin', |
|
124 | - ), |
|
125 | - 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
126 | - 'title' => esc_html__('Event Check-In Table Column Headings', 'event_espresso'), |
|
127 | - 'filename' => 'registrations_event_checkin_table_column_headings', |
|
128 | - ), |
|
129 | - 'registrations_event_checkin_filters_help_tab' => array( |
|
130 | - 'title' => esc_html__('Event Check-In Filters', 'event_espresso'), |
|
131 | - 'filename' => 'registrations_event_checkin_filters', |
|
132 | - ), |
|
133 | - 'registrations_event_checkin_views_help_tab' => array( |
|
134 | - 'title' => esc_html__('Event Check-In Views', 'event_espresso'), |
|
135 | - 'filename' => 'registrations_event_checkin_views', |
|
136 | - ), |
|
137 | - 'registrations_event_checkin_other_help_tab' => array( |
|
138 | - 'title' => esc_html__('Event Check-In Other', 'event_espresso'), |
|
139 | - 'filename' => 'registrations_event_checkin_other', |
|
140 | - ), |
|
141 | - ), |
|
142 | - 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
143 | - 'qtips' => array('Registration_List_Table_Tips'), |
|
144 | - 'list_table' => 'EE_Event_Registrations_List_Table', |
|
145 | - 'metaboxes' => array(), |
|
146 | - 'require_nonce' => false, |
|
147 | - ), |
|
148 | - 'registration_checkins' => array( |
|
149 | - 'nav' => array( |
|
150 | - 'label' => esc_html__('Check-In Records', 'event_espresso'), |
|
151 | - 'order' => 15, |
|
152 | - 'persistent' => false, |
|
153 | - 'url' => '', |
|
154 | - ), |
|
155 | - 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
156 | - // 'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
157 | - 'metaboxes' => array(), |
|
158 | - 'require_nonce' => false, |
|
159 | - ), |
|
160 | - ); |
|
161 | - $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
162 | - $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
163 | - $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
164 | - } |
|
43 | + /** |
|
44 | + * Extending page configuration. |
|
45 | + */ |
|
46 | + protected function _extend_page_config() |
|
47 | + { |
|
48 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
49 | + $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
50 | + ? $this->_req_data['_REG_ID'] |
|
51 | + : 0; |
|
52 | + $new_page_routes = array( |
|
53 | + 'reports' => array( |
|
54 | + 'func' => '_registration_reports', |
|
55 | + 'capability' => 'ee_read_registrations', |
|
56 | + ), |
|
57 | + 'registration_checkins' => array( |
|
58 | + 'func' => '_registration_checkin_list_table', |
|
59 | + 'capability' => 'ee_read_checkins', |
|
60 | + ), |
|
61 | + 'newsletter_selected_send' => array( |
|
62 | + 'func' => '_newsletter_selected_send', |
|
63 | + 'noheader' => true, |
|
64 | + 'capability' => 'ee_send_message', |
|
65 | + ), |
|
66 | + 'delete_checkin_rows' => array( |
|
67 | + 'func' => '_delete_checkin_rows', |
|
68 | + 'noheader' => true, |
|
69 | + 'capability' => 'ee_delete_checkins', |
|
70 | + ), |
|
71 | + 'delete_checkin_row' => array( |
|
72 | + 'func' => '_delete_checkin_row', |
|
73 | + 'noheader' => true, |
|
74 | + 'capability' => 'ee_delete_checkin', |
|
75 | + 'obj_id' => $reg_id, |
|
76 | + ), |
|
77 | + 'toggle_checkin_status' => array( |
|
78 | + 'func' => '_toggle_checkin_status', |
|
79 | + 'noheader' => true, |
|
80 | + 'capability' => 'ee_edit_checkin', |
|
81 | + 'obj_id' => $reg_id, |
|
82 | + ), |
|
83 | + 'toggle_checkin_status_bulk' => array( |
|
84 | + 'func' => '_toggle_checkin_status', |
|
85 | + 'noheader' => true, |
|
86 | + 'capability' => 'ee_edit_checkins', |
|
87 | + ), |
|
88 | + 'event_registrations' => array( |
|
89 | + 'func' => '_event_registrations_list_table', |
|
90 | + 'capability' => 'ee_read_checkins', |
|
91 | + ), |
|
92 | + 'registrations_checkin_report' => array( |
|
93 | + 'func' => '_registrations_checkin_report', |
|
94 | + 'noheader' => true, |
|
95 | + 'capability' => 'ee_read_registrations', |
|
96 | + ), |
|
97 | + ); |
|
98 | + $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
99 | + $new_page_config = array( |
|
100 | + 'reports' => array( |
|
101 | + 'nav' => array( |
|
102 | + 'label' => esc_html__('Reports', 'event_espresso'), |
|
103 | + 'order' => 30, |
|
104 | + ), |
|
105 | + 'help_tabs' => array( |
|
106 | + 'registrations_reports_help_tab' => array( |
|
107 | + 'title' => esc_html__('Registration Reports', 'event_espresso'), |
|
108 | + 'filename' => 'registrations_reports', |
|
109 | + ), |
|
110 | + ), |
|
111 | + /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
112 | + 'require_nonce' => false, |
|
113 | + ), |
|
114 | + 'event_registrations' => array( |
|
115 | + 'nav' => array( |
|
116 | + 'label' => esc_html__('Event Check-In', 'event_espresso'), |
|
117 | + 'order' => 10, |
|
118 | + 'persistent' => true, |
|
119 | + ), |
|
120 | + 'help_tabs' => array( |
|
121 | + 'registrations_event_checkin_help_tab' => array( |
|
122 | + 'title' => esc_html__('Registrations Event Check-In', 'event_espresso'), |
|
123 | + 'filename' => 'registrations_event_checkin', |
|
124 | + ), |
|
125 | + 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
126 | + 'title' => esc_html__('Event Check-In Table Column Headings', 'event_espresso'), |
|
127 | + 'filename' => 'registrations_event_checkin_table_column_headings', |
|
128 | + ), |
|
129 | + 'registrations_event_checkin_filters_help_tab' => array( |
|
130 | + 'title' => esc_html__('Event Check-In Filters', 'event_espresso'), |
|
131 | + 'filename' => 'registrations_event_checkin_filters', |
|
132 | + ), |
|
133 | + 'registrations_event_checkin_views_help_tab' => array( |
|
134 | + 'title' => esc_html__('Event Check-In Views', 'event_espresso'), |
|
135 | + 'filename' => 'registrations_event_checkin_views', |
|
136 | + ), |
|
137 | + 'registrations_event_checkin_other_help_tab' => array( |
|
138 | + 'title' => esc_html__('Event Check-In Other', 'event_espresso'), |
|
139 | + 'filename' => 'registrations_event_checkin_other', |
|
140 | + ), |
|
141 | + ), |
|
142 | + 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
143 | + 'qtips' => array('Registration_List_Table_Tips'), |
|
144 | + 'list_table' => 'EE_Event_Registrations_List_Table', |
|
145 | + 'metaboxes' => array(), |
|
146 | + 'require_nonce' => false, |
|
147 | + ), |
|
148 | + 'registration_checkins' => array( |
|
149 | + 'nav' => array( |
|
150 | + 'label' => esc_html__('Check-In Records', 'event_espresso'), |
|
151 | + 'order' => 15, |
|
152 | + 'persistent' => false, |
|
153 | + 'url' => '', |
|
154 | + ), |
|
155 | + 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
156 | + // 'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
157 | + 'metaboxes' => array(), |
|
158 | + 'require_nonce' => false, |
|
159 | + ), |
|
160 | + ); |
|
161 | + $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
162 | + $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
163 | + $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
164 | + } |
|
165 | 165 | |
166 | 166 | |
167 | - /** |
|
168 | - * Ajax hooks for all routes in this page. |
|
169 | - */ |
|
170 | - protected function _ajax_hooks() |
|
171 | - { |
|
172 | - parent::_ajax_hooks(); |
|
173 | - add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
174 | - } |
|
167 | + /** |
|
168 | + * Ajax hooks for all routes in this page. |
|
169 | + */ |
|
170 | + protected function _ajax_hooks() |
|
171 | + { |
|
172 | + parent::_ajax_hooks(); |
|
173 | + add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
174 | + } |
|
175 | 175 | |
176 | 176 | |
177 | - /** |
|
178 | - * Global scripts for all routes in this page. |
|
179 | - */ |
|
180 | - public function load_scripts_styles() |
|
181 | - { |
|
182 | - parent::load_scripts_styles(); |
|
183 | - // if newsletter message type is active then let's add filter and load js for it. |
|
184 | - if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
185 | - // enqueue newsletter js |
|
186 | - wp_enqueue_script( |
|
187 | - 'ee-newsletter-trigger', |
|
188 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
189 | - array('ee-dialog'), |
|
190 | - EVENT_ESPRESSO_VERSION, |
|
191 | - true |
|
192 | - ); |
|
193 | - wp_enqueue_style( |
|
194 | - 'ee-newsletter-trigger-css', |
|
195 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
196 | - array(), |
|
197 | - EVENT_ESPRESSO_VERSION |
|
198 | - ); |
|
199 | - // hook in buttons for newsletter message type trigger. |
|
200 | - add_action( |
|
201 | - 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
202 | - array($this, 'add_newsletter_action_buttons'), |
|
203 | - 10 |
|
204 | - ); |
|
205 | - } |
|
206 | - } |
|
177 | + /** |
|
178 | + * Global scripts for all routes in this page. |
|
179 | + */ |
|
180 | + public function load_scripts_styles() |
|
181 | + { |
|
182 | + parent::load_scripts_styles(); |
|
183 | + // if newsletter message type is active then let's add filter and load js for it. |
|
184 | + if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
185 | + // enqueue newsletter js |
|
186 | + wp_enqueue_script( |
|
187 | + 'ee-newsletter-trigger', |
|
188 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
189 | + array('ee-dialog'), |
|
190 | + EVENT_ESPRESSO_VERSION, |
|
191 | + true |
|
192 | + ); |
|
193 | + wp_enqueue_style( |
|
194 | + 'ee-newsletter-trigger-css', |
|
195 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
196 | + array(), |
|
197 | + EVENT_ESPRESSO_VERSION |
|
198 | + ); |
|
199 | + // hook in buttons for newsletter message type trigger. |
|
200 | + add_action( |
|
201 | + 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
202 | + array($this, 'add_newsletter_action_buttons'), |
|
203 | + 10 |
|
204 | + ); |
|
205 | + } |
|
206 | + } |
|
207 | 207 | |
208 | 208 | |
209 | - /** |
|
210 | - * Scripts and styles for just the reports route. |
|
211 | - */ |
|
212 | - public function load_scripts_styles_reports() |
|
213 | - { |
|
214 | - wp_register_script( |
|
215 | - 'ee-reg-reports-js', |
|
216 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
217 | - array('google-charts'), |
|
218 | - EVENT_ESPRESSO_VERSION, |
|
219 | - true |
|
220 | - ); |
|
221 | - wp_enqueue_script('ee-reg-reports-js'); |
|
222 | - $this->_registration_reports_js_setup(); |
|
223 | - } |
|
209 | + /** |
|
210 | + * Scripts and styles for just the reports route. |
|
211 | + */ |
|
212 | + public function load_scripts_styles_reports() |
|
213 | + { |
|
214 | + wp_register_script( |
|
215 | + 'ee-reg-reports-js', |
|
216 | + REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
217 | + array('google-charts'), |
|
218 | + EVENT_ESPRESSO_VERSION, |
|
219 | + true |
|
220 | + ); |
|
221 | + wp_enqueue_script('ee-reg-reports-js'); |
|
222 | + $this->_registration_reports_js_setup(); |
|
223 | + } |
|
224 | 224 | |
225 | 225 | |
226 | - /** |
|
227 | - * Register screen options for event_registrations route. |
|
228 | - */ |
|
229 | - protected function _add_screen_options_event_registrations() |
|
230 | - { |
|
231 | - $this->_per_page_screen_option(); |
|
232 | - } |
|
226 | + /** |
|
227 | + * Register screen options for event_registrations route. |
|
228 | + */ |
|
229 | + protected function _add_screen_options_event_registrations() |
|
230 | + { |
|
231 | + $this->_per_page_screen_option(); |
|
232 | + } |
|
233 | 233 | |
234 | 234 | |
235 | - /** |
|
236 | - * Register screen options for registration_checkins route |
|
237 | - */ |
|
238 | - protected function _add_screen_options_registration_checkins() |
|
239 | - { |
|
240 | - $page_title = $this->_admin_page_title; |
|
241 | - $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso'); |
|
242 | - $this->_per_page_screen_option(); |
|
243 | - $this->_admin_page_title = $page_title; |
|
244 | - } |
|
235 | + /** |
|
236 | + * Register screen options for registration_checkins route |
|
237 | + */ |
|
238 | + protected function _add_screen_options_registration_checkins() |
|
239 | + { |
|
240 | + $page_title = $this->_admin_page_title; |
|
241 | + $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso'); |
|
242 | + $this->_per_page_screen_option(); |
|
243 | + $this->_admin_page_title = $page_title; |
|
244 | + } |
|
245 | 245 | |
246 | 246 | |
247 | - /** |
|
248 | - * Set views property for event_registrations route. |
|
249 | - */ |
|
250 | - protected function _set_list_table_views_event_registrations() |
|
251 | - { |
|
252 | - $this->_views = array( |
|
253 | - 'all' => array( |
|
254 | - 'slug' => 'all', |
|
255 | - 'label' => esc_html__('All', 'event_espresso'), |
|
256 | - 'count' => 0, |
|
257 | - 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
258 | - ? array() |
|
259 | - : array( |
|
260 | - 'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'), |
|
261 | - ), |
|
262 | - ), |
|
263 | - ); |
|
264 | - } |
|
247 | + /** |
|
248 | + * Set views property for event_registrations route. |
|
249 | + */ |
|
250 | + protected function _set_list_table_views_event_registrations() |
|
251 | + { |
|
252 | + $this->_views = array( |
|
253 | + 'all' => array( |
|
254 | + 'slug' => 'all', |
|
255 | + 'label' => esc_html__('All', 'event_espresso'), |
|
256 | + 'count' => 0, |
|
257 | + 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
258 | + ? array() |
|
259 | + : array( |
|
260 | + 'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'), |
|
261 | + ), |
|
262 | + ), |
|
263 | + ); |
|
264 | + } |
|
265 | 265 | |
266 | 266 | |
267 | - /** |
|
268 | - * Set views property for registration_checkins route. |
|
269 | - */ |
|
270 | - protected function _set_list_table_views_registration_checkins() |
|
271 | - { |
|
272 | - $this->_views = array( |
|
273 | - 'all' => array( |
|
274 | - 'slug' => 'all', |
|
275 | - 'label' => esc_html__('All', 'event_espresso'), |
|
276 | - 'count' => 0, |
|
277 | - 'bulk_action' => array('delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')), |
|
278 | - ), |
|
279 | - ); |
|
280 | - } |
|
267 | + /** |
|
268 | + * Set views property for registration_checkins route. |
|
269 | + */ |
|
270 | + protected function _set_list_table_views_registration_checkins() |
|
271 | + { |
|
272 | + $this->_views = array( |
|
273 | + 'all' => array( |
|
274 | + 'slug' => 'all', |
|
275 | + 'label' => esc_html__('All', 'event_espresso'), |
|
276 | + 'count' => 0, |
|
277 | + 'bulk_action' => array('delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')), |
|
278 | + ), |
|
279 | + ); |
|
280 | + } |
|
281 | 281 | |
282 | 282 | |
283 | - /** |
|
284 | - * callback for ajax action. |
|
285 | - * |
|
286 | - * @since 4.3.0 |
|
287 | - * @return void (JSON) |
|
288 | - * @throws EE_Error |
|
289 | - * @throws InvalidArgumentException |
|
290 | - * @throws InvalidDataTypeException |
|
291 | - * @throws InvalidInterfaceException |
|
292 | - */ |
|
293 | - public function get_newsletter_form_content() |
|
294 | - { |
|
295 | - // do a nonce check cause we're not coming in from an normal route here. |
|
296 | - $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
297 | - $this->_req_data['get_newsletter_form_content_nonce'] |
|
298 | - ) : ''; |
|
299 | - $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
300 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
301 | - // let's get the mtp for the incoming MTP_ ID |
|
302 | - if (! isset($this->_req_data['GRP_ID'])) { |
|
303 | - EE_Error::add_error( |
|
304 | - esc_html__( |
|
305 | - 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
|
306 | - 'event_espresso' |
|
307 | - ), |
|
308 | - __FILE__, |
|
309 | - __FUNCTION__, |
|
310 | - __LINE__ |
|
311 | - ); |
|
312 | - $this->_template_args['success'] = false; |
|
313 | - $this->_template_args['error'] = true; |
|
314 | - $this->_return_json(); |
|
315 | - } |
|
316 | - $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
317 | - if (! $MTPG instanceof EE_Message_Template_Group) { |
|
318 | - EE_Error::add_error( |
|
319 | - sprintf( |
|
320 | - esc_html__( |
|
321 | - 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
322 | - 'event_espresso' |
|
323 | - ), |
|
324 | - $this->_req_data['GRP_ID'] |
|
325 | - ), |
|
326 | - __FILE__, |
|
327 | - __FUNCTION__, |
|
328 | - __LINE__ |
|
329 | - ); |
|
330 | - $this->_template_args['success'] = false; |
|
331 | - $this->_template_args['error'] = true; |
|
332 | - $this->_return_json(); |
|
333 | - } |
|
334 | - $MTPs = $MTPG->context_templates(); |
|
335 | - $MTPs = $MTPs['attendee']; |
|
336 | - $template_fields = array(); |
|
337 | - /** @var EE_Message_Template $MTP */ |
|
338 | - foreach ($MTPs as $MTP) { |
|
339 | - $field = $MTP->get('MTP_template_field'); |
|
340 | - if ($field === 'content') { |
|
341 | - $content = $MTP->get('MTP_content'); |
|
342 | - if (! empty($content['newsletter_content'])) { |
|
343 | - $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
344 | - } |
|
345 | - continue; |
|
346 | - } |
|
347 | - $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
348 | - } |
|
349 | - $this->_template_args['success'] = true; |
|
350 | - $this->_template_args['error'] = false; |
|
351 | - $this->_template_args['data'] = array( |
|
352 | - 'batch_message_from' => isset($template_fields['from']) |
|
353 | - ? $template_fields['from'] |
|
354 | - : '', |
|
355 | - 'batch_message_subject' => isset($template_fields['subject']) |
|
356 | - ? $template_fields['subject'] |
|
357 | - : '', |
|
358 | - 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
359 | - ? $template_fields['newsletter_content'] |
|
360 | - : '', |
|
361 | - ); |
|
362 | - $this->_return_json(); |
|
363 | - } |
|
283 | + /** |
|
284 | + * callback for ajax action. |
|
285 | + * |
|
286 | + * @since 4.3.0 |
|
287 | + * @return void (JSON) |
|
288 | + * @throws EE_Error |
|
289 | + * @throws InvalidArgumentException |
|
290 | + * @throws InvalidDataTypeException |
|
291 | + * @throws InvalidInterfaceException |
|
292 | + */ |
|
293 | + public function get_newsletter_form_content() |
|
294 | + { |
|
295 | + // do a nonce check cause we're not coming in from an normal route here. |
|
296 | + $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
297 | + $this->_req_data['get_newsletter_form_content_nonce'] |
|
298 | + ) : ''; |
|
299 | + $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
300 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
301 | + // let's get the mtp for the incoming MTP_ ID |
|
302 | + if (! isset($this->_req_data['GRP_ID'])) { |
|
303 | + EE_Error::add_error( |
|
304 | + esc_html__( |
|
305 | + 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
|
306 | + 'event_espresso' |
|
307 | + ), |
|
308 | + __FILE__, |
|
309 | + __FUNCTION__, |
|
310 | + __LINE__ |
|
311 | + ); |
|
312 | + $this->_template_args['success'] = false; |
|
313 | + $this->_template_args['error'] = true; |
|
314 | + $this->_return_json(); |
|
315 | + } |
|
316 | + $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
317 | + if (! $MTPG instanceof EE_Message_Template_Group) { |
|
318 | + EE_Error::add_error( |
|
319 | + sprintf( |
|
320 | + esc_html__( |
|
321 | + 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
322 | + 'event_espresso' |
|
323 | + ), |
|
324 | + $this->_req_data['GRP_ID'] |
|
325 | + ), |
|
326 | + __FILE__, |
|
327 | + __FUNCTION__, |
|
328 | + __LINE__ |
|
329 | + ); |
|
330 | + $this->_template_args['success'] = false; |
|
331 | + $this->_template_args['error'] = true; |
|
332 | + $this->_return_json(); |
|
333 | + } |
|
334 | + $MTPs = $MTPG->context_templates(); |
|
335 | + $MTPs = $MTPs['attendee']; |
|
336 | + $template_fields = array(); |
|
337 | + /** @var EE_Message_Template $MTP */ |
|
338 | + foreach ($MTPs as $MTP) { |
|
339 | + $field = $MTP->get('MTP_template_field'); |
|
340 | + if ($field === 'content') { |
|
341 | + $content = $MTP->get('MTP_content'); |
|
342 | + if (! empty($content['newsletter_content'])) { |
|
343 | + $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
344 | + } |
|
345 | + continue; |
|
346 | + } |
|
347 | + $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
348 | + } |
|
349 | + $this->_template_args['success'] = true; |
|
350 | + $this->_template_args['error'] = false; |
|
351 | + $this->_template_args['data'] = array( |
|
352 | + 'batch_message_from' => isset($template_fields['from']) |
|
353 | + ? $template_fields['from'] |
|
354 | + : '', |
|
355 | + 'batch_message_subject' => isset($template_fields['subject']) |
|
356 | + ? $template_fields['subject'] |
|
357 | + : '', |
|
358 | + 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
359 | + ? $template_fields['newsletter_content'] |
|
360 | + : '', |
|
361 | + ); |
|
362 | + $this->_return_json(); |
|
363 | + } |
|
364 | 364 | |
365 | 365 | |
366 | - /** |
|
367 | - * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
368 | - * |
|
369 | - * @since 4.3.0 |
|
370 | - * @param EE_Admin_List_Table $list_table |
|
371 | - * @return void |
|
372 | - * @throws InvalidArgumentException |
|
373 | - * @throws InvalidDataTypeException |
|
374 | - * @throws InvalidInterfaceException |
|
375 | - */ |
|
376 | - public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
377 | - { |
|
378 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
379 | - 'ee_send_message', |
|
380 | - 'espresso_registrations_newsletter_selected_send' |
|
381 | - ) |
|
382 | - ) { |
|
383 | - return; |
|
384 | - } |
|
385 | - $routes_to_add_to = array( |
|
386 | - 'contact_list', |
|
387 | - 'event_registrations', |
|
388 | - 'default', |
|
389 | - ); |
|
390 | - if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
391 | - if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
392 | - || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
393 | - ) { |
|
394 | - echo ''; |
|
395 | - } else { |
|
396 | - $button_text = sprintf( |
|
397 | - esc_html__('Send Batch Message (%s selected)', 'event_espresso'), |
|
398 | - '<span class="send-selected-newsletter-count">0</span>' |
|
399 | - ); |
|
400 | - echo '<button id="selected-batch-send-trigger" class="button secondary-button">' |
|
401 | - . '<span class="dashicons dashicons-email "></span>' |
|
402 | - . $button_text |
|
403 | - . '</button>'; |
|
404 | - add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
405 | - } |
|
406 | - } |
|
407 | - } |
|
366 | + /** |
|
367 | + * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
368 | + * |
|
369 | + * @since 4.3.0 |
|
370 | + * @param EE_Admin_List_Table $list_table |
|
371 | + * @return void |
|
372 | + * @throws InvalidArgumentException |
|
373 | + * @throws InvalidDataTypeException |
|
374 | + * @throws InvalidInterfaceException |
|
375 | + */ |
|
376 | + public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
377 | + { |
|
378 | + if (! EE_Registry::instance()->CAP->current_user_can( |
|
379 | + 'ee_send_message', |
|
380 | + 'espresso_registrations_newsletter_selected_send' |
|
381 | + ) |
|
382 | + ) { |
|
383 | + return; |
|
384 | + } |
|
385 | + $routes_to_add_to = array( |
|
386 | + 'contact_list', |
|
387 | + 'event_registrations', |
|
388 | + 'default', |
|
389 | + ); |
|
390 | + if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
391 | + if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
392 | + || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
393 | + ) { |
|
394 | + echo ''; |
|
395 | + } else { |
|
396 | + $button_text = sprintf( |
|
397 | + esc_html__('Send Batch Message (%s selected)', 'event_espresso'), |
|
398 | + '<span class="send-selected-newsletter-count">0</span>' |
|
399 | + ); |
|
400 | + echo '<button id="selected-batch-send-trigger" class="button secondary-button">' |
|
401 | + . '<span class="dashicons dashicons-email "></span>' |
|
402 | + . $button_text |
|
403 | + . '</button>'; |
|
404 | + add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
405 | + } |
|
406 | + } |
|
407 | + } |
|
408 | 408 | |
409 | 409 | |
410 | - /** |
|
411 | - * @throws DomainException |
|
412 | - * @throws EE_Error |
|
413 | - * @throws InvalidArgumentException |
|
414 | - * @throws InvalidDataTypeException |
|
415 | - * @throws InvalidInterfaceException |
|
416 | - */ |
|
417 | - public function newsletter_send_form_skeleton() |
|
418 | - { |
|
419 | - $list_table = $this->_list_table_object; |
|
420 | - $codes = array(); |
|
421 | - // need to templates for the newsletter message type for the template selector. |
|
422 | - $values[] = array('text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
423 | - $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
424 | - array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
425 | - ); |
|
426 | - foreach ($mtps as $mtp) { |
|
427 | - $name = $mtp->name(); |
|
428 | - $values[] = array( |
|
429 | - 'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name, |
|
430 | - 'id' => $mtp->ID(), |
|
431 | - ); |
|
432 | - } |
|
433 | - // need to get a list of shortcodes that are available for the newsletter message type. |
|
434 | - $shortcodes = EEH_MSG_Template::get_shortcodes( |
|
435 | - 'newsletter', |
|
436 | - 'email', |
|
437 | - array(), |
|
438 | - 'attendee', |
|
439 | - false |
|
440 | - ); |
|
441 | - foreach ($shortcodes as $field => $shortcode_array) { |
|
442 | - $available_shortcodes = array(); |
|
443 | - foreach ($shortcode_array as $shortcode => $shortcode_details) { |
|
444 | - $field_id = $field === '[NEWSLETTER_CONTENT]' |
|
445 | - ? 'content' |
|
446 | - : $field; |
|
447 | - $field_id = 'batch-message-' . strtolower($field_id); |
|
448 | - $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
|
449 | - . $shortcode |
|
450 | - . '" data-linked-input-id="' . $field_id . '">' |
|
451 | - . $shortcode |
|
452 | - . '</span>'; |
|
453 | - } |
|
454 | - $codes[ $field ] = implode(', ', $available_shortcodes); |
|
455 | - } |
|
456 | - $shortcodes = $codes; |
|
457 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
458 | - $form_template_args = array( |
|
459 | - 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
460 | - 'form_route' => 'newsletter_selected_send', |
|
461 | - 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
462 | - 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
463 | - 'redirect_back_to' => $this->_req_action, |
|
464 | - 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
465 | - 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
466 | - 'shortcodes' => $shortcodes, |
|
467 | - 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
468 | - ); |
|
469 | - EEH_Template::display_template($form_template, $form_template_args); |
|
470 | - } |
|
410 | + /** |
|
411 | + * @throws DomainException |
|
412 | + * @throws EE_Error |
|
413 | + * @throws InvalidArgumentException |
|
414 | + * @throws InvalidDataTypeException |
|
415 | + * @throws InvalidInterfaceException |
|
416 | + */ |
|
417 | + public function newsletter_send_form_skeleton() |
|
418 | + { |
|
419 | + $list_table = $this->_list_table_object; |
|
420 | + $codes = array(); |
|
421 | + // need to templates for the newsletter message type for the template selector. |
|
422 | + $values[] = array('text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
423 | + $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
424 | + array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
425 | + ); |
|
426 | + foreach ($mtps as $mtp) { |
|
427 | + $name = $mtp->name(); |
|
428 | + $values[] = array( |
|
429 | + 'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name, |
|
430 | + 'id' => $mtp->ID(), |
|
431 | + ); |
|
432 | + } |
|
433 | + // need to get a list of shortcodes that are available for the newsletter message type. |
|
434 | + $shortcodes = EEH_MSG_Template::get_shortcodes( |
|
435 | + 'newsletter', |
|
436 | + 'email', |
|
437 | + array(), |
|
438 | + 'attendee', |
|
439 | + false |
|
440 | + ); |
|
441 | + foreach ($shortcodes as $field => $shortcode_array) { |
|
442 | + $available_shortcodes = array(); |
|
443 | + foreach ($shortcode_array as $shortcode => $shortcode_details) { |
|
444 | + $field_id = $field === '[NEWSLETTER_CONTENT]' |
|
445 | + ? 'content' |
|
446 | + : $field; |
|
447 | + $field_id = 'batch-message-' . strtolower($field_id); |
|
448 | + $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
|
449 | + . $shortcode |
|
450 | + . '" data-linked-input-id="' . $field_id . '">' |
|
451 | + . $shortcode |
|
452 | + . '</span>'; |
|
453 | + } |
|
454 | + $codes[ $field ] = implode(', ', $available_shortcodes); |
|
455 | + } |
|
456 | + $shortcodes = $codes; |
|
457 | + $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
458 | + $form_template_args = array( |
|
459 | + 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
460 | + 'form_route' => 'newsletter_selected_send', |
|
461 | + 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
462 | + 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
463 | + 'redirect_back_to' => $this->_req_action, |
|
464 | + 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
465 | + 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
466 | + 'shortcodes' => $shortcodes, |
|
467 | + 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
468 | + ); |
|
469 | + EEH_Template::display_template($form_template, $form_template_args); |
|
470 | + } |
|
471 | 471 | |
472 | 472 | |
473 | - /** |
|
474 | - * Handles sending selected registrations/contacts a newsletter. |
|
475 | - * |
|
476 | - * @since 4.3.0 |
|
477 | - * @return void |
|
478 | - * @throws EE_Error |
|
479 | - * @throws InvalidArgumentException |
|
480 | - * @throws InvalidDataTypeException |
|
481 | - * @throws InvalidInterfaceException |
|
482 | - */ |
|
483 | - protected function _newsletter_selected_send() |
|
484 | - { |
|
485 | - $success = true; |
|
486 | - // first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
487 | - if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
488 | - EE_Error::add_error( |
|
489 | - esc_html__( |
|
490 | - 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
491 | - 'event_espresso' |
|
492 | - ), |
|
493 | - __FILE__, |
|
494 | - __FUNCTION__, |
|
495 | - __LINE__ |
|
496 | - ); |
|
497 | - $success = false; |
|
498 | - } |
|
499 | - if ($success) { |
|
500 | - // update Message template in case there are any changes |
|
501 | - $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
502 | - $this->_req_data['newsletter_mtp_selected'] |
|
503 | - ); |
|
504 | - $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
505 | - ? $Message_Template_Group->context_templates() |
|
506 | - : array(); |
|
507 | - if (empty($Message_Templates)) { |
|
508 | - EE_Error::add_error( |
|
509 | - esc_html__( |
|
510 | - 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
511 | - 'event_espresso' |
|
512 | - ), |
|
513 | - __FILE__, |
|
514 | - __FUNCTION__, |
|
515 | - __LINE__ |
|
516 | - ); |
|
517 | - } |
|
518 | - // let's just update the specific fields |
|
519 | - foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
520 | - if ($Message_Template instanceof EE_Message_Template) { |
|
521 | - $field = $Message_Template->get('MTP_template_field'); |
|
522 | - $content = $Message_Template->get('MTP_content'); |
|
523 | - $new_content = $content; |
|
524 | - switch ($field) { |
|
525 | - case 'from': |
|
526 | - $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
527 | - ? $this->_req_data['batch_message']['from'] |
|
528 | - : $content; |
|
529 | - break; |
|
530 | - case 'subject': |
|
531 | - $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
532 | - ? $this->_req_data['batch_message']['subject'] |
|
533 | - : $content; |
|
534 | - break; |
|
535 | - case 'content': |
|
536 | - $new_content = $content; |
|
537 | - $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
538 | - ? $this->_req_data['batch_message']['content'] |
|
539 | - : $content['newsletter_content']; |
|
540 | - break; |
|
541 | - default: |
|
542 | - // continue the foreach loop, we don't want to set $new_content nor save. |
|
543 | - continue 2; |
|
544 | - } |
|
545 | - $Message_Template->set('MTP_content', $new_content); |
|
546 | - $Message_Template->save(); |
|
547 | - } |
|
548 | - } |
|
549 | - // great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
550 | - $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
551 | - ? $this->_req_data['batch_message']['id_type'] |
|
552 | - : 'registration'; |
|
553 | - // id_type will affect how we assemble the ids. |
|
554 | - $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
555 | - ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
556 | - : array(); |
|
557 | - $registrations_used_for_contact_data = array(); |
|
558 | - // using switch because eventually we'll have other contexts that will be used for generating messages. |
|
559 | - switch ($id_type) { |
|
560 | - case 'registration': |
|
561 | - $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
562 | - array( |
|
563 | - array( |
|
564 | - 'REG_ID' => array('IN', $ids), |
|
565 | - ), |
|
566 | - ) |
|
567 | - ); |
|
568 | - break; |
|
569 | - case 'contact': |
|
570 | - $registrations_used_for_contact_data = EEM_Registration::instance() |
|
571 | - ->get_latest_registration_for_each_of_given_contacts( |
|
572 | - $ids |
|
573 | - ); |
|
574 | - break; |
|
575 | - } |
|
576 | - do_action_ref_array( |
|
577 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
578 | - array( |
|
579 | - $registrations_used_for_contact_data, |
|
580 | - $Message_Template_Group->ID(), |
|
581 | - ) |
|
582 | - ); |
|
583 | - // kept for backward compat, internally we no longer use this action. |
|
584 | - // @deprecated 4.8.36.rc.002 |
|
585 | - $contacts = $id_type === 'registration' |
|
586 | - ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
587 | - : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
588 | - do_action_ref_array( |
|
589 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
590 | - array( |
|
591 | - $contacts, |
|
592 | - $Message_Template_Group->ID(), |
|
593 | - ) |
|
594 | - ); |
|
595 | - } |
|
596 | - $query_args = array( |
|
597 | - 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
598 | - ? $this->_req_data['redirect_back_to'] |
|
599 | - : 'default', |
|
600 | - ); |
|
601 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
602 | - } |
|
473 | + /** |
|
474 | + * Handles sending selected registrations/contacts a newsletter. |
|
475 | + * |
|
476 | + * @since 4.3.0 |
|
477 | + * @return void |
|
478 | + * @throws EE_Error |
|
479 | + * @throws InvalidArgumentException |
|
480 | + * @throws InvalidDataTypeException |
|
481 | + * @throws InvalidInterfaceException |
|
482 | + */ |
|
483 | + protected function _newsletter_selected_send() |
|
484 | + { |
|
485 | + $success = true; |
|
486 | + // first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
487 | + if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
488 | + EE_Error::add_error( |
|
489 | + esc_html__( |
|
490 | + 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
491 | + 'event_espresso' |
|
492 | + ), |
|
493 | + __FILE__, |
|
494 | + __FUNCTION__, |
|
495 | + __LINE__ |
|
496 | + ); |
|
497 | + $success = false; |
|
498 | + } |
|
499 | + if ($success) { |
|
500 | + // update Message template in case there are any changes |
|
501 | + $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
502 | + $this->_req_data['newsletter_mtp_selected'] |
|
503 | + ); |
|
504 | + $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
505 | + ? $Message_Template_Group->context_templates() |
|
506 | + : array(); |
|
507 | + if (empty($Message_Templates)) { |
|
508 | + EE_Error::add_error( |
|
509 | + esc_html__( |
|
510 | + 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
511 | + 'event_espresso' |
|
512 | + ), |
|
513 | + __FILE__, |
|
514 | + __FUNCTION__, |
|
515 | + __LINE__ |
|
516 | + ); |
|
517 | + } |
|
518 | + // let's just update the specific fields |
|
519 | + foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
520 | + if ($Message_Template instanceof EE_Message_Template) { |
|
521 | + $field = $Message_Template->get('MTP_template_field'); |
|
522 | + $content = $Message_Template->get('MTP_content'); |
|
523 | + $new_content = $content; |
|
524 | + switch ($field) { |
|
525 | + case 'from': |
|
526 | + $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
527 | + ? $this->_req_data['batch_message']['from'] |
|
528 | + : $content; |
|
529 | + break; |
|
530 | + case 'subject': |
|
531 | + $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
532 | + ? $this->_req_data['batch_message']['subject'] |
|
533 | + : $content; |
|
534 | + break; |
|
535 | + case 'content': |
|
536 | + $new_content = $content; |
|
537 | + $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
538 | + ? $this->_req_data['batch_message']['content'] |
|
539 | + : $content['newsletter_content']; |
|
540 | + break; |
|
541 | + default: |
|
542 | + // continue the foreach loop, we don't want to set $new_content nor save. |
|
543 | + continue 2; |
|
544 | + } |
|
545 | + $Message_Template->set('MTP_content', $new_content); |
|
546 | + $Message_Template->save(); |
|
547 | + } |
|
548 | + } |
|
549 | + // great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
550 | + $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
551 | + ? $this->_req_data['batch_message']['id_type'] |
|
552 | + : 'registration'; |
|
553 | + // id_type will affect how we assemble the ids. |
|
554 | + $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
555 | + ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
556 | + : array(); |
|
557 | + $registrations_used_for_contact_data = array(); |
|
558 | + // using switch because eventually we'll have other contexts that will be used for generating messages. |
|
559 | + switch ($id_type) { |
|
560 | + case 'registration': |
|
561 | + $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
562 | + array( |
|
563 | + array( |
|
564 | + 'REG_ID' => array('IN', $ids), |
|
565 | + ), |
|
566 | + ) |
|
567 | + ); |
|
568 | + break; |
|
569 | + case 'contact': |
|
570 | + $registrations_used_for_contact_data = EEM_Registration::instance() |
|
571 | + ->get_latest_registration_for_each_of_given_contacts( |
|
572 | + $ids |
|
573 | + ); |
|
574 | + break; |
|
575 | + } |
|
576 | + do_action_ref_array( |
|
577 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
578 | + array( |
|
579 | + $registrations_used_for_contact_data, |
|
580 | + $Message_Template_Group->ID(), |
|
581 | + ) |
|
582 | + ); |
|
583 | + // kept for backward compat, internally we no longer use this action. |
|
584 | + // @deprecated 4.8.36.rc.002 |
|
585 | + $contacts = $id_type === 'registration' |
|
586 | + ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
587 | + : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
588 | + do_action_ref_array( |
|
589 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
590 | + array( |
|
591 | + $contacts, |
|
592 | + $Message_Template_Group->ID(), |
|
593 | + ) |
|
594 | + ); |
|
595 | + } |
|
596 | + $query_args = array( |
|
597 | + 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
598 | + ? $this->_req_data['redirect_back_to'] |
|
599 | + : 'default', |
|
600 | + ); |
|
601 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
602 | + } |
|
603 | 603 | |
604 | 604 | |
605 | - /** |
|
606 | - * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
607 | - * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
608 | - */ |
|
609 | - protected function _registration_reports_js_setup() |
|
610 | - { |
|
611 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
612 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
613 | - } |
|
605 | + /** |
|
606 | + * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
607 | + * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
608 | + */ |
|
609 | + protected function _registration_reports_js_setup() |
|
610 | + { |
|
611 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
612 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
613 | + } |
|
614 | 614 | |
615 | 615 | |
616 | - /** |
|
617 | - * generates Business Reports regarding Registrations |
|
618 | - * |
|
619 | - * @access protected |
|
620 | - * @return void |
|
621 | - * @throws DomainException |
|
622 | - */ |
|
623 | - protected function _registration_reports() |
|
624 | - { |
|
625 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
626 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
627 | - $template_path, |
|
628 | - $this->_reports_template_data, |
|
629 | - true |
|
630 | - ); |
|
631 | - // the final template wrapper |
|
632 | - $this->display_admin_page_with_no_sidebar(); |
|
633 | - } |
|
616 | + /** |
|
617 | + * generates Business Reports regarding Registrations |
|
618 | + * |
|
619 | + * @access protected |
|
620 | + * @return void |
|
621 | + * @throws DomainException |
|
622 | + */ |
|
623 | + protected function _registration_reports() |
|
624 | + { |
|
625 | + $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
626 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
627 | + $template_path, |
|
628 | + $this->_reports_template_data, |
|
629 | + true |
|
630 | + ); |
|
631 | + // the final template wrapper |
|
632 | + $this->display_admin_page_with_no_sidebar(); |
|
633 | + } |
|
634 | 634 | |
635 | 635 | |
636 | - /** |
|
637 | - * Generates Business Report showing total registrations per day. |
|
638 | - * |
|
639 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
640 | - * @return string |
|
641 | - * @throws EE_Error |
|
642 | - * @throws InvalidArgumentException |
|
643 | - * @throws InvalidDataTypeException |
|
644 | - * @throws InvalidInterfaceException |
|
645 | - */ |
|
646 | - private function _registrations_per_day_report($period = '-1 month') |
|
647 | - { |
|
648 | - $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
649 | - $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
650 | - $results = (array) $results; |
|
651 | - $regs = array(); |
|
652 | - $subtitle = ''; |
|
653 | - if ($results) { |
|
654 | - $column_titles = array(); |
|
655 | - $tracker = 0; |
|
656 | - foreach ($results as $result) { |
|
657 | - $report_column_values = array(); |
|
658 | - foreach ($result as $property_name => $property_value) { |
|
659 | - $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
660 | - : (int) $property_value; |
|
661 | - $report_column_values[] = $property_value; |
|
662 | - if ($tracker === 0) { |
|
663 | - if ($property_name === 'Registration_REG_date') { |
|
664 | - $column_titles[] = esc_html__( |
|
665 | - 'Date (only days with registrations are shown)', |
|
666 | - 'event_espresso' |
|
667 | - ); |
|
668 | - } else { |
|
669 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
670 | - } |
|
671 | - } |
|
672 | - } |
|
673 | - $tracker++; |
|
674 | - $regs[] = $report_column_values; |
|
675 | - } |
|
676 | - // make sure the column_titles is pushed to the beginning of the array |
|
677 | - array_unshift($regs, $column_titles); |
|
678 | - // setup the date range. |
|
679 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
680 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
681 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
682 | - $subtitle = sprintf( |
|
683 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
684 | - $beginning_date->format('Y-m-d'), |
|
685 | - $ending_date->format('Y-m-d') |
|
686 | - ); |
|
687 | - } |
|
688 | - $report_title = esc_html__('Total Registrations per Day', 'event_espresso'); |
|
689 | - $report_params = array( |
|
690 | - 'title' => $report_title, |
|
691 | - 'subtitle' => $subtitle, |
|
692 | - 'id' => $report_ID, |
|
693 | - 'regs' => $regs, |
|
694 | - 'noResults' => empty($regs), |
|
695 | - 'noRegsMsg' => sprintf( |
|
696 | - esc_html__( |
|
697 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
698 | - 'event_espresso' |
|
699 | - ), |
|
700 | - '<h2>' . $report_title . '</h2><p>', |
|
701 | - '</p>' |
|
702 | - ), |
|
703 | - ); |
|
704 | - wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
705 | - return $report_ID; |
|
706 | - } |
|
636 | + /** |
|
637 | + * Generates Business Report showing total registrations per day. |
|
638 | + * |
|
639 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
640 | + * @return string |
|
641 | + * @throws EE_Error |
|
642 | + * @throws InvalidArgumentException |
|
643 | + * @throws InvalidDataTypeException |
|
644 | + * @throws InvalidInterfaceException |
|
645 | + */ |
|
646 | + private function _registrations_per_day_report($period = '-1 month') |
|
647 | + { |
|
648 | + $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
649 | + $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
650 | + $results = (array) $results; |
|
651 | + $regs = array(); |
|
652 | + $subtitle = ''; |
|
653 | + if ($results) { |
|
654 | + $column_titles = array(); |
|
655 | + $tracker = 0; |
|
656 | + foreach ($results as $result) { |
|
657 | + $report_column_values = array(); |
|
658 | + foreach ($result as $property_name => $property_value) { |
|
659 | + $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
660 | + : (int) $property_value; |
|
661 | + $report_column_values[] = $property_value; |
|
662 | + if ($tracker === 0) { |
|
663 | + if ($property_name === 'Registration_REG_date') { |
|
664 | + $column_titles[] = esc_html__( |
|
665 | + 'Date (only days with registrations are shown)', |
|
666 | + 'event_espresso' |
|
667 | + ); |
|
668 | + } else { |
|
669 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
670 | + } |
|
671 | + } |
|
672 | + } |
|
673 | + $tracker++; |
|
674 | + $regs[] = $report_column_values; |
|
675 | + } |
|
676 | + // make sure the column_titles is pushed to the beginning of the array |
|
677 | + array_unshift($regs, $column_titles); |
|
678 | + // setup the date range. |
|
679 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
680 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
681 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
682 | + $subtitle = sprintf( |
|
683 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
684 | + $beginning_date->format('Y-m-d'), |
|
685 | + $ending_date->format('Y-m-d') |
|
686 | + ); |
|
687 | + } |
|
688 | + $report_title = esc_html__('Total Registrations per Day', 'event_espresso'); |
|
689 | + $report_params = array( |
|
690 | + 'title' => $report_title, |
|
691 | + 'subtitle' => $subtitle, |
|
692 | + 'id' => $report_ID, |
|
693 | + 'regs' => $regs, |
|
694 | + 'noResults' => empty($regs), |
|
695 | + 'noRegsMsg' => sprintf( |
|
696 | + esc_html__( |
|
697 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
698 | + 'event_espresso' |
|
699 | + ), |
|
700 | + '<h2>' . $report_title . '</h2><p>', |
|
701 | + '</p>' |
|
702 | + ), |
|
703 | + ); |
|
704 | + wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
705 | + return $report_ID; |
|
706 | + } |
|
707 | 707 | |
708 | 708 | |
709 | - /** |
|
710 | - * Generates Business Report showing total registrations per event. |
|
711 | - * |
|
712 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
713 | - * @return string |
|
714 | - * @throws EE_Error |
|
715 | - * @throws InvalidArgumentException |
|
716 | - * @throws InvalidDataTypeException |
|
717 | - * @throws InvalidInterfaceException |
|
718 | - */ |
|
719 | - private function _registrations_per_event_report($period = '-1 month') |
|
720 | - { |
|
721 | - $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
722 | - $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
723 | - $results = (array) $results; |
|
724 | - $regs = array(); |
|
725 | - $subtitle = ''; |
|
726 | - if ($results) { |
|
727 | - $column_titles = array(); |
|
728 | - $tracker = 0; |
|
729 | - foreach ($results as $result) { |
|
730 | - $report_column_values = array(); |
|
731 | - foreach ($result as $property_name => $property_value) { |
|
732 | - $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
733 | - $property_value, |
|
734 | - 4, |
|
735 | - '...' |
|
736 | - ) : (int) $property_value; |
|
737 | - $report_column_values[] = $property_value; |
|
738 | - if ($tracker === 0) { |
|
739 | - if ($property_name === 'Registration_Event') { |
|
740 | - $column_titles[] = esc_html__('Event', 'event_espresso'); |
|
741 | - } else { |
|
742 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
743 | - } |
|
744 | - } |
|
745 | - } |
|
746 | - $tracker++; |
|
747 | - $regs[] = $report_column_values; |
|
748 | - } |
|
749 | - // make sure the column_titles is pushed to the beginning of the array |
|
750 | - array_unshift($regs, $column_titles); |
|
751 | - // setup the date range. |
|
752 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
753 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
754 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
755 | - $subtitle = sprintf( |
|
756 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
757 | - $beginning_date->format('Y-m-d'), |
|
758 | - $ending_date->format('Y-m-d') |
|
759 | - ); |
|
760 | - } |
|
761 | - $report_title = esc_html__('Total Registrations per Event', 'event_espresso'); |
|
762 | - $report_params = array( |
|
763 | - 'title' => $report_title, |
|
764 | - 'subtitle' => $subtitle, |
|
765 | - 'id' => $report_ID, |
|
766 | - 'regs' => $regs, |
|
767 | - 'noResults' => empty($regs), |
|
768 | - 'noRegsMsg' => sprintf( |
|
769 | - esc_html__( |
|
770 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
771 | - 'event_espresso' |
|
772 | - ), |
|
773 | - '<h2>' . $report_title . '</h2><p>', |
|
774 | - '</p>' |
|
775 | - ), |
|
776 | - ); |
|
777 | - wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
778 | - return $report_ID; |
|
779 | - } |
|
709 | + /** |
|
710 | + * Generates Business Report showing total registrations per event. |
|
711 | + * |
|
712 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
713 | + * @return string |
|
714 | + * @throws EE_Error |
|
715 | + * @throws InvalidArgumentException |
|
716 | + * @throws InvalidDataTypeException |
|
717 | + * @throws InvalidInterfaceException |
|
718 | + */ |
|
719 | + private function _registrations_per_event_report($period = '-1 month') |
|
720 | + { |
|
721 | + $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
722 | + $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
723 | + $results = (array) $results; |
|
724 | + $regs = array(); |
|
725 | + $subtitle = ''; |
|
726 | + if ($results) { |
|
727 | + $column_titles = array(); |
|
728 | + $tracker = 0; |
|
729 | + foreach ($results as $result) { |
|
730 | + $report_column_values = array(); |
|
731 | + foreach ($result as $property_name => $property_value) { |
|
732 | + $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
733 | + $property_value, |
|
734 | + 4, |
|
735 | + '...' |
|
736 | + ) : (int) $property_value; |
|
737 | + $report_column_values[] = $property_value; |
|
738 | + if ($tracker === 0) { |
|
739 | + if ($property_name === 'Registration_Event') { |
|
740 | + $column_titles[] = esc_html__('Event', 'event_espresso'); |
|
741 | + } else { |
|
742 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
743 | + } |
|
744 | + } |
|
745 | + } |
|
746 | + $tracker++; |
|
747 | + $regs[] = $report_column_values; |
|
748 | + } |
|
749 | + // make sure the column_titles is pushed to the beginning of the array |
|
750 | + array_unshift($regs, $column_titles); |
|
751 | + // setup the date range. |
|
752 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
753 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
754 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
755 | + $subtitle = sprintf( |
|
756 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
757 | + $beginning_date->format('Y-m-d'), |
|
758 | + $ending_date->format('Y-m-d') |
|
759 | + ); |
|
760 | + } |
|
761 | + $report_title = esc_html__('Total Registrations per Event', 'event_espresso'); |
|
762 | + $report_params = array( |
|
763 | + 'title' => $report_title, |
|
764 | + 'subtitle' => $subtitle, |
|
765 | + 'id' => $report_ID, |
|
766 | + 'regs' => $regs, |
|
767 | + 'noResults' => empty($regs), |
|
768 | + 'noRegsMsg' => sprintf( |
|
769 | + esc_html__( |
|
770 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
771 | + 'event_espresso' |
|
772 | + ), |
|
773 | + '<h2>' . $report_title . '</h2><p>', |
|
774 | + '</p>' |
|
775 | + ), |
|
776 | + ); |
|
777 | + wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
778 | + return $report_ID; |
|
779 | + } |
|
780 | 780 | |
781 | 781 | |
782 | - /** |
|
783 | - * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
784 | - * |
|
785 | - * @access protected |
|
786 | - * @return void |
|
787 | - * @throws EE_Error |
|
788 | - * @throws InvalidArgumentException |
|
789 | - * @throws InvalidDataTypeException |
|
790 | - * @throws InvalidInterfaceException |
|
791 | - * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
792 | - */ |
|
793 | - protected function _registration_checkin_list_table() |
|
794 | - { |
|
795 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
796 | - $reg_id = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : null; |
|
797 | - /** @var EE_Registration $registration */ |
|
798 | - $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
799 | - if (! $registration instanceof EE_Registration) { |
|
800 | - throw new EE_Error( |
|
801 | - sprintf( |
|
802 | - esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
|
803 | - $reg_id |
|
804 | - ) |
|
805 | - ); |
|
806 | - } |
|
807 | - $attendee = $registration->attendee(); |
|
808 | - $this->_admin_page_title .= $this->get_action_link_or_button( |
|
809 | - 'new_registration', |
|
810 | - 'add-registrant', |
|
811 | - array('event_id' => $registration->event_ID()), |
|
812 | - 'add-new-h2' |
|
813 | - ); |
|
814 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
815 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
816 | - $legend_items = array( |
|
817 | - 'checkin' => array( |
|
818 | - 'class' => $checked_in->cssClasses(), |
|
819 | - 'desc' => $checked_in->legendLabel(), |
|
820 | - ), |
|
821 | - 'checkout' => array( |
|
822 | - 'class' => $checked_out->cssClasses(), |
|
823 | - 'desc' => $checked_out->legendLabel(), |
|
824 | - ), |
|
825 | - ); |
|
826 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
827 | - $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
828 | - /** @var EE_Datetime $datetime */ |
|
829 | - $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
830 | - $datetime_label = ''; |
|
831 | - if ($datetime instanceof EE_Datetime) { |
|
832 | - $datetime_label = $datetime->get_dtt_display_name(true); |
|
833 | - $datetime_label .= ! empty($datetime_label) |
|
834 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
835 | - : $datetime->get_dtt_display_name(); |
|
836 | - } |
|
837 | - $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
838 | - ? EE_Admin_Page::add_query_args_and_nonce( |
|
839 | - array( |
|
840 | - 'action' => 'event_registrations', |
|
841 | - 'event_id' => $registration->event_ID(), |
|
842 | - 'DTT_ID' => $dtt_id, |
|
843 | - ), |
|
844 | - $this->_admin_base_url |
|
845 | - ) |
|
846 | - : ''; |
|
847 | - $datetime_link = ! empty($datetime_link) |
|
848 | - ? '<a href="' . $datetime_link . '">' |
|
849 | - . '<span id="checkin-dtt">' |
|
850 | - . $datetime_label |
|
851 | - . '</span></a>' |
|
852 | - : $datetime_label; |
|
853 | - $attendee_name = $attendee instanceof EE_Attendee |
|
854 | - ? $attendee->full_name() |
|
855 | - : ''; |
|
856 | - $attendee_link = $attendee instanceof EE_Attendee |
|
857 | - ? $attendee->get_admin_details_link() |
|
858 | - : ''; |
|
859 | - $attendee_link = ! empty($attendee_link) |
|
860 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
861 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
862 | - . '<span id="checkin-attendee-name">' |
|
863 | - . $attendee_name |
|
864 | - . '</span></a>' |
|
865 | - : ''; |
|
866 | - $event_link = $registration->event() instanceof EE_Event |
|
867 | - ? $registration->event()->get_admin_details_link() |
|
868 | - : ''; |
|
869 | - $event_link = ! empty($event_link) |
|
870 | - ? '<a href="' . $event_link . '"' |
|
871 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
872 | - . '<span id="checkin-event-name">' |
|
873 | - . $registration->event_name() |
|
874 | - . '</span>' |
|
875 | - . '</a>' |
|
876 | - : ''; |
|
877 | - $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
878 | - ? '<h2>' . sprintf( |
|
879 | - esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
880 | - $attendee_link, |
|
881 | - $datetime_link, |
|
882 | - $event_link |
|
883 | - ) . '</h2>' |
|
884 | - : ''; |
|
885 | - $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
886 | - ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
887 | - $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
888 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
889 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
890 | - } |
|
782 | + /** |
|
783 | + * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
784 | + * |
|
785 | + * @access protected |
|
786 | + * @return void |
|
787 | + * @throws EE_Error |
|
788 | + * @throws InvalidArgumentException |
|
789 | + * @throws InvalidDataTypeException |
|
790 | + * @throws InvalidInterfaceException |
|
791 | + * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
792 | + */ |
|
793 | + protected function _registration_checkin_list_table() |
|
794 | + { |
|
795 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
796 | + $reg_id = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : null; |
|
797 | + /** @var EE_Registration $registration */ |
|
798 | + $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
799 | + if (! $registration instanceof EE_Registration) { |
|
800 | + throw new EE_Error( |
|
801 | + sprintf( |
|
802 | + esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
|
803 | + $reg_id |
|
804 | + ) |
|
805 | + ); |
|
806 | + } |
|
807 | + $attendee = $registration->attendee(); |
|
808 | + $this->_admin_page_title .= $this->get_action_link_or_button( |
|
809 | + 'new_registration', |
|
810 | + 'add-registrant', |
|
811 | + array('event_id' => $registration->event_ID()), |
|
812 | + 'add-new-h2' |
|
813 | + ); |
|
814 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
815 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
816 | + $legend_items = array( |
|
817 | + 'checkin' => array( |
|
818 | + 'class' => $checked_in->cssClasses(), |
|
819 | + 'desc' => $checked_in->legendLabel(), |
|
820 | + ), |
|
821 | + 'checkout' => array( |
|
822 | + 'class' => $checked_out->cssClasses(), |
|
823 | + 'desc' => $checked_out->legendLabel(), |
|
824 | + ), |
|
825 | + ); |
|
826 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
827 | + $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
828 | + /** @var EE_Datetime $datetime */ |
|
829 | + $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
830 | + $datetime_label = ''; |
|
831 | + if ($datetime instanceof EE_Datetime) { |
|
832 | + $datetime_label = $datetime->get_dtt_display_name(true); |
|
833 | + $datetime_label .= ! empty($datetime_label) |
|
834 | + ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
835 | + : $datetime->get_dtt_display_name(); |
|
836 | + } |
|
837 | + $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
838 | + ? EE_Admin_Page::add_query_args_and_nonce( |
|
839 | + array( |
|
840 | + 'action' => 'event_registrations', |
|
841 | + 'event_id' => $registration->event_ID(), |
|
842 | + 'DTT_ID' => $dtt_id, |
|
843 | + ), |
|
844 | + $this->_admin_base_url |
|
845 | + ) |
|
846 | + : ''; |
|
847 | + $datetime_link = ! empty($datetime_link) |
|
848 | + ? '<a href="' . $datetime_link . '">' |
|
849 | + . '<span id="checkin-dtt">' |
|
850 | + . $datetime_label |
|
851 | + . '</span></a>' |
|
852 | + : $datetime_label; |
|
853 | + $attendee_name = $attendee instanceof EE_Attendee |
|
854 | + ? $attendee->full_name() |
|
855 | + : ''; |
|
856 | + $attendee_link = $attendee instanceof EE_Attendee |
|
857 | + ? $attendee->get_admin_details_link() |
|
858 | + : ''; |
|
859 | + $attendee_link = ! empty($attendee_link) |
|
860 | + ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
861 | + . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
862 | + . '<span id="checkin-attendee-name">' |
|
863 | + . $attendee_name |
|
864 | + . '</span></a>' |
|
865 | + : ''; |
|
866 | + $event_link = $registration->event() instanceof EE_Event |
|
867 | + ? $registration->event()->get_admin_details_link() |
|
868 | + : ''; |
|
869 | + $event_link = ! empty($event_link) |
|
870 | + ? '<a href="' . $event_link . '"' |
|
871 | + . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
872 | + . '<span id="checkin-event-name">' |
|
873 | + . $registration->event_name() |
|
874 | + . '</span>' |
|
875 | + . '</a>' |
|
876 | + : ''; |
|
877 | + $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
878 | + ? '<h2>' . sprintf( |
|
879 | + esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
880 | + $attendee_link, |
|
881 | + $datetime_link, |
|
882 | + $event_link |
|
883 | + ) . '</h2>' |
|
884 | + : ''; |
|
885 | + $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
886 | + ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
887 | + $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
888 | + ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
889 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
890 | + } |
|
891 | 891 | |
892 | 892 | |
893 | - /** |
|
894 | - * toggle the Check-in status for the given registration (coming from ajax) |
|
895 | - * |
|
896 | - * @return void (JSON) |
|
897 | - * @throws EE_Error |
|
898 | - * @throws InvalidArgumentException |
|
899 | - * @throws InvalidDataTypeException |
|
900 | - * @throws InvalidInterfaceException |
|
901 | - */ |
|
902 | - public function toggle_checkin_status() |
|
903 | - { |
|
904 | - // first make sure we have the necessary data |
|
905 | - if (! isset($this->_req_data['_regid'])) { |
|
906 | - EE_Error::add_error( |
|
907 | - esc_html__( |
|
908 | - 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
|
909 | - 'event_espresso' |
|
910 | - ), |
|
911 | - __FILE__, |
|
912 | - __FUNCTION__, |
|
913 | - __LINE__ |
|
914 | - ); |
|
915 | - $this->_template_args['success'] = false; |
|
916 | - $this->_template_args['error'] = true; |
|
917 | - $this->_return_json(); |
|
918 | - }; |
|
919 | - // do a nonce check cause we're not coming in from an normal route here. |
|
920 | - $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
921 | - : ''; |
|
922 | - $nonce_ref = 'checkin_nonce'; |
|
923 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
924 | - // beautiful! Made it this far so let's get the status. |
|
925 | - $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
926 | - // setup new class to return via ajax |
|
927 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
928 | - $this->_template_args['success'] = true; |
|
929 | - $this->_return_json(); |
|
930 | - } |
|
893 | + /** |
|
894 | + * toggle the Check-in status for the given registration (coming from ajax) |
|
895 | + * |
|
896 | + * @return void (JSON) |
|
897 | + * @throws EE_Error |
|
898 | + * @throws InvalidArgumentException |
|
899 | + * @throws InvalidDataTypeException |
|
900 | + * @throws InvalidInterfaceException |
|
901 | + */ |
|
902 | + public function toggle_checkin_status() |
|
903 | + { |
|
904 | + // first make sure we have the necessary data |
|
905 | + if (! isset($this->_req_data['_regid'])) { |
|
906 | + EE_Error::add_error( |
|
907 | + esc_html__( |
|
908 | + 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
|
909 | + 'event_espresso' |
|
910 | + ), |
|
911 | + __FILE__, |
|
912 | + __FUNCTION__, |
|
913 | + __LINE__ |
|
914 | + ); |
|
915 | + $this->_template_args['success'] = false; |
|
916 | + $this->_template_args['error'] = true; |
|
917 | + $this->_return_json(); |
|
918 | + }; |
|
919 | + // do a nonce check cause we're not coming in from an normal route here. |
|
920 | + $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
921 | + : ''; |
|
922 | + $nonce_ref = 'checkin_nonce'; |
|
923 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
924 | + // beautiful! Made it this far so let's get the status. |
|
925 | + $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
926 | + // setup new class to return via ajax |
|
927 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
928 | + $this->_template_args['success'] = true; |
|
929 | + $this->_return_json(); |
|
930 | + } |
|
931 | 931 | |
932 | 932 | |
933 | - /** |
|
934 | - * handles toggling the checkin status for the registration, |
|
935 | - * |
|
936 | - * @access protected |
|
937 | - * @return int|void |
|
938 | - * @throws EE_Error |
|
939 | - * @throws InvalidArgumentException |
|
940 | - * @throws InvalidDataTypeException |
|
941 | - * @throws InvalidInterfaceException |
|
942 | - */ |
|
943 | - protected function _toggle_checkin_status() |
|
944 | - { |
|
945 | - // first let's get the query args out of the way for the redirect |
|
946 | - $query_args = array( |
|
947 | - 'action' => 'event_registrations', |
|
948 | - 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
949 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
950 | - ); |
|
951 | - $new_status = false; |
|
952 | - // bulk action check in toggle |
|
953 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
954 | - // cycle thru checkboxes |
|
955 | - while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
956 | - $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
957 | - $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
958 | - } |
|
959 | - } elseif (isset($this->_req_data['_regid'])) { |
|
960 | - // coming from ajax request |
|
961 | - $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
962 | - $query_args['DTT_ID'] = $DTT_ID; |
|
963 | - $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
964 | - } else { |
|
965 | - EE_Error::add_error( |
|
966 | - esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
967 | - __FILE__, |
|
968 | - __FUNCTION__, |
|
969 | - __LINE__ |
|
970 | - ); |
|
971 | - } |
|
972 | - if (defined('DOING_AJAX')) { |
|
973 | - return $new_status; |
|
974 | - } |
|
975 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
976 | - } |
|
933 | + /** |
|
934 | + * handles toggling the checkin status for the registration, |
|
935 | + * |
|
936 | + * @access protected |
|
937 | + * @return int|void |
|
938 | + * @throws EE_Error |
|
939 | + * @throws InvalidArgumentException |
|
940 | + * @throws InvalidDataTypeException |
|
941 | + * @throws InvalidInterfaceException |
|
942 | + */ |
|
943 | + protected function _toggle_checkin_status() |
|
944 | + { |
|
945 | + // first let's get the query args out of the way for the redirect |
|
946 | + $query_args = array( |
|
947 | + 'action' => 'event_registrations', |
|
948 | + 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
949 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
950 | + ); |
|
951 | + $new_status = false; |
|
952 | + // bulk action check in toggle |
|
953 | + if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
954 | + // cycle thru checkboxes |
|
955 | + while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
956 | + $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
957 | + $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
958 | + } |
|
959 | + } elseif (isset($this->_req_data['_regid'])) { |
|
960 | + // coming from ajax request |
|
961 | + $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
962 | + $query_args['DTT_ID'] = $DTT_ID; |
|
963 | + $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
964 | + } else { |
|
965 | + EE_Error::add_error( |
|
966 | + esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
967 | + __FILE__, |
|
968 | + __FUNCTION__, |
|
969 | + __LINE__ |
|
970 | + ); |
|
971 | + } |
|
972 | + if (defined('DOING_AJAX')) { |
|
973 | + return $new_status; |
|
974 | + } |
|
975 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
976 | + } |
|
977 | 977 | |
978 | 978 | |
979 | - /** |
|
980 | - * This is toggles a single Check-in for the given registration and datetime. |
|
981 | - * |
|
982 | - * @param int $REG_ID The registration we're toggling |
|
983 | - * @param int $DTT_ID The datetime we're toggling |
|
984 | - * @return int The new status toggled to. |
|
985 | - * @throws EE_Error |
|
986 | - * @throws InvalidArgumentException |
|
987 | - * @throws InvalidDataTypeException |
|
988 | - * @throws InvalidInterfaceException |
|
989 | - */ |
|
990 | - private function _toggle_checkin($REG_ID, $DTT_ID) |
|
991 | - { |
|
992 | - /** @var EE_Registration $REG */ |
|
993 | - $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
994 | - $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
995 | - if ($new_status !== false) { |
|
996 | - EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
997 | - } else { |
|
998 | - EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
999 | - $new_status = false; |
|
1000 | - } |
|
1001 | - return $new_status; |
|
1002 | - } |
|
979 | + /** |
|
980 | + * This is toggles a single Check-in for the given registration and datetime. |
|
981 | + * |
|
982 | + * @param int $REG_ID The registration we're toggling |
|
983 | + * @param int $DTT_ID The datetime we're toggling |
|
984 | + * @return int The new status toggled to. |
|
985 | + * @throws EE_Error |
|
986 | + * @throws InvalidArgumentException |
|
987 | + * @throws InvalidDataTypeException |
|
988 | + * @throws InvalidInterfaceException |
|
989 | + */ |
|
990 | + private function _toggle_checkin($REG_ID, $DTT_ID) |
|
991 | + { |
|
992 | + /** @var EE_Registration $REG */ |
|
993 | + $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
994 | + $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
995 | + if ($new_status !== false) { |
|
996 | + EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
997 | + } else { |
|
998 | + EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
999 | + $new_status = false; |
|
1000 | + } |
|
1001 | + return $new_status; |
|
1002 | + } |
|
1003 | 1003 | |
1004 | 1004 | |
1005 | - /** |
|
1006 | - * Takes care of deleting multiple EE_Checkin table rows |
|
1007 | - * |
|
1008 | - * @access protected |
|
1009 | - * @return void |
|
1010 | - * @throws EE_Error |
|
1011 | - * @throws InvalidArgumentException |
|
1012 | - * @throws InvalidDataTypeException |
|
1013 | - * @throws InvalidInterfaceException |
|
1014 | - */ |
|
1015 | - protected function _delete_checkin_rows() |
|
1016 | - { |
|
1017 | - $query_args = array( |
|
1018 | - 'action' => 'registration_checkins', |
|
1019 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
1020 | - '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
1021 | - ); |
|
1022 | - $errors = 0; |
|
1023 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
1024 | - while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
1025 | - if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
1026 | - $errors++; |
|
1027 | - } |
|
1028 | - } |
|
1029 | - } else { |
|
1030 | - EE_Error::add_error( |
|
1031 | - esc_html__( |
|
1032 | - 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
1033 | - 'event_espresso' |
|
1034 | - ), |
|
1035 | - __FILE__, |
|
1036 | - __FUNCTION__, |
|
1037 | - __LINE__ |
|
1038 | - ); |
|
1039 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
1040 | - } |
|
1041 | - if ($errors > 0) { |
|
1042 | - EE_Error::add_error( |
|
1043 | - sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
1044 | - __FILE__, |
|
1045 | - __FUNCTION__, |
|
1046 | - __LINE__ |
|
1047 | - ); |
|
1048 | - } else { |
|
1049 | - EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
1050 | - } |
|
1051 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
1052 | - } |
|
1005 | + /** |
|
1006 | + * Takes care of deleting multiple EE_Checkin table rows |
|
1007 | + * |
|
1008 | + * @access protected |
|
1009 | + * @return void |
|
1010 | + * @throws EE_Error |
|
1011 | + * @throws InvalidArgumentException |
|
1012 | + * @throws InvalidDataTypeException |
|
1013 | + * @throws InvalidInterfaceException |
|
1014 | + */ |
|
1015 | + protected function _delete_checkin_rows() |
|
1016 | + { |
|
1017 | + $query_args = array( |
|
1018 | + 'action' => 'registration_checkins', |
|
1019 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
1020 | + '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
1021 | + ); |
|
1022 | + $errors = 0; |
|
1023 | + if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
1024 | + while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
1025 | + if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
1026 | + $errors++; |
|
1027 | + } |
|
1028 | + } |
|
1029 | + } else { |
|
1030 | + EE_Error::add_error( |
|
1031 | + esc_html__( |
|
1032 | + 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
1033 | + 'event_espresso' |
|
1034 | + ), |
|
1035 | + __FILE__, |
|
1036 | + __FUNCTION__, |
|
1037 | + __LINE__ |
|
1038 | + ); |
|
1039 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
1040 | + } |
|
1041 | + if ($errors > 0) { |
|
1042 | + EE_Error::add_error( |
|
1043 | + sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
1044 | + __FILE__, |
|
1045 | + __FUNCTION__, |
|
1046 | + __LINE__ |
|
1047 | + ); |
|
1048 | + } else { |
|
1049 | + EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
1050 | + } |
|
1051 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
1052 | + } |
|
1053 | 1053 | |
1054 | 1054 | |
1055 | - /** |
|
1056 | - * Deletes a single EE_Checkin row |
|
1057 | - * |
|
1058 | - * @return void |
|
1059 | - * @throws EE_Error |
|
1060 | - * @throws InvalidArgumentException |
|
1061 | - * @throws InvalidDataTypeException |
|
1062 | - * @throws InvalidInterfaceException |
|
1063 | - */ |
|
1064 | - protected function _delete_checkin_row() |
|
1065 | - { |
|
1066 | - $query_args = array( |
|
1067 | - 'action' => 'registration_checkins', |
|
1068 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
1069 | - '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
1070 | - ); |
|
1071 | - if (! empty($this->_req_data['CHK_ID'])) { |
|
1072 | - if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
1073 | - EE_Error::add_error( |
|
1074 | - esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
1075 | - __FILE__, |
|
1076 | - __FUNCTION__, |
|
1077 | - __LINE__ |
|
1078 | - ); |
|
1079 | - } else { |
|
1080 | - EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
1081 | - } |
|
1082 | - } else { |
|
1083 | - EE_Error::add_error( |
|
1084 | - esc_html__( |
|
1085 | - 'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', |
|
1086 | - 'event_espresso' |
|
1087 | - ), |
|
1088 | - __FILE__, |
|
1089 | - __FUNCTION__, |
|
1090 | - __LINE__ |
|
1091 | - ); |
|
1092 | - } |
|
1093 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
1094 | - } |
|
1055 | + /** |
|
1056 | + * Deletes a single EE_Checkin row |
|
1057 | + * |
|
1058 | + * @return void |
|
1059 | + * @throws EE_Error |
|
1060 | + * @throws InvalidArgumentException |
|
1061 | + * @throws InvalidDataTypeException |
|
1062 | + * @throws InvalidInterfaceException |
|
1063 | + */ |
|
1064 | + protected function _delete_checkin_row() |
|
1065 | + { |
|
1066 | + $query_args = array( |
|
1067 | + 'action' => 'registration_checkins', |
|
1068 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
1069 | + '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
1070 | + ); |
|
1071 | + if (! empty($this->_req_data['CHK_ID'])) { |
|
1072 | + if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
1073 | + EE_Error::add_error( |
|
1074 | + esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
1075 | + __FILE__, |
|
1076 | + __FUNCTION__, |
|
1077 | + __LINE__ |
|
1078 | + ); |
|
1079 | + } else { |
|
1080 | + EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
1081 | + } |
|
1082 | + } else { |
|
1083 | + EE_Error::add_error( |
|
1084 | + esc_html__( |
|
1085 | + 'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', |
|
1086 | + 'event_espresso' |
|
1087 | + ), |
|
1088 | + __FILE__, |
|
1089 | + __FUNCTION__, |
|
1090 | + __LINE__ |
|
1091 | + ); |
|
1092 | + } |
|
1093 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
1094 | + } |
|
1095 | 1095 | |
1096 | 1096 | |
1097 | - /** |
|
1098 | - * generates HTML for the Event Registrations List Table |
|
1099 | - * |
|
1100 | - * @access protected |
|
1101 | - * @return void |
|
1102 | - * @throws EE_Error |
|
1103 | - * @throws InvalidArgumentException |
|
1104 | - * @throws InvalidDataTypeException |
|
1105 | - * @throws InvalidInterfaceException |
|
1106 | - */ |
|
1107 | - protected function _event_registrations_list_table() |
|
1108 | - { |
|
1109 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
1110 | - $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
1111 | - ? $this->get_action_link_or_button( |
|
1112 | - 'new_registration', |
|
1113 | - 'add-registrant', |
|
1114 | - array('event_id' => $this->_req_data['event_id']), |
|
1115 | - 'add-new-h2', |
|
1116 | - '', |
|
1117 | - false |
|
1118 | - ) |
|
1119 | - : ''; |
|
1120 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
1121 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
1122 | - $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
1123 | - $legend_items = array( |
|
1124 | - 'star-icon' => array( |
|
1125 | - 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
1126 | - 'desc' => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'), |
|
1127 | - ), |
|
1128 | - 'checkin' => array( |
|
1129 | - 'class' => $checked_in->cssClasses(), |
|
1130 | - 'desc' => $checked_in->legendLabel(), |
|
1131 | - ), |
|
1132 | - 'checkout' => array( |
|
1133 | - 'class' => $checked_out->cssClasses(), |
|
1134 | - 'desc' => $checked_out->legendLabel(), |
|
1135 | - ), |
|
1136 | - 'nocheckinrecord' => array( |
|
1137 | - 'class' => $checked_never->cssClasses(), |
|
1138 | - 'desc' => $checked_never->legendLabel(), |
|
1139 | - ), |
|
1140 | - 'approved_status' => array( |
|
1141 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
1142 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
1143 | - ), |
|
1144 | - 'cancelled_status' => array( |
|
1145 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
1146 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
1147 | - ), |
|
1148 | - 'declined_status' => array( |
|
1149 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
1150 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
1151 | - ), |
|
1152 | - 'not_approved' => array( |
|
1153 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
1154 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
1155 | - ), |
|
1156 | - 'pending_status' => array( |
|
1157 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
1158 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
1159 | - ), |
|
1160 | - 'wait_list' => array( |
|
1161 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
1162 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
1163 | - ), |
|
1164 | - ); |
|
1165 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
1166 | - $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
1167 | - /** @var EE_Event $event */ |
|
1168 | - $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
1169 | - $this->_template_args['before_list_table'] = $event instanceof EE_Event |
|
1170 | - ? '<h2>' . sprintf( |
|
1171 | - esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
|
1172 | - EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
1173 | - ) . '</h2>' |
|
1174 | - : ''; |
|
1175 | - // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
|
1176 | - // the event. |
|
1177 | - $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
1178 | - $datetime = null; |
|
1179 | - if ($event instanceof EE_Event) { |
|
1180 | - $datetimes_on_event = $event->datetimes(); |
|
1181 | - if (count($datetimes_on_event) === 1) { |
|
1182 | - $datetime = reset($datetimes_on_event); |
|
1183 | - } |
|
1184 | - } |
|
1185 | - $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
1186 | - if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
1187 | - $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
1188 | - $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
1189 | - $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
1190 | - $this->_template_args['before_list_table'] .= $datetime->name(); |
|
1191 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
1192 | - $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
1193 | - } |
|
1194 | - // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
|
1195 | - // column represents |
|
1196 | - if (! $datetime instanceof EE_Datetime) { |
|
1197 | - $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
1198 | - . esc_html__( |
|
1199 | - 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
1200 | - 'event_espresso' |
|
1201 | - ) |
|
1202 | - . '</p>'; |
|
1203 | - } |
|
1204 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
1205 | - } |
|
1097 | + /** |
|
1098 | + * generates HTML for the Event Registrations List Table |
|
1099 | + * |
|
1100 | + * @access protected |
|
1101 | + * @return void |
|
1102 | + * @throws EE_Error |
|
1103 | + * @throws InvalidArgumentException |
|
1104 | + * @throws InvalidDataTypeException |
|
1105 | + * @throws InvalidInterfaceException |
|
1106 | + */ |
|
1107 | + protected function _event_registrations_list_table() |
|
1108 | + { |
|
1109 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
1110 | + $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
1111 | + ? $this->get_action_link_or_button( |
|
1112 | + 'new_registration', |
|
1113 | + 'add-registrant', |
|
1114 | + array('event_id' => $this->_req_data['event_id']), |
|
1115 | + 'add-new-h2', |
|
1116 | + '', |
|
1117 | + false |
|
1118 | + ) |
|
1119 | + : ''; |
|
1120 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
1121 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
1122 | + $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
1123 | + $legend_items = array( |
|
1124 | + 'star-icon' => array( |
|
1125 | + 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
1126 | + 'desc' => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'), |
|
1127 | + ), |
|
1128 | + 'checkin' => array( |
|
1129 | + 'class' => $checked_in->cssClasses(), |
|
1130 | + 'desc' => $checked_in->legendLabel(), |
|
1131 | + ), |
|
1132 | + 'checkout' => array( |
|
1133 | + 'class' => $checked_out->cssClasses(), |
|
1134 | + 'desc' => $checked_out->legendLabel(), |
|
1135 | + ), |
|
1136 | + 'nocheckinrecord' => array( |
|
1137 | + 'class' => $checked_never->cssClasses(), |
|
1138 | + 'desc' => $checked_never->legendLabel(), |
|
1139 | + ), |
|
1140 | + 'approved_status' => array( |
|
1141 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
1142 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
1143 | + ), |
|
1144 | + 'cancelled_status' => array( |
|
1145 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
1146 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
1147 | + ), |
|
1148 | + 'declined_status' => array( |
|
1149 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
1150 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
1151 | + ), |
|
1152 | + 'not_approved' => array( |
|
1153 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
1154 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
1155 | + ), |
|
1156 | + 'pending_status' => array( |
|
1157 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
1158 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
1159 | + ), |
|
1160 | + 'wait_list' => array( |
|
1161 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
1162 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
1163 | + ), |
|
1164 | + ); |
|
1165 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
1166 | + $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
1167 | + /** @var EE_Event $event */ |
|
1168 | + $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
1169 | + $this->_template_args['before_list_table'] = $event instanceof EE_Event |
|
1170 | + ? '<h2>' . sprintf( |
|
1171 | + esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
|
1172 | + EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
1173 | + ) . '</h2>' |
|
1174 | + : ''; |
|
1175 | + // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
|
1176 | + // the event. |
|
1177 | + $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
1178 | + $datetime = null; |
|
1179 | + if ($event instanceof EE_Event) { |
|
1180 | + $datetimes_on_event = $event->datetimes(); |
|
1181 | + if (count($datetimes_on_event) === 1) { |
|
1182 | + $datetime = reset($datetimes_on_event); |
|
1183 | + } |
|
1184 | + } |
|
1185 | + $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
1186 | + if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
1187 | + $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
1188 | + $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
1189 | + $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
1190 | + $this->_template_args['before_list_table'] .= $datetime->name(); |
|
1191 | + $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
1192 | + $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
1193 | + } |
|
1194 | + // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
|
1195 | + // column represents |
|
1196 | + if (! $datetime instanceof EE_Datetime) { |
|
1197 | + $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
1198 | + . esc_html__( |
|
1199 | + 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
1200 | + 'event_espresso' |
|
1201 | + ) |
|
1202 | + . '</p>'; |
|
1203 | + } |
|
1204 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
1205 | + } |
|
1206 | 1206 | |
1207 | - /** |
|
1208 | - * Download the registrations check-in report (same as the normal registration report, but with different where |
|
1209 | - * conditions) |
|
1210 | - * |
|
1211 | - * @return void ends the request by a redirect or download |
|
1212 | - */ |
|
1213 | - public function _registrations_checkin_report() |
|
1214 | - { |
|
1215 | - $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
1216 | - } |
|
1207 | + /** |
|
1208 | + * Download the registrations check-in report (same as the normal registration report, but with different where |
|
1209 | + * conditions) |
|
1210 | + * |
|
1211 | + * @return void ends the request by a redirect or download |
|
1212 | + */ |
|
1213 | + public function _registrations_checkin_report() |
|
1214 | + { |
|
1215 | + $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
1216 | + } |
|
1217 | 1217 | |
1218 | - /** |
|
1219 | - * Gets the query params from the request, plus adds a where condition for the registration status, |
|
1220 | - * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
1221 | - * |
|
1222 | - * @param array $request |
|
1223 | - * @param int $per_page |
|
1224 | - * @param bool $count |
|
1225 | - * @return array |
|
1226 | - * @throws EE_Error |
|
1227 | - */ |
|
1228 | - protected function _get_checkin_query_params_from_request( |
|
1229 | - $request, |
|
1230 | - $per_page = 10, |
|
1231 | - $count = false |
|
1232 | - ) { |
|
1233 | - $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
1234 | - // unlike the regular registrations list table, |
|
1235 | - $status_ids_array = apply_filters( |
|
1236 | - 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
1237 | - array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
1238 | - ); |
|
1239 | - $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
1240 | - return $query_params; |
|
1241 | - } |
|
1218 | + /** |
|
1219 | + * Gets the query params from the request, plus adds a where condition for the registration status, |
|
1220 | + * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
1221 | + * |
|
1222 | + * @param array $request |
|
1223 | + * @param int $per_page |
|
1224 | + * @param bool $count |
|
1225 | + * @return array |
|
1226 | + * @throws EE_Error |
|
1227 | + */ |
|
1228 | + protected function _get_checkin_query_params_from_request( |
|
1229 | + $request, |
|
1230 | + $per_page = 10, |
|
1231 | + $count = false |
|
1232 | + ) { |
|
1233 | + $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
1234 | + // unlike the regular registrations list table, |
|
1235 | + $status_ids_array = apply_filters( |
|
1236 | + 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
1237 | + array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
1238 | + ); |
|
1239 | + $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
1240 | + return $query_params; |
|
1241 | + } |
|
1242 | 1242 | |
1243 | 1243 | |
1244 | - /** |
|
1245 | - * Gets registrations for an event |
|
1246 | - * |
|
1247 | - * @param int $per_page |
|
1248 | - * @param bool $count whether to return count or data. |
|
1249 | - * @param bool $trash |
|
1250 | - * @param string $orderby |
|
1251 | - * @return EE_Registration[]|int |
|
1252 | - * @throws EE_Error |
|
1253 | - * @throws InvalidArgumentException |
|
1254 | - * @throws InvalidDataTypeException |
|
1255 | - * @throws InvalidInterfaceException |
|
1256 | - */ |
|
1257 | - public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
1258 | - { |
|
1259 | - // normalize some request params that get setup by the parent `get_registrations` method. |
|
1260 | - $request = $this->_req_data; |
|
1261 | - $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
1262 | - $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
1263 | - if ($trash) { |
|
1264 | - $request['status'] = 'trash'; |
|
1265 | - } |
|
1266 | - $query_params = $this->_get_checkin_query_params_from_request($request, $per_page, $count); |
|
1267 | - /** |
|
1268 | - * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
1269 | - * |
|
1270 | - * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
1271 | - * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1272 | - * or if you have the development copy of EE you can view this at the path: |
|
1273 | - * /docs/G--Model-System/model-query-params.md |
|
1274 | - */ |
|
1275 | - $query_params['group_by'] = ''; |
|
1244 | + /** |
|
1245 | + * Gets registrations for an event |
|
1246 | + * |
|
1247 | + * @param int $per_page |
|
1248 | + * @param bool $count whether to return count or data. |
|
1249 | + * @param bool $trash |
|
1250 | + * @param string $orderby |
|
1251 | + * @return EE_Registration[]|int |
|
1252 | + * @throws EE_Error |
|
1253 | + * @throws InvalidArgumentException |
|
1254 | + * @throws InvalidDataTypeException |
|
1255 | + * @throws InvalidInterfaceException |
|
1256 | + */ |
|
1257 | + public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
1258 | + { |
|
1259 | + // normalize some request params that get setup by the parent `get_registrations` method. |
|
1260 | + $request = $this->_req_data; |
|
1261 | + $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
1262 | + $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
1263 | + if ($trash) { |
|
1264 | + $request['status'] = 'trash'; |
|
1265 | + } |
|
1266 | + $query_params = $this->_get_checkin_query_params_from_request($request, $per_page, $count); |
|
1267 | + /** |
|
1268 | + * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
1269 | + * |
|
1270 | + * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
1271 | + * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1272 | + * or if you have the development copy of EE you can view this at the path: |
|
1273 | + * /docs/G--Model-System/model-query-params.md |
|
1274 | + */ |
|
1275 | + $query_params['group_by'] = ''; |
|
1276 | 1276 | |
1277 | - return $count |
|
1278 | - ? EEM_Registration::instance()->count($query_params) |
|
1279 | - /** @type EE_Registration[] */ |
|
1280 | - : EEM_Registration::instance()->get_all($query_params); |
|
1281 | - } |
|
1277 | + return $count |
|
1278 | + ? EEM_Registration::instance()->count($query_params) |
|
1279 | + /** @type EE_Registration[] */ |
|
1280 | + : EEM_Registration::instance()->get_all($query_params); |
|
1281 | + } |
|
1282 | 1282 | } |
@@ -32,10 +32,10 @@ discard block |
||
32 | 32 | public function __construct($routing = true) |
33 | 33 | { |
34 | 34 | parent::__construct($routing); |
35 | - if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
36 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
37 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
38 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
35 | + if ( ! defined('REG_CAF_TEMPLATE_PATH')) { |
|
36 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'registrations/templates/'); |
|
37 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'registrations/assets/'); |
|
38 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registrations/assets/'); |
|
39 | 39 | } |
40 | 40 | } |
41 | 41 | |
@@ -45,7 +45,7 @@ discard block |
||
45 | 45 | */ |
46 | 46 | protected function _extend_page_config() |
47 | 47 | { |
48 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
48 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'registrations'; |
|
49 | 49 | $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
50 | 50 | ? $this->_req_data['_REG_ID'] |
51 | 51 | : 0; |
@@ -185,14 +185,14 @@ discard block |
||
185 | 185 | // enqueue newsletter js |
186 | 186 | wp_enqueue_script( |
187 | 187 | 'ee-newsletter-trigger', |
188 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
188 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.js', |
|
189 | 189 | array('ee-dialog'), |
190 | 190 | EVENT_ESPRESSO_VERSION, |
191 | 191 | true |
192 | 192 | ); |
193 | 193 | wp_enqueue_style( |
194 | 194 | 'ee-newsletter-trigger-css', |
195 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
195 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.css', |
|
196 | 196 | array(), |
197 | 197 | EVENT_ESPRESSO_VERSION |
198 | 198 | ); |
@@ -213,7 +213,7 @@ discard block |
||
213 | 213 | { |
214 | 214 | wp_register_script( |
215 | 215 | 'ee-reg-reports-js', |
216 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
216 | + REG_CAF_ASSETS_URL.'ee-registration-admin-reports.js', |
|
217 | 217 | array('google-charts'), |
218 | 218 | EVENT_ESPRESSO_VERSION, |
219 | 219 | true |
@@ -299,7 +299,7 @@ discard block |
||
299 | 299 | $nonce_ref = 'get_newsletter_form_content_nonce'; |
300 | 300 | $this->_verify_nonce($nonce, $nonce_ref); |
301 | 301 | // let's get the mtp for the incoming MTP_ ID |
302 | - if (! isset($this->_req_data['GRP_ID'])) { |
|
302 | + if ( ! isset($this->_req_data['GRP_ID'])) { |
|
303 | 303 | EE_Error::add_error( |
304 | 304 | esc_html__( |
305 | 305 | 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
@@ -314,7 +314,7 @@ discard block |
||
314 | 314 | $this->_return_json(); |
315 | 315 | } |
316 | 316 | $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
317 | - if (! $MTPG instanceof EE_Message_Template_Group) { |
|
317 | + if ( ! $MTPG instanceof EE_Message_Template_Group) { |
|
318 | 318 | EE_Error::add_error( |
319 | 319 | sprintf( |
320 | 320 | esc_html__( |
@@ -339,12 +339,12 @@ discard block |
||
339 | 339 | $field = $MTP->get('MTP_template_field'); |
340 | 340 | if ($field === 'content') { |
341 | 341 | $content = $MTP->get('MTP_content'); |
342 | - if (! empty($content['newsletter_content'])) { |
|
342 | + if ( ! empty($content['newsletter_content'])) { |
|
343 | 343 | $template_fields['newsletter_content'] = $content['newsletter_content']; |
344 | 344 | } |
345 | 345 | continue; |
346 | 346 | } |
347 | - $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
347 | + $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content'); |
|
348 | 348 | } |
349 | 349 | $this->_template_args['success'] = true; |
350 | 350 | $this->_template_args['error'] = false; |
@@ -375,7 +375,7 @@ discard block |
||
375 | 375 | */ |
376 | 376 | public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
377 | 377 | { |
378 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
378 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
379 | 379 | 'ee_send_message', |
380 | 380 | 'espresso_registrations_newsletter_selected_send' |
381 | 381 | ) |
@@ -444,17 +444,17 @@ discard block |
||
444 | 444 | $field_id = $field === '[NEWSLETTER_CONTENT]' |
445 | 445 | ? 'content' |
446 | 446 | : $field; |
447 | - $field_id = 'batch-message-' . strtolower($field_id); |
|
447 | + $field_id = 'batch-message-'.strtolower($field_id); |
|
448 | 448 | $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
449 | 449 | . $shortcode |
450 | - . '" data-linked-input-id="' . $field_id . '">' |
|
450 | + . '" data-linked-input-id="'.$field_id.'">' |
|
451 | 451 | . $shortcode |
452 | 452 | . '</span>'; |
453 | 453 | } |
454 | - $codes[ $field ] = implode(', ', $available_shortcodes); |
|
454 | + $codes[$field] = implode(', ', $available_shortcodes); |
|
455 | 455 | } |
456 | 456 | $shortcodes = $codes; |
457 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
457 | + $form_template = REG_CAF_TEMPLATE_PATH.'newsletter-send-form.template.php'; |
|
458 | 458 | $form_template_args = array( |
459 | 459 | 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
460 | 460 | 'form_route' => 'newsletter_selected_send', |
@@ -622,7 +622,7 @@ discard block |
||
622 | 622 | */ |
623 | 623 | protected function _registration_reports() |
624 | 624 | { |
625 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
625 | + $template_path = EE_ADMIN_TEMPLATE.'admin_reports.template.php'; |
|
626 | 626 | $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
627 | 627 | $template_path, |
628 | 628 | $this->_reports_template_data, |
@@ -677,7 +677,7 @@ discard block |
||
677 | 677 | array_unshift($regs, $column_titles); |
678 | 678 | // setup the date range. |
679 | 679 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
680 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
680 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
681 | 681 | $ending_date = new DateTime("now", $DateTimeZone); |
682 | 682 | $subtitle = sprintf( |
683 | 683 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -697,7 +697,7 @@ discard block |
||
697 | 697 | '%sThere are currently no registration records in the last month for this report.%s', |
698 | 698 | 'event_espresso' |
699 | 699 | ), |
700 | - '<h2>' . $report_title . '</h2><p>', |
|
700 | + '<h2>'.$report_title.'</h2><p>', |
|
701 | 701 | '</p>' |
702 | 702 | ), |
703 | 703 | ); |
@@ -750,7 +750,7 @@ discard block |
||
750 | 750 | array_unshift($regs, $column_titles); |
751 | 751 | // setup the date range. |
752 | 752 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
753 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
753 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
754 | 754 | $ending_date = new DateTime("now", $DateTimeZone); |
755 | 755 | $subtitle = sprintf( |
756 | 756 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -770,7 +770,7 @@ discard block |
||
770 | 770 | '%sThere are currently no registration records in the last month for this report.%s', |
771 | 771 | 'event_espresso' |
772 | 772 | ), |
773 | - '<h2>' . $report_title . '</h2><p>', |
|
773 | + '<h2>'.$report_title.'</h2><p>', |
|
774 | 774 | '</p>' |
775 | 775 | ), |
776 | 776 | ); |
@@ -796,7 +796,7 @@ discard block |
||
796 | 796 | $reg_id = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : null; |
797 | 797 | /** @var EE_Registration $registration */ |
798 | 798 | $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
799 | - if (! $registration instanceof EE_Registration) { |
|
799 | + if ( ! $registration instanceof EE_Registration) { |
|
800 | 800 | throw new EE_Error( |
801 | 801 | sprintf( |
802 | 802 | esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
@@ -831,7 +831,7 @@ discard block |
||
831 | 831 | if ($datetime instanceof EE_Datetime) { |
832 | 832 | $datetime_label = $datetime->get_dtt_display_name(true); |
833 | 833 | $datetime_label .= ! empty($datetime_label) |
834 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
834 | + ? ' ('.$datetime->get_dtt_display_name().')' |
|
835 | 835 | : $datetime->get_dtt_display_name(); |
836 | 836 | } |
837 | 837 | $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
@@ -845,7 +845,7 @@ discard block |
||
845 | 845 | ) |
846 | 846 | : ''; |
847 | 847 | $datetime_link = ! empty($datetime_link) |
848 | - ? '<a href="' . $datetime_link . '">' |
|
848 | + ? '<a href="'.$datetime_link.'">' |
|
849 | 849 | . '<span id="checkin-dtt">' |
850 | 850 | . $datetime_label |
851 | 851 | . '</span></a>' |
@@ -857,8 +857,8 @@ discard block |
||
857 | 857 | ? $attendee->get_admin_details_link() |
858 | 858 | : ''; |
859 | 859 | $attendee_link = ! empty($attendee_link) |
860 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
861 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
860 | + ? '<a href="'.$attendee->get_admin_details_link().'"' |
|
861 | + . ' title="'.esc_html__('Click for attendee details', 'event_espresso').'">' |
|
862 | 862 | . '<span id="checkin-attendee-name">' |
863 | 863 | . $attendee_name |
864 | 864 | . '</span></a>' |
@@ -867,25 +867,25 @@ discard block |
||
867 | 867 | ? $registration->event()->get_admin_details_link() |
868 | 868 | : ''; |
869 | 869 | $event_link = ! empty($event_link) |
870 | - ? '<a href="' . $event_link . '"' |
|
871 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
870 | + ? '<a href="'.$event_link.'"' |
|
871 | + . ' title="'.esc_html__('Click here to edit event.', 'event_espresso').'">' |
|
872 | 872 | . '<span id="checkin-event-name">' |
873 | 873 | . $registration->event_name() |
874 | 874 | . '</span>' |
875 | 875 | . '</a>' |
876 | 876 | : ''; |
877 | 877 | $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
878 | - ? '<h2>' . sprintf( |
|
878 | + ? '<h2>'.sprintf( |
|
879 | 879 | esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
880 | 880 | $attendee_link, |
881 | 881 | $datetime_link, |
882 | 882 | $event_link |
883 | - ) . '</h2>' |
|
883 | + ).'</h2>' |
|
884 | 884 | : ''; |
885 | 885 | $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
886 | - ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
886 | + ? '<input type="hidden" name="_REG_ID" value="'.$reg_id.'">' : ''; |
|
887 | 887 | $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
888 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
888 | + ? '<input type="hidden" name="DTT_ID" value="'.$dtt_id.'">' : ''; |
|
889 | 889 | $this->display_admin_list_table_page_with_no_sidebar(); |
890 | 890 | } |
891 | 891 | |
@@ -902,7 +902,7 @@ discard block |
||
902 | 902 | public function toggle_checkin_status() |
903 | 903 | { |
904 | 904 | // first make sure we have the necessary data |
905 | - if (! isset($this->_req_data['_regid'])) { |
|
905 | + if ( ! isset($this->_req_data['_regid'])) { |
|
906 | 906 | EE_Error::add_error( |
907 | 907 | esc_html__( |
908 | 908 | 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
@@ -924,7 +924,7 @@ discard block |
||
924 | 924 | // beautiful! Made it this far so let's get the status. |
925 | 925 | $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
926 | 926 | // setup new class to return via ajax |
927 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
927 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin '.$new_status->cssClasses(); |
|
928 | 928 | $this->_template_args['success'] = true; |
929 | 929 | $this->_return_json(); |
930 | 930 | } |
@@ -950,7 +950,7 @@ discard block |
||
950 | 950 | ); |
951 | 951 | $new_status = false; |
952 | 952 | // bulk action check in toggle |
953 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
953 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
954 | 954 | // cycle thru checkboxes |
955 | 955 | while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
956 | 956 | $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
@@ -1020,9 +1020,9 @@ discard block |
||
1020 | 1020 | '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
1021 | 1021 | ); |
1022 | 1022 | $errors = 0; |
1023 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
1023 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
1024 | 1024 | while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
1025 | - if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
1025 | + if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
1026 | 1026 | $errors++; |
1027 | 1027 | } |
1028 | 1028 | } |
@@ -1068,8 +1068,8 @@ discard block |
||
1068 | 1068 | 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
1069 | 1069 | '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
1070 | 1070 | ); |
1071 | - if (! empty($this->_req_data['CHK_ID'])) { |
|
1072 | - if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
1071 | + if ( ! empty($this->_req_data['CHK_ID'])) { |
|
1072 | + if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
1073 | 1073 | EE_Error::add_error( |
1074 | 1074 | esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
1075 | 1075 | __FILE__, |
@@ -1138,27 +1138,27 @@ discard block |
||
1138 | 1138 | 'desc' => $checked_never->legendLabel(), |
1139 | 1139 | ), |
1140 | 1140 | 'approved_status' => array( |
1141 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
1141 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_approved, |
|
1142 | 1142 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
1143 | 1143 | ), |
1144 | 1144 | 'cancelled_status' => array( |
1145 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
1145 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_cancelled, |
|
1146 | 1146 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
1147 | 1147 | ), |
1148 | 1148 | 'declined_status' => array( |
1149 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
1149 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_declined, |
|
1150 | 1150 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
1151 | 1151 | ), |
1152 | 1152 | 'not_approved' => array( |
1153 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
1153 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_not_approved, |
|
1154 | 1154 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
1155 | 1155 | ), |
1156 | 1156 | 'pending_status' => array( |
1157 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
1157 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_pending_payment, |
|
1158 | 1158 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
1159 | 1159 | ), |
1160 | 1160 | 'wait_list' => array( |
1161 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
1161 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_wait_list, |
|
1162 | 1162 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
1163 | 1163 | ), |
1164 | 1164 | ); |
@@ -1167,10 +1167,10 @@ discard block |
||
1167 | 1167 | /** @var EE_Event $event */ |
1168 | 1168 | $event = EEM_Event::instance()->get_one_by_ID($event_id); |
1169 | 1169 | $this->_template_args['before_list_table'] = $event instanceof EE_Event |
1170 | - ? '<h2>' . sprintf( |
|
1170 | + ? '<h2>'.sprintf( |
|
1171 | 1171 | esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
1172 | 1172 | EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
1173 | - ) . '</h2>' |
|
1173 | + ).'</h2>' |
|
1174 | 1174 | : ''; |
1175 | 1175 | // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
1176 | 1176 | // the event. |
@@ -1188,12 +1188,12 @@ discard block |
||
1188 | 1188 | $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
1189 | 1189 | $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
1190 | 1190 | $this->_template_args['before_list_table'] .= $datetime->name(); |
1191 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
1191 | + $this->_template_args['before_list_table'] .= ' ( '.$datetime->date_and_time_range().' )'; |
|
1192 | 1192 | $this->_template_args['before_list_table'] .= '</span></h2>'; |
1193 | 1193 | } |
1194 | 1194 | // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
1195 | 1195 | // column represents |
1196 | - if (! $datetime instanceof EE_Datetime) { |
|
1196 | + if ( ! $datetime instanceof EE_Datetime) { |
|
1197 | 1197 | $this->_template_args['before_list_table'] .= '<br><p class="description">' |
1198 | 1198 | . esc_html__( |
1199 | 1199 | 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
@@ -6,16 +6,16 @@ discard block |
||
6 | 6 | <?php if (!is_admin()) : ?> |
7 | 7 | <p id="spco-attendee_information-pg" class="spco-steps-pg small-text drk-grey-text"> |
8 | 8 | <?php echo apply_filters( |
9 | - 'FHEE__registration_page_attendee_information__attendee_information_pg', |
|
10 | - sprintf( |
|
11 | - esc_html__( |
|
12 | - 'In order to process your registration, we ask you to provide the following information.%1$sPlease note that all fields marked with an asterisk (%2$s) are required.', |
|
13 | - 'event_espresso' |
|
14 | - ), |
|
15 | - '<br />', |
|
16 | - '<span class="asterisk">*</span>' |
|
17 | - ) |
|
18 | - ); ?> |
|
9 | + 'FHEE__registration_page_attendee_information__attendee_information_pg', |
|
10 | + sprintf( |
|
11 | + esc_html__( |
|
12 | + 'In order to process your registration, we ask you to provide the following information.%1$sPlease note that all fields marked with an asterisk (%2$s) are required.', |
|
13 | + 'event_espresso' |
|
14 | + ), |
|
15 | + '<br />', |
|
16 | + '<span class="asterisk">*</span>' |
|
17 | + ) |
|
18 | + ); ?> |
|
19 | 19 | </p> |
20 | 20 | <?php endif; ?> |
21 | 21 | |
@@ -25,8 +25,8 @@ discard block |
||
25 | 25 | $prev_ticket = 0; |
26 | 26 | |
27 | 27 | if (count($registrations) > 0) { |
28 | - $ticketID = key($template_args['ticket_count']); |
|
29 | - ?> |
|
28 | + $ticketID = key($template_args['ticket_count']); |
|
29 | + ?> |
|
30 | 30 | |
31 | 31 | <div id="spco-attendee-panel-dv-<?php echo $ticketID; ?>" |
32 | 32 | class="spco-attendee-panel-dv spco-attendee-ticket-<?php echo $ticketID; ?>"> |
@@ -41,54 +41,54 @@ discard block |
||
41 | 41 | <th scope="col" width="" class="jst-left"><?php esc_html_e('Name and Description', 'event_espresso'); ?></th> |
42 | 42 | <th scope="col" width="7.5%" class="jst-rght"> |
43 | 43 | <?php esc_html_e( |
44 | - 'Qty', |
|
45 | - 'event_espresso' |
|
46 | - ); ?></th> |
|
44 | + 'Qty', |
|
45 | + 'event_espresso' |
|
46 | + ); ?></th> |
|
47 | 47 | <th scope="col" width="17.5%" class="jst-rght"> |
48 | 48 | <?php esc_html_e( |
49 | - 'Price', |
|
50 | - 'event_espresso' |
|
51 | - ); ?></th> |
|
49 | + 'Price', |
|
50 | + 'event_espresso' |
|
51 | + ); ?></th> |
|
52 | 52 | <th scope="col" width="17.5%" class="jst-rght"> |
53 | 53 | <?php esc_html_e( |
54 | - 'Total', |
|
55 | - 'event_espresso' |
|
56 | - ); ?></th> |
|
54 | + 'Total', |
|
55 | + 'event_espresso' |
|
56 | + ); ?></th> |
|
57 | 57 | </tr> |
58 | 58 | </thead> |
59 | 59 | <tbody> |
60 | 60 | <?php |
61 | - // Store previous values to avoid duplicated rows. |
|
62 | - $prev_ticket = 0; |
|
63 | - // Display all tickets inside. |
|
64 | - foreach ($registrations as $registration) { |
|
65 | - if ($registration instanceof EE_Registration) { |
|
66 | - if ($registration->ticket()->ID() !== $prev_ticket) { |
|
67 | - echo $ticket_line_item[ $registration->ticket()->ID() ]; |
|
68 | - } |
|
61 | + // Store previous values to avoid duplicated rows. |
|
62 | + $prev_ticket = 0; |
|
63 | + // Display all tickets inside. |
|
64 | + foreach ($registrations as $registration) { |
|
65 | + if ($registration instanceof EE_Registration) { |
|
66 | + if ($registration->ticket()->ID() !== $prev_ticket) { |
|
67 | + echo $ticket_line_item[ $registration->ticket()->ID() ]; |
|
68 | + } |
|
69 | 69 | |
70 | - $prev_ticket = $registration->ticket()->ID(); |
|
71 | - } |
|
72 | - } |
|
73 | - ?> |
|
70 | + $prev_ticket = $registration->ticket()->ID(); |
|
71 | + } |
|
72 | + } |
|
73 | + ?> |
|
74 | 74 | </tbody> |
75 | 75 | </table> |
76 | 76 | </div> |
77 | 77 | |
78 | 78 | <?php |
79 | - // Display the forms below the table. |
|
80 | - foreach ($registrations as $registration) { |
|
81 | - if ($registration instanceof EE_Registration) { |
|
82 | - // Attendee Questions. |
|
83 | - $reg_form = EE_Template_Layout::get_subform_name($registration->reg_url_link()); |
|
84 | - echo ${$reg_form}; |
|
85 | - ?> |
|
79 | + // Display the forms below the table. |
|
80 | + foreach ($registrations as $registration) { |
|
81 | + if ($registration instanceof EE_Registration) { |
|
82 | + // Attendee Questions. |
|
83 | + $reg_form = EE_Template_Layout::get_subform_name($registration->reg_url_link()); |
|
84 | + echo ${$reg_form}; |
|
85 | + ?> |
|
86 | 86 | </div> |
87 | 87 | <?php |
88 | - } // if ( $registration instanceof EE_Registration ) |
|
89 | - } // end foreach ( $registrations as $registration ) |
|
88 | + } // if ( $registration instanceof EE_Registration ) |
|
89 | + } // end foreach ( $registrations as $registration ) |
|
90 | 90 | |
91 | - echo $default_hidden_inputs; |
|
91 | + echo $default_hidden_inputs; |
|
92 | 92 | } // end if ( count( $registrations ) > 0 ) |
93 | 93 | |
94 | 94 | ?> |
@@ -134,7 +134,7 @@ discard block |
||
134 | 134 | |
135 | 135 | |
136 | 136 | // If there is no event objecdt by now then get out. |
137 | - if (! $this->_event instanceof EE_Event) { |
|
137 | + if ( ! $this->_event instanceof EE_Event) { |
|
138 | 138 | return ''; |
139 | 139 | } |
140 | 140 | |
@@ -187,11 +187,11 @@ discard block |
||
187 | 187 | $image = $this->_event->feature_image_url(array(600, 300)); |
188 | 188 | // @todo: eventually we should make this an attribute shortcode so that em can send along what size they want returned. |
189 | 189 | return ! empty($image) |
190 | - ? '<img src="' . $image . '" alt="' |
|
190 | + ? '<img src="'.$image.'" alt="' |
|
191 | 191 | . sprintf( |
192 | 192 | esc_attr__('%s Feature Image', 'event_espresso'), |
193 | 193 | $this->_event->get('EVT_name') |
194 | - ) . '" />' |
|
194 | + ).'" />' |
|
195 | 195 | : ''; |
196 | 196 | break; |
197 | 197 | |
@@ -251,7 +251,7 @@ discard block |
||
251 | 251 | // Add a filter to allow all instances of EVENT_META_* to run through do_shortcode, default to false. |
252 | 252 | // Check if a do_shortcode attribute was set to true and if so run $event_meta through that function. |
253 | 253 | if (apply_filters('FHEE__EventEspresso_core_libraries_shortcodes_EE_Event_Shortcodes___parser__event_meta_do_shortcode', false) |
254 | - || !empty($attrs['do_shortcode']) && filter_var($attrs['do_shortcode'], FILTER_VALIDATE_BOOLEAN) |
|
254 | + || ! empty($attrs['do_shortcode']) && filter_var($attrs['do_shortcode'], FILTER_VALIDATE_BOOLEAN) |
|
255 | 255 | ) { |
256 | 256 | return do_shortcode($event_meta); |
257 | 257 | } |
@@ -269,11 +269,11 @@ discard block |
||
269 | 269 | |
270 | 270 | if (strpos($shortcode, '[EVENT_IMAGE_*') !== false) { |
271 | 271 | $attrs = $this->_get_shortcode_attrs($shortcode); |
272 | - $width = empty($attrs['width']) ? '' : ' width="' . $attrs['width'] . '"'; |
|
273 | - $height = empty($attrs['height']) ? '' : ' height="' . $attrs['height'] . '"'; |
|
272 | + $width = empty($attrs['width']) ? '' : ' width="'.$attrs['width'].'"'; |
|
273 | + $height = empty($attrs['height']) ? '' : ' height="'.$attrs['height'].'"'; |
|
274 | 274 | |
275 | 275 | // Size may be set to a string such as 'tumbnail' or "width, height" eg - '200,200' |
276 | - if (! empty($attrs['size'])) { |
|
276 | + if ( ! empty($attrs['size'])) { |
|
277 | 277 | $size = explode(',', $attrs['size']); |
278 | 278 | if (count($size) === 1) { |
279 | 279 | $size = $size[0]; |
@@ -285,11 +285,11 @@ discard block |
||
285 | 285 | $image = $this->_event->feature_image_url($size); |
286 | 286 | |
287 | 287 | return ! empty($image) |
288 | - ? '<img src="' . $image . '" alt="' |
|
288 | + ? '<img src="'.$image.'" alt="' |
|
289 | 289 | . sprintf( |
290 | 290 | esc_attr__('%s Feature Image', 'event_espresso'), |
291 | 291 | $this->_event->get('EVT_name') |
292 | - ) . '"' . $width . $height . '/>' |
|
292 | + ).'"'.$width.$height.'/>' |
|
293 | 293 | : ''; |
294 | 294 | } |
295 | 295 | |
@@ -308,6 +308,6 @@ discard block |
||
308 | 308 | { |
309 | 309 | $url = get_permalink($event->ID()); |
310 | 310 | |
311 | - return $full_link ? '<a href="' . $url . '">' . $event->get('EVT_name') . '</a>' : $url; |
|
311 | + return $full_link ? '<a href="'.$url.'">'.$event->get('EVT_name').'</a>' : $url; |
|
312 | 312 | } |
313 | 313 | } |
@@ -19,296 +19,296 @@ |
||
19 | 19 | { |
20 | 20 | |
21 | 21 | |
22 | - /** |
|
23 | - * Will hold the EE_Event if available |
|
24 | - * |
|
25 | - * @var EE_Event |
|
26 | - */ |
|
27 | - protected $_event; |
|
28 | - |
|
29 | - |
|
30 | - public function __construct() |
|
31 | - { |
|
32 | - parent::__construct(); |
|
33 | - } |
|
34 | - |
|
35 | - |
|
36 | - protected function _init_props() |
|
37 | - { |
|
38 | - $this->label = __('Event Shortcodes', 'event_espresso'); |
|
39 | - $this->description = __('All shortcodes specific to event related data', 'event_espresso'); |
|
40 | - $this->_shortcodes = array( |
|
41 | - '[EVENT_ID]' => __( |
|
42 | - 'Will be replaced by the event ID of an event', |
|
43 | - 'event_espresso' |
|
44 | - ), |
|
45 | - '[EVENT]' => __('The name of the event', 'event_espresso'), |
|
46 | - '[EVENT_NAME]' => __( |
|
47 | - "This also can be used for the name of the event", |
|
48 | - 'event_espresso' |
|
49 | - ), |
|
50 | - '[EVENT_PHONE]' => __( |
|
51 | - 'The phone number for the event (usually an info number)', |
|
52 | - 'event_espresso' |
|
53 | - ), |
|
54 | - '[EVENT_DESCRIPTION]' => __('The description of the event', 'event_espresso'), |
|
55 | - '[EVENT_EXCERPT]' => __( |
|
56 | - 'This gets parsed to the value for the excerpt field in the event or blank if there is no excerpt.', |
|
57 | - 'event_espresso' |
|
58 | - ), |
|
59 | - '[EVENT_LINK]' => __('A link associated with the event', 'event_espresso'), |
|
60 | - '[EVENT_URL]' => __( |
|
61 | - 'A link to the event set up on the host site.', |
|
62 | - 'event_espresso' |
|
63 | - ), |
|
64 | - '[VIRTUAL_URL]' => __( |
|
65 | - 'What was used for the "URL of Event" field in the Venue settings', |
|
66 | - 'event_espresso' |
|
67 | - ), |
|
68 | - '[VIRTUAL_PHONE]' => __( |
|
69 | - 'An alternate phone number for the event. Typically used as a "call-in" number', |
|
70 | - 'event_espresso' |
|
71 | - ), |
|
72 | - '[EVENT_IMAGE]' => __( |
|
73 | - 'This will parse to the Feature image for the event.', |
|
74 | - 'event_espresso' |
|
75 | - ), |
|
76 | - '[EVENT_IMAGE_*]' => sprintf( |
|
77 | - __( |
|
78 | - 'This will parse to the Feature image for the event, %1$ssize%2$s can be set to determine the size of the image loaded by the shortcode. The %1$swidth%2$s and/or %1$sheight%2$s can also be set to determine the width and height of the image when output. By default the shortcode will load the %1$sthumbnail%2$s image size.', |
|
79 | - 'event_espresso' |
|
80 | - ), |
|
81 | - '<code>', |
|
82 | - '</code>' |
|
83 | - ), |
|
84 | - '[EVENT_TOTAL_AVAILABLE_SPACES_*]' => sprintf( |
|
85 | - __( |
|
86 | - 'This will parse to the total available spaces for an event. Calculating total spaces is approximate because it is dependent on the complexity of limits on your event. There are two methods of calculation (which can be indicated by the %1$smethod%2$s param on the shortcode). %1$scurrent%2$s which will do a more accurate calculation of total available spaces based on current sales, and %1$sfull%2$s which will be the maximum total available spaces that is on the event in optimal conditions. The shortcode will default to current.', |
|
87 | - 'event_espresso' |
|
88 | - ), |
|
89 | - '<code>', |
|
90 | - '</code>' |
|
91 | - ), |
|
92 | - '[EVENT_TOTAL_SPOTS_TAKEN]' => __( |
|
93 | - 'This shortcode will parse to the output the total approved registrations for this event', |
|
94 | - 'event_espresso' |
|
95 | - ), |
|
96 | - '[EVENT_FACEBOOK_URL]' => __( |
|
97 | - 'This will return the Facebook URL for the event if you have it set via custom field in your event, otherwise it will use the Facebook URL set in "Your Organization Settings". To set the facebook url in your event, add a custom field with the key as <code>event_facebook</code> and the value as your facebook url.', |
|
98 | - 'event_espresso' |
|
99 | - ), |
|
100 | - '[EVENT_TWITTER_URL]' => __( |
|
101 | - 'This will return the Twitter URL for the event if you have it set via custom field in your event, otherwise it will use the Twitter URL set in "Your Organization Settings". To set the facebook url in your event, add a custom field with the key as <code>event_twitter</code> and the value as your facebook url', |
|
102 | - 'event_espresso' |
|
103 | - ), |
|
104 | - '[EVENT_META_*]' => sprintf( |
|
105 | - __( |
|
106 | - 'This is a special dynamic shortcode. After the "*", add the exact name for your custom field, if there is a value set for that custom field within the event then it will be output in place of this shortcode. If you use shortcodes within your custom fields set %1$sdo_shortcode=true%2$s at the end of the shortcode to run the value through the do_shortcode function. ', |
|
107 | - 'event_espresso' |
|
108 | - ), |
|
109 | - '<code>', |
|
110 | - '</code>' |
|
111 | - ), |
|
112 | - '[REGISTRATION_LIST_TABLE_FOR_EVENT_URL]' => __( |
|
113 | - 'This parses to the url for the registration list table filtered by registrations for this event.', |
|
114 | - 'event_espresso' |
|
115 | - ), |
|
116 | - ); |
|
117 | - } |
|
118 | - |
|
119 | - |
|
120 | - protected function _parser($shortcode) |
|
121 | - { |
|
122 | - |
|
123 | - |
|
124 | - $this->_event = $this->_data instanceof EE_Event ? $this->_data : null; |
|
125 | - |
|
126 | - // if no event, then let's see if there is a reg_obj. If there IS, then we'll try and grab the event from the reg_obj instead. |
|
127 | - if (empty($this->_event)) { |
|
128 | - $aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null; |
|
129 | - $aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee; |
|
130 | - |
|
131 | - $this->_event = $aee instanceof EE_Messages_Addressee && $aee->reg_obj instanceof EE_Registration |
|
132 | - ? $aee->reg_obj->event() : null; |
|
133 | - } |
|
134 | - |
|
135 | - |
|
136 | - // If there is no event objecdt by now then get out. |
|
137 | - if (! $this->_event instanceof EE_Event) { |
|
138 | - return ''; |
|
139 | - } |
|
140 | - |
|
141 | - switch ($shortcode) { |
|
142 | - case '[EVENT_ID]': |
|
143 | - return $this->_event->ID(); |
|
144 | - break; |
|
145 | - |
|
146 | - case '[EVENT]': |
|
147 | - case '[EVENT_NAME]': |
|
148 | - return $this->_event->get('EVT_name'); |
|
149 | - break; |
|
150 | - |
|
151 | - case '[EVENT_PHONE]': |
|
152 | - return $this->_event->get('EVT_phone'); |
|
153 | - break; |
|
154 | - |
|
155 | - case '[EVENT_DESCRIPTION]': |
|
156 | - return $this->_event->get('EVT_desc'); |
|
157 | - break; |
|
158 | - |
|
159 | - case '[EVENT_EXCERPT]': |
|
160 | - return $this->_event->get('EVT_short_desc'); |
|
161 | - break; |
|
162 | - |
|
163 | - case '[EVENT_LINK]': |
|
164 | - return $this->_get_event_link($this->_event); |
|
165 | - break; |
|
166 | - |
|
167 | - case '[EVENT_URL]': |
|
168 | - return $this->_get_event_link($this->_event, false); |
|
169 | - break; |
|
170 | - |
|
171 | - case '[VIRTUAL_URL]': |
|
172 | - $venue = $this->_event->get_first_related('Venue'); |
|
173 | - if (empty($venue)) { |
|
174 | - return ''; |
|
175 | - } |
|
176 | - return $venue->get('VNU_virtual_url'); |
|
177 | - |
|
178 | - case '[VIRTUAL_PHONE]': |
|
179 | - $venue = $this->_event->get_first_related('Venue'); |
|
180 | - if (empty($venue)) { |
|
181 | - return ''; |
|
182 | - } |
|
183 | - return $venue->get('VNU_virtual_phone'); |
|
184 | - break; |
|
185 | - |
|
186 | - case '[EVENT_IMAGE]': |
|
187 | - $image = $this->_event->feature_image_url(array(600, 300)); |
|
188 | - // @todo: eventually we should make this an attribute shortcode so that em can send along what size they want returned. |
|
189 | - return ! empty($image) |
|
190 | - ? '<img src="' . $image . '" alt="' |
|
191 | - . sprintf( |
|
192 | - esc_attr__('%s Feature Image', 'event_espresso'), |
|
193 | - $this->_event->get('EVT_name') |
|
194 | - ) . '" />' |
|
195 | - : ''; |
|
196 | - break; |
|
197 | - |
|
198 | - case '[EVENT_FACEBOOK_URL]': |
|
199 | - $facebook_url = $this->_event->get_post_meta('event_facebook', true); |
|
200 | - return empty($facebook_url) ? EE_Registry::instance()->CFG->organization->get_pretty('facebook') |
|
201 | - : $facebook_url; |
|
202 | - break; |
|
203 | - |
|
204 | - case '[EVENT_TWITTER_URL]': |
|
205 | - $twitter_url = $this->_event->get_post_meta('event_twitter', true); |
|
206 | - return empty($twitter_url) ? EE_Registry::instance()->CFG->organization->get_pretty('twitter') |
|
207 | - : $twitter_url; |
|
208 | - break; |
|
209 | - |
|
210 | - case '[EVENT_AUTHOR_EMAIL]': |
|
211 | - $author_id = $this->_event->get('EVT_wp_user'); |
|
212 | - $user_data = get_userdata((int) $author_id); |
|
213 | - return $user_data->user_email; |
|
214 | - break; |
|
215 | - |
|
216 | - case '[EVENT_TOTAL_SPOTS_TAKEN]': |
|
217 | - return EEM_Registration::instance()->count( |
|
218 | - array(array('EVT_ID' => $this->_event->ID(), 'STS_ID' => EEM_Registration::status_id_approved)), |
|
219 | - 'REG_ID', |
|
220 | - true |
|
221 | - ); |
|
222 | - break; |
|
223 | - |
|
224 | - case '[REGISTRATION_LIST_TABLE_FOR_EVENT_URL]': |
|
225 | - return EEH_URL::add_query_args_and_nonce( |
|
226 | - array( |
|
227 | - 'event_id' => $this->_event->ID(), |
|
228 | - 'page' => 'espresso_registrations', |
|
229 | - 'action' => 'default', |
|
230 | - ), |
|
231 | - admin_url('admin.php'), |
|
232 | - true |
|
233 | - ); |
|
234 | - break; |
|
235 | - } |
|
236 | - |
|
237 | - if (strpos($shortcode, '[EVENT_META_*') !== false) { |
|
238 | - // Strip the shortcode itself from $shortcode leaving any attributes set. |
|
239 | - // Removing the * is correct here as _* is used to indiciate a dynamic shortcode. |
|
240 | - $shortcode = str_replace('[EVENT_META_*', '', $shortcode); |
|
241 | - $shortcode = trim(str_replace(']', '', $shortcode)); |
|
242 | - // Get any attributes set on this shortcode. |
|
243 | - $attrs = $this->_get_shortcode_attrs($shortcode); |
|
244 | - // The meta_key set on the shortcode should always be the first value in the array. |
|
245 | - $meta_key = $attrs[0]; |
|
246 | - // Pull the meta value from the event post. |
|
247 | - $event_meta = $this->_event->get_post_meta($meta_key, true); |
|
248 | - // If we have no event_meta, just return an empty string. |
|
249 | - if (empty($event_meta)) { |
|
250 | - return ''; |
|
251 | - } |
|
252 | - // Add a filter to allow all instances of EVENT_META_* to run through do_shortcode, default to false. |
|
253 | - // Check if a do_shortcode attribute was set to true and if so run $event_meta through that function. |
|
254 | - if (apply_filters('FHEE__EventEspresso_core_libraries_shortcodes_EE_Event_Shortcodes___parser__event_meta_do_shortcode', false) |
|
255 | - || !empty($attrs['do_shortcode']) && filter_var($attrs['do_shortcode'], FILTER_VALIDATE_BOOLEAN) |
|
256 | - ) { |
|
257 | - return do_shortcode($event_meta); |
|
258 | - } |
|
259 | - // Still here? We just need to return the event_meta value as is. |
|
260 | - return $event_meta; |
|
261 | - } |
|
262 | - |
|
263 | - if (strpos($shortcode, '[EVENT_TOTAL_AVAILABLE_SPACES_*') !== false) { |
|
264 | - $attrs = $this->_get_shortcode_attrs($shortcode); |
|
265 | - $method = empty($attrs['method']) ? 'current' : $attrs['method']; |
|
266 | - $method = $method === 'current'; |
|
267 | - $available = $this->_event->total_available_spaces($method); |
|
268 | - return $available === EE_INF ? '∞' : $available; |
|
269 | - } |
|
270 | - |
|
271 | - if (strpos($shortcode, '[EVENT_IMAGE_*') !== false) { |
|
272 | - $attrs = $this->_get_shortcode_attrs($shortcode); |
|
273 | - $width = empty($attrs['width']) ? '' : ' width="' . $attrs['width'] . '"'; |
|
274 | - $height = empty($attrs['height']) ? '' : ' height="' . $attrs['height'] . '"'; |
|
275 | - |
|
276 | - // Size may be set to a string such as 'tumbnail' or "width, height" eg - '200,200' |
|
277 | - if (! empty($attrs['size'])) { |
|
278 | - $size = explode(',', $attrs['size']); |
|
279 | - if (count($size) === 1) { |
|
280 | - $size = $size[0]; |
|
281 | - } |
|
282 | - } else { |
|
283 | - $size = 'thumbnail'; |
|
284 | - } |
|
285 | - |
|
286 | - $image = $this->_event->feature_image_url($size); |
|
287 | - |
|
288 | - return ! empty($image) |
|
289 | - ? '<img src="' . $image . '" alt="' |
|
290 | - . sprintf( |
|
291 | - esc_attr__('%s Feature Image', 'event_espresso'), |
|
292 | - $this->_event->get('EVT_name') |
|
293 | - ) . '"' . $width . $height . '/>' |
|
294 | - : ''; |
|
295 | - } |
|
296 | - |
|
297 | - return ''; |
|
298 | - } |
|
299 | - |
|
300 | - |
|
301 | - /** |
|
302 | - * returns the link to the event |
|
303 | - * |
|
304 | - * @param boolean $full_link if TRUE (default) we return the html for the name of the event linked to the event. |
|
305 | - * Otherwise we just return the url of the event. |
|
306 | - * @return string |
|
307 | - */ |
|
308 | - private function _get_event_link($event, $full_link = true) |
|
309 | - { |
|
310 | - $url = get_permalink($event->ID()); |
|
311 | - |
|
312 | - return $full_link ? '<a href="' . $url . '">' . $event->get('EVT_name') . '</a>' : $url; |
|
313 | - } |
|
22 | + /** |
|
23 | + * Will hold the EE_Event if available |
|
24 | + * |
|
25 | + * @var EE_Event |
|
26 | + */ |
|
27 | + protected $_event; |
|
28 | + |
|
29 | + |
|
30 | + public function __construct() |
|
31 | + { |
|
32 | + parent::__construct(); |
|
33 | + } |
|
34 | + |
|
35 | + |
|
36 | + protected function _init_props() |
|
37 | + { |
|
38 | + $this->label = __('Event Shortcodes', 'event_espresso'); |
|
39 | + $this->description = __('All shortcodes specific to event related data', 'event_espresso'); |
|
40 | + $this->_shortcodes = array( |
|
41 | + '[EVENT_ID]' => __( |
|
42 | + 'Will be replaced by the event ID of an event', |
|
43 | + 'event_espresso' |
|
44 | + ), |
|
45 | + '[EVENT]' => __('The name of the event', 'event_espresso'), |
|
46 | + '[EVENT_NAME]' => __( |
|
47 | + "This also can be used for the name of the event", |
|
48 | + 'event_espresso' |
|
49 | + ), |
|
50 | + '[EVENT_PHONE]' => __( |
|
51 | + 'The phone number for the event (usually an info number)', |
|
52 | + 'event_espresso' |
|
53 | + ), |
|
54 | + '[EVENT_DESCRIPTION]' => __('The description of the event', 'event_espresso'), |
|
55 | + '[EVENT_EXCERPT]' => __( |
|
56 | + 'This gets parsed to the value for the excerpt field in the event or blank if there is no excerpt.', |
|
57 | + 'event_espresso' |
|
58 | + ), |
|
59 | + '[EVENT_LINK]' => __('A link associated with the event', 'event_espresso'), |
|
60 | + '[EVENT_URL]' => __( |
|
61 | + 'A link to the event set up on the host site.', |
|
62 | + 'event_espresso' |
|
63 | + ), |
|
64 | + '[VIRTUAL_URL]' => __( |
|
65 | + 'What was used for the "URL of Event" field in the Venue settings', |
|
66 | + 'event_espresso' |
|
67 | + ), |
|
68 | + '[VIRTUAL_PHONE]' => __( |
|
69 | + 'An alternate phone number for the event. Typically used as a "call-in" number', |
|
70 | + 'event_espresso' |
|
71 | + ), |
|
72 | + '[EVENT_IMAGE]' => __( |
|
73 | + 'This will parse to the Feature image for the event.', |
|
74 | + 'event_espresso' |
|
75 | + ), |
|
76 | + '[EVENT_IMAGE_*]' => sprintf( |
|
77 | + __( |
|
78 | + 'This will parse to the Feature image for the event, %1$ssize%2$s can be set to determine the size of the image loaded by the shortcode. The %1$swidth%2$s and/or %1$sheight%2$s can also be set to determine the width and height of the image when output. By default the shortcode will load the %1$sthumbnail%2$s image size.', |
|
79 | + 'event_espresso' |
|
80 | + ), |
|
81 | + '<code>', |
|
82 | + '</code>' |
|
83 | + ), |
|
84 | + '[EVENT_TOTAL_AVAILABLE_SPACES_*]' => sprintf( |
|
85 | + __( |
|
86 | + 'This will parse to the total available spaces for an event. Calculating total spaces is approximate because it is dependent on the complexity of limits on your event. There are two methods of calculation (which can be indicated by the %1$smethod%2$s param on the shortcode). %1$scurrent%2$s which will do a more accurate calculation of total available spaces based on current sales, and %1$sfull%2$s which will be the maximum total available spaces that is on the event in optimal conditions. The shortcode will default to current.', |
|
87 | + 'event_espresso' |
|
88 | + ), |
|
89 | + '<code>', |
|
90 | + '</code>' |
|
91 | + ), |
|
92 | + '[EVENT_TOTAL_SPOTS_TAKEN]' => __( |
|
93 | + 'This shortcode will parse to the output the total approved registrations for this event', |
|
94 | + 'event_espresso' |
|
95 | + ), |
|
96 | + '[EVENT_FACEBOOK_URL]' => __( |
|
97 | + 'This will return the Facebook URL for the event if you have it set via custom field in your event, otherwise it will use the Facebook URL set in "Your Organization Settings". To set the facebook url in your event, add a custom field with the key as <code>event_facebook</code> and the value as your facebook url.', |
|
98 | + 'event_espresso' |
|
99 | + ), |
|
100 | + '[EVENT_TWITTER_URL]' => __( |
|
101 | + 'This will return the Twitter URL for the event if you have it set via custom field in your event, otherwise it will use the Twitter URL set in "Your Organization Settings". To set the facebook url in your event, add a custom field with the key as <code>event_twitter</code> and the value as your facebook url', |
|
102 | + 'event_espresso' |
|
103 | + ), |
|
104 | + '[EVENT_META_*]' => sprintf( |
|
105 | + __( |
|
106 | + 'This is a special dynamic shortcode. After the "*", add the exact name for your custom field, if there is a value set for that custom field within the event then it will be output in place of this shortcode. If you use shortcodes within your custom fields set %1$sdo_shortcode=true%2$s at the end of the shortcode to run the value through the do_shortcode function. ', |
|
107 | + 'event_espresso' |
|
108 | + ), |
|
109 | + '<code>', |
|
110 | + '</code>' |
|
111 | + ), |
|
112 | + '[REGISTRATION_LIST_TABLE_FOR_EVENT_URL]' => __( |
|
113 | + 'This parses to the url for the registration list table filtered by registrations for this event.', |
|
114 | + 'event_espresso' |
|
115 | + ), |
|
116 | + ); |
|
117 | + } |
|
118 | + |
|
119 | + |
|
120 | + protected function _parser($shortcode) |
|
121 | + { |
|
122 | + |
|
123 | + |
|
124 | + $this->_event = $this->_data instanceof EE_Event ? $this->_data : null; |
|
125 | + |
|
126 | + // if no event, then let's see if there is a reg_obj. If there IS, then we'll try and grab the event from the reg_obj instead. |
|
127 | + if (empty($this->_event)) { |
|
128 | + $aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null; |
|
129 | + $aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee; |
|
130 | + |
|
131 | + $this->_event = $aee instanceof EE_Messages_Addressee && $aee->reg_obj instanceof EE_Registration |
|
132 | + ? $aee->reg_obj->event() : null; |
|
133 | + } |
|
134 | + |
|
135 | + |
|
136 | + // If there is no event objecdt by now then get out. |
|
137 | + if (! $this->_event instanceof EE_Event) { |
|
138 | + return ''; |
|
139 | + } |
|
140 | + |
|
141 | + switch ($shortcode) { |
|
142 | + case '[EVENT_ID]': |
|
143 | + return $this->_event->ID(); |
|
144 | + break; |
|
145 | + |
|
146 | + case '[EVENT]': |
|
147 | + case '[EVENT_NAME]': |
|
148 | + return $this->_event->get('EVT_name'); |
|
149 | + break; |
|
150 | + |
|
151 | + case '[EVENT_PHONE]': |
|
152 | + return $this->_event->get('EVT_phone'); |
|
153 | + break; |
|
154 | + |
|
155 | + case '[EVENT_DESCRIPTION]': |
|
156 | + return $this->_event->get('EVT_desc'); |
|
157 | + break; |
|
158 | + |
|
159 | + case '[EVENT_EXCERPT]': |
|
160 | + return $this->_event->get('EVT_short_desc'); |
|
161 | + break; |
|
162 | + |
|
163 | + case '[EVENT_LINK]': |
|
164 | + return $this->_get_event_link($this->_event); |
|
165 | + break; |
|
166 | + |
|
167 | + case '[EVENT_URL]': |
|
168 | + return $this->_get_event_link($this->_event, false); |
|
169 | + break; |
|
170 | + |
|
171 | + case '[VIRTUAL_URL]': |
|
172 | + $venue = $this->_event->get_first_related('Venue'); |
|
173 | + if (empty($venue)) { |
|
174 | + return ''; |
|
175 | + } |
|
176 | + return $venue->get('VNU_virtual_url'); |
|
177 | + |
|
178 | + case '[VIRTUAL_PHONE]': |
|
179 | + $venue = $this->_event->get_first_related('Venue'); |
|
180 | + if (empty($venue)) { |
|
181 | + return ''; |
|
182 | + } |
|
183 | + return $venue->get('VNU_virtual_phone'); |
|
184 | + break; |
|
185 | + |
|
186 | + case '[EVENT_IMAGE]': |
|
187 | + $image = $this->_event->feature_image_url(array(600, 300)); |
|
188 | + // @todo: eventually we should make this an attribute shortcode so that em can send along what size they want returned. |
|
189 | + return ! empty($image) |
|
190 | + ? '<img src="' . $image . '" alt="' |
|
191 | + . sprintf( |
|
192 | + esc_attr__('%s Feature Image', 'event_espresso'), |
|
193 | + $this->_event->get('EVT_name') |
|
194 | + ) . '" />' |
|
195 | + : ''; |
|
196 | + break; |
|
197 | + |
|
198 | + case '[EVENT_FACEBOOK_URL]': |
|
199 | + $facebook_url = $this->_event->get_post_meta('event_facebook', true); |
|
200 | + return empty($facebook_url) ? EE_Registry::instance()->CFG->organization->get_pretty('facebook') |
|
201 | + : $facebook_url; |
|
202 | + break; |
|
203 | + |
|
204 | + case '[EVENT_TWITTER_URL]': |
|
205 | + $twitter_url = $this->_event->get_post_meta('event_twitter', true); |
|
206 | + return empty($twitter_url) ? EE_Registry::instance()->CFG->organization->get_pretty('twitter') |
|
207 | + : $twitter_url; |
|
208 | + break; |
|
209 | + |
|
210 | + case '[EVENT_AUTHOR_EMAIL]': |
|
211 | + $author_id = $this->_event->get('EVT_wp_user'); |
|
212 | + $user_data = get_userdata((int) $author_id); |
|
213 | + return $user_data->user_email; |
|
214 | + break; |
|
215 | + |
|
216 | + case '[EVENT_TOTAL_SPOTS_TAKEN]': |
|
217 | + return EEM_Registration::instance()->count( |
|
218 | + array(array('EVT_ID' => $this->_event->ID(), 'STS_ID' => EEM_Registration::status_id_approved)), |
|
219 | + 'REG_ID', |
|
220 | + true |
|
221 | + ); |
|
222 | + break; |
|
223 | + |
|
224 | + case '[REGISTRATION_LIST_TABLE_FOR_EVENT_URL]': |
|
225 | + return EEH_URL::add_query_args_and_nonce( |
|
226 | + array( |
|
227 | + 'event_id' => $this->_event->ID(), |
|
228 | + 'page' => 'espresso_registrations', |
|
229 | + 'action' => 'default', |
|
230 | + ), |
|
231 | + admin_url('admin.php'), |
|
232 | + true |
|
233 | + ); |
|
234 | + break; |
|
235 | + } |
|
236 | + |
|
237 | + if (strpos($shortcode, '[EVENT_META_*') !== false) { |
|
238 | + // Strip the shortcode itself from $shortcode leaving any attributes set. |
|
239 | + // Removing the * is correct here as _* is used to indiciate a dynamic shortcode. |
|
240 | + $shortcode = str_replace('[EVENT_META_*', '', $shortcode); |
|
241 | + $shortcode = trim(str_replace(']', '', $shortcode)); |
|
242 | + // Get any attributes set on this shortcode. |
|
243 | + $attrs = $this->_get_shortcode_attrs($shortcode); |
|
244 | + // The meta_key set on the shortcode should always be the first value in the array. |
|
245 | + $meta_key = $attrs[0]; |
|
246 | + // Pull the meta value from the event post. |
|
247 | + $event_meta = $this->_event->get_post_meta($meta_key, true); |
|
248 | + // If we have no event_meta, just return an empty string. |
|
249 | + if (empty($event_meta)) { |
|
250 | + return ''; |
|
251 | + } |
|
252 | + // Add a filter to allow all instances of EVENT_META_* to run through do_shortcode, default to false. |
|
253 | + // Check if a do_shortcode attribute was set to true and if so run $event_meta through that function. |
|
254 | + if (apply_filters('FHEE__EventEspresso_core_libraries_shortcodes_EE_Event_Shortcodes___parser__event_meta_do_shortcode', false) |
|
255 | + || !empty($attrs['do_shortcode']) && filter_var($attrs['do_shortcode'], FILTER_VALIDATE_BOOLEAN) |
|
256 | + ) { |
|
257 | + return do_shortcode($event_meta); |
|
258 | + } |
|
259 | + // Still here? We just need to return the event_meta value as is. |
|
260 | + return $event_meta; |
|
261 | + } |
|
262 | + |
|
263 | + if (strpos($shortcode, '[EVENT_TOTAL_AVAILABLE_SPACES_*') !== false) { |
|
264 | + $attrs = $this->_get_shortcode_attrs($shortcode); |
|
265 | + $method = empty($attrs['method']) ? 'current' : $attrs['method']; |
|
266 | + $method = $method === 'current'; |
|
267 | + $available = $this->_event->total_available_spaces($method); |
|
268 | + return $available === EE_INF ? '∞' : $available; |
|
269 | + } |
|
270 | + |
|
271 | + if (strpos($shortcode, '[EVENT_IMAGE_*') !== false) { |
|
272 | + $attrs = $this->_get_shortcode_attrs($shortcode); |
|
273 | + $width = empty($attrs['width']) ? '' : ' width="' . $attrs['width'] . '"'; |
|
274 | + $height = empty($attrs['height']) ? '' : ' height="' . $attrs['height'] . '"'; |
|
275 | + |
|
276 | + // Size may be set to a string such as 'tumbnail' or "width, height" eg - '200,200' |
|
277 | + if (! empty($attrs['size'])) { |
|
278 | + $size = explode(',', $attrs['size']); |
|
279 | + if (count($size) === 1) { |
|
280 | + $size = $size[0]; |
|
281 | + } |
|
282 | + } else { |
|
283 | + $size = 'thumbnail'; |
|
284 | + } |
|
285 | + |
|
286 | + $image = $this->_event->feature_image_url($size); |
|
287 | + |
|
288 | + return ! empty($image) |
|
289 | + ? '<img src="' . $image . '" alt="' |
|
290 | + . sprintf( |
|
291 | + esc_attr__('%s Feature Image', 'event_espresso'), |
|
292 | + $this->_event->get('EVT_name') |
|
293 | + ) . '"' . $width . $height . '/>' |
|
294 | + : ''; |
|
295 | + } |
|
296 | + |
|
297 | + return ''; |
|
298 | + } |
|
299 | + |
|
300 | + |
|
301 | + /** |
|
302 | + * returns the link to the event |
|
303 | + * |
|
304 | + * @param boolean $full_link if TRUE (default) we return the html for the name of the event linked to the event. |
|
305 | + * Otherwise we just return the url of the event. |
|
306 | + * @return string |
|
307 | + */ |
|
308 | + private function _get_event_link($event, $full_link = true) |
|
309 | + { |
|
310 | + $url = get_permalink($event->ID()); |
|
311 | + |
|
312 | + return $full_link ? '<a href="' . $url . '">' . $event->get('EVT_name') . '</a>' : $url; |
|
313 | + } |
|
314 | 314 | } |
@@ -38,103 +38,103 @@ |
||
38 | 38 | * @since 4.0 |
39 | 39 | */ |
40 | 40 | if (function_exists('espresso_version')) { |
41 | - if (! function_exists('espresso_duplicate_plugin_error')) { |
|
42 | - /** |
|
43 | - * espresso_duplicate_plugin_error |
|
44 | - * displays if more than one version of EE is activated at the same time |
|
45 | - */ |
|
46 | - function espresso_duplicate_plugin_error() |
|
47 | - { |
|
48 | - ?> |
|
41 | + if (! function_exists('espresso_duplicate_plugin_error')) { |
|
42 | + /** |
|
43 | + * espresso_duplicate_plugin_error |
|
44 | + * displays if more than one version of EE is activated at the same time |
|
45 | + */ |
|
46 | + function espresso_duplicate_plugin_error() |
|
47 | + { |
|
48 | + ?> |
|
49 | 49 | <div class="error"> |
50 | 50 | <p> |
51 | 51 | <?php |
52 | - echo esc_html__( |
|
53 | - 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
54 | - 'event_espresso' |
|
55 | - ); ?> |
|
52 | + echo esc_html__( |
|
53 | + 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
54 | + 'event_espresso' |
|
55 | + ); ?> |
|
56 | 56 | </p> |
57 | 57 | </div> |
58 | 58 | <?php |
59 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
60 | - } |
|
61 | - } |
|
62 | - add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
59 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
60 | + } |
|
61 | + } |
|
62 | + add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
63 | 63 | } else { |
64 | - define('EE_MIN_PHP_VER_REQUIRED', '5.4.0'); |
|
65 | - if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
66 | - /** |
|
67 | - * espresso_minimum_php_version_error |
|
68 | - * |
|
69 | - * @return void |
|
70 | - */ |
|
71 | - function espresso_minimum_php_version_error() |
|
72 | - { |
|
73 | - ?> |
|
64 | + define('EE_MIN_PHP_VER_REQUIRED', '5.4.0'); |
|
65 | + if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
66 | + /** |
|
67 | + * espresso_minimum_php_version_error |
|
68 | + * |
|
69 | + * @return void |
|
70 | + */ |
|
71 | + function espresso_minimum_php_version_error() |
|
72 | + { |
|
73 | + ?> |
|
74 | 74 | <div class="error"> |
75 | 75 | <p> |
76 | 76 | <?php |
77 | - printf( |
|
78 | - esc_html__( |
|
79 | - 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
80 | - 'event_espresso' |
|
81 | - ), |
|
82 | - EE_MIN_PHP_VER_REQUIRED, |
|
83 | - PHP_VERSION, |
|
84 | - '<br/>', |
|
85 | - '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>' |
|
86 | - ); |
|
87 | - ?> |
|
77 | + printf( |
|
78 | + esc_html__( |
|
79 | + 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
80 | + 'event_espresso' |
|
81 | + ), |
|
82 | + EE_MIN_PHP_VER_REQUIRED, |
|
83 | + PHP_VERSION, |
|
84 | + '<br/>', |
|
85 | + '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>' |
|
86 | + ); |
|
87 | + ?> |
|
88 | 88 | </p> |
89 | 89 | </div> |
90 | 90 | <?php |
91 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
92 | - } |
|
91 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
92 | + } |
|
93 | 93 | |
94 | - add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
95 | - } else { |
|
96 | - define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
97 | - /** |
|
98 | - * espresso_version |
|
99 | - * Returns the plugin version |
|
100 | - * |
|
101 | - * @return string |
|
102 | - */ |
|
103 | - function espresso_version() |
|
104 | - { |
|
105 | - return apply_filters('FHEE__espresso__espresso_version', '4.10.3.rc.031'); |
|
106 | - } |
|
94 | + add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
95 | + } else { |
|
96 | + define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
97 | + /** |
|
98 | + * espresso_version |
|
99 | + * Returns the plugin version |
|
100 | + * |
|
101 | + * @return string |
|
102 | + */ |
|
103 | + function espresso_version() |
|
104 | + { |
|
105 | + return apply_filters('FHEE__espresso__espresso_version', '4.10.3.rc.031'); |
|
106 | + } |
|
107 | 107 | |
108 | - /** |
|
109 | - * espresso_plugin_activation |
|
110 | - * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
111 | - */ |
|
112 | - function espresso_plugin_activation() |
|
113 | - { |
|
114 | - update_option('ee_espresso_activation', true); |
|
115 | - } |
|
108 | + /** |
|
109 | + * espresso_plugin_activation |
|
110 | + * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
111 | + */ |
|
112 | + function espresso_plugin_activation() |
|
113 | + { |
|
114 | + update_option('ee_espresso_activation', true); |
|
115 | + } |
|
116 | 116 | |
117 | - register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
117 | + register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
118 | 118 | |
119 | - require_once __DIR__ . '/core/bootstrap_espresso.php'; |
|
120 | - bootstrap_espresso(); |
|
121 | - } |
|
119 | + require_once __DIR__ . '/core/bootstrap_espresso.php'; |
|
120 | + bootstrap_espresso(); |
|
121 | + } |
|
122 | 122 | } |
123 | 123 | if (! function_exists('espresso_deactivate_plugin')) { |
124 | - /** |
|
125 | - * deactivate_plugin |
|
126 | - * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
127 | - * |
|
128 | - * @access public |
|
129 | - * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
130 | - * @return void |
|
131 | - */ |
|
132 | - function espresso_deactivate_plugin($plugin_basename = '') |
|
133 | - { |
|
134 | - if (! function_exists('deactivate_plugins')) { |
|
135 | - require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
136 | - } |
|
137 | - unset($_GET['activate'], $_REQUEST['activate']); |
|
138 | - deactivate_plugins($plugin_basename); |
|
139 | - } |
|
124 | + /** |
|
125 | + * deactivate_plugin |
|
126 | + * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
127 | + * |
|
128 | + * @access public |
|
129 | + * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
130 | + * @return void |
|
131 | + */ |
|
132 | + function espresso_deactivate_plugin($plugin_basename = '') |
|
133 | + { |
|
134 | + if (! function_exists('deactivate_plugins')) { |
|
135 | + require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
136 | + } |
|
137 | + unset($_GET['activate'], $_REQUEST['activate']); |
|
138 | + deactivate_plugins($plugin_basename); |
|
139 | + } |
|
140 | 140 | } |