Completed
Branch BUG-9774-email-validation (c72797)
by
unknown
1171:55 queued 1157:09
created

EED_Single_Page_Checkout   F

Complexity

Total Complexity 165

Size/Duplication

Total Lines 1446
Duplicated Lines 1.38 %

Coupling/Cohesion

Components 1
Dependencies 24

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 165
c 1
b 0
f 1
lcom 1
cbo 24
dl 20
loc 1446
rs 0.5665

49 Methods

Rating   Name   Duplication   Size   Complexity  
C _initialize() 0 70 9
D _final_verifications() 0 44 9
A instance() 0 4 1
A cart() 0 3 1
A transaction() 0 3 1
A set_hooks() 0 3 1
A set_hooks_admin() 0 19 2
A process_ajax_request() 0 4 1
A display_reg_step() 0 3 1
A process_reg_step() 0 3 1
A update_reg_step() 0 3 1
A update_checkout() 0 3 1
A load_request_handler() 0 6 2
A set_definitions() 0 10 1
C load_reg_steps() 0 36 8
B get_reg_steps() 0 32 2
A registration_checkout_for_admin() 0 9 1
A process_registration_from_admin() 0 19 4
A run() 0 9 4
A init() 0 3 1
B _initialize_checkout() 0 23 5
B _get_request_vars() 0 24 2
A _display_request_vars() 0 13 2
A _get_first_step() 0 4 2
D _load_and_instantiate_reg_steps() 0 46 10
C _load_and_instantiate_reg_step() 9 53 10
A _get_transaction_and_cart_for_previous_visit() 8 15 2
A _get_cart_for_transaction() 0 3 1
A get_cart_for_transaction() 0 3 1
A _get_cart_for_current_session_and_setup_new_transaction() 0 17 2
A _initialize_transaction() 0 19 3
D _get_registrations() 0 35 10
B _initialize_registrations() 0 27 5
A sort_registrations_by_REG_count() 0 7 3
B _initialize_reg_steps() 0 23 6
D _check_form_submission() 3 43 10
B _process_form_action() 0 55 8
A add_styles_and_scripts() 0 9 2
B translate_js_strings() 0 41 1
B enqueue_styles_and_scripts() 0 25 1
B _display_spco_reg_form() 0 62 6
A add_extra_finalize_registration_inputs() 0 5 2
A display_registration_footer() 0 19 3
A unlock_transaction() 0 3 1
A _setup_redirect() 0 9 4
B go_to_next_step() 0 21 5
B _handle_json_response() 0 25 2
A _handle_html_redirects() 0 18 3
A set_checkout_anchor() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EED_Single_Page_Checkout often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EED_Single_Page_Checkout, and based on these observations, apply Extract Interface, too.

1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {exit('No direct script access allowed');}
2
/**
3
 * Single Page Checkout (SPCO)
4
 *
5
 * @package			Event Espresso
6
 * @subpackage		/modules/single_page_checkout/
7
 * @author				Brent Christensen
8
 *
9
 */
10
class EED_Single_Page_Checkout  extends EED_Module {
11
12
13
	/**
14
	 * $_initialized - has the SPCO controller already been initialized ?
15
	 * @access private
16
	 * @var bool $_initialized
17
	 */
18
	private static $_initialized = false;
19
20
21
	/**
22
	 * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
23
	 *
24
	 * @access private
25
	 * @var bool $_valid_checkout
26
	 */
27
	private static $_checkout_verified = true;
28
29
	/**
30
	 * 	$_reg_steps_array - holds initial array of reg steps
31
	 * 	@access private
32
	 *	@var array $_reg_steps_array
33
	 */
34
	private static $_reg_steps_array = array();
35
36
	/**
37
	 * 	$checkout - EE_Checkout object for handling the properties of the current checkout process
38
	 * 	@access public
39
	 *	@var EE_Checkout $checkout
40
	 */
41
	public $checkout;
42
43
44
45
46
	/**
47
	 * @return EED_Single_Page_Checkout
48
	 */
49
	public static function instance() {
50
		add_filter( 'EED_Single_Page_Checkout__SPCO_active', '__return_true' );
51
		return parent::get_instance( __CLASS__ );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (get_instance() instead of instance()). Are you sure this is correct? If so, you might want to change this to $this->get_instance().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
52
	}
53
54
55
56
	/**
57
	 * @return EE_CART
58
	 */
59
	public function cart() {
60
		return $this->checkout->cart;
61
	}
62
63
64
65
	/**
66
	 * @return EE_Transaction
67
	 */
68
	public function transaction() {
69
		return $this->checkout->transaction;
70
	}
71
72
73
74
	/**
75
	 *    set_hooks - for hooking into EE Core, other modules, etc
76
	 *
77
	 * @access    public
78
	 * @return    void
79
	 * @throws \EE_Error
80
	 */
81
	public static function set_hooks() {
82
		EED_Single_Page_Checkout::set_definitions();
83
	}
84
85
86
87
	/**
88
	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
89
	 *
90
	 * @access    public
91
	 * @return    void
92
	 * @throws \EE_Error
93
	 */
94
	public static function set_hooks_admin() {
95
		EED_Single_Page_Checkout::set_definitions();
96
		if ( defined( 'DOING_AJAX' )) {
97
			// going to start an output buffer in case anything gets accidentally output that might disrupt our JSON response
98
			ob_start();
99
			EED_Single_Page_Checkout::load_request_handler();
100
			EED_Single_Page_Checkout::load_reg_steps();
101
		} else {
102
			// hook into the top of pre_get_posts to set the reg step routing, which gives other modules or plugins a chance to modify the reg steps, but just before the routes get called
103
			add_action( 'pre_get_posts', array( 'EED_Single_Page_Checkout', 'load_reg_steps' ), 1 );
104
		}
105
		// set ajax hooks
106
		add_action( 'wp_ajax_process_reg_step', array( 'EED_Single_Page_Checkout', 'process_reg_step' ));
107
		add_action( 'wp_ajax_nopriv_process_reg_step', array( 'EED_Single_Page_Checkout', 'process_reg_step' ));
108
		add_action( 'wp_ajax_display_spco_reg_step', array( 'EED_Single_Page_Checkout', 'display_reg_step' ));
109
		add_action( 'wp_ajax_nopriv_display_spco_reg_step', array( 'EED_Single_Page_Checkout', 'display_reg_step' ));
110
		add_action( 'wp_ajax_update_reg_step', array( 'EED_Single_Page_Checkout', 'update_reg_step' ));
111
		add_action( 'wp_ajax_nopriv_update_reg_step', array( 'EED_Single_Page_Checkout', 'update_reg_step' ));
112
	}
113
114
115
116
	/**
117
	 *    process ajax request
118
	 *
119
	 * @param string $ajax_action
120
	 * @throws \EE_Error
121
	 */
122
	public static function process_ajax_request( $ajax_action ) {
123
		EE_Registry::instance()->REQ->set( 'action', $ajax_action );
124
		EED_Single_Page_Checkout::instance()->_initialize();
125
	}
126
127
128
129
	/**
130
	 *    ajax display registration step
131
	 *
132
	 * @throws \EE_Error
133
	 */
134
	public static function display_reg_step() {
135
		EED_Single_Page_Checkout::process_ajax_request( 'display_spco_reg_step' );
136
	}
137
138
139
140
	/**
141
	 *    ajax process registration step
142
	 *
143
	 * @throws \EE_Error
144
	 */
145
	public static function process_reg_step() {
146
		EED_Single_Page_Checkout::process_ajax_request( 'process_reg_step' );
147
	}
148
149
150
151
	/**
152
	 *    ajax process registration step
153
	 *
154
	 * @throws \EE_Error
155
	 */
156
	public static function update_reg_step() {
157
		EED_Single_Page_Checkout::process_ajax_request( 'update_reg_step' );
158
	}
159
160
161
162
	/**
163
	 *   update_checkout
164
	 *
165
	 * @access public
166
	 * @return void
167
	 * @throws \EE_Error
168
	 */
169
	public static function update_checkout() {
170
		EED_Single_Page_Checkout::process_ajax_request( 'update_checkout' );
171
	}
172
173
174
175
	/**
176
	 *    load_request_handler
177
	 *
178
	 * @access    public
179
	 * @return    void
180
	 */
181
	public static function load_request_handler() {
182
		// load core Request_Handler class
183
		if ( ! isset( EE_Registry::instance()->REQ )) {
184
			EE_Registry::instance()->load_core( 'Request_Handler' );
185
		}
186
	}
187
188
189
190
	/**
191
	 *    set_definitions
192
	 *
193
	 * @access    public
194
	 * @return    void
195
	 * @throws \EE_Error
196
	 */
197
	public static function set_definitions() {
198
		define( 'SPCO_BASE_PATH', rtrim( str_replace( array( '\\', '/' ), DS, plugin_dir_path( __FILE__ )), DS ) . DS );
199
		define( 'SPCO_CSS_URL', plugin_dir_url( __FILE__ ) . 'css' . DS );
200
		define( 'SPCO_IMG_URL', plugin_dir_url( __FILE__ ) . 'img' . DS );
201
		define( 'SPCO_JS_URL', plugin_dir_url( __FILE__ ) . 'js' . DS );
202
		define( 'SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS );
203
		define( 'SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS );
204
		define( 'SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS );
205
		EEH_Autoloader::register_autoloaders_for_each_file_in_folder( SPCO_BASE_PATH, TRUE );
206
	}
207
208
209
210
	/**
211
	 * load_reg_steps
212
	 * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
213
	 *
214
	 * @access    private
215
	 * @throws EE_Error
216
	 * @return    array
217
	 */
218
	public static function load_reg_steps() {
219
		static $reg_steps_loaded = FALSE;
220
		if ( $reg_steps_loaded ) {
221
			return;
222
		}
223
		// filter list of reg_steps
224
		$reg_steps_to_load = apply_filters(
225
			'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
226
			EED_Single_Page_Checkout::get_reg_steps()
227
		);
228
		// sort by key (order)
229
		ksort( $reg_steps_to_load );
230
		// loop through folders
231
		foreach ( $reg_steps_to_load as $order => $reg_step ) {
232
			// we need a
233
			if ( isset( $reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'] )) {
234
				// copy over to the reg_steps_array
235
				EED_Single_Page_Checkout::$_reg_steps_array[ $order ] = $reg_step;
236
				// register custom key route for each reg step
237
				// ie: step=>"slug" - this is the entire reason we load the reg steps array now
238
				EE_Config::register_route( $reg_step['slug'], 'EED_Single_Page_Checkout', 'run', 'step' );
239
				// add AJAX or other hooks
240
				if ( isset( $reg_step['has_hooks'] ) && $reg_step['has_hooks'] ) {
241
					// setup autoloaders if necessary
242
					if ( ! class_exists( $reg_step['class_name'] )) {
243
						EEH_Autoloader::register_autoloaders_for_each_file_in_folder( $reg_step['file_path'], TRUE );
244
					}
245
					if ( is_callable( $reg_step['class_name'], 'set_hooks' )) {
246
						call_user_func( array( $reg_step['class_name'], 'set_hooks' ));
247
					}
248
				}
249
			}
250
		}
251
252
		$reg_steps_loaded = TRUE;
253
	}
254
255
256
257
	/**
258
	 *    get_reg_steps
259
	 *
260
	 * @access 	public
261
	 * @return 	array
262
	 */
263
	public static function get_reg_steps() {
264
		$reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
265
		if ( empty( $reg_steps )) {
266
			$reg_steps = array(
267
				10 => array(
268
					'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information',
269
					'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
270
					'slug' => 'attendee_information',
271
					'has_hooks' => FALSE
272
				),
273
				20 => array(
274
					'file_path' => SPCO_REG_STEPS_PATH . 'registration_confirmation',
275
					'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
276
					'slug' => 'registration_confirmation',
277
					'has_hooks' => FALSE
278
				),
279
				30 => array(
280
					'file_path' => SPCO_REG_STEPS_PATH . 'payment_options',
281
					'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
282
					'slug' => 'payment_options',
283
					'has_hooks' => TRUE
284
				),
285
				999 => array(
286
					'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration',
287
					'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
288
					'slug' => 'finalize_registration',
289
					'has_hooks' => FALSE
290
				)
291
			);
292
		}
293
		return $reg_steps;
294
	}
295
296
297
298
	/**
299
	 *    registration_checkout_for_admin
300
	 *
301
	 * @access    public
302
	 * @return    string
303
	 * @throws \EE_Error
304
	 */
305
	public static function registration_checkout_for_admin() {
306
		EED_Single_Page_Checkout::load_reg_steps();
307
		EE_Registry::instance()->REQ->set( 'step', 'attendee_information' );
308
		EE_Registry::instance()->REQ->set( 'action', 'display_spco_reg_step' );
309
		EE_Registry::instance()->REQ->set( 'process_form_submission', false );
310
		EED_Single_Page_Checkout::instance()->_initialize();
311
		EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
312
		return EE_Registry::instance()->REQ->get_output();
313
	}
314
315
316
317
	/**
318
	 *    process_registration_from_admin
319
	 *
320
	 * @access    public
321
	 * @return    int
322
	 * @throws \EE_Error
323
	 */
324
	public static function process_registration_from_admin() {
325
		EED_Single_Page_Checkout::load_reg_steps();
326
		EE_Registry::instance()->REQ->set( 'step', 'attendee_information' );
327
		EE_Registry::instance()->REQ->set( 'action', 'process_reg_step' );
328
		EE_Registry::instance()->REQ->set( 'process_form_submission', true );
329
		EED_Single_Page_Checkout::instance()->_initialize();
330
		if ( EED_Single_Page_Checkout::instance()->checkout->current_step->completed() ) {
331
			$final_reg_step = end( EED_Single_Page_Checkout::instance()->checkout->reg_steps );
332
			if ( $final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration ) {
333
				EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated( $final_reg_step );
334
				if ( $final_reg_step->process_reg_step() ) {
335
					$final_reg_step->set_completed();
336
					EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
337
					return EED_Single_Page_Checkout::instance()->checkout->transaction;
338
				}
339
			}
340
		}
341
		return FALSE;
342
	}
343
344
345
346
	/**
347
	 *    run
348
	 *
349
	 * @access    public
350
	 * @param WP_Query $WP_Query
351
	 * @return    void
352
	 * @throws \EE_Error
353
	 */
354
	public function run( $WP_Query ) {
355
		if (
356
			$WP_Query instanceof WP_Query
0 ignored issues
show
Bug introduced by
The class WP_Query does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
357
			&& $WP_Query->is_main_query()
358
			&& apply_filters( 'FHEE__EED_Single_Page_Checkout__run', true )
359
		) {
360
			$this->_initialize();
361
		}
362
	}
363
364
365
366
	/**
367
	 *    run
368
	 *
369
	 * @access    public
370
	 * @param WP_Query $WP_Query
371
	 * @return    void
372
	 * @throws \EE_Error
373
	 */
374
	public static function init( $WP_Query ) {
375
		EED_Single_Page_Checkout::instance()->run( $WP_Query );
376
	}
377
378
379
380
	/**
381
	 *    _initialize - initial module setup
382
	 *
383
	 * @access    private
384
	 * @throws EE_Error
385
	 * @return    void
386
	 */
387
	private function _initialize() {
388
		// ensure SPCO doesn't run twice
389
		if ( EED_Single_Page_Checkout::$_initialized ) {
390
			return;
391
		}
392
		try {
393
			// setup the EE_Checkout object
394
			$this->checkout = $this->_initialize_checkout();
395
			// filter checkout
396
			$this->checkout = apply_filters( 'FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout );
397
			// get the $_GET
398
			$this->_get_request_vars();
399
			// filter continue_reg
400
			$this->checkout->continue_reg = apply_filters( 'FHEE__EED_Single_Page_Checkout__init___continue_reg', TRUE, $this->checkout );
401
			// load the reg steps array
402
			if ( ! $this->_load_and_instantiate_reg_steps() ) {
403
				EED_Single_Page_Checkout::$_initialized = true;
404
				return;
405
			}
406
			// set the current step
407
			$this->checkout->set_current_step( $this->checkout->step );
408
			// and the next step
409
			$this->checkout->set_next_step();
410
			// was there already a valid transaction in the checkout from the session ?
411
			if ( ! $this->checkout->transaction instanceof EE_Transaction ) {
412
				// get transaction from db or session
413
				$this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
414
					? $this->_get_transaction_and_cart_for_previous_visit()
415
					: $this->_get_cart_for_current_session_and_setup_new_transaction();
416
				if ( ! $this->checkout->transaction instanceof EE_Transaction ) {
417
					// add some style and make it dance
418
					$this->checkout->transaction = EE_Transaction::new_instance();
419
					$this->add_styles_and_scripts();
420
					EED_Single_Page_Checkout::$_initialized = true;
421
					return;
422
				}
423
				// and the registrations for the transaction
424
				$this->_get_registrations( $this->checkout->transaction );
425
			}
426
			// verify that everything has been setup correctly
427
			if ( ! $this->_final_verifications() ) {
428
				EED_Single_Page_Checkout::$_initialized = true;
429
				return;
430
			}
431
			// lock the transaction
432
			$this->checkout->transaction->lock();
433
			// make sure all of our cached objects are added to their respective model entity mappers
434
			$this->checkout->refresh_all_entities();
435
			// set amount owing
436
			$this->checkout->amount_owing = $this->checkout->transaction->remaining();
437
			// initialize each reg step, which gives them the chance to potentially alter the process
438
			$this->_initialize_reg_steps();
439
			// DEBUG LOG
440
			//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
441
			// get reg form
442
			$this->_check_form_submission();
443
			// checkout the action!!!
444
			$this->_process_form_action();
445
			// add some style and make it dance
446
			$this->add_styles_and_scripts();
447
			// kk... SPCO has successfully run
448
			EED_Single_Page_Checkout::$_initialized = TRUE;
449
			// set no cache headers and constants
450
			EE_System::do_not_cache();
451
			// add anchor
452
			add_action( 'loop_start', array( $this, 'set_checkout_anchor' ), 1 );
453
		} catch ( Exception $e ) {
454
			EE_Error::add_error( $e->getMessage(), __FILE__, __FUNCTION__, __LINE__ );
455
		}
456
	}
457
458
459
460
	/**
461
	 *    _initialize_checkout
462
	 * loads and instantiates EE_Checkout
463
	 *
464
	 * @access    private
465
	 * @throws EE_Error
466
	 * @return EE_Checkout
467
	 */
468
	private function _initialize_checkout() {
469
		// look in session for existing checkout
470
		$checkout = EE_Registry::instance()->SSN->checkout();
471
		// verify
472
		if ( ! $checkout instanceof EE_Checkout ) {
473
			// instantiate EE_Checkout object for handling the properties of the current checkout process
474
			$checkout = EE_Registry::instance()->load_file( SPCO_INC_PATH, 'EE_Checkout', 'class', array(), FALSE  );
475
		} else {
476
			if ( $checkout->current_step->is_final_step() && $checkout->exit_spco() === true )  {
477
				$this->unlock_transaction();
478
				wp_safe_redirect( $checkout->redirect_url );
479
				exit();
480
			}
481
		}
482
		$checkout = apply_filters( 'FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout );
483
		// verify again
484
		if ( ! $checkout instanceof EE_Checkout ) {
485
			throw new EE_Error( __( 'The EE_Checkout class could not be loaded.', 'event_espresso' ) );
486
		}
487
		// reset anything that needs a clean slate for each request
488
		$checkout->reset_for_current_request();
489
		return $checkout;
490
	}
491
492
493
494
	/**
495
	 *    _get_request_vars
496
	 *
497
	 * @access    private
498
	 * @return    void
499
	 * @throws \EE_Error
500
	 */
501
	private function _get_request_vars() {
502
		// load classes
503
		EED_Single_Page_Checkout::load_request_handler();
504
		//make sure this request is marked as belonging to EE
505
		EE_Registry::instance()->REQ->set_espresso_page( TRUE );
506
		// which step is being requested ?
507
		$this->checkout->step = EE_Registry::instance()->REQ->get( 'step', $this->_get_first_step() );
508
		// which step is being edited ?
509
		$this->checkout->edit_step = EE_Registry::instance()->REQ->get( 'edit_step', '' );
510
		// and what we're doing on the current step
511
		$this->checkout->action = EE_Registry::instance()->REQ->get( 'action', 'display_spco_reg_step' );
512
		// returning to edit ?
513
		$this->checkout->reg_url_link = EE_Registry::instance()->REQ->get( 'e_reg_url_link', '' );
514
		// or some other kind of revisit ?
515
		$this->checkout->revisit = EE_Registry::instance()->REQ->get( 'revisit', FALSE );
516
		// and whether or not to generate a reg form for this request
517
		$this->checkout->generate_reg_form = EE_Registry::instance()->REQ->get( 'generate_reg_form', TRUE ); 		// TRUE 	FALSE
518
		// and whether or not to process a reg form submission for this request
519
		$this->checkout->process_form_submission = EE_Registry::instance()->REQ->get( 'process_form_submission', FALSE ); 		// TRUE 	FALSE
520
		$this->checkout->process_form_submission = $this->checkout->action !== 'display_spco_reg_step'
521
			? $this->checkout->process_form_submission
522
			: FALSE; 		// TRUE 	FALSE
523
		// $this->_display_request_vars();
524
	}
525
526
527
528
	/**
529
	 *  _display_request_vars
530
	 *
531
	 * @access    protected
532
	 * @return    void
533
	 */
534
	protected function _display_request_vars() {
535
		if ( ! WP_DEBUG ) {
536
			return;
537
		}
538
		EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ );
539
		EEH_Debug_Tools::printr( $this->checkout->step, '$this->checkout->step', __FILE__, __LINE__ );
540
		EEH_Debug_Tools::printr( $this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__ );
541
		EEH_Debug_Tools::printr( $this->checkout->action, '$this->checkout->action', __FILE__, __LINE__ );
542
		EEH_Debug_Tools::printr( $this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__ );
543
		EEH_Debug_Tools::printr( $this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__ );
544
		EEH_Debug_Tools::printr( $this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__ );
545
		EEH_Debug_Tools::printr( $this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__ );
546
	}
547
548
549
550
	/**
551
	 *    _get_first_step
552
	 *  gets slug for first step in $_reg_steps_array
553
	 *
554
	 * @access    private
555
	 * @throws EE_Error
556
	 * @return    array
557
	 */
558
	private function _get_first_step() {
559
		$first_step = reset( EED_Single_Page_Checkout::$_reg_steps_array );
560
		return isset( $first_step['slug'] ) ? $first_step['slug'] : 'attendee_information';
561
	}
562
563
564
565
	/**
566
	 *    _load_and_instantiate_reg_steps
567
	 *  instantiates each reg step based on the loaded reg_steps array
568
	 *
569
	 * @access    private
570
	 * @throws EE_Error
571
	 * @return    bool
572
	 */
573
	private function _load_and_instantiate_reg_steps() {
574
		// have reg_steps already been instantiated ?
575
		if (
576
			empty( $this->checkout->reg_steps ) ||
577
			apply_filters( 'FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout )
578
		) {
579
			// if not, then loop through raw reg steps array
580
			foreach ( EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step ) {
581
				if ( ! $this->_load_and_instantiate_reg_step( $reg_step, $order )) {
582
					return false;
583
				}
584
			}
585
			EE_Registry::instance()->CFG->registration->skip_reg_confirmation = TRUE;
586
			EE_Registry::instance()->CFG->registration->reg_confirmation_last = TRUE;
587
			// skip the registration_confirmation page ?
588
			if ( EE_Registry::instance()->CFG->registration->skip_reg_confirmation ) {
589
				// just remove it from the reg steps array
590
				$this->checkout->remove_reg_step( 'registration_confirmation', false );
591
			} else if (
592
				isset( $this->checkout->reg_steps['registration_confirmation'] )
593
				&& EE_Registry::instance()->CFG->registration->reg_confirmation_last
594
			) {
595
				// set the order to something big like 100
596
				$this->checkout->set_reg_step_order( 'registration_confirmation', 100 );
597
			}
598
			// filter the array for good luck
599
			$this->checkout->reg_steps = apply_filters(
600
				'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
601
				$this->checkout->reg_steps
602
			);
603
			// finally re-sort based on the reg step class order properties
604
			$this->checkout->sort_reg_steps();
605
		} else {
606
			foreach ( $this->checkout->reg_steps as $reg_step ) {
607
				// set all current step stati to FALSE
608
				$reg_step->set_is_current_step( FALSE );
609
			}
610
		}
611
		if ( empty( $this->checkout->reg_steps )) {
612
			EE_Error::add_error( __( 'No Reg Steps were loaded..', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
613
			return false;
614
		}
615
			// make reg step details available to JS
616
		$this->checkout->set_reg_step_JSON_info();
617
		return true;
618
	}
619
620
621
622
	/**
623
	 *     _load_and_instantiate_reg_step
624
	 *
625
	 * @access    private
626
	 * @param array $reg_step
627
	 * @param int   $order
628
	 * @return bool
629
	 */
630
	private function _load_and_instantiate_reg_step( $reg_step = array(), $order = 0 ) {
631
632
		// we need a file_path, class_name, and slug to add a reg step
633
		if ( isset( $reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'] )) {
634
			// if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
635
			if (
636
				$this->checkout->reg_url_link
637
				&& $this->checkout->step !== $reg_step['slug']
638
				&& $reg_step['slug'] !== 'finalize_registration'
639
			) {
640
				return true;
641
			}
642
			// instantiate step class using file path and class name
643
			$reg_step_obj = EE_Registry::instance()->load_file(
644
				$reg_step['file_path'],
645
				$reg_step['class_name'],
646
				'class',
647
				$this->checkout,
648
				FALSE
649
			);
650
			// did we gets the goods ?
651 View Code Duplication
			if ( $reg_step_obj instanceof EE_SPCO_Reg_Step ) {
652
				// set reg step order based on config
653
				$reg_step_obj->set_order( $order );
654
				// add instantiated reg step object to the master reg steps array
655
				$this->checkout->add_reg_step( $reg_step_obj );
656
			} else {
657
				EE_Error::add_error(
658
					__( 'The current step could not be set.', 'event_espresso' ),
659
					__FILE__, __FUNCTION__, __LINE__
660
				);
661
				return false;
662
			}
663
		} else {
664
			if ( WP_DEBUG ) {
665
				EE_Error::add_error(
666
					sprintf(
667
						__( 'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s', 'event_espresso' ),
668
						isset( $reg_step['file_path'] ) ? $reg_step['file_path'] : '',
669
						isset( $reg_step['class_name'] ) ? $reg_step['class_name'] : '',
670
						isset( $reg_step['slug'] ) ? $reg_step['slug'] : '',
671
						'<ul>',
672
						'<li>',
673
						'</li>',
674
						'</ul>'
675
					),
676
					__FILE__, __FUNCTION__, __LINE__
677
				);
678
			}
679
			return false;
680
		}
681
		return true;
682
	}
683
684
685
686
	/**
687
	 * _get_transaction_and_cart_for_previous_visit
688
	 *
689
	 * @access private
690
	 * 	@return mixed EE_Transaction|NULL
691
	 */
692
	private function _get_transaction_and_cart_for_previous_visit() {
693
		/** @var $TXN_model EEM_Transaction */
694
		$TXN_model = EE_Registry::instance()->load_model( 'Transaction' );
695
		// because the reg_url_link is present in the request, this is a return visit to SPCO, so we'll get the transaction data from the db
696
		$transaction = $TXN_model->get_transaction_from_reg_url_link( $this->checkout->reg_url_link );
697
		// verify transaction
698 View Code Duplication
		if ( $transaction instanceof EE_Transaction ) {
699
			// and get the cart that was used for that transaction
700
			$this->checkout->cart = $this->_get_cart_for_transaction( $transaction );
701
			return $transaction;
702
		} else {
703
			EE_Error::add_error( __( 'Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
704
			return NULL;
705
		}
706
	}
707
708
709
710
	/**
711
	 * _get_cart_for_transaction
712
	 *
713
	 * @access private
714
	 * @param EE_Transaction $transaction
715
	 * @return EE_Cart
716
	 */
717
	private function _get_cart_for_transaction( $transaction ) {
718
		return $this->checkout->get_cart_for_transaction( $transaction );
719
	}
720
721
722
723
	/**
724
	 * get_cart_for_transaction
725
	 *
726
	 * @access public
727
	 * @param EE_Transaction $transaction
728
	 * @return EE_Cart
729
	 */
730
	public function get_cart_for_transaction( EE_Transaction $transaction ) {
731
		return $this->checkout->get_cart_for_transaction( $transaction );
732
	}
733
734
735
736
	/**
737
	 * _get_transaction_and_cart_for_current_session
738
	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
739
	 *
740
	 * @access private
741
	 * @return EE_Transaction
742
	 * @throws \EE_Error
743
	 */
744
	private function _get_cart_for_current_session_and_setup_new_transaction() {
745
		//  if there's no transaction, then this is the FIRST visit to SPCO
746
		// so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
747
		$this->checkout->cart = $this->_get_cart_for_transaction( NULL );
0 ignored issues
show
Documentation introduced by
NULL is of type null, but the function expects a object<EE_Transaction>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
748
		// and then create a new transaction
749
		$transaction = $this->_initialize_transaction();
750
		// verify transaction
751
		if ( $transaction instanceof EE_Transaction ) {
752
			// save it so that we have an ID for other objects to use
753
			$transaction->save();
754
			// and save TXN data to the cart
755
			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn( $transaction->ID() );
756
		} else {
757
			EE_Error::add_error( __( 'A Valid Transaction could not be initialized.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
758
		}
759
		return $transaction;
760
	}
761
762
763
764
	/**
765
	 * 	generates a new EE_Transaction object and adds it to the $_transaction property.
766
	 *
767
	 * 	@access private
768
	 * 	@return mixed EE_Transaction|NULL
769
	 */
770
	private function _initialize_transaction() {
771
		try {
772
			// ensure cart totals have been calculated
773
			$this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
774
			// grab the cart grand total
775
			$cart_total = $this->checkout->cart->get_cart_grand_total();
776
			// create new TXN
777
			return EE_Transaction::new_instance( array(
778
				'TXN_timestamp' 	=> time(),
779
				'TXN_reg_steps' 		=> $this->checkout->initialize_txn_reg_steps_array(),
780
				'TXN_total' 				=> $cart_total > 0 ? $cart_total : 0,
781
				'TXN_paid' 				=> 0,
782
				'STS_ID' 					=> EEM_Transaction::failed_status_code,
783
			));
784
		} catch( Exception $e ) {
785
			EE_Error::add_error( $e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
786
		}
787
		return NULL;
788
	}
789
790
791
792
	/**
793
	 * _get_registrations
794
	 *
795
	 * @access private
796
	 * @param EE_Transaction $transaction
797
	 * @return EE_Cart
798
	 * @throws \EE_Error
799
	 */
800
	private function _get_registrations( EE_Transaction $transaction ) {
801
		// first step: grab the registrants  { : o
802
		$registrations = $transaction->registrations( $this->checkout->reg_cache_where_params, true );
803
		// verify registrations have been set
804
		if ( empty( $registrations )) {
805
			// if no cached registrations, then check the db
806
			$registrations = $transaction->registrations( $this->checkout->reg_cache_where_params, false );
807
			// still nothing ? well as long as this isn't a revisit
808
			if ( empty( $registrations ) && ! $this->checkout->revisit ) {
809
				// generate new registrations from scratch
810
				$registrations = $this->_initialize_registrations( $transaction );
811
			}
812
		}
813
		// sort by their original registration order
814
		usort( $registrations, array( 'EED_Single_Page_Checkout', 'sort_registrations_by_REG_count' ));
815
		// then loop thru the array
816
		foreach ( $registrations as $registration ) {
817
			// verify each registration
818
			if ( $registration instanceof EE_Registration ) {
819
				// we display all attendee info for the primary registrant
820
				if ( $this->checkout->reg_url_link === $registration->reg_url_link()
821
				     && $registration->is_primary_registrant()
822
				) {
823
					$this->checkout->primary_revisit = true;
824
					break;
825
				} else if ( $this->checkout->revisit
826
				            && $this->checkout->reg_url_link !== $registration->reg_url_link()
827
				) {
828
					// but hide info if it doesn't belong to you
829
					$transaction->clear_cache( 'Registration', $registration->ID() );
830
				}
831
				$this->checkout->set_reg_status_updated( $registration->ID(), false );
832
			}
833
		}
834
	}
835
836
837
838
	/**
839
	 *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
840
	 *
841
	 * @access private
842
	 * @param EE_Transaction $transaction
843
	 * @return    array
844
	 * @throws \EE_Error
845
	 */
846
	private function _initialize_registrations( EE_Transaction $transaction ) {
847
		$att_nmbr = 0;
848
		$registrations = array();
849
		if ( $transaction instanceof EE_Transaction ) {
850
			/** @type EE_Registration_Processor $registration_processor */
851
			$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
852
			$this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
853
			// now let's add the cart items to the $transaction
854
			foreach ( $this->checkout->cart->get_tickets() as $line_item ) {
855
				//do the following for each ticket of this type they selected
856
				for ( $x = 1; $x <= $line_item->quantity(); $x++ ) {
857
					$att_nmbr++;
858
					$registration = $registration_processor->generate_ONE_registration_from_line_item(
859
						$line_item,
860
						$transaction,
861
						$att_nmbr,
862
						$this->checkout->total_ticket_count
863
					);
864
					if ( $registration instanceof EE_Registration ) {
865
						$registrations[ $registration->ID() ] = $registration;
866
					}
867
				}
868
			}
869
			$registration_processor->fix_reg_final_price_rounding_issue( $transaction );
870
		}
871
		return $registrations;
872
	}
873
874
875
876
	/**
877
	 * sorts registrations by REG_count
878
	 *
879
	 * @access public
880
	 * @param EE_Registration $reg_A
881
	 * @param EE_Registration $reg_B
882
	 * @return array()
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
883
	 */
884
	public static function sort_registrations_by_REG_count( EE_Registration $reg_A, EE_Registration $reg_B ) {
885
		// this shouldn't ever happen within the same TXN, but oh well
886
		if ( $reg_A->count() === $reg_B->count() ) {
887
			return 0;
888
		}
889
		return ( $reg_A->count() > $reg_B->count() ) ? 1 : -1;
890
	}
891
892
893
894
	/**
895
	 *    _final_verifications
896
	 * just makes sure that everything is set up correctly before proceeding
897
	 *
898
	 * @access    private
899
	 * @return    bool
900
	 * @throws \EE_Error
901
	 */
902
	private function _final_verifications() {
903
		// filter checkout
904
		$this->checkout = apply_filters( 'FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout );
905
		//verify that current step is still set correctly
906
		if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step ) {
907
			EE_Error::add_error( __( 'We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
908
			return false;
909
		}
910
		// if returning to SPCO, then verify that primary registrant is set
911
		if ( ! empty( $this->checkout->reg_url_link )) {
912
			$valid_registrant = $this->checkout->transaction->primary_registration();
913
			if ( ! $valid_registrant instanceof EE_Registration ) {
914
				EE_Error::add_error( __( 'We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
915
				return false;
916
			}
917
			$valid_registrant = null;
918
			foreach ( $this->checkout->transaction->registrations( $this->checkout->reg_cache_where_params ) as $registration ) {
919
				if (
920
					$registration instanceof EE_Registration
921
					&& $registration->reg_url_link() === $this->checkout->reg_url_link
922
				) {
923
					$valid_registrant = $registration;
924
				}
925
			}
926
			if ( ! $valid_registrant instanceof EE_Registration ) {
927
				// hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
928
				if ( EED_Single_Page_Checkout::$_checkout_verified ) {
929
					// clear the session, mark the checkout as unverified, and try again
930
					EE_Registry::instance()->SSN->clear_session();
931
					EED_Single_Page_Checkout::$_initialized = false;
932
					EED_Single_Page_Checkout::$_checkout_verified = false;
933
					$this->_initialize();
934
					EE_Error::reset_notices();
935
					return false;
936
				}
937
				EE_Error::add_error( __( 'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
938
				return false;
939
			}
940
		}
941
		// now that things have been kinda sufficiently verified,
942
		// let's add the checkout to the session so that's available other systems
943
		EE_Registry::instance()->SSN->set_checkout( $this->checkout );
944
		return true;
945
	}
946
947
948
949
	/**
950
	 *    _initialize_reg_steps
951
	 * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
952
	 * then loops thru all of the active reg steps and calls the initialize_reg_step() method
953
	 *
954
	 * @access    private
955
	 * @param bool $reinitializing
956
	 * @throws \EE_Error
957
	 */
958
	private function _initialize_reg_steps( $reinitializing = false ) {
959
		$this->checkout->set_reg_step_initiated( $this->checkout->current_step );
960
		// loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
961
		foreach ( $this->checkout->reg_steps as $reg_step ) {
962
			if ( ! $reg_step->initialize_reg_step() ) {
963
				// if not initialized then maybe this step is being removed...
964
				if ( ! $reinitializing && $reg_step->is_current_step() ) {
965
					// if it was the current step, then we need to start over here
966
					$this->_initialize_reg_steps( true );
967
					return;
968
				}
969
				continue;
970
			}
971
			// i18n
972
			$reg_step->translate_js_strings();
973
			if ( $reg_step->is_current_step() ) {
974
				// the text that appears on the reg step form submit button
975
				$reg_step->set_submit_button_text();
976
			}
977
		}
978
		// dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
979
		do_action( "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", $this->checkout->current_step );
980
	}
981
982
983
984
	/**
985
	 * _check_form_submission
986
	 *
987
	 * @access private
988
	 * 	@return void
989
	 */
990
	private function _check_form_submission() {
991
		//does this request require the reg form to be generated ?
992
		if ( $this->checkout->generate_reg_form ) {
993
			// ever heard that song by Blue Rodeo ?
994
			try {
995
				$this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->checkout->current...ep->generate_reg_form() of type string is incompatible with the declared type object<EE_Form_Section_Proper> of property $reg_form.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
996
				// if not displaying a form, then check for form submission
997
				if ( $this->checkout->process_form_submission && $this->checkout->current_step->reg_form->was_submitted() ) {
0 ignored issues
show
Bug introduced by
The method was_submitted cannot be called on $this->checkout->current_step->reg_form (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
998
					// clear out any old data in case this step is being run again
999
					$this->checkout->current_step->set_valid_data( array() );
1000
					// capture submitted form data
1001
					$this->checkout->current_step->reg_form->receive_form_submission(
0 ignored issues
show
Bug introduced by
The method receive_form_submission cannot be called on $this->checkout->current_step->reg_form (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1002
						apply_filters( 'FHEE__Single_Page_Checkout___check_form_submission__request_params', EE_Registry::instance()->REQ->params(), $this->checkout )
1003
					);
1004
					// validate submitted form data
1005
					if ( ! $this->checkout->continue_reg && ! $this->checkout->current_step->reg_form->is_valid() ) {
0 ignored issues
show
Bug introduced by
The method is_valid cannot be called on $this->checkout->current_step->reg_form (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1006
						// thou shall not pass !!!
1007
						$this->checkout->continue_reg = FALSE;
1008
						// any form validation errors?
1009
						if ( $this->checkout->current_step->reg_form->submission_error_message() !== '' ) {
0 ignored issues
show
Bug introduced by
The method submission_error_message cannot be called on $this->checkout->current_step->reg_form (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1010
							$submission_error_messages = array();
1011
							// bad, bad, bad registrant
1012
							foreach( $this->checkout->current_step->reg_form->get_validation_errors_accumulated() as $validation_error ){
0 ignored issues
show
Bug introduced by
The method get_validation_errors_accumulated cannot be called on $this->checkout->current_step->reg_form (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1013 View Code Duplication
								if ( $validation_error instanceof EE_Validation_Error ) {
1014
									$submission_error_messages[] = sprintf(
1015
										__( '%s : %s', 'event_espresso' ),
1016
										$validation_error->get_form_section()->html_label_text(),
1017
										$validation_error->getMessage()
1018
									);
1019
								}
1020
							}
1021
							EE_Error::add_error( implode( '<br />', $submission_error_messages ), __FILE__, __FUNCTION__, __LINE__ );
1022
						}
1023
						// well not really... what will happen is we'll just get redirected back to redo the current step
1024
						$this->go_to_next_step();
1025
						return;
1026
					}
1027
				}
1028
			} catch( EE_Error $e ) {
1029
				$e->get_error();
1030
			}
1031
		}
1032
	}
1033
1034
1035
1036
	/**
1037
	 * _process_action
1038
	 *
1039
	 * @access private
1040
	 * @return void
1041
	 * @throws \EE_Error
1042
	 */
1043
	private function _process_form_action() {
1044
		// what cha wanna do?
1045
		switch( $this->checkout->action ) {
1046
			// AJAX next step reg form
1047
			case 'display_spco_reg_step' :
1048
				$this->checkout->redirect = FALSE;
1049
				if ( EE_Registry::instance()->REQ->ajax ) {
1050
					$this->checkout->json_response->set_reg_step_html( $this->checkout->current_step->display_reg_form() );
1051
				}
1052
				break;
1053
1054
			default :
1055
				// meh... do one of those other steps first
1056
				if ( ! empty( $this->checkout->action ) && is_callable( array( $this->checkout->current_step, $this->checkout->action ))) {
1057
					// dynamically creates hook point like: AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1058
					do_action( "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step );
1059
					// call action on current step
1060
					if ( call_user_func( array( $this->checkout->current_step, $this->checkout->action )) ) {
1061
						// good registrant, you get to proceed
1062
						if (
1063
							$this->checkout->current_step->success_message() !== ''
1064
							&& apply_filters(
1065
								'FHEE__Single_Page_Checkout___process_form_action__display_success',
1066
								false
1067
							)
1068
						) {
1069
								EE_Error::add_success(
1070
									$this->checkout->current_step->success_message()
1071
									. '<br />' . $this->checkout->next_step->_instructions()
1072
								);
1073
1074
						}
1075
						// pack it up, pack it in...
1076
						$this->_setup_redirect();
1077
					}
1078
					// dynamically creates hook point like: AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1079
					do_action( "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", $this->checkout->current_step );
1080
1081
				} else {
1082
					EE_Error::add_error(
1083
						sprintf(
1084
							__( 'The requested form action "%s" does not exist for the current "%s" registration step.', 'event_espresso' ),
1085
							$this->checkout->action,
1086
							$this->checkout->current_step->name()
1087
						),
1088
						__FILE__, __FUNCTION__, __LINE__
1089
					);
1090
				}
1091
			// end default
1092
		}
1093
		// store our progress so far
1094
		$this->checkout->stash_transaction_and_checkout();
1095
		// advance to the next step! If you pass GO, collect $200
1096
		$this->go_to_next_step();
1097
	}
1098
1099
1100
1101
	/**
1102
	 * 		add_styles_and_scripts
1103
	 *
1104
	 * 		@access 		public
1105
	 * 		@return 		void
1106
	 */
1107
	public function add_styles_and_scripts() {
1108
		// i18n
1109
		$this->translate_js_strings();
1110
		if ( $this->checkout->admin_request ) {
1111
			add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10 );
1112
		} else {
1113
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles_and_scripts' ), 10 );
1114
		}
1115
	}
1116
1117
1118
1119
	/**
1120
	 * 		translate_js_strings
1121
	 *
1122
	 * 		@access 		public
1123
	 * 		@return 		void
1124
	 */
1125
	public function translate_js_strings() {
1126
		EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1127
		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1128
		EE_Registry::$i18n_js_strings['server_error'] = __('An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso');
1129
		EE_Registry::$i18n_js_strings['invalid_json_response'] = __( 'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', 'event_espresso' );
1130
		EE_Registry::$i18n_js_strings['validation_error'] = __( 'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', 'event_espresso' );
1131
		EE_Registry::$i18n_js_strings['invalid_payment_method'] = __( 'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', 'event_espresso' );
1132
		EE_Registry::$i18n_js_strings['reg_step_error'] = __('This registration step could not be completed. Please refresh the page and try again.', 'event_espresso');
1133
		EE_Registry::$i18n_js_strings['invalid_coupon'] = __('We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', 'event_espresso');
1134
		EE_Registry::$i18n_js_strings['process_registration'] = sprintf( __( 'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', 'event_espresso' ), '<br/>', '<br/>' );
1135
		EE_Registry::$i18n_js_strings['language'] = get_bloginfo( 'language' );
1136
		EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1137
		EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1138
		EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1139
		EE_Registry::$i18n_js_strings['timer_years'] = __( 'years', 'event_espresso' );
1140
		EE_Registry::$i18n_js_strings['timer_months'] = __( 'months', 'event_espresso' );
1141
		EE_Registry::$i18n_js_strings['timer_weeks'] = __( 'weeks', 'event_espresso' );
1142
		EE_Registry::$i18n_js_strings['timer_days'] = __( 'days', 'event_espresso' );
1143
		EE_Registry::$i18n_js_strings['timer_hours'] = __( 'hours', 'event_espresso' );
1144
		EE_Registry::$i18n_js_strings['timer_minutes'] = __( 'minutes', 'event_espresso' );
1145
		EE_Registry::$i18n_js_strings['timer_seconds'] = __( 'seconds', 'event_espresso' );
1146
		EE_Registry::$i18n_js_strings['timer_year'] = __( 'year', 'event_espresso' );
1147
		EE_Registry::$i18n_js_strings['timer_month'] = __( 'month', 'event_espresso' );
1148
		EE_Registry::$i18n_js_strings['timer_week'] = __( 'week', 'event_espresso' );
1149
		EE_Registry::$i18n_js_strings['timer_day'] = __( 'day', 'event_espresso' );
1150
		EE_Registry::$i18n_js_strings['timer_hour'] = __( 'hour', 'event_espresso' );
1151
		EE_Registry::$i18n_js_strings['timer_minute'] = __( 'minute', 'event_espresso' );
1152
		EE_Registry::$i18n_js_strings['timer_second'] = __( 'second', 'event_espresso' );
1153
		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1154
			__( '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s', 'event_espresso' ),
1155
			'<h4 class="important-notice">',
1156
			'</h4>',
1157
			'<br />',
1158
			'<p>',
1159
			'<a href="'. get_post_type_archive_link( 'espresso_events' ) . '" title="',
1160
			'">',
1161
			'</a>',
1162
			'</p>'
1163
		);
1164
		EE_Registry::$i18n_js_strings[ 'ajax_submit' ] = apply_filters( 'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', true );
1165
	}
1166
1167
1168
1169
	/**
1170
	 * 	enqueue_styles_and_scripts
1171
	 *
1172
	 * 	@access 		public
1173
	 * 	@return 		void
1174
	 */
1175
	public function enqueue_styles_and_scripts() {
1176
		// load css
1177
		wp_register_style( 'single_page_checkout', SPCO_CSS_URL . 'single_page_checkout.css', array(), EVENT_ESPRESSO_VERSION );
1178
		wp_enqueue_style( 'single_page_checkout' );
1179
		// load JS
1180
		wp_register_script( 'jquery_plugin', EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js', array( 'jquery' ), '1.0.1', TRUE );
1181
		wp_register_script( 'jquery_countdown', EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js', array( 'jquery_plugin' ), '2.0.2', TRUE );
1182
		wp_register_script( 'single_page_checkout', SPCO_JS_URL . 'single_page_checkout.js', array( 'espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown' ), EVENT_ESPRESSO_VERSION, TRUE );
1183
		wp_enqueue_script( 'single_page_checkout' );
1184
1185
		/**
1186
		 * global action hook for enqueueing styles and scripts with
1187
		 * spco calls.
1188
		 */
1189
		do_action( 'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this );
1190
1191
		/**
1192
		 * dynamic action hook for enqueueing styles and scripts with spco calls.
1193
		 * The hook will end up being something like AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1194
		 */
1195
		do_action( 'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), $this );
1196
1197
		// add css and JS for current step
1198
		$this->checkout->current_step->enqueue_styles_and_scripts();
1199
	}
1200
1201
1202
1203
	/**
1204
	 *    display the Registration Single Page Checkout Form
1205
	 *
1206
	 * @access    private
1207
	 * @return    void
1208
	 * @throws \EE_Error
1209
	 */
1210
	private function _display_spco_reg_form() {
1211
		// if registering via the admin, just display the reg form for the current step
1212
		if ( $this->checkout->admin_request ) {
1213
			EE_Registry::instance()->REQ->add_output( $this->checkout->current_step->display_reg_form() );
1214
		} else {
1215
			// add powered by EE msg
1216
			add_action( 'AHEE__SPCO__reg_form_footer', array( 'EED_Single_Page_Checkout', 'display_registration_footer' ));
1217
1218
			$empty_cart = count( $this->checkout->transaction->registrations( $this->checkout->reg_cache_where_params ) ) < 1 ? true : false;
1219
			$cookies_not_set_msg = '';
1220
			if ( $empty_cart && ! isset( $_COOKIE[ 'ee_cookie_test' ] ) ) {
1221
				$cookies_not_set_msg = apply_filters(
1222
					'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1223
					sprintf(
1224
						__( '%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', 'event_espresso' ),
1225
						'<div class="ee-attention">',
1226
						'</div>',
1227
						'<h6 class="important-notice">',
1228
						'</h6>',
1229
						'<p>',
1230
						'</p>',
1231
						'<br />',
1232
						'<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1233
						'</a>'
1234
					)
1235
				);
1236
			}
1237
			$this->checkout->registration_form = new EE_Form_Section_Proper(
1238
				array(
1239
					'name' 	=> 'single-page-checkout',
1240
					'html_id' 	=> 'ee-single-page-checkout-dv',
1241
					'layout_strategy' =>
1242
						new EE_Template_Layout(
1243
							array(
1244
								'layout_template_file' 			=> SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1245
								'template_args' => array(
1246
									'empty_cart' 		=> $empty_cart,
1247
									'revisit' 				=> $this->checkout->revisit,
1248
									'reg_steps' 			=> $this->checkout->reg_steps,
1249
									'next_step' 			=>  $this->checkout->next_step instanceof EE_SPCO_Reg_Step ? $this->checkout->next_step->slug() : '',
1250
									'empty_msg' 		=> apply_filters(
1251
										'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1252
										sprintf(
1253
											__( 'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', 'event_espresso' ),
1254
											'<a href="' . get_post_type_archive_link( 'espresso_events' ) . '" title="',
1255
											'">',
1256
											'</a>'
1257
										)
1258
									),
1259
									'cookies_not_set_msg' 		=> $cookies_not_set_msg,
1260
									'registration_time_limit' 	=> $this->checkout->get_registration_time_limit(),
1261
									'session_expiration' 			=>
1262
										gmdate( 'M d, Y H:i:s', EE_Registry::instance()->SSN->expiration() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) )
1263
							)
1264
						)
1265
					)
1266
				)
1267
			);
1268
			// load template and add to output sent that gets filtered into the_content()
1269
			EE_Registry::instance()->REQ->add_output( $this->checkout->registration_form->get_html_and_js() );
1270
		}
1271
	}
1272
1273
1274
1275
	/**
1276
	 *    add_extra_finalize_registration_inputs
1277
	 *
1278
	 * @access    public
1279
	 * @param $next_step
1280
	 * @internal  param string $label
1281
	 * @return        string
1282
	 */
1283
	public function add_extra_finalize_registration_inputs( $next_step ) {
1284
		if ( $next_step === 'finalize_registration' ) {
1285
			echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1286
		}
1287
	}
1288
1289
1290
1291
	/**
1292
	 * 	display_registration_footer
1293
	 *
1294
	 *  @access 	public
1295
	 *  @return 	string
1296
	 */
1297
	public static function display_registration_footer() {
1298
		if ( apply_filters( 'FHEE__EE_Front__Controller__show_reg_footer', EE_Registry::instance()->CFG->admin->show_reg_footer ) ) {
1299
			EE_Registry::instance()->CFG->admin->affiliate_id = ! empty( EE_Registry::instance()->CFG->admin->affiliate_id ) ? EE_Registry::instance()->CFG->admin->affiliate_id : 'default';
1300
			$url = add_query_arg( array( 'ap_id' => EE_Registry::instance()->CFG->admin->affiliate_id ), 'https://eventespresso.com/' );
1301
			$url = apply_filters( 'FHEE__EE_Front_Controller__registration_footer__url', $url );
1302
			echo apply_filters(
1303
				'FHEE__EE_Front_Controller__display_registration_footer',
1304
				sprintf(
1305
					__( '%1$sEvent Registration Powered by Event Espresso%2$sEvent Registration and Ticketing%3$s Powered by %4$sEvent Espresso - Event Registration and Management System for WordPress%5$sEvent Espresso%6$s', 'event_espresso' ),
1306
					'<div id="espresso-registration-footer-dv"><a href="' . $url . '" title="',
1307
					'" target="_blank">',
1308
					'</a>',
1309
					'<a href="' . $url . '" title="',
1310
					'" target="_blank">',
1311
					'</a></div>'
1312
				)
1313
			);
1314
		}
1315
	}
1316
1317
1318
1319
	/**
1320
	 *    unlock_transaction
1321
	 *
1322
	 * @access    public
1323
	 * @return    void
1324
	 * @throws \EE_Error
1325
	 */
1326
	public function unlock_transaction() {
1327
		$this->checkout->transaction->unlock();
1328
	}
1329
1330
1331
1332
1333
	/**
1334
	 *        _setup_redirect
1335
	 *
1336
	 * @access 	private
1337
	 * @return 	array
1338
	 */
1339
	private function _setup_redirect() {
1340
		if ( $this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step ) {
1341
			$this->checkout->redirect = TRUE;
1342
			if ( empty( $this->checkout->redirect_url )) {
1343
				$this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1344
			}
1345
			$this->checkout->redirect_url = apply_filters( 'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url', $this->checkout->redirect_url, $this->checkout );
1346
		}
1347
	}
1348
1349
1350
1351
	/**
1352
	 *   handle ajax message responses and redirects
1353
	 *
1354
	 * @access public
1355
	 * @return void
1356
	 * @throws \EE_Error
1357
	 */
1358
	public function go_to_next_step() {
1359
		if ( EE_Registry::instance()->REQ->ajax ) {
1360
			// capture contents of output buffer we started earlier in the request, and insert into JSON response
1361
			$this->checkout->json_response->set_unexpected_errors( ob_get_clean() );
1362
		}
1363
		$this->unlock_transaction();
1364
		// just return for these conditions
1365
		if (
1366
			$this->checkout->admin_request
1367
			|| $this->checkout->action === 'redirect_form'
1368
			|| $this->checkout->action === 'update_checkout'
1369
		) {
1370
			return;
1371
		}
1372
		// AJAX response
1373
		$this->_handle_json_response();
1374
		// redirect to next step or the Thank You page
1375
		$this->_handle_html_redirects();
1376
		// hmmm... must be something wrong, so let's just display the form again !
1377
		$this->_display_spco_reg_form();
1378
	}
1379
1380
1381
1382
	/**
1383
	 *   _handle_json_response
1384
	 *
1385
	 * @access protected
1386
	 * @return void
1387
	 */
1388
	protected function _handle_json_response() {
1389
		// if this is an ajax request
1390
		if ( EE_Registry::instance()->REQ->ajax ) {
1391
			// DEBUG LOG
1392
			//$this->checkout->log(
1393
			//	__CLASS__, __FUNCTION__, __LINE__,
1394
			//	array(
1395
			//		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1396
			//		'redirect'                   => $this->checkout->redirect,
1397
			//		'continue_reg'               => $this->checkout->continue_reg,
1398
			//	)
1399
			//);
1400
			$this->checkout->json_response->set_registration_time_limit(
1401
				$this->checkout->get_registration_time_limit()
1402
			);
1403
			$this->checkout->json_response->set_payment_amount( $this->checkout->amount_owing );
1404
			// just send the ajax (
1405
			$json_response = apply_filters(
1406
				'FHEE__EE_Single_Page_Checkout__JSON_response',
1407
				$this->checkout->json_response
1408
			);
1409
			echo $json_response;
1410
			exit();
1411
		}
1412
	}
1413
1414
1415
1416
	/**
1417
	 *   _handle_redirects
1418
	 *
1419
	 * @access protected
1420
	 * @return void
1421
	 */
1422
	protected function _handle_html_redirects() {
1423
		// going somewhere ?
1424
		if ( $this->checkout->redirect && ! empty( $this->checkout->redirect_url ) ) {
1425
			// store notices in a transient
1426
			EE_Error::get_notices( false, true, true );
1427
			// DEBUG LOG
1428
			//$this->checkout->log(
1429
			//	__CLASS__, __FUNCTION__, __LINE__,
1430
			//	array(
1431
			//		'headers_sent' => headers_sent(),
1432
			//		'redirect_url'     => $this->checkout->redirect_url,
1433
			//		'headers_list'    => headers_list(),
1434
			//	)
1435
			//);
1436
			wp_safe_redirect( $this->checkout->redirect_url );
1437
			exit();
1438
		}
1439
	}
1440
1441
1442
1443
	/**
1444
	 *   set_checkout_anchor
1445
	 *
1446
	 * @access public
1447
	 * @return string
1448
	 */
1449
	public function set_checkout_anchor() {
1450
		echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1451
	}
1452
1453
1454
1455
}
1456
// End of file EED_Single_Page_Checkout.module.php
1457
// Location: /modules/single_page_checkout/EED_Single_Page_Checkout.module.php
1458