/** * Process failed transaction - would be nice to do this through api too but for now lets put in * here - this is a copy & paste of the completetransaction api * @param unknown $contributionID */ function processFailedTransaction($contributionID) { $input = $ids = array(); $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = $contributionID; $contribution->find(TRUE); if (!$contribution->id == $contributionID) { throw new Exception('A valid contribution ID is required', 'invalid_data'); } try { if (!$contribution->loadRelatedObjects($input, $ids, FALSE, TRUE)) { throw new Exception('failed to load related objects'); } $objects = $contribution->_relatedObjects; $objects['contribution'] =& $contribution; $input['component'] = $contribution->_component; $input['is_test'] = $contribution->is_test; $input['amount'] = $contribution->total_amount; // @todo required for base ipn but problematic as api layer handles this $transaction = new CRM_Core_Transaction(); $ipn = new CRM_Core_Payment_BaseIPN(); $ipn->failed($objects, $transaction, $input); } catch (Exception $e) { } }
/** * Load objects related to contribution. * * @input array information from Payment processor * @param array $ids * @param array $objects * @param boolean $required * @param integer $paymentProcessorID * @param array $error_handling * @return multitype:number NULL |boolean */ function loadObjects(&$input, &$ids, &$objects, $required, $paymentProcessorID, $error_handling = NULL) { if (empty($error_handling)) { // default options are that we log an error & echo it out // note that we should refactor this error handling into error code @ some point // but for now setting up enough separation so we can do unit tests $error_handling = array('log_error' => 1, 'echo_error' => 1); } $ids['paymentProcessor'] = $paymentProcessorID; if (is_a($objects['contribution'], 'CRM_Contribute_BAO_Contribution')) { $contribution =& $objects['contribution']; } else { //legacy support - functions are 'used' to be able to pass in a DAO $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = CRM_Utils_Array::value('contribution', $ids); $contribution->find(TRUE); $objects['contribution'] =& $contribution; } try { $success = $contribution->loadRelatedObjects($input, $ids, $required); } catch (Exception $e) { $success = FALSE; if (CRM_Utils_Array::value('log_error', $error_handling)) { CRM_Core_Error::debug_log_message($e->getMessage()); } if (CRM_Utils_Array::value('echo_error', $error_handling)) { echo $e->getMessage(); } if (CRM_Utils_Array::value('return_error', $error_handling)) { return array('is_error' => 1, 'error_message' => $e->getMessage()); } } $objects = array_merge($objects, $contribution->_relatedObjects); return $success; }
/** * Complete an existing (pending) transaction. * * This will update related entities (participant, membership, pledge etc) * and take any complete actions from the contribution page (e.g. send receipt). * * @todo - most of this should live in the BAO layer but as we want it to be an addition * to 4.3 which is already stable we should add it to the api layer & re-factor into the BAO layer later * * @param array $params * Input parameters. * * @throws API_Exception * Api result array. */ function civicrm_api3_contribution_repeattransaction(&$params) { $input = $ids = array(); civicrm_api3_verify_one_mandatory($params, NULL, array('contribution_recur_id', 'original_contribution_id')); if (empty($params['original_contribution_id'])) { $params['original_contribution_id'] = civicrm_api3('contribution', 'getvalue', array('return' => 'id', 'contribution_recur_id' => $params['contribution_recur_id'], 'options' => array('limit' => 1, 'sort' => 'id DESC'))); } $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = $params['original_contribution_id']; if (!$contribution->find(TRUE)) { throw new API_Exception('A valid original contribution ID is required', 'invalid_data'); } $original_contribution = clone $contribution; try { if (!$contribution->loadRelatedObjects($input, $ids, TRUE)) { throw new API_Exception('failed to load related objects'); } unset($contribution->id, $contribution->receive_date, $contribution->invoice_id); $contribution->receive_date = $params['receive_date']; $passThroughParams = array('trxn_id', 'total_amount', 'campaign_id', 'fee_amount', 'financial_type_id', 'contribution_status_id'); $input = array_intersect_key($params, array_fill_keys($passThroughParams, NULL)); $params = _ipn_process_transaction($params, $contribution, $input, $ids, $original_contribution); } catch (Exception $e) { throw new API_Exception('failed to load related objects' . $e->getMessage() . "\n" . $e->getTraceAsString()); } }
/** * Complete an existing (pending) transaction. * * This will update related entities (participant, membership, pledge etc) * and take any complete actions from the contribution page (e.g. send receipt). * * @todo - most of this should live in the BAO layer but as we want it to be an addition * to 4.3 which is already stable we should add it to the api layer & re-factor into the BAO layer later * * @param array $params * Input parameters. * * @throws API_Exception * Api result array. */ function civicrm_api3_contribution_repeattransaction(&$params) { $input = $ids = array(); $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = $params['original_contribution_id']; if (!$contribution->find(TRUE)) { throw new API_Exception('A valid original contribution ID is required', 'invalid_data'); } $original_contribution = clone $contribution; try { if (!$contribution->loadRelatedObjects($input, $ids, TRUE)) { throw new API_Exception('failed to load related objects'); } unset($contribution->id, $contribution->receive_date, $contribution->invoice_id); $contribution->contribution_status_id = $params['contribution_status_id']; $contribution->receive_date = $params['receive_date']; $passThroughParams = array('trxn_id', 'total_amount', 'campaign_id', 'fee_amount'); $input = array_intersect_key($params, array_fill_keys($passThroughParams, NULL)); $params = _ipn_process_transaction($params, $contribution, $input, $ids, $original_contribution); } catch (Exception $e) { throw new API_Exception('failed to load related objects' . $e->getMessage() . "\n" . $e->getTraceAsString()); } }
/** * Test the LoadObjects function with recurring membership data. */ public function testLoadMembershipObjectsLoadAll() { $this->_setUpMembershipObjects(); $this->_setUpRecurringContribution(); unset($this->ids['membership']); $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = $this->_contributionId; $contribution->find(TRUE); $contribution->loadRelatedObjects($this->input, $this->ids, FALSE, TRUE); $this->assertFalse(empty($contribution->_relatedObjects['membership'])); $this->assertArrayHasKey($this->_membershipTypeID, $contribution->_relatedObjects['membership']); $this->assertTrue(is_a($contribution->_relatedObjects['membership'][$this->_membershipTypeID], 'CRM_Member_BAO_Membership')); $this->assertTrue(is_a($contribution->_relatedObjects['contributionType'], 'CRM_Financial_BAO_FinancialType')); $this->assertFalse(empty($contribution->_relatedObjects['contributionRecur'])); $this->assertFalse(empty($contribution->_relatedObjects['paymentProcessor'])); }
/** * Send receipt from contribution. * * Do not call this directly - it is being refactored. use contribution.sendmessage api call. * * Note that the compose message part has been moved to contribution * In general LoadObjects is called first to get the objects but the composeMessageArray function now calls it. * * @param array $input * Incoming data from Payment processor. * @param array $ids * Related object IDs. * @param int $contributionID * @param array $values * Values related to objects that have already been loaded. * @param bool $recur * Is it part of a recurring contribution. * @param bool $returnMessageText * Should text be returned instead of sent. This. * is because the function is also used to generate pdfs * * @return array * @throws \CRM_Core_Exception * @throws \CiviCRM_API3_Exception */ public static function sendMail(&$input, &$ids, $contributionID, &$values, $recur = FALSE, $returnMessageText = FALSE) { $input['is_recur'] = $recur; $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = $contributionID; if (!$contribution->find(TRUE)) { throw new CRM_Core_Exception('Contribution does not exist'); } $contribution->loadRelatedObjects($input, $ids, TRUE); // set receipt from e-mail and name in value if (!$returnMessageText) { $session = CRM_Core_Session::singleton(); $userID = $session->get('userID'); if (!empty($userID)) { list($userName, $userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID); $values['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', $input, $userEmail); $values['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', $input, $userName); } } $return = $contribution->composeMessageArray($input, $ids, $values, $recur, $returnMessageText); // Contribution ID should really always be set. But ? if (!$returnMessageText && (!isset($input['receipt_update']) || $input['receipt_update']) && empty($contribution->receipt_date)) { civicrm_api3('Contribution', 'create', array('receipt_date' => 'now', 'id' => $contribution->id)); } return $return; }
/** * Complete an existing (pending) transaction, updating related entities (participant, membership, pledge etc) * and taking any complete actions from the contribution page (e.g. send receipt) * * @todo - most of this should live in the BAO layer but as we want it to be an addition * to 4.3 which is already stable we should add it to the api layer & re-factor into the BAO layer later * * @param array $params input parameters * {@getfields Contribution_completetransaction} * @return array Api result array * @static void * @access public * */ function civicrm_api3_contribution_completetransaction(&$params) { $input = $ids = array(); $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->id = $params['id']; $contribution->find(TRUE); if (!$contribution->id == $params['id']) { throw new API_Exception('A valid contribution ID is required', 'invalid_data'); } try { if (!$contribution->loadRelatedObjects($input, $ids, FALSE, TRUE)) { throw new API_Exception('failed to load related objects'); } $objects = $contribution->_relatedObjects; $objects['contribution'] =& $contribution; $input['component'] = $contribution->_component; $input['is_test'] = $contribution->is_test; $input['trxn_id'] = $contribution->trxn_id; $input['amount'] = $contribution->total_amount; if (isset($params['is_email_receipt'])) { $input['is_email_receipt'] = $params['is_email_receipt']; } // @todo required for base ipn but problematic as api layer handles this $transaction = new CRM_Core_Transaction(); $ipn = new CRM_Core_Payment_BaseIPN(); $ipn->completeTransaction($input, $ids, $objects, $transaction); } catch (Exception $e) { throw new API_Exception('failed to load related objects' . $e->getMessage() . "\n" . $e->getTraceAsString()); } }