/**
  *
  * @param EE_Payment_Method $pm_instance
  * @throws EE_Error
  * @return EE_PMT_Base
  */
 function __construct($pm_instance = NULL)
 {
     if ($pm_instance instanceof EE_Payment_Method) {
         $this->set_instance($pm_instance);
     }
     $this->_set_file_folder();
     $this->_set_file_url();
     if ($this->_gateway) {
         $this->_gateway->set_payment_model(EEM_Payment::instance());
         $this->_gateway->set_payment_log(EEM_Change_Log::instance());
         EE_Registry::instance()->load_helper('Template');
         $this->_gateway->set_template_helper(new EEH_Template());
         EE_Registry::instance()->load_helper('Line_Item');
         $this->_gateway->set_line_item_helper(new EEH_Line_Item());
         EE_Registry::instance()->load_helper('Money');
         $this->_gateway->set_money_helper(new EEH_Money());
     }
     if (!isset($this->_has_billing_form)) {
         // by default, On Site gateways have a billing form
         if ($this->payment_occurs() == EE_PMT_Base::onsite) {
             $this->set_has_billing_form(true);
         } else {
             $this->set_has_billing_form(false);
         }
     }
     if (!$this->_pretty_name) {
         throw new EE_Error(sprintf(__("You must set the pretty name for the Payment Method Type in the constructor (_pretty_name), and please make it internationalized", "event_espresso")));
     }
     //if the child didn't specify a default button, use the credit card one
     if ($this->_default_button_url === NULL) {
         $this->_default_button_url = EE_PLUGIN_DIR_URL . 'payment_methods' . DS . 'pay-by-credit-card.png';
     }
 }
 protected function _payment_log_details()
 {
     EE_Registry::instance()->load_model('Change_Log');
     /** @var $payment_log EE_Change_Log */
     $payment_log = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
     $payment_method = NULL;
     $transaction = NULL;
     if ($payment_log instanceof EE_Change_Log) {
         if ($payment_log->object() instanceof EE_Payment) {
             $payment_method = $payment_log->object()->payment_method();
             $transaction = $payment_log->object()->transaction();
         } elseif ($payment_log->object() instanceof EE_Payment_Method) {
             $payment_method = $payment_log->object();
         }
     }
     $this->_template_args['admin_page_content'] = EEH_Template::display_template(EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php', array('payment_log' => $payment_log, 'payment_method' => $payment_method, 'transaction' => $transaction), TRUE);
     $this->display_admin_page_with_sidebar();
 }
 /**
  * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so
  * we can easily find what registration the IPN is for and what payment method.
  * However, if not, we'll give all payment methods a chance to claim it and process it.
  * If a payment is found for the IPN info, it is saved.
  *
  * @param array             $_req_data eg $_REQUEST
  * @param EE_Transaction|int $transaction          optional (or a transactions id)
  * @param EE_Payment_Method $payment_method       (or a slug or id of one)
  * @param boolean           $update_txn           whether or not to call
  *                                                EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()
  * @param bool              $separate_IPN_request whether the IPN uses a separate request ( true like PayPal )
  *                                                or is processed manually ( false like Mijireh )
  * @throws EE_Error
  * @throws Exception
  * @return EE_Payment
  */
 public function process_ipn($_req_data, $transaction = null, $payment_method = null, $update_txn = true, $separate_IPN_request = true)
 {
     EE_Registry::instance()->load_model('Change_Log');
     $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data);
     EE_Processor_Base::set_IPN($separate_IPN_request);
     $obj_for_log = null;
     if ($transaction instanceof EE_Transaction) {
         $obj_for_log = $transaction;
         if ($payment_method instanceof EE_Payment_Method) {
             $obj_for_log = EEM_Payment::instance()->get_one(array(array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), 'order_by' => array('PAY_timestamp' => 'desc')));
         }
     } else {
         if ($payment_method instanceof EE_Payment) {
             $obj_for_log = $payment_method;
         }
     }
     $log = EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data received' => $_req_data), $obj_for_log);
     try {
         /**
          * @var EE_Payment $payment
          */
         $payment = NULL;
         if ($transaction && $payment_method) {
             /** @type EE_Transaction $transaction */
             $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction);
             /** @type EE_Payment_Method $payment_method */
             $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method);
             if ($payment_method->type_obj() instanceof EE_PMT_Base) {
                 $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction);
                 $log->set_object($payment);
             } else {
                 // not a payment
                 EE_Error::add_error(sprintf(__('A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', 'event_espresso'), '<br/>', EE_Registry::instance()->CFG->organization->get_pretty('email')), __FILE__, __FUNCTION__, __LINE__);
             }
         } else {
             //that's actually pretty ok. The IPN just wasn't able
             //to identify which transaction or payment method this was for
             // give all active payment methods a chance to claim it
             $active_payment_methods = EEM_Payment_Method::instance()->get_all_active();
             foreach ($active_payment_methods as $active_payment_method) {
                 try {
                     $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data);
                     $payment_method = $active_payment_method;
                     EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment);
                     break;
                 } catch (EE_Error $e) {
                     //that's fine- it apparently couldn't handle the IPN
                 }
             }
         }
         // 			EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method);
         if ($payment instanceof EE_Payment) {
             $payment->save();
             //  update the TXN
             $this->update_txn_based_on_payment($transaction, $payment, $update_txn, $separate_IPN_request);
         } else {
             //we couldn't find the payment for this IPN... let's try and log at least SOMETHING
             if ($payment_method) {
                 EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment_method);
             } elseif ($transaction) {
                 EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $transaction);
             }
         }
         return $payment;
     } catch (EE_Error $e) {
         do_action('AHEE__log', __FILE__, __FUNCTION__, sprintf(__('Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', 'event_espresso'), print_r($transaction, TRUE), print_r($_req_data, TRUE), $e->getMessage()));
         throw $e;
     }
 }
 /**
  * @group github-102
  * @group 8589
  */
 public function test_get__serialized_data__twice()
 {
     $log_message = serialize(array('key1' => 'value1', 'key2' => 'value2'));
     $log = EE_Change_Log::new_instance();
     $log->set('LOG_message', $log_message);
     $log->save();
     //verify that when we get its LOG_message its still serialized
     $this->assertTrue(is_array($log->get('LOG_message')));
     $this->assertEquals(unserialize($log_message), $log->get('LOG_message'));
     //now when we get it from the DB, and get its LOG_message, its still serialized
     $log_id = $log->ID();
     EEM_Change_Log::reset();
     unset($log);
     $log_from_db = EEM_Change_Log::instance()->get_one_by_ID($log_id);
     $this->assertTrue(is_array($log_from_db->get('LOG_message')));
     $this->assertEquals(unserialize($log_message), $log_from_db->get('LOG_message'));
 }