/**
  *    run - initial shortcode module setup called during "wp_loaded" hook
  *    this method is primarily used for loading resources that will be required by the shortcode when it is actually processed
  *
  * @access    public
  * @param WP $WP
  * @return    void
  */
 public function run(WP $WP)
 {
     if (!did_action('pre_get_posts')) {
         // 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
         add_action('pre_get_posts', array('EED_Single_Page_Checkout', 'load_reg_steps'), 1);
         // this will trigger the EED_Single_Page_Checkout module's run() method during the pre_get_posts hook point,
         // this allows us to initialize things, enqueue assets, etc,
         add_action('pre_get_posts', array('EED_Single_Page_Checkout', 'init'), 10, 1);
     } else {
         global $wp_query;
         EED_Single_Page_Checkout::load_reg_steps();
         EED_Single_Page_Checkout::init($wp_query);
     }
 }
 /**
  *    run - initial shortcode module setup called during "wp_loaded" hook
  *    this method is primarily used for loading resources that will be required by the shortcode when it is actually processed
  *
  * @access    public
  * @param WP $WP
  * @return    void
  */
 public function run(WP $WP)
 {
     // SPCO is large and resource intensive, so it's better to do a double check before loading it up, so let's grab the post_content for the requested post
     global $wpdb;
     $SQL = 'SELECT post_content from ' . $wpdb->posts . ' WHERE post_type="page" AND post_status="publish" AND post_name=%s';
     if ($post_content = $wpdb->get_var($wpdb->prepare($SQL, EE_Registry::instance()->REQ->get('post_name')))) {
         // now check for this shortcode
         if (strpos($post_content, '[ESPRESSO_CHECKOUT') !== FALSE) {
             if (!did_action('pre_get_posts')) {
                 // this will trigger the EED_Events_Archive module's event_list() method during the pre_get_posts hook point,
                 // this allows us to initialize things, enqueue assets, etc,
                 // as well, this saves an instantiation of the module in an array using 'espresso_events' as the key, so that we can retrieve it
                 add_action('pre_get_posts', array(EED_Single_Page_Checkout::instance(), 'run'));
             } else {
                 global $wp;
                 EED_Single_Page_Checkout::instance()->run($wp);
             }
         }
     }
 }
 /**
  * 		process_reg_step
  *
  * 		@access 		public
  * 		@return 		string
  */
 public function process_reg_step()
 {
     $this->_set_reg_event();
     EE_Registry::instance()->REQ->set_espresso_page(TRUE);
     //what step are we on?
     $cart = EE_Registry::instance()->SSN->get_session_data('cart');
     $step = empty($cart) ? 'ticket' : 'questions';
     //if doing ajax then we need to verify the nonce
     if ('DOING_AJAX') {
         $nonce = isset($this->_req_data[$this->_req_nonce]) ? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
         $this->_verify_nonce($nonce, $this->_req_nonce);
     }
     switch ($step) {
         case 'ticket':
             //process ticket selection
             $success = EED_Ticket_Selector::instance()->process_ticket_selections();
             if ($success) {
                 EE_Error::add_success(__('Tickets Selected. Now complete the registration.'), 'event_espresso');
             } else {
                 $query_args['step_error'] = $this->_req_data['step_error'] = TRUE;
             }
             if (defined('DOING_AJAX')) {
                 $this->new_registration();
                 //display next step
             } else {
                 $query_args['action'] = 'new_registration';
                 $query_args['processing_registration'] = true;
                 $query_args['event_id'] = $this->_reg_event->ID();
                 $this->_redirect_after_action(FALSE, '', '', $query_args, TRUE);
             }
             break;
         case 'questions':
             if (!isset($this->_req_data['txn_reg_status_change'], $this->_req_data['txn_reg_status_change']['send_notifications'])) {
                 add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
             }
             //process registration
             $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
             if (!$transaction instanceof EE_Transaction) {
                 $query_args = array('action' => 'new_registration', 'processing_registration' => true, 'event_id' => $this->_reg_event->ID());
                 if (defined('DOING_AJAX')) {
                     //display registration form again because there are errors (maybe validation?)
                     $this->new_registration();
                     return;
                 } else {
                     $this->_redirect_after_action(FALSE, '', '', $query_args, TRUE);
                     return;
                 }
             }
             /** @type EE_Transaction_Payments $transaction_payments */
             $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
             // maybe update status, and make sure to save transaction if not done already
             if (!$transaction_payments->update_transaction_status_based_on_total_paid($transaction)) {
                 $transaction->save();
             }
             $query_args = array('action' => 'view_transaction', 'TXN_ID' => $transaction->ID(), 'page' => 'espresso_transactions');
             EE_Error::add_success(__('Registration Created.  Please review the transaction and add any payments as necessary', 'event_espresso'));
             $this->_redirect_after_action(FALSE, '', '', $query_args, TRUE);
             break;
     }
     //what are you looking here for?  Should be nothing to do at this point.
 }
 /**
  *    _get_request_vars
  *
  * @access 	private
  * @return 	void
  */
 private function _get_request_vars()
 {
     // load classes
     EED_Single_Page_Checkout::load_request_handler();
     //make sure this request is marked as belonging to EE
     EE_Registry::instance()->REQ->set_espresso_page(TRUE);
     // which step is being requested ?
     $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
     // which step is being edited ?
     $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
     // and what we're doing on the current step
     $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
     // returning to edit ?
     $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
     // or some other kind of revisit ?
     $this->checkout->revisit = EE_Registry::instance()->REQ->get('revisit', FALSE);
     // and whether or not to generate a reg form for this request
     $this->checkout->generate_reg_form = EE_Registry::instance()->REQ->get('generate_reg_form', TRUE);
     // TRUE 	FALSE
     // and whether or not to process a reg form submission for this request
     $this->checkout->process_form_submission = EE_Registry::instance()->REQ->get('process_form_submission', FALSE);
     // TRUE 	FALSE
     $this->checkout->process_form_submission = $this->checkout->action !== 'display_spco_reg_step' ? $this->checkout->process_form_submission : FALSE;
     // TRUE 	FALSE
     //$this->_display_request_vars();
 }
 /**
  * 	ajax get_transaction_details
  */
 public static function get_transaction_details()
 {
     EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways');
 }
 /**
  * 		_process_registration_step
  *
  * 		@access 		public
  * 		@return 		string
  */
 public function _process_registration_step()
 {
     $this->_set_reg_event();
     EE_Registry::instance()->REQ->set_espresso_page(TRUE);
     //what step are we on?
     $cart = EE_Registry::instance()->SSN->get_session_data('cart');
     $step = empty($cart) ? 'ticket' : 'questions';
     //if doing ajax then we need to verify the nonce
     if ('DOING_AJAX') {
         $nonce = isset($this->_req_data[$this->_req_nonce]) ? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
         $this->_verify_nonce($nonce, $this->_req_nonce);
     }
     switch ($step) {
         case 'ticket':
             //process ticket selection
             $success = EED_Ticket_Selector::instance()->process_ticket_selections();
             if ($success) {
                 EE_Error::add_success(__('Tickets Selected. Now complete the registration.'), 'event_espresso');
             } else {
                 $query_args['step_error'] = $this->_req_data['step_error'] = TRUE;
             }
             if (defined('DOING_AJAX')) {
                 $this->new_registration();
                 //display next step
             } else {
                 $query_args['action'] = 'new_registration';
                 $query_args['processing_registration'] = true;
                 $query_args['event_id'] = $this->_reg_event->ID();
                 $this->_redirect_after_action(FALSE, '', '', $query_args, TRUE);
             }
             break;
         case 'questions':
             //process registration
             $TXN_ID = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
             if (!$TXN_ID) {
                 $query_args = array('action' => 'new_registration', 'processing_registration' => true, 'event_id' => $this->_reg_event->ID());
                 if (defined('DOING_AJAX')) {
                     $this->new_registration();
                     //display registration form again because there are errors (maybe validation?)
                 } else {
                     $this->_redirect_after_action(FALSE, '', '', $query_args, TRUE);
                 }
             }
             $query_args = array('action' => 'view_transaction', 'TXN_ID' => $TXN_ID, 'page' => 'espresso_transactions');
             EE_Error::add_success(__('Registration Created.  Please review the transaction and add any payments as necessary', 'event_espresso'));
             $this->_redirect_after_action(FALSE, '', '', $query_args, TRUE);
             break;
     }
     //what are you looking here for?  Should be nothing to do at this point.
 }
 /**
  * 	load_js
  *
  * 	@access 		public
  * 	@return 		void
  */
 public static function load_js()
 {
     EED_Single_Page_Checkout::translate_js_strings();
     wp_enqueue_script('underscore');
     wp_register_script('single_page_checkout', SPCO_ASSETS_URL . 'single_page_checkout.js', array('espresso_core', 'underscore'), EVENT_ESPRESSO_VERSION, TRUE);
     wp_enqueue_script('single_page_checkout');
     wp_localize_script('single_page_checkout', 'eei18n', EE_Registry::$i18n_js_strings);
 }
 /**
  * 	_submit_promo_code
  *
  * @access        private
  * @return        void
  */
 private function _submit_promo_code()
 {
     $return_data = array();
     // get the EE_Cart object being used for the current transaction
     /** @type EE_Cart $cart */
     $cart = EE_Registry::instance()->SSN->cart();
     if ($cart instanceof EE_Cart) {
         // and make sure the model cache is
         $cart->get_grand_total()->get_model()->refresh_entity_map_with($cart->get_grand_total()->ID(), $cart->get_grand_total());
         $promotion = $this->get_promotion_details_from_request();
         if ($promotion instanceof EE_Promotion) {
             // determine if the promotion can be applied to an item in the current cart
             $applicable_items = $this->get_applicable_items($promotion, $cart, false, true);
             if (!empty($applicable_items)) {
                 // add line item
                 if ($this->generate_promotion_line_items($promotion, $applicable_items, $this->_config->affects_tax())) {
                     // ensure cart totals have been recalculated and saved
                     $cart->get_grand_total()->recalculate_total_including_taxes();
                     $cart->get_grand_total()->save();
                     /** @type EE_Registration_Processor $registration_processor */
                     $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
                     $registration_processor->update_registration_final_prices($cart->get_grand_total()->transaction());
                     $cart->save_cart(false);
                     $return_data = $this->_get_payment_info($cart);
                     $return_data['success'] = $promotion->accept_message();
                     EED_Single_Page_Checkout::update_checkout();
                 } else {
                     EE_Error::add_attention($promotion->decline_message(), __FILE__, __FUNCTION__, __LINE__);
                 }
             }
         }
     } else {
         EE_Error::add_error(sprintf(apply_filters('FHEE__EED_Promotions___submit_promo_code__invalid_cart_notice', __('We\'re sorry, but the %1$s could not be applied because the event cart could not be retrieved.', 'event_espresso')), strtolower($this->_config->label->singular)), __FILE__, __FUNCTION__, __LINE__);
     }
     $this->generate_JSON_response($return_data);
 }
 /**
  *    _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;
 }