/** * takes an associative array and creates a financial transaction object * * @param array $params (reference ) an assoc array of name/value pairs * * @return object CRM_Core_BAO_FinancialTrxn object * @access public * @static */ static function create(&$params) { $trxn = new CRM_Core_DAO_FinancialTrxn(); $trxn->copyValues($params); require_once 'CRM/Utils/Rule.php'; if (!CRM_Utils_Rule::currencyCode($trxn->currency)) { require_once 'CRM/Core/Config.php'; $config = CRM_Core_Config::singleton(); $trxn->currency = $config->defaultCurrency; } // if a transaction already exists for a contribution id, lets get the finTrxnId and entityFinTrxId $fids = self::getFinancialTrxnIds($params['contribution_id'], 'civicrm_contribution'); if ($fids['financialTrxnId']) { $trxn->id = $fids['financialTrxnId']; } $trxn->save(); $contributionAmount = CRM_Utils_Array::value('net_amount', $params); if (!$contributionAmount && isset($params['total_amount'])) { $contributionAmount = $params['total_amount']; } // save to entity_financial_trxn table $entity_financial_trxn_params = array('entity_table' => "civicrm_contribution", 'entity_id' => $params['contribution_id'], 'financial_trxn_id' => $trxn->id, 'amount' => $contributionAmount, 'currency' => $trxn->currency); $entity_trxn =& new CRM_Core_DAO_EntityFinancialTrxn(); $entity_trxn->copyValues($entity_financial_trxn_params); if ($fids['entityFinancialTrxnId']) { $entity_trxn->id = $fids['entityFinancialTrxnId']; } $entity_trxn->save(); return $trxn; }
/** * takes an associative array and creates a financial transaction object * * @param array $params (reference ) an assoc array of name/value pairs * * @return object CRM_Contribute_BAO_FinancialTrxn object * @access public * @static */ function create(&$params) { $trxn =& new CRM_Contribute_DAO_FinancialTrxn(); $trxn->copyValues($params); $trxn->domain_id = CRM_Core_Config::domainID(); require_once 'CRM/Utils/Rule.php'; if (!CRM_Utils_Rule::currencyCode($contribution->currency)) { require_once 'CRM/Core/Config.php'; $config =& CRM_Core_Config::singleton(); $contribution->currency = $config->defaultCurrency; } return $trxn->save(); }
/** * takes an associative array and creates a financial transaction object * * @param array $params (reference ) an assoc array of name/value pairs * * @return object CRM_Contribute_BAO_FinancialTrxn object * @access public * @static */ static function create(&$params) { $trxn =& new CRM_Contribute_DAO_FinancialTrxn(); $trxn->copyValues($params); require_once 'CRM/Utils/Rule.php'; if (!CRM_Utils_Rule::currencyCode($trxn->currency)) { require_once 'CRM/Core/Config.php'; $config =& CRM_Core_Config::singleton(); $trxn->currency = $config->defaultCurrency; } // if a transaction already exists for a contribution id, lets get the id $id = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_FinancialTrxn', $trxn->contribution_id, 'id', 'contribution_id'); if ($id) { $trxn->id = $id; } return $trxn->save(); }
/** * Takes an associative array and creates a financial transaction object. * * @param array $params * (reference ) an assoc array of name/value pairs. * * @param string $trxnEntityTable * Entity_table. * * @return CRM_Core_BAO_FinancialTrxn */ public static function create(&$params, $trxnEntityTable = NULL) { $trxn = new CRM_Financial_DAO_FinancialTrxn(); $trxn->copyValues($params); if (!CRM_Utils_Rule::currencyCode($trxn->currency)) { $trxn->currency = CRM_Core_Config::singleton()->defaultCurrency; } $trxn->save(); // save to entity_financial_trxn table $entityFinancialTrxnParams = array('entity_table' => "civicrm_contribution", 'financial_trxn_id' => $trxn->id, 'amount' => $params['total_amount'], 'currency' => $trxn->currency); if (!empty($trxnEntityTable)) { $entityFinancialTrxnParams['entity_table'] = $trxnEntityTable['entity_table']; $entityFinancialTrxnParams['entity_id'] = $trxnEntityTable['entity_id']; } else { $entityFinancialTrxnParams['entity_id'] = $params['contribution_id']; } $entityTrxn = new CRM_Financial_DAO_EntityFinancialTrxn(); $entityTrxn->copyValues($entityFinancialTrxnParams); $entityTrxn->save(); return $trxn; }
/** * takes an associative array and creates a participant object * * the function extract all the params it needs to initialize the create a * participant object. the params array could contain additional unused name/value * pairs * * @param array $params (reference ) an assoc array of name/value pairs * @param array $ids the array that holds all the db ids * * @return object CRM_Event_BAO_Participant object * @access public * @static */ static function &add(&$params) { require_once 'CRM/Utils/Hook.php'; if (CRM_Utils_Array::value('id', $params)) { CRM_Utils_Hook::pre('edit', 'Participant', $params['id'], $params); } else { CRM_Utils_Hook::pre('create', 'Participant', null, $params); } // converting dates to mysql format if (CRM_Utils_Array::value('register_date', $params)) { $params['register_date'] = CRM_Utils_Date::isoToMysql($params['register_date']); } if (CRM_Utils_Array::value('participant_fee_amount', $params)) { $params['participant_fee_amount'] = CRM_Utils_Rule::cleanMoney($params['participant_fee_amount']); } if (CRM_Utils_Array::value('participant_fee_amount', $params)) { $params['fee_amount'] = CRM_Utils_Rule::cleanMoney($params['fee_amount']); } $participantBAO = new CRM_Event_BAO_Participant(); if (CRM_Utils_Array::value('id', $params)) { $participantBAO->id = CRM_Utils_Array::value('id', $params); $participantBAO->find(true); $participantBAO->register_date = CRM_Utils_Date::isoToMysql($participantBAO->register_date); } $participantBAO->copyValues($params); //CRM-6910 //1. If currency present, it should be valid one. //2. We should have currency when amount is not null. require_once 'CRM/Utils/Rule.php'; $currency = $participantBAO->fee_currency; if ($currency || !CRM_Utils_System::isNull($participantBAO->fee_amount)) { if (!CRM_Utils_Rule::currencyCode($currency)) { $config = CRM_Core_Config::singleton(); $currency = $config->defaultCurrency; } } $participantBAO->fee_currency = $currency; $participantBAO->save(); $session =& CRM_Core_Session::singleton(); // reset the group contact cache for this group require_once 'CRM/Contact/BAO/GroupContactCache.php'; CRM_Contact_BAO_GroupContactCache::remove(); if (CRM_Utils_Array::value('id', $params)) { CRM_Utils_Hook::post('edit', 'Participant', $participantBAO->id, $participantBAO); } else { CRM_Utils_Hook::post('create', 'Participant', $participantBAO->id, $participantBAO); } return $participantBAO; }
function validate() { if (CRM_Utils_System::isNull($this->_value)) { return true; } switch ($this->_name) { case 'contact_id': // note: we validate extistence of the contact in API, upon // insert (it would be too costlty to do a db call here) return CRM_Utils_Rule::integer($this->_value); break; case 'receive_date': case 'cancel_date': case 'receipt_date': case 'thankyou_date': return CRM_Utils_Rule::date($this->_value); break; case 'non_deductible_amount': case 'total_amount': case 'fee_amount': case 'net_amount': return CRM_Utils_Rule::money($this->_value); break; case 'trxn_id': static $seenTrxnIds = array(); if (in_array($this->_value, $seenTrxnIds)) { return false; } elseif ($this->_value) { $seenTrxnIds[] = $this->_value; return true; } else { $this->_value = null; return true; } break; case 'currency': return CRM_Utils_Rule::currencyCode($this->_value); break; case 'contribution_type': static $contributionTypes = null; if (!$contributionTypes) { $contributionTypes =& CRM_Contribute_PseudoConstant::contributionType(); } if (in_array($this->_value, $contributionTypes)) { return true; } else { return false; } break; case 'payment_instrument': static $paymentInstruments = null; if (!$paymentInstruments) { $paymentInstruments =& CRM_Contribute_PseudoConstant::paymentInstrument(); } if (in_array($this->_value, $paymentInstruments)) { return true; } else { return false; } break; default: break; } // check whether that's a valid custom field id // and if so, check the contents' validity if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($this->_name)) { static $customFields = null; if (!$customFields) { $customFields =& CRM_Core_BAO_CustomField::getFields('Contribution'); } if (!array_key_exists($customFieldID, $customFields)) { return false; } return CRM_Core_BAO_CustomValue::typecheck($customFields[$customFieldID]['data_type'], $this->_value); } return true; }
/** * take the input parameter list as specified in the data model and * convert it into the same format that we use in QF and BAO object * * @param array $params Associative array of property name/value * pairs to insert in new contact. * @param array $values The reformatted properties that we can use internally * ' * @return array|CRM_Error * @access public */ function _crm_format_contrib_params(&$params, &$values, $create = false) { // copy all the contribution fields as is $fields =& CRM_Contribute_DAO_Contribution::fields(); _crm_store_values($fields, $params, $values); foreach ($params as $key => $value) { // ignore empty values or empty arrays etc if (CRM_Utils_System::isNull($value)) { continue; } switch ($key) { case 'contribution_contact_id': if (!CRM_Utils_Rule::integer($value)) { return _crm_error("contact_id not valid: {$value}"); } $dao =& new CRM_Core_DAO(); $qParams = array(); $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = {$value}", $qParams); if (!$svq) { return _crm_error("Invalid Contact ID: There is no contact record with contact_id = {$value}."); } $values['contact_id'] = $values['contribution_contact_id']; unset($values['contribution_contact_id']); break; case 'receive_date': case 'cancel_date': case 'receipt_date': case 'thankyou_date': if (!CRM_Utils_Rule::date($value)) { return _crm_error("{$key} not a valid date: {$value}"); } break; case 'non_deductible_amount': case 'total_amount': case 'fee_amount': case 'net_amount': if (!CRM_Utils_Rule::money($value)) { return _crm_error("{$key} not a valid amount: {$value}"); } break; case 'currency': if (!CRM_Utils_Rule::currencyCode($value)) { return _crm_error("currency not a valid code: {$value}"); } break; case 'contribution_type': require_once 'CRM/Contribute/PseudoConstant.php'; $values['contribution_type_id'] = CRM_Utils_Array::key(ucfirst($value), CRM_Contribute_PseudoConstant::contributionType()); break; case 'payment_instrument': require_once 'CRM/Core/OptionGroup.php'; $values['payment_instrument_id'] = CRM_Core_OptionGroup::getValue('payment_instrument', $value); break; case 'contribution_status_id': require_once 'CRM/Core/OptionGroup.php'; $values['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', $value); break; default: break; } } if (array_key_exists('note', $params)) { $values['note'] = $params['note']; } _crm_format_custom_params($params, $values, 'Contribution'); if ($create) { // CRM_Contribute_BAO_Contribution::add() handles contribution_source // So, if $values contains contribution_source, convert it to source $changes = array('contribution_source' => 'source'); foreach ($changes as $orgVal => $changeVal) { if (isset($values[$orgVal])) { $values[$changeVal] = $values[$orgVal]; unset($values[$orgVal]); } } } return null; }
/** * take the input parameter list as specified in the data model and * convert it into the same format that we use in QF and BAO object * * @param array $params * Associative array of property name/value. * pairs to insert in new contact. * @param array $values * The reformatted properties that we can use internally. * ' * * @param bool $create * @param null $onDuplicate * * @return array|CRM_Error */ function _civicrm_api3_deprecated_formatted_param($params, &$values, $create = FALSE, $onDuplicate = NULL) { // copy all the contribution fields as is $fields = CRM_Contribute_DAO_Contribution::fields(); _civicrm_api3_store_values($fields, $params, $values); require_once 'CRM/Core/OptionGroup.php'; $customFields = CRM_Core_BAO_CustomField::getFields('Contribution', FALSE, FALSE, NULL, NULL, FALSE, FALSE, FALSE); foreach ($params as $key => $value) { // ignore empty values or empty arrays etc if (CRM_Utils_System::isNull($value)) { continue; } // Handling Custom Data if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) { $values[$key] = $value; $type = $customFields[$customFieldID]['html_type']; if ($type == 'CheckBox' || $type == 'Multi-Select') { $mulValues = explode(',', $value); $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE); $values[$key] = array(); foreach ($mulValues as $v1) { foreach ($customOption as $customValueID => $customLabel) { $customValue = $customLabel['value']; if (strtolower($customLabel['label']) == strtolower(trim($v1)) || strtolower($customValue) == strtolower(trim($v1))) { if ($type == 'CheckBox') { $values[$key][$customValue] = 1; } else { $values[$key][] = $customValue; } } } } } elseif ($type == 'Select' || $type == 'Radio' || $type == 'Autocomplete-Select' && $customFields[$customFieldID]['data_type'] == 'String') { $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE); foreach ($customOption as $customFldID => $customValue) { $val = CRM_Utils_Array::value('value', $customValue); $label = CRM_Utils_Array::value('label', $customValue); $label = strtolower($label); $value = strtolower(trim($value)); if ($value == $label || $value == strtolower($val)) { $values[$key] = $val; } } } } switch ($key) { case 'contribution_contact_id': if (!CRM_Utils_Rule::integer($value)) { return civicrm_api3_create_error("contact_id not valid: {$value}"); } $dao = new CRM_Core_DAO(); $qParams = array(); $svq = $dao->singleValueQuery("SELECT is_deleted FROM civicrm_contact WHERE id = {$value}", $qParams); if (!isset($svq)) { return civicrm_api3_create_error("Invalid Contact ID: There is no contact record with contact_id = {$value}."); } elseif ($svq == 1) { return civicrm_api3_create_error("Invalid Contact ID: contact_id {$value} is a soft-deleted contact."); } $values['contact_id'] = $values['contribution_contact_id']; unset($values['contribution_contact_id']); break; case 'contact_type': // import contribution record according to select contact type require_once 'CRM/Contact/DAO/Contact.php'; $contactType = new CRM_Contact_DAO_Contact(); // when insert mode check contact id or external identifier if (!empty($params['contribution_contact_id']) || !empty($params['external_identifier'])) { if (!empty($params['contribution_contact_id'])) { $contactType->id = CRM_Utils_Array::value('contribution_contact_id', $params); } elseif (!empty($params['external_identifier'])) { $contactType->external_identifier = $params['external_identifier']; } if ($contactType->find(TRUE)) { if ($params['contact_type'] != $contactType->contact_type) { return civicrm_api3_create_error("Contact Type is wrong: {$contactType->contact_type}"); } } } elseif (!empty($params['contribution_id']) || !empty($params['trxn_id']) || !empty($params['invoice_id'])) { // when update mode check contribution id or trxn id or // invoice id $contactId = new CRM_Contribute_DAO_Contribution(); if (!empty($params['contribution_id'])) { $contactId->id = $params['contribution_id']; } elseif (!empty($params['trxn_id'])) { $contactId->trxn_id = $params['trxn_id']; } elseif (!empty($params['invoice_id'])) { $contactId->invoice_id = $params['invoice_id']; } if ($contactId->find(TRUE)) { $contactType->id = $contactId->contact_id; if ($contactType->find(TRUE)) { if ($params['contact_type'] != $contactType->contact_type) { return civicrm_api3_create_error("Contact Type is wrong: {$contactType->contact_type}"); } } } } else { if ($onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) { return civicrm_api3_create_error("Empty Contribution and Invoice and Transaction ID. Row was skipped."); } else { return civicrm_api3_create_error("Empty Contact and External ID. Row was skipped."); } } break; case 'receive_date': case 'cancel_date': case 'receipt_date': case 'thankyou_date': if (!CRM_Utils_Rule::dateTime($value)) { return civicrm_api3_create_error("{$key} not a valid date: {$value}"); } break; case 'non_deductible_amount': case 'total_amount': case 'fee_amount': case 'net_amount': if (!CRM_Utils_Rule::money($value)) { return civicrm_api3_create_error("{$key} not a valid amount: {$value}"); } break; case 'currency': if (!CRM_Utils_Rule::currencyCode($value)) { return civicrm_api3_create_error("currency not a valid code: {$value}"); } break; case 'financial_type': require_once 'CRM/Contribute/PseudoConstant.php'; $contriTypes = CRM_Contribute_PseudoConstant::financialType(); foreach ($contriTypes as $val => $type) { if (strtolower($value) == strtolower($type)) { $values['financial_type_id'] = $val; break; } } if (empty($values['financial_type_id'])) { return civicrm_api3_create_error("Financial Type is not valid: {$value}"); } break; case 'payment_instrument': require_once 'CRM/Core/OptionGroup.php'; $values['payment_instrument_id'] = CRM_Core_OptionGroup::getValue('payment_instrument', $value); if (empty($values['payment_instrument_id'])) { return civicrm_api3_create_error("Payment Instrument is not valid: {$value}"); } break; case 'contribution_status_id': require_once 'CRM/Core/OptionGroup.php'; if (!($values['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', $value))) { return civicrm_api3_create_error("Contribution Status is not valid: {$value}"); } break; case 'soft_credit': // import contribution record according to select contact type // validate contact id and external identifier. $value[$key] = $mismatchContactType = $softCreditContactIds = ''; if (isset($params[$key]) && is_array($params[$key])) { foreach ($params[$key] as $softKey => $softParam) { $contactId = CRM_Utils_Array::value('contact_id', $softParam); $externalId = CRM_Utils_Array::value('external_identifier', $softParam); $email = CRM_Utils_Array::value('email', $softParam); if ($contactId || $externalId) { require_once 'CRM/Contact/DAO/Contact.php'; $contact = new CRM_Contact_DAO_Contact(); $contact->id = $contactId; $contact->external_identifier = $externalId; $errorMsg = NULL; if (!$contact->find(TRUE)) { $field = $contactId ? ts('Contact ID') : ts('External ID'); $errorMsg = ts("Soft Credit %1 - %2 doesn't exist. Row was skipped.", array(1 => $field, 2 => $contactId ? $contactId : $externalId)); } if ($errorMsg) { return civicrm_api3_create_error($errorMsg, $value[$key]); } // finally get soft credit contact id. $values[$key][$softKey] = $softParam; $values[$key][$softKey]['contact_id'] = $contact->id; } elseif ($email) { if (!CRM_Utils_Rule::email($email)) { return civicrm_api3_create_error("Invalid email address {$email} provided for Soft Credit. Row was skipped"); } // get the contact id from duplicate contact rule, if more than one contact is returned // we should return error, since current interface allows only one-one mapping $emailParams = array('email' => $email, 'contact_type' => $params['contact_type']); $checkDedupe = _civicrm_api3_deprecated_duplicate_formatted_contact($emailParams); if (!$checkDedupe['is_error']) { return civicrm_api3_create_error("Invalid email address(doesn't exist) {$email} for Soft Credit. Row was skipped"); } else { $matchingContactIds = explode(',', $checkDedupe['error_message']['params'][0]); if (count($matchingContactIds) > 1) { return civicrm_api3_create_error("Invalid email address(duplicate) {$email} for Soft Credit. Row was skipped"); } elseif (count($matchingContactIds) == 1) { $contactId = $matchingContactIds[0]; unset($softParam['email']); $values[$key][$softKey] = $softParam + array('contact_id' => $contactId); } } } } } break; case 'pledge_payment': case 'pledge_id': // giving respect to pledge_payment flag. if (empty($params['pledge_payment'])) { continue; } // get total amount of from import fields $totalAmount = CRM_Utils_Array::value('total_amount', $params); $onDuplicate = CRM_Utils_Array::value('onDuplicate', $params); // we need to get contact id $contributionContactID to // retrieve pledge details as well as to validate pledge ID // first need to check for update mode if ($onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE && ($params['contribution_id'] || $params['trxn_id'] || $params['invoice_id'])) { $contribution = new CRM_Contribute_DAO_Contribution(); if ($params['contribution_id']) { $contribution->id = $params['contribution_id']; } elseif ($params['trxn_id']) { $contribution->trxn_id = $params['trxn_id']; } elseif ($params['invoice_id']) { $contribution->invoice_id = $params['invoice_id']; } if ($contribution->find(TRUE)) { $contributionContactID = $contribution->contact_id; if (!$totalAmount) { $totalAmount = $contribution->total_amount; } } else { return civicrm_api3_create_error('No match found for specified contact in contribution data. Row was skipped.', 'pledge_payment'); } } else { // first get the contact id for given contribution record. if (!empty($params['contribution_contact_id'])) { $contributionContactID = $params['contribution_contact_id']; } elseif (!empty($params['external_identifier'])) { require_once 'CRM/Contact/DAO/Contact.php'; $contact = new CRM_Contact_DAO_Contact(); $contact->external_identifier = $params['external_identifier']; if ($contact->find(TRUE)) { $contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $contact->id; } else { return civicrm_api3_create_error('No match found for specified contact in contribution data. Row was skipped.', 'pledge_payment'); } } else { // we need to get contribution contact using de dupe $error = _civicrm_api3_deprecated_check_contact_dedupe($params); if (isset($error['error_message']['params'][0])) { $matchedIDs = explode(',', $error['error_message']['params'][0]); // check if only one contact is found if (count($matchedIDs) > 1) { return civicrm_api3_create_error($error['error_message']['message'], 'pledge_payment'); } else { $contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $matchedIDs[0]; } } else { return civicrm_api3_create_error('No match found for specified contact in contribution data. Row was skipped.', 'pledge_payment'); } } } if (!empty($params['pledge_id'])) { if (CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $params['pledge_id'], 'contact_id') != $contributionContactID) { return civicrm_api3_create_error('Invalid Pledge ID provided. Contribution row was skipped.', 'pledge_payment'); } $values['pledge_id'] = $params['pledge_id']; } else { // check if there are any pledge related to this contact, with payments pending or in progress require_once 'CRM/Pledge/BAO/Pledge.php'; $pledgeDetails = CRM_Pledge_BAO_Pledge::getContactPledges($contributionContactID); if (empty($pledgeDetails)) { return civicrm_api3_create_error('No open pledges found for this contact. Contribution row was skipped.', 'pledge_payment'); } elseif (count($pledgeDetails) > 1) { return civicrm_api3_create_error('This contact has more than one open pledge. Unable to determine which pledge to apply the contribution to. Contribution row was skipped.', 'pledge_payment'); } // this mean we have only one pending / in progress pledge $values['pledge_id'] = $pledgeDetails[0]; } // we need to check if oldest payment amount equal to contribution amount require_once 'CRM/Pledge/BAO/PledgePayment.php'; $pledgePaymentDetails = CRM_Pledge_BAO_PledgePayment::getOldestPledgePayment($values['pledge_id']); if ($pledgePaymentDetails['amount'] == $totalAmount) { $values['pledge_payment_id'] = $pledgePaymentDetails['id']; } else { return civicrm_api3_create_error('Contribution and Pledge Payment amount mismatch for this record. Contribution row was skipped.', 'pledge_payment'); } break; default: break; } } if (array_key_exists('note', $params)) { $values['note'] = $params['note']; } if ($create) { // CRM_Contribute_BAO_Contribution::add() handles contribution_source // So, if $values contains contribution_source, convert it to source $changes = array('contribution_source' => 'source'); foreach ($changes as $orgVal => $changeVal) { if (isset($values[$orgVal])) { $values[$changeVal] = $values[$orgVal]; unset($values[$orgVal]); } } } return NULL; }
/** * Validate string fields being passed into API. * @param array $params params from civicrm_api * @param string $fieldName uniquename of field being checked * @param array $fieldInfo array of fields from getfields function * @param string $entity * @throws API_Exception * @throws Exception */ function _civicrm_api3_validate_string(&$params, &$fieldName, &$fieldInfo, $entity) { // If fieldname exists in params $value = CRM_Utils_Array::value($fieldName, $params, ''); if (!is_array($value)) { $value = (string) $value; } else { //@todo what do we do about passed in arrays. For many of these fields // the missing piece of functionality is separating them to a separated string // & many save incorrectly. But can we change them wholesale? } if ($value) { if (!CRM_Utils_Rule::xssString($value)) { throw new Exception('Illegal characters in input (potential scripting attack)'); } if ($fieldName == 'currency') { if (!CRM_Utils_Rule::currencyCode($value)) { throw new Exception("Currency not a valid code: {$value}"); } } if (!empty($fieldInfo['pseudoconstant']) || !empty($fieldInfo['options'])) { _civicrm_api3_api_match_pseudoconstant($params, $entity, $fieldName, $fieldInfo); } elseif (is_string($value) && !empty($fieldInfo['maxlength']) && strlen(utf8_decode($value)) > $fieldInfo['maxlength']) { throw new API_Exception("Value for {$fieldName} is " . strlen(utf8_decode($value)) . " characters - This field has a maxlength of {$fieldInfo['maxlength']} characters.", 2100, array('field' => $fieldName)); } } }
/** * Validate string fields being passed into API. * * @param array $params * Params from civicrm_api. * @param string $fieldName * Uniquename of field being checked. * @param array $fieldInfo * Array of fields from getfields function. * @param string $entity * * @throws API_Exception * @throws Exception */ function _civicrm_api3_validate_string(&$params, &$fieldName, &$fieldInfo, $entity) { list($fieldValue, $op) = _civicrm_api3_field_value_check($params, $fieldName); if (strpos($op, 'NULL') !== FALSE || strpos($op, 'EMPTY') !== FALSE || CRM_Utils_System::isNull($fieldValue)) { return; } if (!is_array($fieldValue)) { $fieldValue = (string) $fieldValue; } else { //@todo what do we do about passed in arrays. For many of these fields // the missing piece of functionality is separating them to a separated string // & many save incorrectly. But can we change them wholesale? } if ($fieldValue) { foreach ((array) $fieldValue as $value) { if (!CRM_Utils_Rule::xssString($fieldValue)) { throw new Exception('Input contains illegal SCRIPT tag.'); } if ($fieldName == 'currency') { //When using IN operator $fieldValue is a array of currency codes if (!CRM_Utils_Rule::currencyCode($value)) { throw new Exception("Currency not a valid code: {$currency}"); } } } } if (!empty($fieldInfo['pseudoconstant']) || !empty($fieldInfo['options'])) { _civicrm_api3_api_match_pseudoconstant($fieldValue, $entity, $fieldName, $fieldInfo); } elseif (is_string($fieldValue) && !empty($fieldInfo['maxlength']) && strlen(utf8_decode($fieldValue)) > $fieldInfo['maxlength']) { throw new API_Exception("Value for {$fieldName} is " . strlen(utf8_decode($value)) . " characters - This field has a maxlength of {$fieldInfo['maxlength']} characters.", 2100, array('field' => $fieldName)); } if (!empty($op)) { $params[$fieldName][$op] = $fieldValue; } else { $params[$fieldName] = $fieldValue; } }
/** * The constructor. Basically redefines the class variables if * it finds a constant definition for that class variable * * @return object * @access private */ function CRM_Core_Config() { require_once 'CRM/Core/Session.php'; $session =& CRM_Core_Session::singleton(); if (defined('CIVICRM_DOMAIN_ID')) { $GLOBALS['_CRM_CORE_CONFIG']['_domainID'] = CIVICRM_DOMAIN_ID; } else { $GLOBALS['_CRM_CORE_CONFIG']['_domainID'] = 1; } $session->set('domainID', $GLOBALS['_CRM_CORE_CONFIG']['_domainID']); // we figure this out early, since some config parameters are loaded // based on what components are enabled if (defined('ENABLE_COMPONENTS')) { $this->enableComponents = explode(',', ENABLE_COMPONENTS); for ($i = 0; $i < count($this->enableComponents); $i++) { $this->enableComponents[$i] = trim($this->enableComponents[$i]); } } if (defined('CIVICRM_DSN')) { $this->dsn = CIVICRM_DSN; } if (defined('UF_DSN')) { $this->ufDSN = UF_DSN; } if (defined('UF_USERTABLENAME')) { $this->ufUserTableName = UF_USERTABLENAME; } if (defined('CIVICRM_DEBUG')) { $this->debug = CIVICRM_DEBUG; } if (defined('CIVICRM_DAO_DEBUG')) { $this->daoDebug = CIVICRM_DAO_DEBUG; } if (defined('CIVICRM_DAO_FACTORY_CLASS')) { $this->DAOFactoryClass = CIVICRM_DAO_FACTORY_CLASS; } if (defined('CIVICRM_SMARTYDIR')) { $this->smartyDir = CIVICRM_SMARTYDIR; } if (defined('CIVICRM_PLUGINSDIR')) { $this->pluginsDir = CIVICRM_PLUGINSDIR; } if (defined('CIVICRM_TEMPLATEDIR')) { $this->templateDir = CIVICRM_TEMPLATEDIR; } if (defined('CIVICRM_TEMPLATE_COMPILEDIR')) { $this->templateCompileDir = CIVICRM_TEMPLATE_COMPILEDIR; // make sure this directory exists CRM_Utils_File::createDir($this->templateCompileDir); } if (defined('CIVICRM_RESOURCEBASE')) { $this->resourceBase = CRM_Core_Config::addTrailingSlash(CIVICRM_RESOURCEBASE, '/'); } if (defined('CIVICRM_UPLOADDIR')) { $this->uploadDir = CRM_Core_Config::addTrailingSlash(CIVICRM_UPLOADDIR); CRM_Utils_File::createDir($this->uploadDir); } if (defined('CIVICRM_IMAGE_UPLOADDIR')) { $this->imageUploadDir = CRM_Core_Config::addTrailingSlash(CIVICRM_IMAGE_UPLOADDIR); CRM_Utils_File::createDir($this->imageUploadDir); } if (defined('CIVICRM_IMAGE_UPLOADURL')) { $this->imageUploadURL = CRM_Core_Config::addTrailingSlash(CIVICRM_IMAGE_UPLOADURL, '/'); } if (defined('CIVICRM_CLEANURL')) { $this->cleanURL = CIVICRM_CLEANURL; } if (defined('CIVICRM_COUNTRY_LIMIT')) { $isoCodes = preg_split('/[^a-zA-Z]/', CIVICRM_COUNTRY_LIMIT); $this->countryLimit = array_filter($isoCodes); } if (defined('CIVICRM_PROVINCE_LIMIT')) { $isoCodes = preg_split('/[^a-zA-Z]/', CIVICRM_PROVINCE_LIMIT); $provinceLimitList = array_filter($isoCodes); if (!empty($provinceLimitList)) { $this->provinceLimit = array_filter($isoCodes); } } // Note: we can't change the ISO code to country_id // here, as we can't access the database yet... if (defined('CIVICRM_DEFAULT_CONTACT_COUNTRY')) { $this->defaultContactCountry = CIVICRM_DEFAULT_CONTACT_COUNTRY; } if (defined('CIVICONTRIBUTE_DEFAULT_CURRENCY') and CRM_Utils_Rule::currencyCode(CIVICONTRIBUTE_DEFAULT_CURRENCY)) { $this->defaultCurrency = CIVICONTRIBUTE_DEFAULT_CURRENCY; } if (defined('CIVICRM_LC_MESSAGES')) { $this->lcMessages = CIVICRM_LC_MESSAGES; } if (defined('CIVICRM_ADDRESS_FORMAT')) { // trim the format and unify line endings to LF $format = trim(CIVICRM_ADDRESS_FORMAT); $format = str_replace(array("\r\n", "\r"), "\n", $format); // get the field sequence from the format $newSequence = array(); foreach ($this->addressSequence as $field) { if (substr_count($format, $field)) { $newSequence[strpos($format, $field)] = $field; } } ksort($newSequence); // add the addressSequence fields that are missing in the addressFormat // to the end of the list, so that (for example) if state_province is not // specified in the addressFormat it's still in the address-editing form $newSequence = array_merge($newSequence, $this->addressSequence); $newSequence = array_unique($newSequence); $this->addressSequence = $newSequence; $this->addressFormat = $format; } if (defined('CIVICRM_DATEFORMAT_DATETIME')) { $this->dateformatDatetime = CIVICRM_DATEFORMAT_DATETIME; } if (defined('CIVICRM_DATEFORMAT_FULL')) { $this->dateformatFull = CIVICRM_DATEFORMAT_FULL; } if (defined('CIVICRM_DATEFORMAT_PARTIAL')) { $this->dateformatPartial = CIVICRM_DATEFORMAT_PARTIAL; } if (defined('CIVICRM_DATEFORMAT_YEAR')) { $this->dateformatYear = CIVICRM_DATEFORMAT_YEAR; } if (defined('CIVICRM_DATEFORMAT_QF_DATE')) { $this->dateformatQfDate = CIVICRM_DATEFORMAT_QF_DATE; } if (defined('CIVICRM_DATEFORMAT_QF_DATETIME')) { $this->dateformatQfDatetime = CIVICRM_DATEFORMAT_QF_DATETIME; } if (defined('CIVICRM_MONEYFORMAT')) { $this->moneyformat = CIVICRM_MONEYFORMAT; } if (defined('CIVICRM_LC_MONETARY')) { $this->lcMonetary = CIVICRM_LC_MONETARY; setlocale(LC_MONETARY, $this->lcMonetary . '.UTF-8', $this->lcMonetary, 'C'); } if (defined('CIVICRM_GETTEXT_CODESET')) { $this->gettextCodeset = CIVICRM_GETTEXT_CODESET; } if (defined('CIVICRM_GETTEXT_DOMAIN')) { $this->gettextDomain = CIVICRM_GETTEXT_DOMAIN; } if (defined('CIVICRM_GETTEXT_RESOURCEDIR')) { $this->gettextResourceDir = CRM_Core_Config::addTrailingSlash(CIVICRM_GETTEXT_RESOURCEDIR); } if (defined('CIVICRM_SMTP_SERVER')) { $this->smtpServer = CIVICRM_SMTP_SERVER; } if (defined('CIVICRM_SMTP_PORT')) { $this->smtpPort = CIVICRM_SMTP_PORT; } if (defined('CIVICRM_SMTP_AUTH')) { if (CIVICRM_SMTP_AUTH === true) { $this->smtpAuth = true; } // else it stays false } if (defined('CIVICRM_SMTP_USERNAME')) { $this->smtpUsername = CIVICRM_SMTP_USERNAME; } if (defined('CIVICRM_SMTP_PASSWORD')) { $this->smtpPassword = CIVICRM_SMTP_PASSWORD; } if (defined('CIVICRM_UF')) { $this->userFramework = CIVICRM_UF; $this->userFrameworkClass = 'CRM_Utils_System_' . $this->userFramework; $this->userHookClass = 'CRM_Utils_Hook_' . $this->userFramework; $this->userPermissionClass = 'CRM_Core_Permission_' . $this->userFramework; } if (defined('CIVICRM_UF_VERSION')) { $this->userFrameworkVersion = (double) CIVICRM_UF_VERSION; } if (defined('CIVICRM_UF_URLVAR')) { $this->userFrameworkURLVar = CIVICRM_UF_URLVAR; } if (defined('CIVICRM_UF_DSN')) { $this->userFrameworkDSN = CIVICRM_UF_DSN; } if (defined('CIVICRM_UF_USERSTABLENAME')) { $this->userFrameworkUsersTableName = CIVICRM_UF_USERSTABLENAME; } if (defined('CIVICRM_UF_BASEURL')) { $this->userFrameworkBaseURL = CRM_Core_Config::addTrailingSlash(CIVICRM_UF_BASEURL, '/'); } if (defined('CIVICRM_UF_RESOURCEURL')) { $this->userFrameworkResourceURL = CRM_Core_Config::addTrailingSlash(CIVICRM_UF_RESOURCEURL, '/'); } if (defined('CIVICRM_UF_FRONTEND')) { $this->userFrameworkFrontend = CIVICRM_UF_FRONTEND; } if (defined('CIVICRM_MYSQL_VERSION')) { $this->mysqlVersion = CIVICRM_MYSQL_VERSION; } if (defined('CIVICRM_MYSQL_PATH')) { $this->mysqlPath = CIVICRM_MYSQL_PATH; } $size = trim(ini_get('upload_max_filesize')); if ($size) { $last = strtolower($size[strlen($size) - 1]); switch ($last) { // The 'G' modifier is available since PHP 5.1.0 case 'g': $size *= 1024; case 'm': $size *= 1024; case 'k': $size *= 1024; } $this->maxImportFileSize = $size; } if (defined('CIVICRM_MAP_PROVIDER')) { $this->mapProvider = CIVICRM_MAP_PROVIDER; } if (defined('CIVICRM_MAP_API_KEY')) { $this->mapAPIKey = CIVICRM_MAP_API_KEY; } if (defined('CIVICRM_GEOCODE_METHOD')) { if (CIVICRM_GEOCODE_METHOD == 'CRM_Utils_Geocode_ZipTable' || CIVICRM_GEOCODE_METHOD == 'CRM_Utils_Geocode_RPC' || CIVICRM_GEOCODE_METHOD == 'CRM_Utils_Geocode_Yahoo') { $this->geocodeMethod = CIVICRM_GEOCODE_METHOD; } } if (defined('CIVICRM_VERSION_CHECK') and CIVICRM_VERSION_CHECK) { $this->versionCheck = true; } if (defined('CIVICRM_MAILER_SPOOL_PERIOD')) { $this->mailerPeriod = CIVICRM_MAILER_SPOOL_PERIOD; } if (defined('CIVICRM_VERP_SEPARATOR')) { $this->verpSeparator = CIVICRM_VERP_SEPARATOR; } if (defined('CIVICRM_ENABLE_SSL')) { $this->enableSSL = CIVICRM_ENABLE_SSL; } if (in_array('CiviContribute', $this->enableComponents)) { require_once 'CRM/Contribute/Config.php'; CRM_Contribute_Config::add($this); } if (in_array('CiviSMS', $this->enableComponents)) { require_once 'CRM/SMS/Config.php'; CRM_SMS_Config::add($this); } // initialize the framework $this->initialize(); }
/** * Takes an associative array and creates a participant object. * * the function extract all the params it needs to initialize the create a * participant object. the params array could contain additional unused name/value * pairs * * @param array $params * (reference ) an assoc array of name/value pairs. * * @return CRM_Event_BAO_Participant */ public static function &add(&$params) { if (!empty($params['id'])) { CRM_Utils_Hook::pre('edit', 'Participant', $params['id'], $params); } else { CRM_Utils_Hook::pre('create', 'Participant', NULL, $params); } // converting dates to mysql format if (!empty($params['register_date'])) { $params['register_date'] = CRM_Utils_Date::isoToMysql($params['register_date']); } if (!empty($params['participant_fee_amount'])) { $params['participant_fee_amount'] = CRM_Utils_Rule::cleanMoney($params['participant_fee_amount']); } if (!empty($params['fee_amount'])) { $params['fee_amount'] = CRM_Utils_Rule::cleanMoney($params['fee_amount']); } // ensure that role ids are encoded as a string if (isset($params['role_id']) && is_array($params['role_id'])) { if (in_array(key($params['role_id']), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { $op = key($params['role_id']); $params['role_id'] = $params['role_id'][$op]; } else { $params['role_id'] = implode(CRM_Core_DAO::VALUE_SEPARATOR, $params['role_id']); } } $participantBAO = new CRM_Event_BAO_Participant(); if (!empty($params['id'])) { $participantBAO->id = CRM_Utils_Array::value('id', $params); $participantBAO->find(TRUE); $participantBAO->register_date = CRM_Utils_Date::isoToMysql($participantBAO->register_date); } $participantBAO->copyValues($params); //CRM-6910 //1. If currency present, it should be valid one. //2. We should have currency when amount is not null. $currency = $participantBAO->fee_currency; if ($currency || !CRM_Utils_System::isNull($participantBAO->fee_amount)) { if (!CRM_Utils_Rule::currencyCode($currency)) { $config = CRM_Core_Config::singleton(); $currency = $config->defaultCurrency; } } $participantBAO->fee_currency = $currency; $participantBAO->save(); $session = CRM_Core_Session::singleton(); CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush(); if (!empty($params['id'])) { CRM_Utils_Hook::post('edit', 'Participant', $participantBAO->id, $participantBAO); } else { CRM_Utils_Hook::post('create', 'Participant', $participantBAO->id, $participantBAO); } return $participantBAO; }
/** * takes an associative array and creates a contribution object * * the function extract all the params it needs to initialize the create a * contribution object. the params array could contain additional unused name/value * pairs * * @param array $params (reference ) an assoc array of name/value pairs * @param array $ids the array that holds all the db ids * * @return object CRM_Contribute_BAO_Contribution object * @access public * @static */ static function add(&$params, $ids = array()) { if (empty($params)) { return; } //per http://wiki.civicrm.org/confluence/display/CRM/Database+layer we are moving away from $ids array $contributionID = CRM_Utils_Array::value('contribution', $ids, CRM_Utils_Array::value('id', $params)); $duplicates = array(); if (self::checkDuplicate($params, $duplicates, $contributionID)) { $error = CRM_Core_Error::singleton(); $d = implode(', ', $duplicates); $error->push(CRM_Core_Error::DUPLICATE_CONTRIBUTION, 'Fatal', array($d), "Duplicate error - existing contribution record(s) have a matching Transaction ID or Invoice ID. Contribution record ID(s) are: {$d}"); return $error; } // first clean up all the money fields $moneyFields = array('total_amount', 'net_amount', 'fee_amount', 'non_deductible_amount'); //if priceset is used, no need to cleanup money if (CRM_Utils_Array::value('skipCleanMoney', $params)) { unset($moneyFields[0]); } foreach ($moneyFields as $field) { if (isset($params[$field])) { $params[$field] = CRM_Utils_Rule::cleanMoney($params[$field]); } } // CRM-13420, set payment instrument to default if payment_instrument_id is empty if (!$contributionID && !CRM_Utils_Array::value('payment_instrument_id', $params)) { $params['payment_instrument_id'] = key(CRM_Core_OptionGroup::values('payment_instrument', FALSE, FALSE, FALSE, 'AND is_default = 1')); } if (CRM_Utils_Array::value('payment_instrument_id', $params)) { $paymentInstruments = CRM_Contribute_PseudoConstant::paymentInstrument('name'); if ($params['payment_instrument_id'] != array_search('Check', $paymentInstruments)) { $params['check_number'] = 'null'; } } // contribution status is missing, choose Completed as default status // do this for create mode only if (!$contributionID && !CRM_Utils_Array::value('contribution_status_id', $params)) { $params['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'); } if ($contributionID) { CRM_Utils_Hook::pre('edit', 'Contribution', $contributionID, $params); } else { CRM_Utils_Hook::pre('create', 'Contribution', NULL, $params); } $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->copyValues($params); $contribution->id = $contributionID; if (!CRM_Utils_Rule::currencyCode($contribution->currency)) { $config = CRM_Core_Config::singleton(); $contribution->currency = $config->defaultCurrency; } if ($contributionID) { $params['prevContribution'] = self::getValues(array('id' => $contributionID), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } $result = $contribution->save(); // Add financial_trxn details as part of fix for CRM-4724 $contribution->trxn_result_code = CRM_Utils_Array::value('trxn_result_code', $params); $contribution->payment_processor = CRM_Utils_Array::value('payment_processor', $params); //add Account details $params['contribution'] = $contribution; self::recordFinancialAccounts($params); // reset the group contact cache for this group CRM_Contact_BAO_GroupContactCache::remove(); if ($contributionID) { CRM_Utils_Hook::post('edit', 'Contribution', $contribution->id, $contribution); } else { CRM_Utils_Hook::post('create', 'Contribution', $contribution->id, $contribution); } return $result; }
/** * takes an associative array and creates a contribution object * * the function extract all the params it needs to initialize the create a * contribution object. the params array could contain additional unused name/value * pairs * * @param array $params (reference ) an assoc array of name/value pairs * @param array $ids the array that holds all the db ids * * @return object CRM_Contribute_BAO_Contribution object * @access public * @static */ function add(&$params, &$ids) { require_once 'CRM/Utils/Hook.php'; $duplicates = array(); if (CRM_Contribute_BAO_Contribution::checkDuplicate($params, $duplicates)) { $error =& CRM_Core_Error::singleton(); $d = implode(', ', $duplicates); $error->push(CRM_CORE_ERROR_DUPLICATE_CONTRIBUTION, 'Fatal', array($d), "Found matching contribution(s): {$d}"); return $error; } if (CRM_Utils_Array::value('contribution', $ids)) { CRM_Utils_Hook::pre('edit', 'Contribution', $ids['contribution'], $params); } else { CRM_Utils_Hook::pre('create', 'Contribution', null, $params); } $contribution =& new CRM_Contribute_BAO_Contribution(); $contribution->copyValues($params); $contribution->domain_id = CRM_Utils_Array::value('domain', $ids, CRM_Core_Config::domainID()); $contribution->id = CRM_Utils_Array::value('contribution', $ids); require_once 'CRM/Utils/Rule.php'; if (!CRM_Utils_Rule::currencyCode($contribution->currency)) { require_once 'CRM/Core/Config.php'; $config =& CRM_Core_Config::singleton(); $contribution->currency = $config->defaultCurrency; } $result = $contribution->save(); if (CRM_Utils_Array::value('contribution', $ids)) { CRM_Utils_Hook::post('edit', 'Contribution', $contribution->id, $contribution); } else { CRM_Utils_Hook::post('create', 'Contribution', $contribution->id, $contribution); } return $result; }
/** * Validate a formatted contribution parameter list. * * @param array $params Structured parameter list (as in crm_format_params) * * @return bool|CRM_Core_Error * @access public */ function _crm_validate_formatted_contribution(&$params) { static $domainID = null; if (!$domainID) { $config =& CRM_Core_Config::singleton(); $domainID = $config->domainID(); } foreach ($params as $key => $value) { switch ($key) { case 'contact_id': if (!CRM_Utils_Rule::integer($value)) { return _crm_error("contact_id not valid: {$value}"); } $dao =& new CRM_Core_DAO(); $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE domain_id = {$domainID} AND id = {$value}"); if (!$svq) { return _crm_error("there's no contact with contact_id of {$value}"); } break; case 'receive_date': case 'cancel_date': case 'receipt_date': case 'thankyou_date': if (!CRM_Utils_Rule::date($value)) { return _crm_error("{$key} not a valid date: {$value}"); } break; case 'non_deductible_amount': case 'total_amount': case 'fee_amount': case 'net_amount': if (!CRM_Utils_Rule::money($value)) { return _crm_error("{$key} not a valid amount: {$value}"); } break; case 'currency': if (!CRM_Utils_Rule::currencyCode($value)) { return _crm_error("currency not a valid code: {$value}"); } break; default: break; } } /* Validate custom data fields */ if (is_array($params['custom'])) { foreach ($params['custom'] as $key => $custom) { if (is_array($custom)) { $valid = CRM_Core_BAO_CustomValue::typecheck($custom['type'], $custom['value']); if (!$valid) { return _crm_error('Invalid value for custom field \'' . $custom['name'] . '\''); } if ($custom['type'] == 'Date') { $params['custom'][$key]['value'] = str_replace('-', '', $params['custom'][$key]['value']); } } } } return true; }
/** * take the input parameter list as specified in the data model and * convert it into the same format that we use in QF and BAO object * * @param array $params Associative array of property name/value * pairs to insert in new contact. * @param array $values The reformatted properties that we can use internally * ' * * @return array|CRM_Error * @access public */ function _civicrm_pledgepayment_format_params(&$params, &$values, $create = FALSE) { // copy all the pledge fields as is require_once 'CRM/Pledge/BAO/PledgePayment.php'; require_once 'CRM/Pledge/DAO/Pledge.php'; $fields = CRM_Pledge_DAO_Pledge::fields(); _civicrm_store_values($fields, $params, $values); foreach ($params as $key => $value) { // ignore empty values or empty arrays etc if (CRM_Utils_System::isNull($value)) { continue; } switch ($key) { case 'pledge_contact_id': if (!CRM_Utils_Rule::integer($value)) { return civicrm_create_error("contact_id not valid: {$value}"); } $dao = new CRM_Core_DAO(); $qParams = array(); $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = {$value}", $qParams); if (!$svq) { return civicrm_create_error("Invalid Contact ID: There is no contact record with contact_id = {$value}."); } $values['contact_id'] = $values['pledge_contact_id']; unset($values['pledge_contact_id']); break; case 'receive_date': case 'end_date': case 'pledge_create_date': case 'cancel_date': case 'receipt_date': case 'thankyou_date': if (!CRM_Utils_Rule::date($value)) { return civicrm_create_error("{$key} not a valid date: {$value}"); } break; case 'non_deductible_amount': case 'total_amount': case 'fee_amount': case 'net_amount': if (!CRM_Utils_Rule::money($value)) { return civicrm_create_error("{$key} not a valid amount: {$value}"); } break; case 'currency': if (!CRM_Utils_Rule::currencyCode($value)) { return civicrm_create_error("currency not a valid code: {$value}"); } break; case 'pledge_type': $values['pledge_type_id'] = CRM_Utils_Array::key(ucfirst($value), CRM_Pledge_PseudoConstant::pledgeType()); break; case 'payment_instrument': require_once 'CRM/Core/OptionGroup.php'; $values['payment_instrument_id'] = CRM_Core_OptionGroup::getValue('payment_instrument', $value); break; default: break; } } if (array_key_exists('note', $params)) { $values['note'] = $params['note']; } if (array_key_exists('installment_amount', $params)) { $values['installment_amount'] = $params['installment_amount']; } // testing testing - how do I make it take a create_date? It needs $values['create_date'] set but doesn't seem to like it because $fields calls it $pledge_create_date //ditto scheduled date. I don't know why this is needs to be done because I don't fully understand the code above if (array_key_exists('pledge_create_date', $params)) { $values['create_date'] = $params['pledge_create_date']; } if (array_key_exists('pledge_scheduled_date', $params)) { $values['scheduled_date'] = $params['pledge_scheduled_date']; } if (array_key_exists('pledge_create_date', $params)) { $values['create_date'] = $params['pledge_create_date']; } if (array_key_exists('status_id', $params)) { $values['status_id'] = $params['status_id']; $values['pledge_status_id'] = $params['status_id']; } _civicrm_custom_format_params($params, $values, 'Pledge'); if ($create) { // CRM_pledge_BAO_Pledge::add() handles Pledge_source // So, if $values contains Pledge_source, convert it to source $changes = array('pledge_source' => 'source'); foreach ($changes as $orgVal => $changeVal) { if (isset($values[$orgVal])) { $values[$changeVal] = $values[$orgVal]; unset($values[$orgVal]); } } } return array(); }
function make_payment(&$params) { $config = CRM_Core_Config::singleton(); if (isset($params["billing_state_province_id-{$this->_bltID}"]) && $params["billing_state_province_id-{$this->_bltID}"]) { $params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($params["billing_state_province_id-{$this->_bltID}"]); } if (isset($params["billing_country_id-{$this->_bltID}"]) && $params["billing_country_id-{$this->_bltID}"]) { $params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($params["billing_country_id-{$this->_bltID}"]); } $params['ip_address'] = CRM_Utils_System::ipAddress(); $params['currencyID'] = $config->defaultCurrency; $params['payment_action'] = 'Sale'; $payment =& CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this); CRM_Core_Payment_Form::mapParams($this->_bltID, $params, $params, TRUE); $params['month'] = $params['credit_card_exp_date']['M']; $params['year'] = $params['credit_card_exp_date']['Y']; $result =& $payment->doDirectPayment($params); if (is_a($result, 'CRM_Core_Error')) { CRM_Core_Error::displaySessionError($result); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/cart_checkout', "_qf_Payment_display=1&qfKey={$this->controller->_key}", TRUE, NULL, FALSE)); return; } elseif (!$result['trxn_id']) { CRM_Core_Error::fatal(ts("Financial institution didn't return a transaction id.")); } $trxnParams = array('trxn_date' => $params['now'], 'trxn_type' => 'Debit', 'total_amount' => $params['amount'], 'fee_amount' => CRM_Utils_Array::value('fee_amount', $result), 'net_amount' => CRM_Utils_Array::value('net_amount', $result, $params['amount']), 'currency' => CRM_Utils_Array::value('currencyID', $params), 'payment_processor' => $this->_paymentProcessor['payment_processor_type'], 'trxn_id' => $result['trxn_id']); $trxn = new CRM_Core_DAO_FinancialTrxn(); $trxn->copyValues($trxnParams); if (!CRM_Utils_Rule::currencyCode($trxn->currency)) { $config = CRM_Core_Config::singleton(); $trxn->currency = $config->defaultCurrency; } $trxn->save(); return $trxn; }
/** * Takes an associative array and creates a contribution object. * * the function extract all the params it needs to initialize the create a * contribution object. the params array could contain additional unused name/value * pairs * * @param array $params * (reference ) an assoc array of name/value pairs. * @param array $ids * The array that holds all the db ids. * * @return CRM_Contribute_BAO_Contribution|void */ public static function add(&$params, $ids = array()) { if (empty($params)) { return NULL; } //per http://wiki.civicrm.org/confluence/display/CRM/Database+layer we are moving away from $ids array $contributionID = CRM_Utils_Array::value('contribution', $ids, CRM_Utils_Array::value('id', $params)); $duplicates = array(); if (self::checkDuplicate($params, $duplicates, $contributionID)) { $error = CRM_Core_Error::singleton(); $d = implode(', ', $duplicates); $error->push(CRM_Core_Error::DUPLICATE_CONTRIBUTION, 'Fatal', array($d), "Duplicate error - existing contribution record(s) have a matching Transaction ID or Invoice ID. Contribution record ID(s) are: {$d}"); return $error; } // first clean up all the money fields $moneyFields = array('total_amount', 'net_amount', 'fee_amount', 'non_deductible_amount'); //if priceset is used, no need to cleanup money if (!empty($params['skipCleanMoney'])) { unset($moneyFields[0]); } foreach ($moneyFields as $field) { if (isset($params[$field])) { $params[$field] = CRM_Utils_Rule::cleanMoney($params[$field]); } } //set defaults in create mode if (!$contributionID) { CRM_Core_DAO::setCreateDefaults($params, self::getDefaults()); } self::calculateMissingAmountParams($params, $contributionID); if (!empty($params['payment_instrument_id'])) { $paymentInstruments = CRM_Contribute_PseudoConstant::paymentInstrument('name'); if ($params['payment_instrument_id'] != array_search('Check', $paymentInstruments)) { $params['check_number'] = 'null'; } } $setPrevContribution = TRUE; // CRM-13964 partial payment if (!empty($params['partial_payment_total']) && !empty($params['partial_amount_pay'])) { $partialAmtTotal = $params['partial_payment_total']; $partialAmtPay = $params['partial_amount_pay']; $params['total_amount'] = $partialAmtTotal; if ($partialAmtPay < $partialAmtTotal) { $params['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', 'Partially paid', 'name'); $params['is_pay_later'] = 0; $setPrevContribution = FALSE; } } if ($contributionID) { CRM_Utils_Hook::pre('edit', 'Contribution', $contributionID, $params); } else { CRM_Utils_Hook::pre('create', 'Contribution', NULL, $params); } $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->copyValues($params); $contribution->id = $contributionID; if (empty($contribution->id)) { // (only) on 'create', make sure that a valid currency is set (CRM-16845) if (!CRM_Utils_Rule::currencyCode($contribution->currency)) { $config = CRM_Core_Config::singleton(); $contribution->currency = $config->defaultCurrency; } } if ($contributionID && $setPrevContribution) { $params['prevContribution'] = self::getValues(array('id' => $contributionID), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } $result = $contribution->save(); // Add financial_trxn details as part of fix for CRM-4724 $contribution->trxn_result_code = CRM_Utils_Array::value('trxn_result_code', $params); $contribution->payment_processor = CRM_Utils_Array::value('payment_processor', $params); //add Account details $params['contribution'] = $contribution; self::recordFinancialAccounts($params); // reset the group contact cache for this group CRM_Contact_BAO_GroupContactCache::remove(); if ($contributionID) { CRM_Utils_Hook::post('edit', 'Contribution', $contribution->id, $contribution); } else { CRM_Utils_Hook::post('create', 'Contribution', $contribution->id, $contribution); } return $result; }
/** * take the input parameter list as specified in the data model and * convert it into the same format that we use in QF and BAO object * * @param array $params Associative array of property name/value * pairs to insert in new contact. * @param array $values The reformatted properties that we can use internally * ' * * @return array|CRM_Error * @access public */ function _civicrm_pledge_format_params(&$params, &$values, $create = FALSE) { // based on contribution apis - copy all the pledge fields - this function filters out non -valid fields but unfortunately // means we have to put them back where there are 2 names for the field (name in table & unique name) // since there is no clear std to use one or the other. Generally either works ? but not for create date // perhaps we should just copy $params across rather than run it through the 'filter'? // but at least the filter forces anomalies into the open. In several cases it turned out the unique names wouldn't work // even though they are 'generally' what is returned in the GET - implying they should $fields = CRM_Pledge_DAO_Pledge::fields(); _civicrm_store_values($fields, $params, $values); //add back the fields we know of that got dropped by the previous function if ($params['pledge_create_date']) { //pledge_create_date will not be formatted by the format params function so change back to create_date $values['create_date'] = $params['pledge_create_date']; } if ($params['create_date']) { //create_date may have been dropped by the $fields function so retrieve it $values['create_date'] = $params['create_date']; } if (array_key_exists('installment_amount', $params)) { //field has been renamed - don't lose it! Note that this must be called // installment amount not pledge_installment_amount, pledge_original_installment_amount // or original_installment_amount to avoid error // Division by zero in CRM\Pledge\BAO\PledgePayment.php:162 // but we should accept the variant because they are all 'logical assumptions' based on the // 'standards' $values['installment_amount'] = $params['installment_amount']; } if (array_key_exists('original_installment_amount', $params)) { $values['installment_amount'] = $params['original_installment_amount']; } if (array_key_exists('pledge_original_installment_amount', $params)) { $values['installment_amount'] = $params['pledge_original_installment_amount']; } if (array_key_exists('status_id', $params)) { $values['pledge_status_id'] = $params['status_id']; } if ($params['contact_id']) { //this is validity checked further down to make sure the contact exists $values['pledge_contact_id'] = $params['contact_id']; } if (array_key_exists('id', $params)) { //retrieve the id key dropped from params. Note we can't use pledge_id because it //causes an error in CRM_Pledge_BAO_PledgePayment - approx line 302 $values['id'] = $params['id']; } if (array_key_exists('pledge_id', $params)) { //retrieve the id key dropped from params. Note we can't use pledge_id because it //causes an error in CRM_Pledge_BAO_PledgePayment - approx line 302 $values['id'] = $params['pledge_id']; unset($values['pledge_id']); } if (array_key_exists('status_id', $params)) { $values['pledge_status_id'] = $params['status_id']; } if (empty($values['id'])) { //at this point both should be the same so unset both if not set - passing in empty //value causes crash rather creating new - do it before next section as null values ignored in 'switch' unset($values['id']); } if (!empty($params['scheduled_date'])) { //scheduled date is required to set next payment date - defaults to start date $values['scheduled_date'] = $params['scheduled_date']; } elseif (array_key_exists('start_date', $params)) { $values['scheduled_date'] = $params['start_date']; } if (CRM_Utils_Array::value('contribution_type_id', $params)) { $values['contribution_type_id'] = $params['contribution_type_id']; } foreach ($values as $key => $value) { // ignore empty values or empty arrays etc if (CRM_Utils_System::isNull($value)) { continue; } switch ($key) { case 'pledge_contact_id': if (!CRM_Utils_Rule::integer($value)) { return civicrm_create_error("contact_id not valid: {$value}"); } $dao = new CRM_Core_DAO(); $qParams = array(); $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = {$value}", $qParams); if (!$svq) { return civicrm_create_error("Invalid Contact ID: There is no contact record with contact_id = {$value}."); } $values['contact_id'] = $values['pledge_contact_id']; unset($values['pledge_contact_id']); break; case 'pledge_id': if (!CRM_Utils_Rule::integer($value)) { return civicrm_create_error("contact_id not valid: {$value}"); } $dao = new CRM_Core_DAO(); $qParams = array(); $svq = $dao->singleValueQuery("SELECT id FROM civicrm_pledge WHERE id = {$value}", $qParams); if (!$svq) { return civicrm_create_error("Invalid Contact ID: There is no contact record with contact_id = {$value}."); } break; case 'create_date': case 'scheduled_date': case 'start_date': if (!CRM_Utils_Rule::datetime($value)) { return civicrm_create_error("{$key} not a valid date: {$value}"); } break; case 'installment_amount': case 'amount': if (!CRM_Utils_Rule::money($value)) { return civicrm_create_error("{$key} not a valid amount: {$value}"); } break; case 'currency': if (!CRM_Utils_Rule::currencyCode($value)) { return civicrm_create_error("currency not a valid code: {$value}"); } break; case 'contribution_type_id': require_once 'CRM/Contribute/PseudoConstant.php'; $typeId = CRM_Contribute_PseudoConstant::contributionType($value); if (!CRM_Utils_Rule::integer($value) || !$typeId) { return civicrm_create_error("contribution type id is not valid: {$value}"); } default: break; } } //format the parameters _civicrm_custom_format_params($params, $values, 'Pledge'); return array(); }
/** * takes an associative array and creates a contribution object * * the function extract all the params it needs to initialize the create a * contribution object. the params array could contain additional unused name/value * pairs * * @param array $params (reference ) an assoc array of name/value pairs * @param array $ids the array that holds all the db ids * * @return object CRM_Contribute_BAO_Contribution object * @access public * @static */ static function add(&$params, &$ids) { if (empty($params)) { return; } $duplicates = array(); if (self::checkDuplicate($params, $duplicates, CRM_Utils_Array::value('contribution', $ids))) { $error =& CRM_Core_Error::singleton(); $d = implode(', ', $duplicates); $error->push(CRM_Core_Error::DUPLICATE_CONTRIBUTION, 'Fatal', array($d), "Duplicate error - existing contribution record(s) have a matching Transaction ID or Invoice ID. Contribution record ID(s) are: {$d}"); return $error; } // first clean up all the money fields $moneyFields = array('total_amount', 'net_amount', 'fee_amount', 'non_deductible_amount'); //if priceset is used, no need to cleanup money if (CRM_UTils_Array::value('skipCleanMoney', $params)) { unset($moneyFields[0]); } foreach ($moneyFields as $field) { if (isset($params[$field])) { $params[$field] = CRM_Utils_Rule::cleanMoney($params[$field]); } } if (CRM_Utils_Array::value('payment_instrument_id', $params)) { require_once 'CRM/Contribute/PseudoConstant.php'; $paymentInstruments = CRM_Contribute_PseudoConstant::paymentInstrument('name'); if ($params['payment_instrument_id'] != array_search('Check', $paymentInstruments)) { $params['check_number'] = 'null'; } } require_once 'CRM/Utils/Hook.php'; if (CRM_Utils_Array::value('contribution', $ids)) { CRM_Utils_Hook::pre('edit', 'Contribution', $ids['contribution'], $params); } else { CRM_Utils_Hook::pre('create', 'Contribution', null, $params); } $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->copyValues($params); $contribution->id = CRM_Utils_Array::value('contribution', $ids); // also add financial_trxn details as part of fix for CRM-4724 $contribution->trxn_result_code = CRM_Utils_Array::value('trxn_result_code', $params); $contribution->payment_processor = CRM_Utils_Array::value('payment_processor', $params); require_once 'CRM/Utils/Rule.php'; if (!CRM_Utils_Rule::currencyCode($contribution->currency)) { require_once 'CRM/Core/Config.php'; $config = CRM_Core_Config::singleton(); $contribution->currency = $config->defaultCurrency; } $result = $contribution->save(); // reset the group contact cache for this group require_once 'CRM/Contact/BAO/GroupContactCache.php'; CRM_Contact_BAO_GroupContactCache::remove(); if (CRM_Utils_Array::value('contribution', $ids)) { CRM_Utils_Hook::post('edit', 'Contribution', $contribution->id, $contribution); } else { CRM_Utils_Hook::post('create', 'Contribution', $contribution->id, $contribution); } return $result; }
function _civicrm_api3_validate_string(&$params, &$fieldname, &$fieldInfo) { // If fieldname exists in params if ($value = CRM_Utils_Array::value($fieldname, $params)) { if (!CRM_Utils_Rule::xssString($value)) { throw new Exception('Illegal characters in input (potential scripting attack)'); } if ($fieldname == 'currency') { if (!CRM_Utils_Rule::currencyCode($value)) { throw new Exception("Currency not a valid code: {$value}"); } } if (CRM_Utils_Array::value('pseudoconstant', $fieldInfo) && !CRM_Utils_Array::value('FKClassName', $fieldInfo)) { // Validate & swap out any pseudoconstants $constant = $fieldInfo['options']; if (!$constant && ($enum = CRM_Utils_Array::value('enumValues', $fieldInfo))) { $constant = explode(',', $enum); } // If value passed is not a key, it may be a label // Try to lookup key from label - if it can't be found throw error if (!isset($constant[$value])) { if (!($key = array_search($value, $constant))) { throw new Exception("{$fieldname} `{$value}` is not valid."); } else { $value = $key; } } } elseif (is_string($value) && !empty($fieldInfo['maxlength']) && strlen($value) > $fieldInfo['maxlength']) { throw new API_Exception("Value for {$fieldname} is " . strlen($value) . " characters - This field has a maxlength of {$fieldInfo['maxlength']} characters.", 2100, array('field' => $fieldname)); } } }
/** * take the input parameter list as specified in the data model and * convert it into the same format that we use in QF and BAO object * * @param array $params Associative array of property name/value * pairs to insert in new contact. * @param array $values The reformatted properties that we can use internally * ' * * @return array|CRM_Error * @access public */ function _civicrm_contribute_formatted_param(&$params, &$values, $create = FALSE) { // copy all the contribution fields as is $fields = CRM_Contribute_DAO_Contribution::fields(); _civicrm_store_values($fields, $params, $values); require_once 'CRM/Core/OptionGroup.php'; $customFields = CRM_Core_BAO_CustomField::getFields('Contribution'); foreach ($params as $key => $value) { // ignore empty values or empty arrays etc if (CRM_Utils_System::isNull($value)) { continue; } //Handling Custom Data _civicrm_generic_handle_custom_data($key, $value, $values, $customFields); switch ($key) { case 'contribution_contact_id': if (!CRM_Utils_Rule::integer($value)) { return civicrm_create_error("contact_id not valid: {$value}"); } $dao = new CRM_Core_DAO(); $qParams = array(); $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = {$value}", $qParams); if (!$svq) { return civicrm_create_error("Invalid Contact ID: There is no contact record with contact_id = {$value}."); } $values['contact_id'] = $values['contribution_contact_id']; unset($values['contribution_contact_id']); break; case 'contact_type': //import contribution record according to select contact type require_once 'CRM/Contact/DAO/Contact.php'; $contactType = new CRM_Contact_DAO_Contact(); //when insert mode check contact id or external identifire if ($params['contribution_contact_id'] || $params['external_identifier']) { if ($params['contribution_contact_id']) { $contactType->id = $params['contribution_contact_id']; } elseif ($params['external_identifier']) { $contactType->external_identifier = $params['external_identifier']; } if ($contactType->find(TRUE)) { if ($params['contact_type'] != $contactType->contact_type) { return civicrm_create_error("Contact Type is wrong: {$contactType->contact_type}"); } } } elseif ($params['contribution_id'] || $params['trxn_id'] || $params['invoice_id']) { //when update mode check contribution id or trxn id or //invoice id $contactId = new CRM_Contribute_DAO_Contribution(); if ($params['contribution_id']) { $contactId->id = $params['contribution_id']; } elseif ($params['trxn_id']) { $contactId->trxn_id = $params['trxn_id']; } elseif ($params['invoice_id']) { $contactId->invoice_id = $params['invoice_id']; } if ($contactId->find(TRUE)) { $contactType->id = $contactId->contact_id; if ($contactType->find(TRUE)) { if ($params['contact_type'] != $contactType->contact_type) { return civicrm_create_error("Contact Type is wrong: {$contactType->contact_type}"); } } } } break; case 'receive_date': case 'cancel_date': case 'receipt_date': case 'thankyou_date': if (!CRM_Utils_Rule::date($value)) { return civicrm_create_error("{$key} not a valid date: {$value}"); } break; case 'non_deductible_amount': case 'total_amount': case 'fee_amount': case 'net_amount': if (!CRM_Utils_Rule::money($value)) { return civicrm_create_error("{$key} not a valid amount: {$value}"); } break; case 'currency': if (!CRM_Utils_Rule::currencyCode($value)) { return civicrm_create_error("currency not a valid code: {$value}"); } break; case 'contribution_type': require_once 'CRM/Contribute/PseudoConstant.php'; $contriTypes = CRM_Contribute_PseudoConstant::contributionType(); foreach ($contriTypes as $val => $type) { if (strtolower($value) == strtolower($type)) { $values['contribution_type_id'] = $val; break; } } if (!CRM_Utils_Array::value('contribution_type_id', $values)) { return civicrm_create_error("Contribution Type is not valid: {$value}"); } break; case 'payment_instrument': require_once 'CRM/Core/OptionGroup.php'; $values['payment_instrument_id'] = CRM_Core_OptionGroup::getValue('payment_instrument', $value); if (!CRM_Utils_Array::value('payment_instrument_id', $values)) { return civicrm_create_error("Payment Instrument is not valid: {$value}"); } break; case 'contribution_status_id': require_once 'CRM/Core/OptionGroup.php'; if (!($values['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', $value))) { return civicrm_create_error("Contribution Status is not valid: {$value}"); } break; case 'honor_type_id': require_once 'CRM/Core/OptionGroup.php'; $values['honor_type_id'] = CRM_Core_OptionGroup::getValue('honor_type', $value); if (!CRM_Utils_Array::value('honor_type_id', $values)) { return civicrm_create_error("Honor Type is not valid: {$value}"); } break; case 'soft_credit': //import contribution record according to select contact type // validate contact id and external identifier. $contactId = CRM_Utils_Array::value('contact_id', $params['soft_credit']); $externalId = CRM_Utils_Array::value('external_identifier', $params['soft_credit']); if ($contactId || $externalId) { require_once 'CRM/Contact/DAO/Contact.php'; $contact = new CRM_Contact_DAO_Contact(); $contact->id = $contactId; $contact->external_identifier = $externalId; $errorMsg = NULL; if (!$contact->find(TRUE)) { $errorMsg = ts("No match found for specified Soft Credit contact data. Row was skipped."); } elseif ($params['contact_type'] != $contact->contact_type) { $errorMsg = ts("Soft Credit Contact Type is wrong: %1", array(1 => $contact->contact_type)); } if ($errorMsg) { return civicrm_create_error($errorMsg, 'soft_credit'); } // finally get soft credit contact id. $values['soft_credit_to'] = $contact->id; } else { // get the contact id from dupicate contact rule, if more than one contact is returned // we should return error, since current interface allows only one-one mapping $softParams = $params['soft_credit']; $softParams['contact_type'] = $params['contact_type']; $error = _civicrm_duplicate_formatted_contact($softParams); if (isset($error['error_message']['params'][0])) { $matchedIDs = explode(',', $error['error_message']['params'][0]); // check if only one contact is found if (count($matchedIDs) > 1) { return civicrm_create_error($error['error_message']['message'], 'soft_credit'); } else { $values['soft_credit_to'] = $matchedIDs[0]; } } else { return civicrm_create_error('No match found for specified Soft Credit contact data. Row was skipped.', 'soft_credit'); } } break; case 'pledge_payment': case 'pledge_id': //giving respect to pledge_payment flag. if (!CRM_Utils_Array::value('pledge_payment', $params)) { continue; } //get total amount of from import fields $totalAmount = CRM_Utils_Array::value('total_amount', $params); $onDuplicate = CRM_Utils_Array::value('onDuplicate', $params); //we need to get contact id $contributionContactID to //retrieve pledge details as well as to validate pledge ID //first need to check for update mode if ($onDuplicate == CRM_Contribute_Import_Parser::DUPLICATE_UPDATE && ($params['contribution_id'] || $params['trxn_id'] || $params['invoice_id'])) { $contribution = new CRM_Contribute_DAO_Contribution(); if ($params['contribution_id']) { $contribution->id = $params['contribution_id']; } elseif ($params['trxn_id']) { $contribution->trxn_id = $params['trxn_id']; } elseif ($params['invoice_id']) { $contribution->invoice_id = $params['invoice_id']; } if ($contribution->find(TRUE)) { $contributionContactID = $contribution->contact_id; if (!$totalAmount) { $totalAmount = $contribution->total_amount; } } else { return civicrm_create_error('No match found for specified contact in contribution data. Row was skipped.', 'pledge_payment'); } } else { // first get the contact id for given contribution record. if (CRM_Utils_Array::value('contribution_contact_id', $params)) { $contributionContactID = $params['contribution_contact_id']; } elseif (CRM_Utils_Array::value('external_identifier', $params)) { require_once 'CRM/Contact/DAO/Contact.php'; $contact = new CRM_Contact_DAO_Contact(); $contact->external_identifier = $params['external_identifier']; if ($contact->find(TRUE)) { $contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $contact->id; } else { return civicrm_create_error('No match found for specified contact in contribution data. Row was skipped.', 'pledge_payment'); } } else { // we need to get contribution contact using de dupe $error = civicrm_check_contact_dedupe($params); if (isset($error['error_message']['params'][0])) { $matchedIDs = explode(',', $error['error_message']['params'][0]); // check if only one contact is found if (count($matchedIDs) > 1) { return civicrm_create_error($error['error_message']['message'], 'pledge_payment'); } else { $contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $matchedIDs[0]; } } else { return civicrm_create_error('No match found for specified contact in contribution data. Row was skipped.', 'pledge_payment'); } } } if (CRM_Utils_Array::value('pledge_id', $params)) { if (CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $params['pledge_id'], 'contact_id') != $contributionContactID) { return civicrm_create_error('Invalid Pledge ID provided. Contribution row was skipped.', 'pledge_payment'); } $values['pledge_id'] = $params['pledge_id']; } else { //check if there are any pledge related to this contact, with payments pending or in progress require_once 'CRM/Pledge/BAO/Pledge.php'; $pledgeDetails = CRM_Pledge_BAO_Pledge::getContactPledges($contributionContactID); if (empty($pledgeDetails)) { return civicrm_create_error('No open pledges found for this contact. Contribution row was skipped.', 'pledge_payment'); } elseif (count($pledgeDetails) > 1) { return civicrm_create_error('This contact has more than one open pledge. Unable to determine which pledge to apply the contribution to. Contribution row was skipped.', 'pledge_payment'); } // this mean we have only one pending / in progress pledge $values['pledge_id'] = $pledgeDetails[0]; } //we need to check if oldest payment amount equal to contribution amount require_once 'CRM/Pledge/BAO/PledgePayment.php'; $pledgePaymentDetails = CRM_Pledge_BAO_PledgePayment::getOldestPledgePayment($values['pledge_id']); if ($pledgePaymentDetails['amount'] == $totalAmount) { $values['pledge_payment_id'] = $pledgePaymentDetails['id']; } else { return civicrm_create_error('Contribution and Pledge Payment amount mismatch for this record. Contribution row was skipped.', 'pledge_payment'); } break; default: break; } } if (array_key_exists('note', $params)) { $values['note'] = $params['note']; } if ($create) { // CRM_Contribute_BAO_Contribution::add() handles contribution_source // So, if $values contains contribution_source, convert it to source $changes = array('contribution_source' => 'source'); foreach ($changes as $orgVal => $changeVal) { if (isset($values[$orgVal])) { $values[$changeVal] = $values[$orgVal]; unset($values[$orgVal]); } } } return NULL; }
/** * Takes an associative array and creates a contribution object. * * the function extract all the params it needs to initialize the create a * contribution object. the params array could contain additional unused name/value * pairs * * @param array $params * (reference ) an assoc array of name/value pairs. * @param array $ids * The array that holds all the db ids. * * @return CRM_Contribute_BAO_Contribution|void */ public static function add(&$params, $ids = array()) { if (empty($params)) { return NULL; } //per http://wiki.civicrm.org/confluence/display/CRM/Database+layer we are moving away from $ids array $contributionID = CRM_Utils_Array::value('contribution', $ids, CRM_Utils_Array::value('id', $params)); $duplicates = array(); if (self::checkDuplicate($params, $duplicates, $contributionID)) { $error = CRM_Core_Error::singleton(); $d = implode(', ', $duplicates); $error->push(CRM_Core_Error::DUPLICATE_CONTRIBUTION, 'Fatal', array($d), "Duplicate error - existing contribution record(s) have a matching Transaction ID or Invoice ID. Contribution record ID(s) are: {$d}"); return $error; } // first clean up all the money fields $moneyFields = array('total_amount', 'net_amount', 'fee_amount', 'non_deductible_amount'); //if priceset is used, no need to cleanup money if (!empty($params['skipCleanMoney'])) { unset($moneyFields[0]); } foreach ($moneyFields as $field) { if (isset($params[$field])) { $params[$field] = CRM_Utils_Rule::cleanMoney($params[$field]); } } //set defaults in create mode if (!$contributionID) { CRM_Core_DAO::setCreateDefaults($params, self::getDefaults()); } $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); //if contribution is created with cancelled or refunded status, add credit note id if (!empty($params['contribution_status_id'])) { // @todo - should we include Chargeback? If so use self::isContributionStatusNegative($params['contribution_status_id']) if ($params['contribution_status_id'] == array_search('Refunded', $contributionStatus) || $params['contribution_status_id'] == array_search('Cancelled', $contributionStatus)) { if (empty($params['creditnote_id']) || $params['creditnote_id'] == "null") { $params['creditnote_id'] = self::createCreditNoteId(); } } } else { // Since the fee amount is expecting this (later on) ensure it is always set. // It would only not be set for an update where it is unchanged. $params['contribution_status_id'] = civicrm_api3('Contribution', 'getvalue', array('id' => $contributionID, 'return' => 'contribution_status_id')); } if (!$contributionID && CRM_Utils_Array::value('membership_id', $params) && self::checkContributeSettings('deferred_revenue_enabled')) { $memberStartDate = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $params['membership_id'], 'start_date'); if ($memberStartDate) { $params['revenue_recognition_date'] = date('Ymd', strtotime($memberStartDate)); } } self::calculateMissingAmountParams($params, $contributionID); if (!empty($params['payment_instrument_id'])) { $paymentInstruments = CRM_Contribute_PseudoConstant::paymentInstrument('name'); if ($params['payment_instrument_id'] != array_search('Check', $paymentInstruments)) { $params['check_number'] = 'null'; } } $setPrevContribution = TRUE; // CRM-13964 partial payment if (!empty($params['partial_payment_total']) && !empty($params['partial_amount_pay'])) { $partialAmtTotal = $params['partial_payment_total']; $partialAmtPay = $params['partial_amount_pay']; $params['total_amount'] = $partialAmtTotal; if ($partialAmtPay < $partialAmtTotal) { $params['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', 'Partially paid', 'name'); $params['is_pay_later'] = 0; $setPrevContribution = FALSE; } } if ($contributionID && $setPrevContribution) { $params['prevContribution'] = self::getOriginalContribution($contributionID); } // CRM-16189 CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params, $contributionID); if ($contributionID && !empty($params['revenue_recognition_date']) && !empty($params['prevContribution']) && !($contributionStatus[$params['prevContribution']->contribution_status_id] == 'Pending') && !self::allowUpdateRevenueRecognitionDate($contributionID)) { unset($params['revenue_recognition_date']); } if (!isset($params['tax_amount']) && $setPrevContribution && (isset($params['total_amount']) || isset($params['financial_type_id']))) { $params = CRM_Contribute_BAO_Contribution::checkTaxAmount($params); } if ($contributionID) { CRM_Utils_Hook::pre('edit', 'Contribution', $contributionID, $params); } else { CRM_Utils_Hook::pre('create', 'Contribution', NULL, $params); } $contribution = new CRM_Contribute_BAO_Contribution(); $contribution->copyValues($params); $contribution->id = $contributionID; if (empty($contribution->id)) { // (only) on 'create', make sure that a valid currency is set (CRM-16845) if (!CRM_Utils_Rule::currencyCode($contribution->currency)) { $contribution->currency = CRM_Core_Config::singleton()->defaultCurrency; } } $result = $contribution->save(); // Add financial_trxn details as part of fix for CRM-4724 $contribution->trxn_result_code = CRM_Utils_Array::value('trxn_result_code', $params); $contribution->payment_processor = CRM_Utils_Array::value('payment_processor', $params); //add Account details $params['contribution'] = $contribution; self::recordFinancialAccounts($params); if (self::isUpdateToRecurringContribution($params)) { CRM_Contribute_BAO_ContributionRecur::updateOnNewPayment(!empty($params['contribution_recur_id']) ? $params['contribution_recur_id'] : $params['prevContribution']->contribution_recur_id, $contributionStatus[$params['contribution_status_id']]); } CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush(); if ($contributionID) { CRM_Utils_Hook::post('edit', 'Contribution', $contribution->id, $contribution); } else { CRM_Utils_Hook::post('create', 'Contribution', $contribution->id, $contribution); } return $result; }