/**
  * @return EE_Log
  */
 public static function instance()
 {
     if (!self::$_instance instanceof EE_Log) {
         self::$_instance = new self();
     }
     return self::$_instance;
 }
 /**
  * initialize_system_questions
  *
  * 	@access public
  * 	@static
  * 	@return void
  */
 public static function initialize_system_questions()
 {
     // QUESTION GROUPS
     global $wpdb;
     $table_name = EEH_Activation::ensure_table_name_has_prefix('esp_question_group');
     $SQL = "SELECT QSG_system FROM {$table_name} WHERE QSG_system != 0";
     // what we have
     $question_groups = $wpdb->get_col($SQL);
     // check the response
     $question_groups = is_array($question_groups) ? $question_groups : array();
     // what we should have
     $QSG_systems = array(1, 2);
     // loop thru what we should have and compare to what we have
     foreach ($QSG_systems as $QSG_system) {
         // reset values array
         $QSG_values = array();
         // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
         if (!in_array("{$QSG_system}", $question_groups)) {
             // add it
             switch ($QSG_system) {
                 case 1:
                     $QSG_values = array('QSG_name' => __('Personal Information', 'event_espresso'), 'QSG_identifier' => 'personal-information-' . time(), 'QSG_desc' => '', 'QSG_order' => 1, 'QSG_show_group_name' => 1, 'QSG_show_group_desc' => 1, 'QSG_system' => EEM_Question_Group::system_personal, 'QSG_deleted' => 0);
                     break;
                 case 2:
                     $QSG_values = array('QSG_name' => __('Address Information', 'event_espresso'), 'QSG_identifier' => 'address-information-' . time(), 'QSG_desc' => '', 'QSG_order' => 2, 'QSG_show_group_name' => 1, 'QSG_show_group_desc' => 1, 'QSG_system' => EEM_Question_Group::system_address, 'QSG_deleted' => 0);
                     break;
             }
             // make sure we have some values before inserting them
             if (!empty($QSG_values)) {
                 // insert system question
                 $wpdb->insert($table_name, $QSG_values, array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d'));
                 $QSG_IDs[$QSG_system] = $wpdb->insert_id;
             }
         }
     }
     // QUESTIONS
     global $wpdb;
     $table_name = EEH_Activation::ensure_table_name_has_prefix('esp_question');
     $SQL = "SELECT QST_system FROM {$table_name} WHERE QST_system != ''";
     // what we have
     $questions = $wpdb->get_col($SQL);
     // what we should have
     $QST_systems = array('fname', 'lname', 'email', 'address', 'address2', 'city', 'state', 'country', 'zip', 'phone');
     $order_for_group_1 = 1;
     $order_for_group_2 = 1;
     // loop thru what we should have and compare to what we have
     foreach ($QST_systems as $QST_system) {
         // reset values array
         $QST_values = array();
         // if we don't have what we should have
         if (!in_array($QST_system, $questions)) {
             // add it
             switch ($QST_system) {
                 case 'fname':
                     $QST_values = array('QST_display_text' => __('First Name', 'event_espresso'), 'QST_admin_label' => __('First Name - System Question', 'event_espresso'), 'QST_system' => 'fname', 'QST_type' => 'TEXT', 'QST_required' => 1, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 1, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'lname':
                     $QST_values = array('QST_display_text' => __('Last Name', 'event_espresso'), 'QST_admin_label' => __('Last Name - System Question', 'event_espresso'), 'QST_system' => 'lname', 'QST_type' => 'TEXT', 'QST_required' => 1, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 2, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'email':
                     $QST_values = array('QST_display_text' => __('Email Address', 'event_espresso'), 'QST_admin_label' => __('Email Address - System Question', 'event_espresso'), 'QST_system' => 'email', 'QST_type' => 'TEXT', 'QST_required' => 1, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 3, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'address':
                     $QST_values = array('QST_display_text' => __('Address', 'event_espresso'), 'QST_admin_label' => __('Address - System Question', 'event_espresso'), 'QST_system' => 'address', 'QST_type' => 'TEXT', 'QST_required' => 0, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 4, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'address2':
                     $QST_values = array('QST_display_text' => __('Address2', 'event_espresso'), 'QST_admin_label' => __('Address2 - System Question', 'event_espresso'), 'QST_system' => 'address2', 'QST_type' => 'TEXT', 'QST_required' => 0, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 5, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'city':
                     $QST_values = array('QST_display_text' => __('City', 'event_espresso'), 'QST_admin_label' => __('City - System Question', 'event_espresso'), 'QST_system' => 'city', 'QST_type' => 'TEXT', 'QST_required' => 0, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 6, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'state':
                     $QST_values = array('QST_display_text' => __('State/Province', 'event_espresso'), 'QST_admin_label' => __('State/Province - System Question', 'event_espresso'), 'QST_system' => 'state', 'QST_type' => 'STATE', 'QST_required' => 0, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 7, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'country':
                     $QST_values = array('QST_display_text' => __('Country', 'event_espresso'), 'QST_admin_label' => __('Country - System Question', 'event_espresso'), 'QST_system' => 'country', 'QST_type' => 'COUNTRY', 'QST_required' => 0, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 8, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'zip':
                     $QST_values = array('QST_display_text' => __('Zip/Postal Code', 'event_espresso'), 'QST_admin_label' => __('Zip/Postal Code - System Question', 'event_espresso'), 'QST_system' => 'zip', 'QST_type' => 'TEXT', 'QST_required' => 0, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 9, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
                 case 'phone':
                     $QST_values = array('QST_display_text' => __('Phone Number', 'event_espresso'), 'QST_admin_label' => __('Phone Number - System Question', 'event_espresso'), 'QST_system' => 'phone', 'QST_type' => 'TEXT', 'QST_required' => 0, 'QST_required_text' => __('This field is required', 'event_espresso'), 'QST_order' => 10, 'QST_admin_only' => 0, 'QST_wp_user' => self::get_default_creator_id(), 'QST_deleted' => 0);
                     break;
             }
             if (!empty($QST_values)) {
                 // insert system question
                 $wpdb->insert($table_name, $QST_values, array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d'));
                 $QST_ID = $wpdb->insert_id;
                 // QUESTION GROUP QUESTIONS
                 if (in_array($QST_system, array('fname', 'lname', 'email'))) {
                     $system_question_we_want = EEM_Question_Group::system_personal;
                 } else {
                     $system_question_we_want = EEM_Question_Group::system_address;
                 }
                 if (isset($QSG_IDs[$system_question_we_want])) {
                     $QSG_ID = $QSG_IDs[$system_question_we_want];
                 } else {
                     $id_col = EEM_Question_Group::instance()->get_col(array(array('QSG_system' => $system_question_we_want)));
                     if (is_array($id_col)) {
                         $QSG_ID = reset($id_col);
                     } else {
                         //ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
                         EE_Log::instance()->log(__FILE__, __FUNCTION__, sprintf(__('Could not associate question %1$s to a question group because no system question group existed', 'event_espresso'), $QST_ID), 'error');
                         continue;
                     }
                 }
                 // add system questions to groups
                 $wpdb->insert(EEH_Activation::ensure_table_name_has_prefix('esp_question_group_question'), array('QSG_ID' => $QSG_ID, 'QST_ID' => $QST_ID, 'QGQ_order' => $QSG_ID == 1 ? $order_for_group_1++ : $order_for_group_2++), array('%d', '%d', '%d'));
             }
         }
     }
 }
 /**
  * Attempts to run the indicated WPDB method with the provided arguments,
  * and if there's an error tries to verify the DB is correct. Uses
  * the static property EEM_Base::$_db_verification_level to determine whether
  * we should try to fix the EE core db, the addons, or just give up
  * @param string $wpdb_method
  * @param array $arguments_to_provide
  * @return mixed
  */
 private function _process_wpdb_query($wpdb_method, $arguments_to_provide)
 {
     /** @type WPDB $wpdb */
     global $wpdb;
     $wpdb->last_error = null;
     $result = call_user_func_array(array($wpdb, $wpdb_method), $arguments_to_provide);
     // was there an error running the query?
     if ($result === false || !empty($wpdb->last_error)) {
         switch (EEM_Base::$_db_verification_level) {
             case EEM_Base::db_verified_none:
                 // let's double-check core's DB
                 $error_message = $this->_verify_core_db($wpdb_method, $arguments_to_provide);
                 break;
             case EEM_Base::db_verified_core:
                 // STILL NO LOVE?? verify all the addons too. Maybe they need to be fixed
                 $error_message = $this->_verify_addons_db($wpdb_method, $arguments_to_provide);
                 break;
             case EEM_Base::db_verified_addons:
                 // ummmm... you in trouble
                 return $result;
                 break;
         }
         if (!empty($error_message)) {
             EE_Log::instance()->log(__FILE__, __FUNCTION__, $error_message, 'error');
             trigger_error($error_message);
         }
         return $this->_process_wpdb_query($wpdb_method, $arguments_to_provide);
     }
     return $result;
 }
 /**
  * Overrides parent to add some logging for when payment methods get deactivated
  *
  * @param array $set_cols_n_values
  * @return int @see EE_Base_Class::save()
  * @throws \EE_Error
  */
 public function save($set_cols_n_values = array())
 {
     $results = parent::save($set_cols_n_values);
     if ($this->get_original('PMD_scope') !== $this->get('PMD_scope')) {
         EE_Log::instance()->log(__FILE__, __FUNCTION__, sprintf(__('Set new scope on payment method %1$s to %2$s from %3$s on URL %4$s', 'event_espresso'), $this->name(), serialize($this->get_original('PMD_scope')), serialize($this->get('PMD_scope')), EE_Registry::instance()->REQ->get_current_page_permalink()), 'payment_method_change');
     }
     return $results;
 }
 /**
  * generate_ONE_registration_from_line_item
  *
  * Although a ticket line item may have a quantity greater than 1,
  * this method will ONLY CREATE ONE REGISTRATION !!!
  * Regardless of the ticket line item quantity.
  * This means that any code calling this method is responsible for ensuring
  * that the final registration count matches the ticket line item quantity.
  * This was done to make it easier to match the number of registrations
  * to the number of tickets in the cart, when the cart has been edited
  * after SPCO has already been initialized. So if an additional ticket was added to the cart, you can simply pass
  * the line item to this method to add a second ticket, and in this case, you would not want to add 2 tickets.
  *
  * @param EE_Line_Item $line_item
  * @param \EE_Transaction $transaction
  * @param int $att_nmbr
  * @param int $total_ticket_count
  * @return \EE_Registration | null
  * @throws \EE_Error
  */
 public function generate_ONE_registration_from_line_item(EE_Line_Item $line_item, EE_Transaction $transaction, $att_nmbr = 1, $total_ticket_count = 1)
 {
     // grab the related ticket object for this line_item
     $ticket = $line_item->ticket();
     if (!$ticket instanceof EE_Ticket) {
         EE_Error::add_error(sprintf(__("Line item %s did not contain a valid ticket", "event_espresso"), $line_item->ID()), __FILE__, __FUNCTION__, __LINE__);
         return null;
     }
     $first_datetime = $ticket->get_first_related('Datetime');
     if (!$first_datetime instanceof EE_Datetime) {
         EE_Error::add_error(sprintf(__("The ticket (%s) is not associated with any valid datetimes.", "event_espresso"), $ticket->name()), __FILE__, __FUNCTION__, __LINE__);
         return null;
     }
     $event = $first_datetime->get_first_related('Event');
     if (!$event instanceof EE_Event) {
         EE_Error::add_error(sprintf(__("The ticket (%s) is not associated with a valid event.", "event_espresso"), $ticket->name()), __FILE__, __FUNCTION__, __LINE__);
         return null;
     }
     $reg_url_link = $this->generate_reg_url_link($att_nmbr, $line_item);
     if ($this->_reg_final_price_per_tkt_line_item === null) {
         $this->_reg_final_price_per_tkt_line_item = EEH_Line_Item::calculate_reg_final_prices_per_line_item($transaction->total_line_item());
     }
     //ok now find this new registration's final price
     if (isset($this->_reg_final_price_per_tkt_line_item[$line_item->ID()])) {
         $final_price = $this->_reg_final_price_per_tkt_line_item[$line_item->ID()];
     } else {
         $message = sprintf(__('The ticket line item (ID:%1$d) had no entry in the reg_final_price_per_tkt_line_item array.', 'event_espresso'), $line_item->ID());
         if (WP_DEBUG) {
             throw new EE_Error($message);
         } else {
             EE_Log::instance()->log(__CLASS__, __FUNCTION__, $message);
         }
         $final_price = $ticket->get_ticket_total_with_taxes();
     }
     // now create a new registration for the ticket
     $registration = EE_Registration::new_instance(array('EVT_ID' => $event->ID(), 'TXN_ID' => $transaction->ID(), 'TKT_ID' => $ticket->ID(), 'STS_ID' => EEM_Registration::status_id_incomplete, 'REG_date' => $transaction->datetime(), 'REG_final_price' => $final_price, 'REG_session' => EE_Registry::instance()->SSN->id(), 'REG_count' => $att_nmbr, 'REG_group_size' => $total_ticket_count, 'REG_url_link' => $reg_url_link));
     $registration->set_reg_code($this->generate_reg_code($registration));
     $registration->save();
     $registration->_add_relation_to($event, 'Event', array(), $event->ID());
     $registration->_add_relation_to($line_item->ticket(), 'Ticket', array(), $line_item->ticket()->ID());
     $transaction->_add_relation_to($registration, 'Registration');
     return $registration;
 }
 /**
  * Deactivates a payment method of the given payment method slug.
  *
  * @param string $payment_method_slug The slug for the payment method to deactivate.
  *
  * @return int count of rows updated.
  */
 public function deactivate_payment_method($payment_method_slug)
 {
     EE_Log::instance()->log(__FILE__, __FUNCTION__, sprintf(__('Payment method with slug %1$s is being deactivated by site admin', 'event_espresso'), $payment_method_slug), 'payment_method_change');
     $count_updated = EEM_Payment_Method::instance()->update(array('PMD_scope' => array()), array(array('PMD_slug' => $payment_method_slug)));
     return $count_updated;
 }