/**
  *    _initialize - initial module setup
  *
  * @access    private
  * @throws EE_Error
  * @return    void
  */
 private function _initialize()
 {
     // ensure SPCO doesn't run twice
     if (EED_Single_Page_Checkout::$_initialized) {
         return;
     }
     // setup the EE_Checkout object
     $this->checkout = $this->_initialize_checkout();
     // filter checkout
     $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
     // get the $_GET
     $this->_get_request_vars();
     // filter continue_reg
     $this->checkout->continue_reg = apply_filters('FHEE__EED_Single_Page_Checkout__init___continue_reg', TRUE, $this->checkout);
     // load the reg steps array
     if (!$this->_load_and_instantiate_reg_steps()) {
         EED_Single_Page_Checkout::$_initialized = true;
         return;
     }
     // set the current step
     $this->checkout->set_current_step($this->checkout->step);
     // and the next step
     $this->checkout->set_next_step();
     // was there already a valid transaction in the checkout from the session ?
     if (!$this->checkout->transaction instanceof EE_Transaction) {
         // get transaction from db or session
         $this->checkout->transaction = $this->checkout->reg_url_link && !is_admin() ? $this->_get_transaction_and_cart_for_previous_visit() : $this->_get_cart_for_current_session_and_setup_new_transaction();
         if (!$this->checkout->transaction instanceof EE_Transaction) {
             EE_Error::add_error(__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
             // add some style and make it dance
             $this->checkout->transaction = EE_Transaction::new_instance();
             $this->add_styles_and_scripts();
             EED_Single_Page_Checkout::$_initialized = true;
             return;
         }
         // and the registrations for the transaction
         $this->_get_registrations($this->checkout->transaction);
     }
     // verify that everything has been setup correctly
     if (!$this->_final_verifications()) {
         EED_Single_Page_Checkout::$_initialized = true;
         return;
     }
     // lock the transaction
     $this->checkout->transaction->lock();
     // make sure all of our cached objects are added to their respective model entity mappers
     $this->checkout->refresh_all_entities();
     // set amount owing
     $this->checkout->amount_owing = $this->checkout->transaction->remaining();
     // initialize each reg step, which gives them the chance to potentially alter the process
     $this->_initialize_reg_steps();
     // DEBUG LOG
     //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
     // get reg form
     $this->_check_form_submission();
     // checkout the action!!!
     $this->_process_form_action();
     // add some style and make it dance
     $this->add_styles_and_scripts();
     // kk... SPCO has successfully run
     EED_Single_Page_Checkout::$_initialized = TRUE;
     // set no cache headers and constants
     EE_System::do_not_cache();
     // add anchor
     add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
     // remove transaction lock
     add_action('shutdown', array($this, 'unlock_transaction'), 1);
 }
 /**
  *    _final_verifications
  * just makes sure that everything is set up correctly before proceeding
  *
  * @access    private
  * @return    bool
  * @throws \EE_Error
  */
 private function _final_verifications()
 {
     // filter checkout
     $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___final_verifications__checkout', $this->checkout);
     //verify that current step is still set correctly
     if (!$this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
         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__);
         return false;
     }
     // if returning to SPCO, then verify that primary registrant is set
     if (!empty($this->checkout->reg_url_link)) {
         $valid_registrant = $this->checkout->transaction->primary_registration();
         if (!$valid_registrant instanceof EE_Registration) {
             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__);
             return false;
         }
         $valid_registrant = null;
         foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) {
             if ($registration instanceof EE_Registration && $registration->reg_url_link() === $this->checkout->reg_url_link) {
                 $valid_registrant = $registration;
             }
         }
         if (!$valid_registrant instanceof EE_Registration) {
             // hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
             if (EED_Single_Page_Checkout::$_checkout_verified) {
                 // clear the session, mark the checkout as unverified, and try again
                 EE_Registry::instance()->SSN->clear_session();
                 EED_Single_Page_Checkout::$_initialized = false;
                 EED_Single_Page_Checkout::$_checkout_verified = false;
                 $this->_initialize();
                 EE_Error::reset_notices();
                 return false;
             }
             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__);
             return false;
         }
     }
     // now that things have been kinda sufficiently verified,
     // let's add the checkout to the session so that's available other systems
     EE_Registry::instance()->SSN->set_checkout($this->checkout);
     return true;
 }