Fix bug in SQL queue that can cause tasks to be run twice in a multiprocess environment
protected $_settings = [
'max_attachments' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
+ 'max_attachments_backend' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'contact_undelete' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'empoweredBy' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'logging' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
$this->assign('pure_config_settings', [
'empoweredBy',
'max_attachments',
+ 'max_attachments_backend',
'maxFileSize',
'secondDegRelPermissions',
'recentItemsMaxCount',
//temp hack @todo fix to get from metadata
$this->addRule('max_attachments', ts('Value should be a positive number'), 'positiveInteger');
}
+ if ($setting == 'max_attachments_backend') {
+ //temp hack @todo fix to get from metadata
+ $this->addRule('max_attachments_backend', ts('Value should be a positive number'), 'positiveInteger');
+ }
if ($setting == 'maxFileSize') {
//temp hack
$this->addRule('maxFileSize', ts('Value should be a positive number'), 'positiveInteger');
$group->name = substr($group->name, 0, -4) . "_{$group->id}";
}
- $group->buildClause();
$group->save();
// add custom field values
return $group;
}
- /**
- * Given a saved search compute the clause and the tables
- * and store it for future use
- */
- public function buildClause() {
- $params = [['group', 'IN', [$this->id], 0, 0]];
-
- if (!empty($params)) {
- $tables = $whereTables = [];
- $this->where_clause = CRM_Contact_BAO_Query::getWhereClause($params, NULL, $tables, $whereTables);
- if (!empty($tables)) {
- $this->select_tables = serialize($tables);
- }
- if (!empty($whereTables)) {
- $this->where_tables = serialize($whereTables);
- }
- }
- }
-
/**
* Defines a new smart group.
*
if (!empty($pseudoConstantMetadata['optionGroupName'])
|| $this->isPseudoFieldAnFK($fieldSpec)
) {
+ // dev/core#1305 @todo this is not the right thing to do but for now avoid fatal error
+ if (empty($fieldSpec['bao'])) {
+ continue;
+ }
$sortedOptions = $fieldSpec['bao']::buildOptions($fieldSpec['name'], NULL, [
'orderColumn' => CRM_Utils_Array::value('labelColumn', $pseudoConstantMetadata, 'label'),
]);
}
}
- /**
- * Given a saved search compute the clause and the tables and store it for future use.
- */
- public function buildClause() {
- $fv = unserialize($this->form_values);
-
- if ($this->mapping_id) {
- $params = CRM_Core_BAO_Mapping::formattedFields($fv);
- }
- else {
- $params = CRM_Contact_BAO_Query::convertFormValues($fv);
- }
-
- if (!empty($params)) {
- $tables = $whereTables = [];
- $this->where_clause = CRM_Contact_BAO_Query::getWhereClause($params, NULL, $tables, $whereTables);
- if (!empty($tables)) {
- $this->select_tables = serialize($tables);
- }
- if (!empty($whereTables)) {
- $this->where_tables = serialize($whereTables);
- }
- }
- }
-
- /**
- * Save the search.
- *
- * @param bool $hook
- */
- public function save($hook = TRUE) {
- // first build the computed fields
- $this->buildClause();
-
- parent::save($hook);
- }
-
/**
* Given an id, get the name of the saved search.
*
* False, if we want to skip the address sharing features.
* @param bool $inlineEdit
* True when edit used in inline edit.
+ *
+ * @throws \CiviCRM_API3_Exception
*/
public static function buildQuickForm(&$form, $addressBlockCount = NULL, $sharing = TRUE, $inlineEdit = FALSE) {
// passing this via the session is AWFUL. we need to fix this
continue;
}
}
- if ($name == 'address_name') {
+ if ($name === 'address_name') {
$name = 'name';
}
$params = ['entity' => 'address'];
- if ($name == 'postal_code_suffix') {
+ if ($name === 'postal_code_suffix') {
$params['label'] = ts('Suffix');
}
$requireOmission = NULL;
foreach ($groupTree as $csId => $csVal) {
// only process Address entity fields
- if ($csVal['extends'] != 'Address') {
+ if ($csVal['extends'] !== 'Address') {
continue;
}
foreach ($csVal['fields'] as $cdId => $cdVal) {
- if ($cdVal['is_required']) {
+ if (!empty($cdVal['is_required'])) {
$elementName = $cdVal['element_name'];
if (in_array($elementName, $form->_required)) {
// store the omitted rule for a element, to be used later on
* @param CRM_Core_Form $form
* @param int $entityId
* @param int $blockId
+ *
+ * @throws \CRM_Core_Exception
+ * @throws \CiviCRM_API3_Exception
*/
protected static function addCustomDataToForm(&$form, $entityId, $blockId) {
$groupTree = CRM_Core_BAO_CustomGroup::getTree('Address', NULL, $entityId);
continue;
}
- // inorder to set correct defaults for checkbox custom data, we need to converted flat key to array
+ // in order to set correct defaults for checkbox custom data, we need to converted flat key to array
// this works for all types custom data
$keyValues = explode('[', str_replace(']', '', $key));
$addressDefaults[$keyValues[0]][$keyValues[1]][$keyValues[2]] = $val;
}
$tee = NULL;
- if ($isLiveMode && Civi::settings()->get('recordGeneratedLetters') === 'combined-attached') {
+ if (self::isLiveMode($form) && Civi::settings()->get('recordGeneratedLetters') === 'combined-attached') {
if (count($activityIds) !== 1) {
throw new CRM_Core_Exception("When recordGeneratedLetters=combined-attached, there should only be one activity.");
}
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") {
+ if (empty($params['creditnote_id'])) {
$params['creditnote_id'] = self::createCreditNoteId();
}
}
* functions.
*
* @param array $params
- * @param string $context
- * @param array $previousContributionStatus
- * @param string $currentContributionStatus
*
* @return bool[]
* Return indicates whether the updateFinancialAccounts function should continue & whether this is a refund.
*/
- private static function updateFinancialAccountsOnContributionStatusChange(&$params, $context, $previousContributionStatus, $currentContributionStatus) {
+ private static function updateFinancialAccountsOnContributionStatusChange(&$params) {
+ $previousContributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($params['prevContribution']->contribution_status_id, 'name');
+ $currentContributionStatus = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $params['contribution']->contribution_status_id);
+
$isARefund = FALSE;
if ((($previousContributionStatus == 'Partially paid' && $currentContributionStatus == 'Completed')
|| ($previousContributionStatus == 'Pending refund' && $currentContributionStatus == 'Completed')
) {
return [FALSE, $isARefund];
}
- if ($context == 'changedStatus') {
- if ($previousContributionStatus == 'Completed'
- && (self::isContributionStatusNegative($params['contribution']->contribution_status_id))
- ) {
- $isARefund = TRUE;
+
+ if ($previousContributionStatus == 'Completed'
+ && (self::isContributionStatusNegative($params['contribution']->contribution_status_id))
+ ) {
+ $isARefund = TRUE;
+ // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
+ $params['trxnParams']['total_amount'] = -$params['total_amount'];
+ if (empty($params['contribution']->creditnote_id)) {
+ $creditNoteId = self::createCreditNoteId();
+ CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $params['contribution']->id, 'creditnote_id', $creditNoteId);
+ }
+ }
+ elseif (($previousContributionStatus == 'Pending'
+ && $params['prevContribution']->is_pay_later) || $previousContributionStatus == 'In Progress'
+ ) {
+ $financialTypeID = CRM_Utils_Array::value('financial_type_id', $params) ? $params['financial_type_id'] : $params['prevContribution']->financial_type_id;
+ $arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($financialTypeID, 'Accounts Receivable Account is');
+
+ if ($currentContributionStatus == 'Cancelled') {
// @todo we should stop passing $params by reference - splitting this out would be a step towards that.
+ $params['trxnParams']['to_financial_account_id'] = $arAccountId;
$params['trxnParams']['total_amount'] = -$params['total_amount'];
- if (empty($params['contribution']->creditnote_id) || $params['contribution']->creditnote_id == "null") {
+ if (empty($params['contribution']->creditnote_id)) {
$creditNoteId = self::createCreditNoteId();
CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $params['contribution']->id, 'creditnote_id', $creditNoteId);
}
}
- elseif (($previousContributionStatus == 'Pending'
- && $params['prevContribution']->is_pay_later) || $previousContributionStatus == 'In Progress'
- ) {
- $financialTypeID = CRM_Utils_Array::value('financial_type_id', $params) ? $params['financial_type_id'] : $params['prevContribution']->financial_type_id;
- $arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($financialTypeID, 'Accounts Receivable Account is');
-
- if ($currentContributionStatus == 'Cancelled') {
- // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
- $params['trxnParams']['to_financial_account_id'] = $arAccountId;
- $params['trxnParams']['total_amount'] = -$params['total_amount'];
- if (is_null($params['contribution']->creditnote_id) || $params['contribution']->creditnote_id == "null") {
- $creditNoteId = self::createCreditNoteId();
- CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $params['contribution']->id, 'creditnote_id', $creditNoteId);
- }
- }
- else {
- // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
- $params['trxnParams']['from_financial_account_id'] = $arAccountId;
- }
+ else {
+ // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
+ $params['trxnParams']['from_financial_account_id'] = $arAccountId;
}
+ }
- if (($previousContributionStatus == 'Pending'
- || $previousContributionStatus == 'In Progress')
- && ($currentContributionStatus == 'Completed')
- ) {
- if (empty($params['line_item'])) {
- //CRM-15296
- //@todo - check with Joe regarding this situation - payment processors create pending transactions with no line items
- // when creating recurring membership payment - there are 2 lines to comment out in contributonPageTest if fixed
- // & this can be removed
- return [FALSE, $isARefund];
- }
- // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
- // This is an update so original currency if none passed in.
- $params['trxnParams']['currency'] = CRM_Utils_Array::value('currency', $params, $params['prevContribution']->currency);
+ if (($previousContributionStatus == 'Pending'
+ || $previousContributionStatus == 'In Progress')
+ && ($currentContributionStatus == 'Completed')
+ ) {
+ if (empty($params['line_item'])) {
+ //CRM-15296
+ //@todo - check with Joe regarding this situation - payment processors create pending transactions with no line items
+ // when creating recurring membership payment - there are 2 lines to comment out in contributonPageTest if fixed
+ // & this can be removed
+ return [FALSE, $isARefund];
+ }
+ // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
+ // This is an update so original currency if none passed in.
+ $params['trxnParams']['currency'] = CRM_Utils_Array::value('currency', $params, $params['prevContribution']->currency);
- self::recordAlwaysAccountsReceivable($params['trxnParams'], $params);
- $trxn = CRM_Core_BAO_FinancialTrxn::create($params['trxnParams']);
- // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
- $params['entity_id'] = self::$_trxnIDs[] = $trxn->id;
- $query = "UPDATE civicrm_financial_item SET status_id = %1 WHERE entity_id = %2 and entity_table = 'civicrm_line_item'";
- $sql = "SELECT id, amount FROM civicrm_financial_item WHERE entity_id = %1 and entity_table = 'civicrm_line_item'";
+ self::recordAlwaysAccountsReceivable($params['trxnParams'], $params);
+ $trxn = CRM_Core_BAO_FinancialTrxn::create($params['trxnParams']);
+ // @todo we should stop passing $params by reference - splitting this out would be a step towards that.
+ $params['entity_id'] = self::$_trxnIDs[] = $trxn->id;
+ $query = "UPDATE civicrm_financial_item SET status_id = %1 WHERE entity_id = %2 and entity_table = 'civicrm_line_item'";
+ $sql = "SELECT id, amount FROM civicrm_financial_item WHERE entity_id = %1 and entity_table = 'civicrm_line_item'";
- $entityParams = [
- 'entity_table' => 'civicrm_financial_item',
- ];
- foreach ($params['line_item'] as $fieldId => $fields) {
- foreach ($fields as $fieldValueId => $lineItemDetails) {
- $fparams = [
- 1 => [
- CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialItem', 'status_id', 'Paid'),
- 'Integer',
- ],
- 2 => [$lineItemDetails['id'], 'Integer'],
- ];
- CRM_Core_DAO::executeQuery($query, $fparams);
- $fparams = [
- 1 => [$lineItemDetails['id'], 'Integer'],
- ];
- $financialItem = CRM_Core_DAO::executeQuery($sql, $fparams);
- while ($financialItem->fetch()) {
- $entityParams['entity_id'] = $financialItem->id;
- $entityParams['amount'] = $financialItem->amount;
- foreach (self::$_trxnIDs as $tID) {
- $entityParams['financial_trxn_id'] = $tID;
- CRM_Financial_BAO_FinancialItem::createEntityTrxn($entityParams);
- }
+ $entityParams = [
+ 'entity_table' => 'civicrm_financial_item',
+ ];
+ foreach ($params['line_item'] as $fieldId => $fields) {
+ foreach ($fields as $fieldValueId => $lineItemDetails) {
+ $fparams = [
+ 1 => [
+ CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialItem', 'status_id', 'Paid'),
+ 'Integer',
+ ],
+ 2 => [$lineItemDetails['id'], 'Integer'],
+ ];
+ CRM_Core_DAO::executeQuery($query, $fparams);
+ $fparams = [
+ 1 => [$lineItemDetails['id'], 'Integer'],
+ ];
+ $financialItem = CRM_Core_DAO::executeQuery($sql, $fparams);
+ while ($financialItem->fetch()) {
+ $entityParams['entity_id'] = $financialItem->id;
+ $entityParams['amount'] = $financialItem->amount;
+ foreach (self::$_trxnIDs as $tID) {
+ $entityParams['financial_trxn_id'] = $tID;
+ CRM_Financial_BAO_FinancialItem::createEntityTrxn($entityParams);
}
}
}
- return [FALSE, $isARefund];
}
+ return [FALSE, $isARefund];
}
return [TRUE, $isARefund];
}
$trxnID = NULL;
$inputParams = $params;
$isARefund = FALSE;
- $currentContributionStatus = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $params['contribution']->contribution_status_id);
- $previousContributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($params['prevContribution']->contribution_status_id, 'name');
if ($context == 'changedStatus') {
- list($continue, $isARefund) = self::updateFinancialAccountsOnContributionStatusChange($params, $context, $previousContributionStatus, $currentContributionStatus);
+ list($continue, $isARefund) = self::updateFinancialAccountsOnContributionStatusChange($params);
// @todo - it may be that this is always false & the parent function is just a confusing wrapper for the child fn.
if (!$continue) {
return;
$params['line_item'][$fieldId][$fieldValueId]['financial_item_id'] = $financialItem->id;
if (($lineItemDetails['tax_amount'] && $lineItemDetails['tax_amount'] !== 'null') || ($context == 'changeFinancialType')) {
- $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
- $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
$taxAmount = (float) $lineItemDetails['tax_amount'];
if ($context == 'changeFinancialType' && $lineItemDetails['tax_amount'] === 'null') {
// reverse the Sale Tax amount if there is no tax rate associated with new Financial Type
}
if ($taxAmount != 0) {
$itemParams['amount'] = self::getMultiplier($params['contribution']->contribution_status_id, $context) * $taxAmount;
- $itemParams['description'] = $taxTerm;
+ $itemParams['description'] = CRM_Invoicing_Utils::getTaxTerm();
if ($lineItemDetails['financial_type_id']) {
- $itemParams['financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount(
- $lineItemDetails['financial_type_id'],
- 'Sales Tax Account is'
- );
+ $itemParams['financial_account_id'] = CRM_Financial_BAO_FinancialAccount::getSalesTaxFinancialAccount($lineItemDetails['financial_type_id']);
}
CRM_Financial_BAO_FinancialItem::create($itemParams, NULL, $trxnIds);
}
* @throws \CiviCRM_API3_Exception
*/
public static function getTemplateContribution($id, $overrides = []) {
- $templateContribution = civicrm_api3('Contribution', 'get', [
- 'contribution_recur_id' => $id,
- 'options' => ['limit' => 1, 'sort' => ['id DESC']],
- 'sequential' => 1,
- 'contribution_test' => '',
+ // use api3 because api4 doesn't handle ContributionRecur yet...
+ $is_test = civicrm_api3('ContributionRecur', 'getvalue', [
+ 'return' => "is_test",
+ 'id' => $id,
]);
- if ($templateContribution['count']) {
- $result = array_merge($templateContribution['values'][0], $overrides);
+ // First look for new-style template contribution with is_template=1
+ $templateContributions = \Civi\Api4\Contribution::get()
+ ->addWhere('contribution_recur_id', '=', $id)
+ ->addWhere('is_template', '=', 1)
+ ->addWhere('is_test', '=', $is_test)
+ ->addOrderBy('id', 'DESC')
+ ->setLimit(1)
+ ->execute();
+ if (!$templateContributions->count()) {
+ // Fall back to old style template contributions
+ $templateContributions = \Civi\Api4\Contribution::get()
+ ->addWhere('contribution_recur_id', '=', $id)
+ ->addWhere('is_test', '=', $is_test)
+ ->addOrderBy('id', 'DESC')
+ ->setLimit(1)
+ ->execute();
+ }
+ if ($templateContributions->count()) {
+ $templateContribution = $templateContributions->first();
+ $result = array_merge($templateContribution, $overrides);
$result['line_item'] = CRM_Contribute_BAO_ContributionRecur::calculateRecurLineItems($id, $result['total_amount'], $result['financial_type_id']);
return $result;
}
*
* Generated from xml/schema/CRM/Contribute/Contribution.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:b4e84298d9ba23d3b2fae0768fc5cb58)
+ * (GenCodeChecksum:a9f83aa612e82ee87ace74e75fe23466)
*/
/**
*/
public $revenue_recognition_date;
+ /**
+ * Shows this is a template for recurring contributions.
+ *
+ * @var bool
+ */
+ public $is_template;
+
/**
* Class constructor.
*/
'formatType' => 'activityDateTime',
],
],
+ 'is_template' => [
+ 'name' => 'is_template',
+ 'type' => CRM_Utils_Type::T_BOOLEAN,
+ 'title' => ts('Is a Template Contribution'),
+ 'description' => ts('Shows this is a template for recurring contributions.'),
+ 'import' => TRUE,
+ 'where' => 'civicrm_contribution.is_template',
+ 'export' => TRUE,
+ 'default' => '0',
+ 'table_name' => 'civicrm_contribution',
+ 'entity' => 'Contribution',
+ 'bao' => 'CRM_Contribute_BAO_Contribution',
+ 'localizable' => 0,
+ 'html' => [
+ 'type' => 'CheckBox',
+ ],
+ ],
];
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
*
* Generated from xml/schema/CRM/Contribute/ContributionPage.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:70763e4804af1e4e3ddbac7b60cbd242)
+ * (GenCodeChecksum:35e26556fcbed13acc434279f2ebaee5)
*/
/**
*/
public $is_billing_required;
+ /**
+ * Contribution Page Public title
+ *
+ * @var string
+ */
+ public $frontend_title;
+
/**
* Class constructor.
*/
'bao' => 'CRM_Contribute_BAO_ContributionPage',
'localizable' => 0,
],
+ 'contribution_page_frontend_title' => [
+ 'name' => 'frontend_title',
+ 'type' => CRM_Utils_Type::T_STRING,
+ 'title' => ts('Public Title'),
+ 'description' => ts('Contribution Page Public title'),
+ 'maxlength' => 255,
+ 'size' => CRM_Utils_Type::HUGE,
+ 'where' => 'civicrm_contribution_page.frontend_title',
+ 'default' => 'NULL',
+ 'table_name' => 'civicrm_contribution_page',
+ 'entity' => 'ContributionPage',
+ 'bao' => 'CRM_Contribute_BAO_ContributionPage',
+ 'localizable' => 1,
+ 'html' => [
+ 'type' => 'Text',
+ ],
+ ],
];
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
$this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params);
}
$this->assign('credit_card_exp_date', CRM_Utils_Date::mysqlToIso(CRM_Utils_Date::format($this->_params['credit_card_exp_date'])));
- $this->assign('credit_card_number',
- CRM_Utils_System::mungeCreditCard($this->_params['credit_card_number'])
- );
+ $this->assign('credit_card_number', CRM_Utils_System::mungeCreditCard($this->_params['credit_card_number']));
$this->assign('credit_card_type', CRM_Utils_Array::value('credit_card_type', $this->_params));
}
$this->_params['ip_address'] = CRM_Utils_System::ipAddress();
$this->_fromEmails['from_email_id'] = CRM_Core_BAO_Email::getFromEmail();
}
- $paymentInfo = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($this->_id, $entityType);
$paymentDetails = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_id, $this->_component, FALSE, TRUE);
+ $paymentAmt = CRM_Contribute_BAO_Contribution::getContributionBalance($this->_id);
$this->_amtPaid = $paymentDetails['paid'];
$this->_amtTotal = $paymentDetails['total'];
- if (!empty($paymentInfo['refund_due'])) {
- $paymentAmt = $this->_refund = $paymentInfo['refund_due'];
+ if ($paymentAmt < 0) {
+ $this->_refund = $paymentAmt;
$this->_paymentType = 'refund';
}
- elseif (!empty($paymentInfo['amount_owed'])) {
- $paymentAmt = $this->_owed = $paymentInfo['amount_owed'];
+ elseif ($paymentAmt > 0) {
+ $this->_owed = $paymentAmt;
$this->_paymentType = 'owed';
}
else {
if (!empty($params['contribution_id'])) {
$this->_contributionId = $params['contribution_id'];
- $paymentInfo = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($this->_contributionId, $entityType);
$paymentDetails = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_contributionId, $entityType, FALSE, TRUE);
+ $paymentAmount = CRM_Contribute_BAO_Contribution::getContributionBalance($this->_contributionId);
$this->_amtPaid = $paymentDetails['paid'];
$this->_amtTotal = $paymentDetails['total'];
- if (!empty($paymentInfo['refund_due'])) {
- $this->_refund = $paymentInfo['refund_due'];
+ if ($paymentAmount < 0) {
+ $this->_refund = $paymentAmount;
$this->_paymentType = 'refund';
}
- elseif (!empty($paymentInfo['amount_owed'])) {
- $this->_owed = $paymentInfo['amount_owed'];
+ elseif ($paymentAmount > 0) {
+ $this->_owed = $paymentAmount;
$this->_paymentType = 'owed';
}
}
if (!empty($form->_params['membership_source'])) {
$membershipSource = $form->_params['membership_source'];
}
- elseif (isset($form->_values['title']) && !empty($form->_values['title'])) {
- $membershipSource = ts('Online Contribution:') . ' ' . $form->_values['title'];
+ elseif ((isset($form->_values['title']) && !empty($form->_values['title'])) || (isset($form->_values['frontend_title']) && !empty($form->_values['frontend_title']))) {
+ $title = !empty($form->_values['frontend_title']) ? $form->_values['frontend_title'] : $form->_values['title'];
+ $membershipSource = ts('Online Contribution:') . ' ' . $title;
}
$isPayLater = NULL;
if (isset($form->_params)) {
}
}
// add a description field at the very beginning
- $this->_params['description'] = ts('Online Contribution') . ': ' . (($this->_pcpInfo['title']) ? $this->_pcpInfo['title'] : $this->_values['title']);
+ $title = !empty($this->_values['frontend_title']) ? $this->_values['frontend_title'] : $this->_values['title'];
+ $this->_params['description'] = ts('Online Contribution') . ': ' . (!empty($this->_pcpInfo['title']) ? $this->_pcpInfo['title'] : $title);
$this->_params['accountingCode'] = CRM_Utils_Array::value('accountingCode', $this->_values);
$invoiceID = md5(uniqid(rand(), TRUE));
$this->set('invoiceID', $invoiceID);
$params['invoiceID'] = $invoiceID;
- $params['description'] = ts('Online Contribution') . ': ' . ((!empty($this->_pcpInfo['title']) ? $this->_pcpInfo['title'] : $this->_values['title']));
+ $title = !empty($this->_values['frontend_title']) ? $this->_values['frontend_title'] : $this->_values['title'];
+ $params['description'] = ts('Online Contribution') . ': ' . ((!empty($this->_pcpInfo['title']) ? $this->_pcpInfo['title'] : $title));
$params['button'] = $this->controller->getButtonName();
// required only if is_monetary and valid positive amount
// @todo it seems impossible for $memFee to be greater than 0 & $params['amount'] not to
// we do not want to display recently viewed items, so turn off
$this->assign('displayRecent', FALSE);
- // Contribution page values are cleared from session, so can't use normal Printer Friendly view.
- // Use Browser Print instead.
- $this->assign('browserPrint', TRUE);
// action
$this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'add');
CRM_Utils_Array::value('cancelSubscriptionUrl', $this->_values)
);
- $this->setTitle(($this->_pcpId ? $this->_pcpInfo['title'] : $this->_values['title']));
+ $title = !empty($this->_values['frontend_title']) ? $this->_values['frontend_title'] : $this->_values['title'];
+
+ $this->setTitle(($this->_pcpId ? $this->_pcpInfo['title'] : $title));
$this->_defaults = [];
$this->_amount = $this->get('amount');
$monthlyChart = TRUE;
}
- $values['divName'] = "open_flash_chart_{$chartKey}";
+ $values['divName'] = "chart_{$chartKey}";
$funName = ($chartType == 'bvg') ? 'barChart' : 'pieChart';
// build the chart objects.
- $values['object'] = CRM_Utils_OpenFlashChart::$funName($values);
+ $values['object'] = CRM_Utils_Chart::$funName($values);
//build the urls.
$urlCnt = 0;
// finally assign this chart data to template.
$this->assign('hasYearlyChart', $yearlyChart);
$this->assign('hasByMonthChart', $monthlyChart);
- $this->assign('hasOpenFlashChart', empty($chartData) ? FALSE : TRUE);
- $this->assign('openFlashChartData', json_encode($chartData));
+ $this->assign('hasChart', empty($chartData) ? FALSE : TRUE);
+ $this->assign('chartData', json_encode($chartData ?? []));
}
}
// name
$this->add('text', 'title', ts('Title'), $attributes['title'], TRUE);
+ $this->addField('contribution_page_frontend_title', ['entity' => 'ContributionPage']);
//CRM-7362 --add campaigns.
CRM_Campaign_BAO_Campaign::addCampaign($this, CRM_Utils_Array::value('campaign_id', $this->_values));
}
if ($this->_force) {
- // Search field metadata is normally added in buildForm but we are bypassing that in this flow
- // (I've always found the flow kinda confusing & perhaps that is the problem but this mitigates)
- $this->addSearchFieldMetadata(['Contribution' => CRM_Contribute_BAO_Query::getSearchFieldMetadata()]);
- $this->addSearchFieldMetadata(['ContributionRecur' => CRM_Contribute_BAO_ContributionRecur::getContributionRecurSearchFieldMetadata()]);
- $this->postProcess();
- $this->set('force', 0);
+ $this->handleForcedSearch();
}
$sortID = NULL;
return ts('Find Contributions');
}
+ /**
+ * Set the metadata for the form.
+ *
+ * @throws \CiviCRM_API3_Exception
+ */
+ protected function setSearchMetadata() {
+ $this->addSearchFieldMetadata(['Contribution' => CRM_Contribute_BAO_Query::getSearchFieldMetadata()]);
+ $this->addSearchFieldMetadata(['ContributionRecur' => CRM_Contribute_BAO_ContributionRecur::getContributionRecurSearchFieldMetadata()]);
+ }
+
}
}
}
- // Disable inactive widgets
- $dashletClause = $dashletIDs ? "dashboard_id NOT IN (" . implode(',', $dashletIDs) . ")" : '(1)';
+ // Find dashlets in this domain.
+ $domainDashlets = civicrm_api3('Dashboard', 'get', [
+ 'return' => array('id'),
+ 'domain_id' => CRM_Core_Config::domainID(),
+ 'options' => ['limit' => 0],
+ ]);
+
+ // Get the array of IDs.
+ $domainDashletIDs = [];
+ if ($domainDashlets['is_error'] == 0) {
+ $domainDashletIDs = CRM_Utils_Array::collect('id', $domainDashlets['values']);
+ }
+
+ // Restrict query to Dashlets in this domain.
+ $domainDashletClause = !empty($domainDashletIDs) ? "dashboard_id IN (" . implode(',', $domainDashletIDs) . ")" : '(1)';
+
+ // Target only those Dashlets which are inactive.
+ $dashletClause = $dashletIDs ? "dashboard_id NOT IN (" . implode(',', $dashletIDs) . ")" : '(1)';
+
+ // Build params.
+ $params = [
+ 1 => [$contactID, 'Integer'],
+ ];
+
+ // Build query.
$updateQuery = "UPDATE civicrm_dashboard_contact
SET is_active = 0
- WHERE $dashletClause AND contact_id = {$contactID}";
+ WHERE $domainDashletClause
+ AND $dashletClause
+ AND contact_id = %1";
- CRM_Core_DAO::executeQuery($updateQuery);
+ // Disable inactive widgets.
+ CRM_Core_DAO::executeQuery($updateQuery, $params);
}
/**
public static $_signableFields = ['entityTable', 'entityID', 'fileID'];
+ /**
+ * If there is no setting configured on the admin screens, maximum number
+ * of attachments to try to process when given a list of attachments to
+ * process.
+ */
+ const DEFAULT_MAX_ATTACHMENTS_BACKEND = 100;
+
/**
* Takes an associative array and creates a File object.
*
* @param int $entityID
*/
public static function processAttachment(&$params, $entityTable, $entityID) {
- $numAttachments = Civi::settings()->get('max_attachments');
+ $numAttachments = Civi::settings()->get('max_attachments_backend') ?? self::DEFAULT_MAX_ATTACHMENTS_BACKEND;
for ($i = 1; $i <= $numAttachments; $i++) {
- if (
- isset($params["attachFile_$i"]) &&
- is_array($params["attachFile_$i"])
- ) {
- self::filePostProcess(
- $params["attachFile_$i"]['location'],
- NULL,
- $entityTable,
- $entityID,
- NULL,
- TRUE,
- $params["attachFile_$i"],
- "attachFile_$i",
- $params["attachFile_$i"]['type']
- );
+ if (isset($params["attachFile_$i"])) {
+ /**
+ * Moved the second condition into its own if block to avoid changing
+ * how it works if there happens to be an entry that is not an array,
+ * since we now might exit loop early via newly added break below.
+ */
+ if (is_array($params["attachFile_$i"])) {
+ self::filePostProcess(
+ $params["attachFile_$i"]['location'],
+ NULL,
+ $entityTable,
+ $entityID,
+ NULL,
+ TRUE,
+ $params["attachFile_$i"],
+ "attachFile_$i",
+ $params["attachFile_$i"]['type']
+ );
+ }
+ }
+ else {
+ /**
+ * No point looping 100 times if there aren't any more.
+ * This assumes the array is continuous and doesn't skip array keys,
+ * but (a) where would it be doing that, and (b) it would have caused
+ * problems before anyway if there were skipped keys.
+ */
+ break;
}
}
}
* @return array
*/
public static function getPartialPaymentWithType($entityId, $entityName = 'participant', $lineItemTotal = NULL) {
+ CRM_Core_Error::deprecatedFunctionWarning('CRM_Contribute_BAO_Contribution::getContributionBalance');
$value = NULL;
if (empty($entityName)) {
return $value;
'maxFileSize' => ['setting'],
// renamed.
'maxAttachments' => ['setting', 'max_attachments'],
+ 'maxAttachmentsBackend' => ['setting', 'max_attachments_backend'],
'monetaryDecimalPoint' => ['setting'],
'monetaryThousandSeparator' => ['setting'],
'moneyformat' => ['setting'],
$params = array_merge($params, $addressParams);
}
- // @fixme it would be really nice to have a comment here so I had a clue why we are setting $fields[$name] = 1
- // Also how does relate to similar code in CRM_Contact_BAO_Contact::addBillingNameFieldsIfOtherwiseNotSet()
+ // How does this relate to similar code in CRM_Contact_BAO_Contact::addBillingNameFieldsIfOtherwiseNotSet()?
$nameFields = ['first_name', 'middle_name', 'last_name'];
foreach ($nameFields as $name) {
if (array_key_exists("billing_$name", $params)) {
$params['preserveDBName'] = TRUE;
}
}
+
+ // For legacy reasons we set these creditcard expiry fields if present
+ if (isset($params['credit_card_exp_date'])) {
+ $params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($params);
+ $params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($params);
+ }
+
+ // Assign IP address parameter
+ $params['ip_address'] = CRM_Utils_System::ipAddress();
+
return $params;
}
return (array) $this->get('formValues');
}
+ /**
+ * Set the metadata for the form.
+ *
+ * @throws \CiviCRM_API3_Exception
+ */
+ protected function setSearchMetadata() {}
+
+ /**
+ * Handle force=1 in the url.
+ *
+ * Search field metadata is normally added in buildForm but we are bypassing that in this flow
+ * (I've always found the flow kinda confusing & perhaps that is the problem but this mitigates)
+ *
+ * @throws \CiviCRM_API3_Exception
+ */
+ protected function handleForcedSearch() {
+ $this->setSearchMetadata();
+ $this->postProcess();
+ $this->set('force', 0);
+ }
+
}
* The params of the translation (if any).
* - domain: string|array a list of translation domains to search (in order)
* - context: string
+ * - skip_translation: flag (do only escape/replacement, skip the actual translation)
*
* @return string
* the translated string
$raw = !empty($params['raw']);
unset($params['raw']);
- if (!empty($domain)) {
- // It might be prettier to cast to an array, but this is high-traffic stuff.
- if (is_array($domain)) {
- foreach ($domain as $d) {
- $candidate = $this->crm_translate_raw($text, $d, $count, $plural, $context);
- if ($candidate != $text) {
- $text = $candidate;
- break;
+ if (!isset($params['skip_translation'])) {
+ if (!empty($domain)) {
+ // It might be prettier to cast to an array, but this is high-traffic stuff.
+ if (is_array($domain)) {
+ foreach ($domain as $d) {
+ $candidate = $this->crm_translate_raw($text, $d, $count, $plural, $context);
+ if ($candidate != $text) {
+ $text = $candidate;
+ break;
+ }
}
}
+ else {
+ $text = $this->crm_translate_raw($text, $domain, $count, $plural, $context);
+ }
}
else {
- $text = $this->crm_translate_raw($text, $domain, $count, $plural, $context);
+ $text = $this->crm_translate_raw($text, NULL, $count, $plural, $context);
}
}
- else {
- $text = $this->crm_translate_raw($text, NULL, $count, $plural, $context);
- }
// replace the numbered %1, %2, etc. params if present
if (count($params) && !$raw) {
* the translated string
*/
function ts($text, $params = []) {
- static $areSettingsAvailable = FALSE;
+ static $bootstrapReady = FALSE;
static $lastLocale = NULL;
static $i18n = NULL;
static $function = NULL;
}
// When the settings become available, lookup customTranslateFunction.
- if (!$areSettingsAvailable) {
- $areSettingsAvailable = (bool) \Civi\Core\Container::getBootService('settings_manager');
- if ($areSettingsAvailable) {
+ if (!$bootstrapReady) {
+ $bootstrapReady = (bool) \Civi\Core\Container::isContainerBooted();
+ if ($bootstrapReady) {
+ // just got ready: determine whether there is a working custom translation function
$config = CRM_Core_Config::singleton();
if (isset($config->customTranslateFunction) and function_exists($config->customTranslateFunction)) {
$function = $config->customTranslateFunction;
}
}
+ else {
+ // don't _translate_ anything until bootstrap has progressed enough
+ $params['skip_translation'] = 1;
+ }
}
$activeLocale = CRM_Core_I18n::getLocale();
'receipt_from_name' => "varchar(255) COMMENT 'FROM email name used for receipts generated by contributions to this contribution page.'",
'receipt_text' => "text COMMENT 'text to include above standard receipt info on receipt email. emails are text-only, so do not allow html for now'",
'footer_text' => "text COMMENT 'Text and html allowed. Displayed at the bottom of the first page of the contribution wizard.'",
+ 'frontend_title' => "varchar(255) DEFAULT NULL COMMENT 'Contribution Page Public title'",
],
'civicrm_product' => [
'name' => "varchar(255) NOT NULL COMMENT 'Required product/premium name'",
'rows' => "6",
'cols' => "50",
],
+ 'frontend_title' => [
+ 'type' => "Text",
+ ],
],
'civicrm_product' => [
'name' => [
--- /dev/null
+<?php
+/*
++--------------------------------------------------------------------+
+| CiviCRM version 5 |
++--------------------------------------------------------------------+
+| Copyright CiviCRM LLC (c) 2004-2019 |
++--------------------------------------------------------------------+
+| This file is a part of CiviCRM. |
+| |
+| CiviCRM is free software; you can copy, modify, and distribute it |
+| under the terms of the GNU Affero General Public License |
+| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+| |
+| CiviCRM is distributed in the hope that it will be useful, but |
+| WITHOUT ANY WARRANTY; without even the implied warranty of |
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+| See the GNU Affero General Public License for more details. |
+| |
+| You should have received a copy of the GNU Affero General Public |
+| License and the CiviCRM Licensing Exception along |
+| with this program; if not, contact CiviCRM LLC |
+| at info[AT]civicrm[DOT]org. If you have questions about the |
+| GNU Affero General Public License or the licensing of CiviCRM, |
+| see the CiviCRM license FAQ at http://civicrm.org/licensing |
++--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ *
+ * Generated from schema_structure.tpl
+ * DO NOT EDIT. Generated by CRM_Core_CodeGen
+ */
+class CRM_Core_I18n_SchemaStructure_5_20_alpha1 {
+
+ /**
+ * Get translatable columns.
+ *
+ * @return array
+ * A table-indexed array of translatable columns.
+ */
+ public static function &columns() {
+ static $result = NULL;
+ if (!$result) {
+ $result = [
+ 'civicrm_location_type' => [
+ 'display_name' => "varchar(64) COMMENT 'Location Type Display Name.'",
+ ],
+ 'civicrm_option_group' => [
+ 'title' => "varchar(255) COMMENT 'Option Group title.'",
+ 'description' => "varchar(255) COMMENT 'Option group description.'",
+ ],
+ 'civicrm_relationship_type' => [
+ 'label_a_b' => "varchar(64) COMMENT 'label for relationship of contact_a to contact_b.'",
+ 'label_b_a' => "varchar(64) COMMENT 'Optional label for relationship of contact_b to contact_a.'",
+ 'description' => "varchar(255) COMMENT 'Optional verbose description of the relationship type.'",
+ ],
+ 'civicrm_contact_type' => [
+ 'label' => "varchar(64) COMMENT 'localized Name of Contact Type.'",
+ 'description' => "text COMMENT 'localized Optional verbose description of the type.'",
+ ],
+ 'civicrm_batch' => [
+ 'title' => "varchar(255) COMMENT 'Friendly Name.'",
+ 'description' => "text COMMENT 'Description of this batch set.'",
+ ],
+ 'civicrm_premiums' => [
+ 'premiums_intro_title' => "varchar(255) COMMENT 'Title for Premiums section.'",
+ 'premiums_intro_text' => "text COMMENT 'Displayed in <div> at top of Premiums section of page. Text and HTML allowed.'",
+ 'premiums_nothankyou_label' => "varchar(255) COMMENT 'Label displayed for No Thank-you option in premiums block (e.g. No thank you)'",
+ ],
+ 'civicrm_membership_status' => [
+ 'label' => "varchar(128) COMMENT 'Label for Membership Status'",
+ ],
+ 'civicrm_survey' => [
+ 'title' => "varchar(255) NOT NULL COMMENT 'Title of the Survey.'",
+ 'instructions' => "text COMMENT 'Script instructions for volunteers to use for the survey.'",
+ 'thankyou_title' => "varchar(255) COMMENT 'Title for Thank-you page (header title tag, and display at the top of the page).'",
+ 'thankyou_text' => "text COMMENT 'text and html allowed. displayed above result on success page'",
+ ],
+ 'civicrm_participant_status_type' => [
+ 'label' => "varchar(255) COMMENT 'localized label for display of this status type'",
+ ],
+ 'civicrm_case_type' => [
+ 'title' => "varchar(64) NOT NULL COMMENT 'Natural language name for Case Type'",
+ 'description' => "varchar(255) COMMENT 'Description of the Case Type'",
+ ],
+ 'civicrm_tell_friend' => [
+ 'title' => "varchar(255)",
+ 'intro' => "text COMMENT 'Introductory message to contributor or participant displayed on the Tell a Friend form.'",
+ 'suggested_message' => "text COMMENT 'Suggested message to friends, provided as default on the Tell A Friend form.'",
+ 'thankyou_title' => "varchar(255) COMMENT 'Text for Tell a Friend thank you page header and HTML title.'",
+ 'thankyou_text' => "text COMMENT 'Thank you message displayed on success page.'",
+ ],
+ 'civicrm_custom_group' => [
+ 'title' => "varchar(64) NOT NULL COMMENT 'Friendly Name.'",
+ 'help_pre' => "text COMMENT 'Description and/or help text to display before fields in form.'",
+ 'help_post' => "text COMMENT 'Description and/or help text to display after fields in form.'",
+ ],
+ 'civicrm_custom_field' => [
+ 'label' => "varchar(255) NOT NULL COMMENT 'Text for form field label (also friendly name for administering this custom property).'",
+ 'help_pre' => "text COMMENT 'Description and/or help text to display before this field.'",
+ 'help_post' => "text COMMENT 'Description and/or help text to display after this field.'",
+ ],
+ 'civicrm_option_value' => [
+ 'label' => "varchar(512) NOT NULL COMMENT 'Option string as displayed to users - e.g. the label in an HTML OPTION tag.'",
+ 'description' => "text COMMENT 'Optional description.'",
+ ],
+ 'civicrm_group' => [
+ 'title' => "varchar(64) COMMENT 'Name of Group.'",
+ ],
+ 'civicrm_contribution_page' => [
+ 'title' => "varchar(255) COMMENT 'Contribution Page title. For top of page display'",
+ 'intro_text' => "text COMMENT 'Text and html allowed. Displayed below title.'",
+ 'pay_later_text' => "text COMMENT 'The text displayed to the user in the main form'",
+ 'pay_later_receipt' => "text COMMENT 'The receipt sent to the user instead of the normal receipt text'",
+ 'initial_amount_label' => "varchar(255) COMMENT 'Initial amount label for partial payment'",
+ 'initial_amount_help_text' => "text COMMENT 'Initial amount help text for partial payment'",
+ 'thankyou_title' => "varchar(255) COMMENT 'Title for Thank-you page (header title tag, and display at the top of the page).'",
+ 'thankyou_text' => "text COMMENT 'text and html allowed. displayed above result on success page'",
+ 'thankyou_footer' => "text COMMENT 'Text and html allowed. displayed at the bottom of the success page. Common usage is to include link(s) to other pages such as tell-a-friend, etc.'",
+ 'receipt_from_name' => "varchar(255) COMMENT 'FROM email name used for receipts generated by contributions to this contribution page.'",
+ 'receipt_text' => "text COMMENT 'text to include above standard receipt info on receipt email. emails are text-only, so do not allow html for now'",
+ 'footer_text' => "text COMMENT 'Text and html allowed. Displayed at the bottom of the first page of the contribution wizard.'",
+ 'frontend_title' => "varchar(255) COMMENT 'Contribution Page Public title'",
+ ],
+ 'civicrm_product' => [
+ 'name' => "varchar(255) NOT NULL COMMENT 'Required product/premium name'",
+ 'description' => "text COMMENT 'Optional description of the product/premium.'",
+ 'options' => "text COMMENT 'Store comma-delimited list of color, size, etc. options for the product.'",
+ ],
+ 'civicrm_payment_processor' => [
+ 'title' => "varchar(127) COMMENT 'Payment Processor Descriptive Name.'",
+ ],
+ 'civicrm_membership_type' => [
+ 'name' => "varchar(128) COMMENT 'Name of Membership Type'",
+ 'description' => "varchar(255) COMMENT 'Description of Membership Type'",
+ ],
+ 'civicrm_membership_block' => [
+ 'new_title' => "varchar(255) COMMENT 'Title to display at top of block'",
+ 'new_text' => "text COMMENT 'Text to display below title'",
+ 'renewal_title' => "varchar(255) COMMENT 'Title for renewal'",
+ 'renewal_text' => "text COMMENT 'Text to display for member renewal'",
+ ],
+ 'civicrm_price_set' => [
+ 'title' => "varchar(255) NOT NULL COMMENT 'Displayed title for the Price Set.'",
+ 'help_pre' => "text COMMENT 'Description and/or help text to display before fields in form.'",
+ 'help_post' => "text COMMENT 'Description and/or help text to display after fields in form.'",
+ ],
+ 'civicrm_dashboard' => [
+ 'label' => "varchar(255) COMMENT 'dashlet title'",
+ ],
+ 'civicrm_uf_group' => [
+ 'title' => "varchar(64) NOT NULL COMMENT 'Form title.'",
+ 'frontend_title' => "varchar(64) COMMENT 'Profile Form Public title'",
+ 'help_pre' => "text COMMENT 'Description and/or help text to display before fields in form.'",
+ 'help_post' => "text COMMENT 'Description and/or help text to display after fields in form.'",
+ 'cancel_button_text' => "varchar(64) DEFAULT NULL COMMENT 'Custom Text to display on the Cancel button when used in create or edit mode'",
+ 'submit_button_text' => "varchar(64) DEFAULT NULL COMMENT 'Custom Text to display on the submit button on profile edit/create screens'",
+ ],
+ 'civicrm_uf_field' => [
+ 'help_post' => "text COMMENT 'Description and/or help text to display after this field.'",
+ 'help_pre' => "text COMMENT 'Description and/or help text to display before this field.'",
+ 'label' => "varchar(255) NOT NULL COMMENT 'To save label for fields.'",
+ ],
+ 'civicrm_price_field' => [
+ 'label' => "varchar(255) NOT NULL COMMENT 'Text for form field label (also friendly name for administering this field).'",
+ 'help_pre' => "text COMMENT 'Description and/or help text to display before this field.'",
+ 'help_post' => "text COMMENT 'Description and/or help text to display after this field.'",
+ ],
+ 'civicrm_price_field_value' => [
+ 'label' => "varchar(255) COMMENT 'Price field option label'",
+ 'description' => "text DEFAULT NULL COMMENT 'Price field option description.'",
+ 'help_pre' => "text DEFAULT NULL COMMENT 'Price field option pre help text.'",
+ 'help_post' => "text DEFAULT NULL COMMENT 'Price field option post field help.'",
+ ],
+ 'civicrm_pcp_block' => [
+ 'link_text' => "varchar(255) DEFAULT NULL COMMENT 'Link text for PCP.'",
+ ],
+ 'civicrm_event' => [
+ 'title' => "varchar(255) COMMENT 'Event Title (e.g. Fall Fundraiser Dinner)'",
+ 'summary' => "text COMMENT 'Brief summary of event. Text and html allowed. Displayed on Event Registration form and can be used on other CMS pages which need an event summary.'",
+ 'description' => "text COMMENT 'Full description of event. Text and html allowed. Displayed on built-in Event Information screens.'",
+ 'registration_link_text' => "varchar(255) COMMENT 'Text for link to Event Registration form which is displayed on Event Information screen when is_online_registration is true.'",
+ 'event_full_text' => "text COMMENT 'Message to display on Event Information page and INSTEAD OF Event Registration form if maximum participants are signed up. Can include email address/info about getting on a waiting list, etc. Text and html allowed.'",
+ 'fee_label' => "varchar(255)",
+ 'intro_text' => "text COMMENT 'Introductory message for Event Registration page. Text and html allowed. Displayed at the top of Event Registration form.'",
+ 'footer_text' => "text COMMENT 'Footer message for Event Registration page. Text and html allowed. Displayed at the bottom of Event Registration form.'",
+ 'confirm_title' => "varchar(255) DEFAULT NULL COMMENT 'Title for Confirmation page.'",
+ 'confirm_text' => "text COMMENT 'Introductory message for Event Registration page. Text and html allowed. Displayed at the top of Event Registration form.'",
+ 'confirm_footer_text' => "text COMMENT 'Footer message for Event Registration page. Text and html allowed. Displayed at the bottom of Event Registration form.'",
+ 'confirm_email_text' => "text COMMENT 'text to include above standard event info on confirmation email. emails are text-only, so do not allow html for now'",
+ 'confirm_from_name' => "varchar(255) COMMENT 'FROM email name used for confirmation emails.'",
+ 'thankyou_title' => "varchar(255) DEFAULT NULL COMMENT 'Title for ThankYou page.'",
+ 'thankyou_text' => "text COMMENT 'ThankYou Text.'",
+ 'thankyou_footer_text' => "text COMMENT 'Footer message.'",
+ 'pay_later_text' => "text COMMENT 'The text displayed to the user in the main form'",
+ 'pay_later_receipt' => "text COMMENT 'The receipt sent to the user instead of the normal receipt text'",
+ 'initial_amount_label' => "varchar(255) COMMENT 'Initial amount label for partial payment'",
+ 'initial_amount_help_text' => "text COMMENT 'Initial amount help text for partial payment'",
+ 'waitlist_text' => "text COMMENT 'Text to display when the event is full, but participants can signup for a waitlist.'",
+ 'approval_req_text' => "text COMMENT 'Text to display when the approval is required to complete registration for an event.'",
+ 'template_title' => "varchar(255) COMMENT 'Event Template Title'",
+ ],
+ ];
+ }
+ return $result;
+ }
+
+ /**
+ * Get a table indexed array of the indices for translatable fields.
+ *
+ * @return array
+ * Indices for translatable fields.
+ */
+ public static function &indices() {
+ static $result = NULL;
+ if (!$result) {
+ $result = [
+ 'civicrm_custom_group' => [
+ 'UI_title_extends' => [
+ 'name' => 'UI_title_extends',
+ 'field' => [
+ 'title',
+ 'extends',
+ ],
+ 'unique' => 1,
+ ],
+ ],
+ 'civicrm_custom_field' => [
+ 'UI_label_custom_group_id' => [
+ 'name' => 'UI_label_custom_group_id',
+ 'field' => [
+ 'label',
+ 'custom_group_id',
+ ],
+ 'unique' => 1,
+ ],
+ ],
+ 'civicrm_group' => [
+ 'UI_title' => [
+ 'name' => 'UI_title',
+ 'field' => [
+ 'title',
+ ],
+ 'unique' => 1,
+ ],
+ ],
+ ];
+ }
+ return $result;
+ }
+
+ /**
+ * Get tables with translatable fields.
+ *
+ * @return array
+ * Array of names of tables with fields that can be translated.
+ */
+ public static function &tables() {
+ static $result = NULL;
+ if (!$result) {
+ $result = array_keys(self::columns());
+ }
+ return $result;
+ }
+
+ /**
+ * Get a list of widgets for editing translatable fields.
+ *
+ * @return array
+ * Array of the widgets for editing translatable fields.
+ */
+ public static function &widgets() {
+ static $result = NULL;
+ if (!$result) {
+ $result = [
+ 'civicrm_location_type' => [
+ 'display_name' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_option_group' => [
+ 'title' => [
+ 'type' => "Text",
+ ],
+ 'description' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_relationship_type' => [
+ 'label_a_b' => [
+ 'type' => "Text",
+ ],
+ 'label_b_a' => [
+ 'type' => "Text",
+ ],
+ 'description' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_contact_type' => [
+ 'label' => [
+ 'type' => "Text",
+ ],
+ 'description' => [
+ 'type' => "TextArea",
+ 'rows' => "2",
+ 'cols' => "60",
+ ],
+ ],
+ 'civicrm_batch' => [
+ 'title' => [
+ 'type' => "Text",
+ ],
+ 'description' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ ],
+ 'civicrm_premiums' => [
+ 'premiums_intro_title' => [
+ 'type' => "Text",
+ ],
+ 'premiums_intro_text' => [
+ 'type' => "Text",
+ ],
+ 'premiums_nothankyou_label' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_membership_status' => [
+ 'label' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_survey' => [
+ 'title' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'instructions' => [
+ 'type' => "TextArea",
+ 'rows' => "20",
+ 'cols' => "80",
+ ],
+ 'thankyou_title' => [
+ 'type' => "Text",
+ ],
+ 'thankyou_text' => [
+ 'type' => "TextArea",
+ 'rows' => "8",
+ 'cols' => "60",
+ ],
+ ],
+ 'civicrm_participant_status_type' => [
+ 'label' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_case_type' => [
+ 'title' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'description' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_tell_friend' => [
+ 'title' => [
+ 'type' => "Text",
+ ],
+ 'intro' => [
+ 'type' => "Text",
+ ],
+ 'suggested_message' => [
+ 'type' => "Text",
+ ],
+ 'thankyou_title' => [
+ 'type' => "Text",
+ ],
+ 'thankyou_text' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_custom_group' => [
+ 'title' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'help_pre' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ 'help_post' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ ],
+ 'civicrm_custom_field' => [
+ 'label' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'help_pre' => [
+ 'type' => "Text",
+ ],
+ 'help_post' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_option_value' => [
+ 'label' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'description' => [
+ 'type' => "TextArea",
+ 'rows' => "8",
+ 'cols' => "60",
+ ],
+ ],
+ 'civicrm_group' => [
+ 'title' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_contribution_page' => [
+ 'title' => [
+ 'type' => "Text",
+ ],
+ 'intro_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'pay_later_text' => [
+ 'type' => "Text",
+ ],
+ 'pay_later_receipt' => [
+ 'type' => "Text",
+ ],
+ 'initial_amount_label' => [
+ 'type' => "Text",
+ ],
+ 'initial_amount_help_text' => [
+ 'type' => "Text",
+ ],
+ 'thankyou_title' => [
+ 'type' => "Text",
+ ],
+ 'thankyou_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "8",
+ 'cols' => "60",
+ ],
+ 'thankyou_footer' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "8",
+ 'cols' => "60",
+ ],
+ 'receipt_from_name' => [
+ 'type' => "Text",
+ ],
+ 'receipt_text' => [
+ 'type' => "TextArea",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'footer_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'frontend_title' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_product' => [
+ 'name' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'description' => [
+ 'type' => "Text",
+ ],
+ 'options' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_payment_processor' => [
+ 'title' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_membership_type' => [
+ 'name' => [
+ 'type' => "Text",
+ 'label' => "Name",
+ ],
+ 'description' => [
+ 'type' => "TextArea",
+ 'rows' => "6",
+ 'cols' => "50",
+ 'label' => "Description",
+ ],
+ ],
+ 'civicrm_membership_block' => [
+ 'new_title' => [
+ 'type' => "Text",
+ ],
+ 'new_text' => [
+ 'type' => "Text",
+ ],
+ 'renewal_title' => [
+ 'type' => "Text",
+ ],
+ 'renewal_text' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_price_set' => [
+ 'title' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'help_pre' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ 'help_post' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ ],
+ 'civicrm_dashboard' => [
+ 'label' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_uf_group' => [
+ 'title' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'frontend_title' => [
+ 'type' => "Text",
+ ],
+ 'help_pre' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ 'help_post' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ 'cancel_button_text' => [
+ 'type' => "Text",
+ ],
+ 'submit_button_text' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_uf_field' => [
+ 'help_post' => [
+ 'type' => "Text",
+ ],
+ 'help_pre' => [
+ 'type' => "Text",
+ ],
+ 'label' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ ],
+ 'civicrm_price_field' => [
+ 'label' => [
+ 'type' => "Text",
+ 'required' => "true",
+ ],
+ 'help_pre' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ 'help_post' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "80",
+ ],
+ ],
+ 'civicrm_price_field_value' => [
+ 'label' => [
+ 'type' => "Text",
+ ],
+ 'description' => [
+ 'type' => "TextArea",
+ 'rows' => "2",
+ 'cols' => "60",
+ ],
+ 'help_pre' => [
+ 'type' => "TextArea",
+ 'rows' => "2",
+ 'cols' => "60",
+ ],
+ 'help_post' => [
+ 'type' => "TextArea",
+ 'rows' => "2",
+ 'cols' => "60",
+ ],
+ ],
+ 'civicrm_pcp_block' => [
+ 'link_text' => [
+ 'type' => "Text",
+ ],
+ ],
+ 'civicrm_event' => [
+ 'title' => [
+ 'type' => "Text",
+ ],
+ 'summary' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "60",
+ ],
+ 'description' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "8",
+ 'cols' => "60",
+ ],
+ 'registration_link_text' => [
+ 'type' => "Text",
+ ],
+ 'event_full_text' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "60",
+ ],
+ 'fee_label' => [
+ 'type' => "Text",
+ ],
+ 'intro_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'footer_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'confirm_title' => [
+ 'type' => "Text",
+ ],
+ 'confirm_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'confirm_footer_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'confirm_email_text' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "50",
+ ],
+ 'confirm_from_name' => [
+ 'type' => "Text",
+ ],
+ 'thankyou_title' => [
+ 'type' => "Text",
+ ],
+ 'thankyou_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'thankyou_footer_text' => [
+ 'type' => "RichTextEditor",
+ 'rows' => "6",
+ 'cols' => "50",
+ ],
+ 'pay_later_text' => [
+ 'type' => "RichTextEditor",
+ ],
+ 'pay_later_receipt' => [
+ 'type' => "Text",
+ ],
+ 'initial_amount_label' => [
+ 'type' => "Text",
+ ],
+ 'initial_amount_help_text' => [
+ 'type' => "Text",
+ ],
+ 'waitlist_text' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "60",
+ ],
+ 'approval_req_text' => [
+ 'type' => "TextArea",
+ 'rows' => "4",
+ 'cols' => "60",
+ ],
+ 'template_title' => [
+ 'type' => "Text",
+ ],
+ ],
+ ];
+ }
+ return $result;
+ }
+
+}
$template->assign('formTpl', 'default');
if ($item) {
- // CRM-7656 - make sure we send a clean sanitized path to create printer friendly url
- $printerFriendly = CRM_Utils_System::makeURL(
- 'snippet', FALSE, FALSE,
- CRM_Utils_Array::value('path', $item)
- ) . '2';
- $template->assign('printerFriendly', $printerFriendly);
if (!array_key_exists('page_callback', $item)) {
CRM_Core_Error::debug('Bad item', $item);
* @throws Exception
*/
public 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 = $this->prepareParamsForPaymentProcessor($params);
+ $params['currencyID'] = CRM_Core_Config::singleton()->defaultCurrency;
$payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
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'];
+
try {
$result = $payment->doPayment($params);
}
}
// create/update event location
- $location = CRM_Core_BAO_Location::create($params, TRUE, 'event');
- $params['loc_block_id'] = $location['id'];
+ $params['loc_block_id'] = CRM_Core_BAO_Location::create($params, TRUE, 'event')['id'];
// finally update event params
$params['id'] = $this->_id;
if ($this->_mode) {
// add all the additional payment params we need
- $this->_params["state_province-{$this->_bltID}"] = $this->_params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($this->_params["billing_state_province_id-{$this->_bltID}"]);
- $this->_params["country-{$this->_bltID}"] = $this->_params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($this->_params["billing_country_id-{$this->_bltID}"]);
-
+ $this->_params = $this->prepareParamsForPaymentProcessor($this->_params);
$this->_params['amount'] = $params['fee_amount'];
$this->_params['amount_level'] = $params['amount_level'];
$this->_params['currencyID'] = $config->defaultCurrency;
$ppDAO->save();
}
}
- // next create the transaction record
- $transaction = new CRM_Core_Transaction();
// CRM-11124
if ($this->_params['discount_id']) {
CRM_Price_BAO_PriceSet::parseFirstPriceSetValueIDFromParams($this->_params)
);
}
- $transaction->commit();
}
}
// we do not want to display recently viewed items on Registration pages
$this->assign('displayRecent', FALSE);
- // Registration page values are cleared from session, so can't use normal Printer Friendly view.
- // Use Browser Print instead.
- $this->assign('browserPrint', TRUE);
$isShowLocation = CRM_Utils_Array::value('is_show_location', $this->_values['event']);
$this->assign('isShowLocation', $isShowLocation);
* Handle process after the confirmation of payment by User.
*
* @param int $contactID
- * @param null $contribution
- * @param null $payment
+ * @param \CRM_Contribute_BAO_Contribution $contribution
*/
- public function confirmPostProcess($contactID = NULL, $contribution = NULL, $payment = NULL) {
+ public function confirmPostProcess($contactID = NULL, $contribution = NULL) {
// add/update contact information
- $fields = array();
unset($this->_params['note']);
//to avoid conflict overwrite $this->_params
}
$this->set('value', $value);
- $this->confirmPostProcess($contactID, NULL, NULL);
+ $this->confirmPostProcess($contactID, NULL);
//lets get additional participant id to cancel.
if ($this->_allowConfirmation && is_array($cancelledIds)) {
if (!$this->preProcessExpress()) {
//process only primary participant params.
$registerParams = $this->_params[0];
- if (isset($registerParams["billing_state_province_id-{$this->_bltID}"])
- && $registerParams["billing_state_province_id-{$this->_bltID}"]
- ) {
- $registerParams["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($registerParams["billing_state_province_id-{$this->_bltID}"]);
- }
+ $registerParams = $this->prepareParamsForPaymentProcessor($registerParams);
- if (isset($registerParams["billing_country_id-{$this->_bltID}"]) && $registerParams["billing_country_id-{$this->_bltID}"]) {
- $registerParams["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($registerParams["billing_country_id-{$this->_bltID}"]);
- }
- if (isset($registerParams['credit_card_exp_date'])) {
- $registerParams['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($registerParams);
- $registerParams['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($registerParams);
- }
if ($this->_values['event']['is_monetary']) {
- $registerParams['ip_address'] = CRM_Utils_System::ipAddress();
$registerParams['currencyID'] = $this->_params[0]['currencyID'];
}
//assign back primary participant params.
$payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
$paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.');
- $this->participantIDS = [];
$fields = [];
foreach ($params as $key => $value) {
CRM_Event_Form_Registration_Confirm::fixLocationFields($value, $fields, $this);
}
$this->assign('register_date', $registerDate);
- $this->confirmPostProcess($contactID, $contribution, $payment);
+ $this->confirmPostProcess($contactID, $contribution);
}
//handle if no additional participant.
}
//get email primary first if exist
- $subscribtionEmail = ['email' => CRM_Utils_Array::value('email-Primary', $params)];
- if (!$subscribtionEmail['email']) {
- $subscribtionEmail['email'] = CRM_Utils_Array::value("email-{$form->_bltID}", $params);
+ $subscriptionEmail = ['email' => CRM_Utils_Array::value('email-Primary', $params)];
+ if (!$subscriptionEmail['email']) {
+ $subscriptionEmail['email'] = CRM_Utils_Array::value("email-{$form->_bltID}", $params);
}
// subscribing contact to groups
- if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
- CRM_Mailing_Event_BAO_Subscribe::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
+ if (!empty($subscribeGroupIds) && $subscriptionEmail['email']) {
+ CRM_Mailing_Event_BAO_Subscribe::commonSubscribe($subscribeGroupIds, $subscriptionEmail, $contactID);
}
return $contactID;
$this->set('contributeMode', 'direct');
// This code is duplicated multiple places and should be consolidated.
- if (isset($params["state_province_id-{$this->_bltID}"]) &&
- $params["state_province_id-{$this->_bltID}"]
- ) {
- $params["state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($params["state_province_id-{$this->_bltID}"]);
- }
+ $params = $this->prepareParamsForPaymentProcessor($params);
- if (isset($params["country_id-{$this->_bltID}"]) &&
- $params["country_id-{$this->_bltID}"]
- ) {
- $params["country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($params["country_id-{$this->_bltID}"]);
- }
- if (isset($params['credit_card_exp_date'])) {
- $params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($params);
- $params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($params);
- }
if ($this->_values['event']['is_monetary']) {
- $params['ip_address'] = CRM_Utils_System::ipAddress();
$params['currencyID'] = $config->defaultCurrency;
$params['invoiceID'] = $invoiceID;
}
if ($processor->isMergeSameAddress()) {
foreach (array_keys($processor->getAdditionalFieldsForSameAddressMerge()) as $field) {
+ if ($field === 'id') {
+ $field = 'civicrm_primary_id';
+ }
$processor->setColumnAsCalculationOnly($field);
}
}
$addressWhere .= " OR civicrm_address.supplemental_address_1 <> ''";
}
}
- $whereClauses['address'] = $addressWhere;
+ $whereClauses['address'] = '(' . $addressWhere . ')';
}
}
$query = "SELECT * FROM $exportTempTable";
+ $this->instantiateTempTable($headerRows);
while (1) {
$limitQuery = $query . "
LIMIT $offset, $limit
}
$componentDetails[] = $row;
}
- CRM_Core_Report_Excel::writeCSVFile($this->getExportFileName(),
- $headerRows,
- $componentDetails,
- NULL,
- $writeHeader
- );
-
- $writeHeader = FALSE;
+ $this->writeRows($headerRows, $componentDetails);
+
$offset += $limit;
}
}
+ /**
+ * Set up the temp table.
+ *
+ * @param array $headerRows
+ */
+ protected function instantiateTempTable(array $headerRows) {
+ CRM_Utils_System::download(CRM_Utils_String::munge($this->getExportFileName()),
+ 'text/x-csv',
+ CRM_Core_DAO::$_nullObject,
+ 'csv',
+ FALSE
+ );
+ CRM_Core_Report_Excel::makeCSVTable($headerRows, [], NULL, TRUE, TRUE);
+ }
+
+ /**
+ * @param array $headerRows
+ * @param array $componentDetails
+ */
+ protected function writeRows(array $headerRows, array $componentDetails) {
+ CRM_Core_Report_Excel::writeCSVFile($this->getExportFileName(),
+ $headerRows,
+ $componentDetails,
+ NULL,
+ FALSE
+ );
+ }
+
}
return Civi::$statics[__CLASS__]['entity_financial_account'][$financialTypeID][$relationTypeId];
}
+ /**
+ * Get the sales tax financial account id for the financial type id.
+ *
+ * This is a helper wrapper to make the function name more readable.
+ *
+ * @param int $financialAccountID
+ *
+ * @return int
+ */
+ public static function getSalesTaxFinancialAccount($financialAccountID) {
+ return self::getFinancialAccountForFinancialTypeByRelationship($financialAccountID, 'Sales Tax Account is');
+ }
+
/**
* Get Financial Account type relations.
*
*
* Generated from xml/schema/CRM/Financial/FinancialTrxn.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:ea6e4e27680634c1c2e4def15d91e02c)
+ * (GenCodeChecksum:30dff7f6f16ef7cd997187a202a59173)
*/
/**
*/
public $pan_truncation;
+ /**
+ * Payment Processor external order reference
+ *
+ * @var string
+ */
+ public $order_reference;
+
/**
* Class constructor.
*/
'type' => 'Text',
],
],
+ 'financial_trxn_order_reference' => [
+ 'name' => 'order_reference',
+ 'type' => CRM_Utils_Type::T_STRING,
+ 'title' => ts('Order Reference'),
+ 'description' => ts('Payment Processor external order reference'),
+ 'maxlength' => 255,
+ 'size' => 25,
+ 'where' => 'civicrm_financial_trxn.order_reference',
+ 'table_name' => 'civicrm_financial_trxn',
+ 'entity' => 'FinancialTrxn',
+ 'bao' => 'CRM_Financial_DAO_FinancialTrxn',
+ 'localizable' => 0,
+ 'html' => [
+ 'type' => 'Text',
+ ],
+ ],
];
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
}
if ($self->_action & CRM_Core_Action::UPDATE) {
if (!(isset($values['is_tax']))) {
+ // @todo replace with call to CRM_Financial_BAO_FinancialAccount getSalesTaxFinancialAccount
$relationshipId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' "));
$params = [
'financial_account_id' => $self->_id,
];
$defaults = [];
if ($self->_action == CRM_Core_Action::ADD) {
+ // @todo replace with call to CRM_Financial_BAO_FinancialAccount getSalesTaxFinancialAccount
$relationshipId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' "));
$isTax = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', $values['financial_account_id'], 'is_tax');
if ($values['account_relationship'] == $relationshipId) {
/**
* Parse a field which could be represented by a label or name value rather than the DB value.
*
- * We will try to match name first but if not available then see if we have a label that can be converted to a name.
+ * We will try to match name first or (per https://lab.civicrm.org/dev/core/issues/1285 if we have an id.
+ *
+ * but if not available then see if we have a label that can be converted to a name.
*
* @param string|int|null $submittedValue
* @param array $fieldSpec
* @return mixed
*/
protected function parsePseudoConstantField($submittedValue, $fieldSpec) {
+ // dev/core#1289 Somehow we have wound up here but the BAO has not been specified in the fieldspec so we need to check this but future us problem, for now lets just return the submittedValue
+ if (!isset($fieldSpec['bao'])) {
+ return $submittedValue;
+ }
/* @var \CRM_Core_DAO $bao */
$bao = $fieldSpec['bao'];
// For historical reasons use validate as context - ie disabled name matches ARE permitted.
$nameOptions = $bao::buildOptions($fieldSpec['name'], 'validate');
- if (!isset($nameOptions[$submittedValue])) {
- $labelOptions = array_flip($bao::buildOptions($fieldSpec['name'], 'match'));
- if (isset($labelOptions[$submittedValue])) {
- return array_search($labelOptions[$submittedValue], $nameOptions, TRUE);
- }
+ if (isset($nameOptions[$submittedValue])) {
+ return $submittedValue;
+ }
+ if (in_array($submittedValue, $nameOptions)) {
+ return array_search($submittedValue, $nameOptions, TRUE);
+ }
+
+ $labelOptions = array_flip($bao::buildOptions($fieldSpec['name'], 'match'));
+ if (isset($labelOptions[$submittedValue])) {
+ return array_search($labelOptions[$submittedValue], $nameOptions, TRUE);
}
return '';
}
}
$params['skipLineItem'] = TRUE;
- //record contribution for this membership
+ // Record contribution for this membership and create a MembershipPayment
if (!empty($params['contribution_status_id']) && empty($params['relate_contribution_id'])) {
$memInfo = array_merge($params, ['membership_id' => $membership->id]);
$params['contribution'] = self::recordMembershipContribution($memInfo);
}
+ // Add/update MembershipPayment record for this membership if it is a related contribution
+ if (!empty($params['relate_contribution_id'])) {
+ $membershipPaymentParams = [
+ 'membership_id' => $membership->id,
+ 'membership_type_id' => $membership->membership_type_id,
+ 'contribution_id' => $params['relate_contribution_id'],
+ ];
+ civicrm_api3('MembershipPayment', 'create', $membershipPaymentParams);
+ }
+
if (!empty($params['lineItems'])) {
$params['line_item'] = $params['lineItems'];
}
);
}
- //insert payment record for this membership
- if (!empty($params['relate_contribution_id'])) {
- $membershipPaymentParams = [
- 'membership_id' => $membership->id,
- 'membership_type_id' => $membership->membership_type_id,
- 'contribution_id' => $params['relate_contribution_id'],
- ];
- civicrm_api3('MembershipPayment', 'create', $membershipPaymentParams);
- }
-
$transaction->commit();
self::createRelatedMemberships($params, $membership);
/**
* Record contribution record associated with membership.
+ * This will update an existing contribution if $params['contribution_id'] is passed in.
+ * This will create a MembershipPayment to link the contribution and membership
*
* @param array $params
* Array of submitted params.
* @param array $ids
* (@return CRM_Contribute_BAO_Contribution
*
- * @throws \CiviCRM_API3_Exception
+ * @return CRM_Contribute_BAO_Contribution
* @throws \CRM_Core_Exception
+ * @throws \CiviCRM_API3_Exception
*/
public static function recordMembershipContribution(&$params, $ids = []) {
if (!empty($ids)) {
list($this->userDisplayName,
$this->userEmail
) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
- $this->assign('displayName', $this->userDisplayName);
}
$this->setPageTitle(ts('Pledge'));
$this->assign('installments', $defaults['installments']);
}
else {
+ if ($this->_contactID) {
+ $defaults['contact_id'] = $this->_contactID;
+ }
// default values.
$defaults['create_date'] = date('Y-m-d');
$defaults['start_date'] = date('Y-m-d');
return;
}
- if ($this->_context == 'standalone') {
- $this->addEntityRef('contact_id', ts('Contact'), [
- 'create' => TRUE,
- 'api' => ['extra' => ['email']],
- ], TRUE);
+ $contactField = $this->addEntityRef('contact_id', ts('Contact'), ['create' => TRUE, 'api' => ['extra' => ['email']]], TRUE);
+ if ($this->_context != 'standalone') {
+ $contactField->freeze();
}
$showAdditionalInfo = FALSE;
// send Acknowledgment mail.
CRM_Pledge_BAO_Pledge::sendAcknowledgment($this, $params);
- if (!isset($this->userEmail)) {
- list($this->userDisplayName,
- $this->userEmail
- ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
- }
-
$statusMsg .= ' ' . ts("An acknowledgment email has been sent to %1.<br />", [1 => $this->userEmail]);
// build the payment urls.
];
if ($this->_params['charts']) {
// build chart.
- CRM_Utils_OpenFlashChart::reportChart($graphRows, $this->_params['charts'], $interval, $chartInfo);
+ CRM_Utils_Chart::reportChart($graphRows, $this->_params['charts'], $interval, $chartInfo);
$this->assign('chartType', $this->_params['charts']);
}
}
$config = CRM_Core_Config::Singleton();
$graphRows['xname'] = $this->_interval;
$graphRows['yname'] = ts('Amount (%1)', array(1 => $config->defaultCurrency));
- CRM_Utils_OpenFlashChart::chart($graphRows, $this->_params['charts'], $this->_interval);
+ CRM_Utils_Chart::chart($graphRows, $this->_params['charts'], $this->_interval);
$this->assign('chartType', $this->_params['charts']);
}
}
];
if ($this->_params['charts']) {
// build the chart.
- CRM_Utils_OpenFlashChart::reportChart($graphRows, $this->_params['charts'], $interval, $chartInfo);
+ CRM_Utils_Chart::reportChart($graphRows, $this->_params['charts'], $interval, $chartInfo);
$this->assign('chartType', $this->_params['charts']);
}
}
$chartInfo['xLabelAngle'] = 20;
// build the chart.
- CRM_Utils_OpenFlashChart::buildChart($chartInfo, $this->_params['charts']);
+ CRM_Utils_Chart::buildChart($chartInfo, $this->_params['charts']);
}
}
}
$chartInfo['xLabelAngle'] = 20;
// build the chart.
- CRM_Utils_OpenFlashChart::buildChart($chartInfo, $this->_params['charts']);
+ CRM_Utils_Chart::buildChart($chartInfo, $this->_params['charts']);
$this->assign('chartType', $this->_params['charts']);
}
}
}
// build the chart.
- CRM_Utils_OpenFlashChart::buildChart($chartInfo, $this->_params['charts']);
+ CRM_Utils_Chart::buildChart($chartInfo, $this->_params['charts']);
$this->assign('chartType', $this->_params['charts']);
}
}
// build the chart.
- CRM_Utils_OpenFlashChart::buildChart($chartInfo, $this->_params['charts']);
+ CRM_Utils_Chart::buildChart($chartInfo, $this->_params['charts']);
$this->assign('chartType', $this->_params['charts']);
}
}
// build the chart.
- CRM_Utils_OpenFlashChart::buildChart($chartInfo, $this->_params['charts']);
+ CRM_Utils_Chart::buildChart($chartInfo, $this->_params['charts']);
$this->assign('chartType', $this->_params['charts']);
}
protected $_charts = [
'' => 'Tabular',
- 'bar_3dChart' => 'Bar Chart',
+ 'barchart' => 'Bar Chart',
];
/**
$chartInfo['xSize'] = ((count($rows) * 125) + (count($rows) * count($criteria) * 40));
// build the chart.
- CRM_Utils_OpenFlashChart::buildChart($chartInfo, $this->_params['charts']);
+ CRM_Utils_Chart::buildChart($chartInfo, $this->_params['charts']);
$this->assign('chartType', $this->_params['charts']);
}
'xname' => ts('Member Since / Member Type'),
'yname' => ts('Fees'),
];
- CRM_Utils_OpenFlashChart::reportChart($graphRows, $this->_params['charts'], $interval, $chartInfo);
+ CRM_Utils_Chart::reportChart($graphRows, $this->_params['charts'], $interval, $chartInfo);
}
else {
- CRM_Utils_OpenFlashChart::chart($graphRows, $this->_params['charts'], $this->_interval);
+ CRM_Utils_Chart::chart($graphRows, $this->_params['charts'], $this->_interval);
}
}
$this->assign('chartType', $this->_params['charts']);
}
// build chart.
- CRM_Utils_OpenFlashChart::chart($graphRows, $this->_params['charts'], $this->_interval);
+ CRM_Utils_Chart::chart($graphRows, $this->_params['charts'], $this->_interval);
}
parent::endPostProcess();
}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2019 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License along with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * Upgrade logic for FiveTwenty */
+class CRM_Upgrade_Incremental_php_FiveTwenty extends CRM_Upgrade_Incremental_Base {
+
+ /**
+ * Compute any messages which should be displayed beforeupgrade.
+ *
+ * Note: This function is called iteratively for each upcoming
+ * revision to the database.
+ *
+ * @param string $preUpgradeMessage
+ * @param string $rev
+ * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
+ * @param null $currentVer
+ */
+ public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
+ // Example: Generate a pre-upgrade message.
+ // if ($rev == '5.12.34') {
+ // $preUpgradeMessage .= '<p>' . ts('A new permission, "%1", has been added. This permission is now used to control access to the Manage Tags screen.', array(1 => ts('manage tags'))) . '</p>';
+ // }
+ }
+
+ /**
+ * Compute any messages which should be displayed after upgrade.
+ *
+ * @param string $postUpgradeMessage
+ * alterable.
+ * @param string $rev
+ * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
+ */
+ public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
+ // Example: Generate a post-upgrade message.
+ // if ($rev == '5.12.34') {
+ // $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'.");
+ // }
+ }
+
+ /*
+ * Important! All upgrade functions MUST add a 'runSql' task.
+ * Uncomment and use the following template for a new upgrade version
+ * (change the x in the function name):
+ */
+
+ // public static function taskFoo(CRM_Queue_TaskContext $ctx, ...) {
+ // return TRUE;
+ // }
+
+ /**
+ * Upgrade function.
+ *
+ * @param string $rev
+ */
+ public function upgrade_5_20_alpha1($rev) {
+ $this->addTask('Add frontend title column to contribution page table', 'addColumn', 'civicrm_contribution_page',
+ 'frontend_title', "varchar(255) DEFAULT NULL COMMENT 'Contribution Page Public title'", TRUE, '5.20.alpha1');
+ $this->addTask('Add is_template field to civicrm_contribution', 'addColumn', 'civicrm_contribution', 'is_template',
+ "tinyint(4) DEFAULT '0' COMMENT 'Shows this is a template for recurring contributions.'", FALSE, '5.20.alpha1');
+ $this->addTask('Add order_reference field to civicrm_financial_trxn', 'addColumn', 'civicrm_financial_trxn', 'order_reference',
+ "varchar(255) COMMENT 'Payment Processor external order reference'", FALSE, '5.20.alpha1');
+ $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+ }
+
+}
--- /dev/null
+{* file to handle db changes in 5.19.beta1 during upgrade *}
--- /dev/null
+{* file to handle db changes in 5.20.alpha1 during upgrade *}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2019 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ */
+
+/**
+ * Build various graphs using the dc chart library.
+ */
+class CRM_Utils_Chart {
+
+ /**
+ * Colours.
+ * @var array
+ */
+ private static $_colours = [
+ "#C3CC38",
+ "#C8B935",
+ "#CEA632",
+ "#D3932F",
+ "#D9802C",
+ "#FA6900",
+ "#DC9B57",
+ "#F78F01",
+ "#5AB56E",
+ "#6F8069",
+ "#C92200",
+ "#EB6C5C",
+ ];
+
+ /**
+ * Build The Bar Gharph.
+ *
+ * @param array $params
+ * Assoc array of name/value pairs.
+ *
+ * @return object
+ * $chart object of open flash chart.
+ */
+ public static function barChart($params) {
+ $output = static::commonParamsManipulation($params);
+ if (empty($output)) {
+ return NULL;
+ }
+ $output['type'] = 'barchart';
+ // Default title
+ $output += ['title' => ts('Bar Chart')];
+
+ // ? Not sure what reports use this, but it's not implemented.
+ // call user define function to handle on click event.
+ // if ($onClickFunName = CRM_Utils_Array::value('on_click_fun_name', $params)) {
+ // $bars[$barCount]->set_on_click($onClickFunName);
+ // }
+
+ //// get the currency to set in tooltip.
+ //$tooltip = CRM_Utils_Array::value('tip', $params, "$symbol #val#");
+
+ return $output;
+ }
+
+ /**
+ * Build a pie chart.
+ *
+ * @param array $params
+ * Assoc array of name/value pairs.
+ *
+ * @return array
+ */
+ public static function pieChart($params) {
+ $output = static::commonParamsManipulation($params);
+ if (empty($output)) {
+ return NULL;
+ }
+ $output['type'] = 'piechart';
+ $output += ['title' => ts('Pie Chart')];
+
+ // ? Not sure what reports use this, but it's not implemented.
+ // call user define function to handle on click event.
+ // if ($onClickFunName = CRM_Utils_Array::value('on_click_fun_name', $params)) {
+ // $bars[$barCount]->set_on_click($onClickFunName);
+ // }
+
+ //// get the currency to set in tooltip.
+ //$tooltip = CRM_Utils_Array::value('tip', $params, "$symbol #val#");
+
+ return $output;
+ }
+
+ /**
+ * Common data manipulation for charts.
+ *
+ * @param array $params
+ * Assoc array of name/value pairs.
+ *
+ * @return array
+ */
+ public static function commonParamsManipulation($params) {
+ if (empty($params)) {
+ return NULL;
+ }
+ $output = [];
+ if (empty($params['multiValues'])) {
+ $params['multiValues'] = [$params['values']];
+ }
+
+ $output['values'] = [];
+ foreach ($params['multiValues'] as $i => $dataSet) {
+ $output['values'][$i] = [];
+ foreach ($dataSet as $k => $v) {
+ $output['values'][$i][] = ['label' => $k, 'value' => (double) $v];
+ }
+ }
+ if (!$output['values']) {
+ return NULL;
+ }
+
+ // Ensure there's a legend (title)
+ if (!empty($params['legend'])) {
+ $output['title'] = $params['legend'];
+ }
+
+ $output['symbol'] = CRM_Core_BAO_Country::defaultCurrencySymbol();
+
+ // ? Not sure what reports use this, but it's not implemented.
+ // call user define function to handle on click event.
+ // if ($onClickFunName = CRM_Utils_Array::value('on_click_fun_name', $params)) {
+ // $bars[$barCount]->set_on_click($onClickFunName);
+ // }
+
+ //// get the currency to set in tooltip.
+ //$tooltip = CRM_Utils_Array::value('tip', $params, "$symbol #val#");
+
+ return $output;
+ }
+
+ /**
+ * @param $rows
+ * @param $chart
+ * @param $interval
+ *
+ * @return array
+ */
+ public static function chart($rows, $chart, $interval) {
+ $lcInterval = strtolower($interval);
+ $label = ucfirst($lcInterval);
+ $chartData = $dateKeys = [];
+ $intervalLabels = [
+ 'year' => ts('Yearly'),
+ 'fiscalyear' => ts('Yearly (Fiscal)'),
+ 'month' => ts('Monthly'),
+ 'quarter' => ts('Quarterly'),
+ 'week' => ts('Weekly'),
+ 'yearweek' => ts('Weekly'),
+ ];
+
+ switch ($lcInterval) {
+ case 'month':
+ case 'quarter':
+ case 'week':
+ case 'yearweek':
+ foreach ($rows['receive_date'] as $key => $val) {
+ list($year, $month) = explode('-', $val);
+ $dateKeys[] = substr($rows[$interval][$key], 0, 3) . ' of ' . $year;
+ }
+ $legend = $intervalLabels[$lcInterval];
+ break;
+
+ default:
+ foreach ($rows['receive_date'] as $key => $val) {
+ list($year, $month) = explode('-', $val);
+ $dateKeys[] = $year;
+ }
+ $legend = ts("%1", [1 => $label]);
+ if (!empty($intervalLabels[$lcInterval])) {
+ $legend = $intervalLabels[$lcInterval];
+ }
+ break;
+ }
+
+ if (!empty($dateKeys)) {
+ $graph = [];
+ if (!array_key_exists('multiValue', $rows)) {
+ $rows['multiValue'] = [$rows['value']];
+ }
+ foreach ($rows['multiValue'] as $key => $val) {
+ $graph[$key] = array_combine($dateKeys, $rows['multiValue'][$key]);
+ }
+ $chartData = [
+ 'legend' => "$legend " . CRM_Utils_Array::value('legend', $rows, ts('Contribution')) . ' ' . ts('Summary'),
+ 'values' => $graph[0],
+ 'multiValues' => $graph,
+ 'barKeys' => CRM_Utils_Array::value('barKeys', $rows, []),
+ ];
+ }
+
+ // rotate the x labels.
+ $chartData['xLabelAngle'] = CRM_Utils_Array::value('xLabelAngle', $rows, 0);
+ if (!empty($rows['tip'])) {
+ $chartData['tip'] = $rows['tip'];
+ }
+
+ // legend
+ $chartData['xname'] = CRM_Utils_Array::value('xname', $rows);
+ $chartData['yname'] = CRM_Utils_Array::value('yname', $rows);
+
+ // carry some chart params if pass.
+ foreach ([
+ 'xSize',
+ 'ySize',
+ 'divName',
+ ] as $f) {
+ if (!empty($rows[$f])) {
+ $chartData[$f] = $rows[$f];
+ }
+ }
+
+ return self::buildChart($chartData, $chart);
+ }
+
+ /**
+ * @param $rows
+ * @param $chart
+ * @param $interval
+ * @param $chartInfo
+ *
+ * @return array
+ */
+ public static function reportChart($rows, $chart, $interval, &$chartInfo) {
+ foreach ($interval as $key => $val) {
+ $graph[$val] = $rows['value'][$key];
+ }
+
+ $chartData = [
+ 'values' => $graph,
+ 'legend' => $chartInfo['legend'],
+ 'xname' => $chartInfo['xname'],
+ 'yname' => $chartInfo['yname'],
+ ];
+
+ // rotate the x labels.
+ $chartData['xLabelAngle'] = CRM_Utils_Array::value('xLabelAngle', $chartInfo, 20);
+ if (!empty($chartInfo['tip'])) {
+ $chartData['tip'] = $chartInfo['tip'];
+ }
+
+ // carry some chart params if pass.
+ foreach ([
+ 'xSize',
+ 'ySize',
+ 'divName',
+ ] as $f) {
+ if (!empty($rows[$f])) {
+ $chartData[$f] = $rows[$f];
+ }
+ }
+
+ return self::buildChart($chartData, $chart);
+ }
+
+ /**
+ * @param array $params
+ * @param $chart
+ *
+ * @return array
+ */
+ public static function buildChart(&$params, $chart) {
+ $theChart = [];
+ if ($chart && is_array($params) && !empty($params)) {
+ // build the chart objects.
+ $chartObj = CRM_Utils_Chart::$chart($params);
+
+ if ($chartObj) {
+ // calculate chart size.
+ $xSize = CRM_Utils_Array::value('xSize', $params, 400);
+ $ySize = CRM_Utils_Array::value('ySize', $params, 300);
+ if ($chart == 'barChart') {
+ $ySize = CRM_Utils_Array::value('ySize', $params, 250);
+ $xSize = 60 * count($params['values']);
+ // hack to show tooltip.
+ if ($xSize < 200) {
+ $xSize = (count($params['values']) > 1) ? 100 * count($params['values']) : 170;
+ }
+ elseif ($xSize > 600 && count($params['values']) > 1) {
+ $xSize = (count($params['values']) + 400 / count($params['values'])) * count($params['values']);
+ }
+ }
+
+ // generate unique id for this chart instance
+ $uniqueId = md5(uniqid(rand(), TRUE));
+
+ $theChart["chart_{$uniqueId}"]['size'] = ['xSize' => $xSize, 'ySize' => $ySize];
+ $theChart["chart_{$uniqueId}"]['object'] = $chartObj;
+
+ // assign chart data to template
+ $template = CRM_Core_Smarty::singleton();
+ $template->assign('uniqueId', $uniqueId);
+ $template->assign("chartData", json_encode($theChart ?? []));
+ }
+ }
+
+ return $theChart;
+ }
+
+}
* @throws \Civi\API\Exception\UnauthorizedException
*/
public function isDisabled($method) {
-
- $checks = $this->getChecksConfig();
- if (!empty($checks[$method])) {
- return (bool) empty($checks[$method]['is_active']);
+ try {
+ $checks = $this->getChecksConfig();
+ if (!empty($checks[$method])) {
+ return (bool) empty($checks[$method]['is_active']);
+ }
}
+ catch (PEAR_Exception $e) {
+ // if we're hitting this, DB migration to 5.19 probably hasn't run yet, so
+ // is_active doesn't exist. Ignore this error so the status check (which
+ // might warn about missing migrations!) still renders.
+ // TODO: remove at some point after 5.19
+ }
+
return FALSE;
}
$params['activity_date_time'] = $result['date'];
$params['details'] = $result['body'];
- for ($i = 1; $i <= 5; $i++) {
+ $numAttachments = Civi::settings()->get('max_attachments_backend') ?? CRM_Core_BAO_File::DEFAULT_MAX_ATTACHMENTS_BACKEND;
+ for ($i = 1; $i <= $numAttachments; $i++) {
if (isset($result["attachFile_$i"])) {
$params["attachFile_$i"] = $result["attachFile_$i"];
}
+ else {
+ // No point looping 100 times if there's only one attachment
+ break;
+ }
}
return $params;
return $event->getReturnValues();
}
else {
+ // We need to ensure tht we will still run known bootstrap related hooks even if the container is not booted.
+ $prebootContainerHooks = array_merge($upgradeFriendlyHooks, ['civicrm_entityTypes', 'civicrm_config']);
+ if (!\Civi\Core\Container::isContainerBooted() && !in_array($fnSuffix, $prebootContainerHooks)) {
+ return;
+ }
$count = is_array($names) ? count($names) : $names;
return $this->invokeViaUF($count, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $fnSuffix);
}
+++ /dev/null
-<?php
-/*
- +--------------------------------------------------------------------+
- | CiviCRM version 5 |
- +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2019 |
- +--------------------------------------------------------------------+
- | This file is a part of CiviCRM. |
- | |
- | CiviCRM is free software; you can copy, modify, and distribute it |
- | under the terms of the GNU Affero General Public License |
- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
- | |
- | CiviCRM is distributed in the hope that it will be useful, but |
- | WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
- | See the GNU Affero General Public License for more details. |
- | |
- | You should have received a copy of the GNU Affero General Public |
- | License and the CiviCRM Licensing Exception along |
- | with this program; if not, contact CiviCRM LLC |
- | at info[AT]civicrm[DOT]org. If you have questions about the |
- | GNU Affero General Public License or the licensing of CiviCRM, |
- | see the CiviCRM license FAQ at http://civicrm.org/licensing |
- +--------------------------------------------------------------------+
- */
-
-/**
- *
- * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2019
- */
-
-require_once 'packages/OpenFlashChart/php-ofc-library/open-flash-chart.php';
-
-/**
- * Build various graphs using Open Flash Chart library.
- */
-class CRM_Utils_OpenFlashChart {
-
- /**
- * Colours.
- * @var array
- */
- private static $_colours = [
- "#C3CC38",
- "#C8B935",
- "#CEA632",
- "#D3932F",
- "#D9802C",
- "#FA6900",
- "#DC9B57",
- "#F78F01",
- "#5AB56E",
- "#6F8069",
- "#C92200",
- "#EB6C5C",
- ];
-
- /**
- * Build The Bar Gharph.
- *
- * @param array $params
- * Assoc array of name/value pairs.
- *
- * @return object
- * $chart object of open flash chart.
- */
- public static function &barChart(&$params) {
- $chart = NULL;
- if (empty($params)) {
- return $chart;
- }
- if (empty($params['multiValues'])) {
- $params['multiValues'] = [$params['values']];
- }
-
- $values = CRM_Utils_Array::value('multiValues', $params);
- if (!is_array($values) || empty($values)) {
- return $chart;
- }
-
- // get the required data.
- $chartTitle = !empty($params['legend']) ? $params['legend'] : ts('Bar Chart');
-
- $xValues = $yValues = [];
- $xValues = array_keys($values[0]);
- $yValues = array_values($values[0]);
-
- // set y axis parameters.
- $yMin = 0;
-
- // calculate max scale for graph.
- $yMax = ceil(max($yValues));
- if ($mod = $yMax % (str_pad(5, strlen($yMax) - 1, 0))) {
- $yMax += str_pad(5, strlen($yMax) - 1, 0) - $mod;
- }
- $ySteps = $yMax / 5;
-
- $bars = [];
- $symbol = CRM_Core_BAO_Country::defaultCurrencySymbol();
- foreach ($values as $barCount => $barVal) {
- $bars[$barCount] = new bar_glass();
-
- $yValues = array_values($barVal);
- foreach ($yValues as &$yVal) {
- // type casting is required for chart to render values correctly
- $yVal = (double) $yVal;
- }
- $bars[$barCount]->set_values($yValues);
- if ($barCount > 0) {
- // FIXME: for bars > 2, we'll need to come out with other colors
- $bars[$barCount]->colour('#BF3B69');
- }
-
- if ($barKey = CRM_Utils_Array::value($barCount, CRM_Utils_Array::value('barKeys', $params))) {
- $bars[$barCount]->key($barKey, 12);
- }
-
- // call user define function to handle on click event.
- if ($onClickFunName = CRM_Utils_Array::value('on_click_fun_name', $params)) {
- $bars[$barCount]->set_on_click($onClickFunName);
- }
-
- // get the currency to set in tooltip.
- $tooltip = CRM_Utils_Array::value('tip', $params, "$symbol #val#");
- $bars[$barCount]->set_tooltip($tooltip);
- }
-
- // create x axis label obj.
- $xLabels = new x_axis_labels();
- // set_labels function requires xValues array of string or x_axis_label
- // so type casting array values to string values
- array_walk($xValues, function (&$value, $index) {
- $value = (string) $value;
- });
- $xLabels->set_labels($xValues);
-
- // set angle for labels.
- if ($xLabelAngle = CRM_Utils_Array::value('xLabelAngle', $params)) {
- $xLabels->rotate($xLabelAngle);
- }
-
- // create x axis obj.
- $xAxis = new x_axis();
- $xAxis->set_labels($xLabels);
-
- // create y axis and set range.
- $yAxis = new y_axis();
- $yAxis->set_range($yMin, $yMax, $ySteps);
-
- // create chart title obj.
- $title = new title($chartTitle);
-
- // create chart.
- $chart = new open_flash_chart();
-
- // add x axis w/ labels to chart.
- $chart->set_x_axis($xAxis);
-
- // add y axis values to chart.
- $chart->add_y_axis($yAxis);
-
- // set title to chart.
- $chart->set_title($title);
-
- // add bar element to chart.
- foreach ($bars as $bar) {
- $chart->add_element($bar);
- }
-
- // add x axis legend.
- if ($xName = CRM_Utils_Array::value('xname', $params)) {
- $xLegend = new x_legend($xName);
- $xLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
- $chart->set_x_legend($xLegend);
- }
-
- // add y axis legend.
- if ($yName = CRM_Utils_Array::value('yname', $params)) {
- $yLegend = new y_legend($yName);
- $yLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
- $chart->set_y_legend($yLegend);
- }
-
- return $chart;
- }
-
- /**
- * Build The Pie Gharph.
- *
- * @param array $params
- * Assoc array of name/value pairs.
- *
- * @return object
- * $chart object of open flash chart.
- */
- public static function &pieChart(&$params) {
- $chart = NULL;
- if (empty($params)) {
- return $chart;
- }
- $allValues = CRM_Utils_Array::value('values', $params);
- if (!is_array($allValues) || empty($allValues)) {
- return $chart;
- }
-
- // get the required data.
- $values = [];
- foreach ($allValues as $label => $value) {
- $values[] = new pie_value((double) $value, $label);
- }
- $graphTitle = !empty($params['legend']) ? $params['legend'] : ts('Pie Chart');
-
- // get the currency.
- $symbol = CRM_Core_BAO_Country::defaultCurrencySymbol();
-
- $pie = new pie();
- $pie->radius(100);
-
- // call user define function to handle on click event.
- if ($onClickFunName = CRM_Utils_Array::value('on_click_fun_name', $params)) {
- $pie->on_click($onClickFunName);
- }
-
- $pie->set_start_angle(35);
- $pie->add_animation(new pie_fade());
- $pie->add_animation(new pie_bounce(2));
-
- // set the tooltip.
- $tooltip = CRM_Utils_Array::value('tip', $params, "Amount is $symbol #val# of $symbol #total# <br>#percent#");
- $pie->set_tooltip($tooltip);
-
- // set colours.
- $pie->set_colours(self::$_colours);
-
- $pie->set_values($values);
-
- // create chart.
- $chart = new open_flash_chart();
-
- // create chart title obj.
- $title = new title($graphTitle);
- $chart->set_title($title);
-
- $chart->add_element($pie);
- $chart->x_axis = NULL;
-
- return $chart;
- }
-
- /**
- * Build The 3-D Bar Gharph.
- *
- * @param array $params
- * Assoc array of name/value pairs.
- *
- * @return object
- * $chart object of open flash chart.
- */
- public static function &bar_3dChart(&$params) {
- $chart = NULL;
- if (empty($params)) {
- return $chart;
- }
-
- // $params['values'] should contains the values for each
- // criteria defined in $params['criteria']
- $values = CRM_Utils_Array::value('values', $params);
- $criteria = CRM_Utils_Array::value('criteria', $params);
- if (!is_array($values) || empty($values) || !is_array($criteria) || empty($criteria)) {
- return $chart;
- }
-
- // get the required data.
- $xReferences = $xValueLabels = $xValues = $yValues = [];
-
- foreach ($values as $xVal => $yVal) {
- if (!is_array($yVal) || empty($yVal)) {
- continue;
- }
-
- $xValueLabels[] = (string) $xVal;
- foreach ($criteria as $criteria) {
- $xReferences[$criteria][$xVal] = (double) CRM_Utils_Array::value($criteria, $yVal, 0);
- $yValues[] = (double) CRM_Utils_Array::value($criteria, $yVal, 0);
- }
- }
-
- if (empty($xReferences)) {
-
- return $chart;
-
- }
-
- // get the currency.
- $symbol = CRM_Core_BAO_Country::defaultCurrencySymbol();
-
- // set the tooltip.
- $tooltip = CRM_Utils_Array::value('tip', $params, "$symbol #val#");
-
- $count = 0;
- foreach ($xReferences as $criteria => $values) {
- $toolTipVal = $tooltip;
- // for separate tooltip for each criteria
- if (is_array($tooltip)) {
- $toolTipVal = CRM_Utils_Array::value($criteria, $tooltip, "$symbol #val#");
- }
-
- // create bar_3d object
- $xValues[$count] = new bar_3d();
- // set colour pattel
- $xValues[$count]->set_colour(self::$_colours[$count]);
- // define colur pattel with bar criteria
- $xValues[$count]->key((string) $criteria, 12);
- // define bar chart values
- $xValues[$count]->set_values(array_values($values));
-
- // set tooltip
- $xValues[$count]->set_tooltip($toolTipVal);
- $count++;
- }
-
- $chartTitle = !empty($params['legend']) ? $params['legend'] : ts('Bar Chart');
-
- // set y axis parameters.
- $yMin = 0;
-
- // calculate max scale for graph.
- $yMax = ceil(max($yValues));
- if ($mod = $yMax % (str_pad(5, strlen($yMax) - 1, 0))) {
- $yMax += str_pad(5, strlen($yMax) - 1, 0) - $mod;
- }
-
- // if max value of y-axis <= 0, then set default values
- if ($yMax <= 0) {
- $ySteps = 1;
- $yMax = 5;
- }
- else {
- $ySteps = $yMax / 5;
- }
-
- // create x axis label obj.
- $xLabels = new x_axis_labels();
- $xLabels->set_labels($xValueLabels);
-
- // set angle for labels.
- if ($xLabelAngle = CRM_Utils_Array::value('xLabelAngle', $params)) {
- $xLabels->rotate($xLabelAngle);
- }
-
- // create x axis obj.
- $xAxis = new x_axis();
- $xAxis->set_labels($xLabels);
-
- // create y axis and set range.
- $yAxis = new y_axis();
- $yAxis->set_range($yMin, $yMax, $ySteps);
-
- // create chart title obj.
- $title = new title($chartTitle);
-
- // create chart.
- $chart = new open_flash_chart();
-
- // add x axis w/ labels to chart.
- $chart->set_x_axis($xAxis);
-
- // add y axis values to chart.
- $chart->add_y_axis($yAxis);
-
- // set title to chart.
- $chart->set_title($title);
-
- foreach ($xValues as $bar) {
- // add bar element to chart.
- $chart->add_element($bar);
- }
-
- // add x axis legend.
- if ($xName = CRM_Utils_Array::value('xname', $params)) {
- $xLegend = new x_legend($xName);
- $xLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
- $chart->set_x_legend($xLegend);
- }
-
- // add y axis legend.
- if ($yName = CRM_Utils_Array::value('yname', $params)) {
- $yLegend = new y_legend($yName);
- $yLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
- $chart->set_y_legend($yLegend);
- }
-
- return $chart;
- }
-
- /**
- * @param $rows
- * @param $chart
- * @param $interval
- *
- * @return array
- */
- public static function chart($rows, $chart, $interval) {
- $lcInterval = strtolower($interval);
- $label = ucfirst($lcInterval);
- $chartData = $dateKeys = [];
- $intervalLabels = [
- 'year' => ts('Yearly'),
- 'fiscalyear' => ts('Yearly (Fiscal)'),
- 'month' => ts('Monthly'),
- 'quarter' => ts('Quarterly'),
- 'week' => ts('Weekly'),
- 'yearweek' => ts('Weekly'),
- ];
-
- switch ($lcInterval) {
- case 'month':
- case 'quarter':
- case 'week':
- case 'yearweek':
- foreach ($rows['receive_date'] as $key => $val) {
- list($year, $month) = explode('-', $val);
- $dateKeys[] = substr($rows[$interval][$key], 0, 3) . ' of ' . $year;
- }
- $legend = $intervalLabels[$lcInterval];
- break;
-
- default:
- foreach ($rows['receive_date'] as $key => $val) {
- list($year, $month) = explode('-', $val);
- $dateKeys[] = $year;
- }
- $legend = ts("%1", [1 => $label]);
- if (!empty($intervalLabels[$lcInterval])) {
- $legend = $intervalLabels[$lcInterval];
- }
- break;
- }
-
- if (!empty($dateKeys)) {
- $graph = [];
- if (!array_key_exists('multiValue', $rows)) {
- $rows['multiValue'] = [$rows['value']];
- }
- foreach ($rows['multiValue'] as $key => $val) {
- $graph[$key] = array_combine($dateKeys, $rows['multiValue'][$key]);
- }
- $chartData = [
- 'legend' => "$legend " . CRM_Utils_Array::value('legend', $rows, ts('Contribution')) . ' ' . ts('Summary'),
- 'values' => $graph[0],
- 'multiValues' => $graph,
- 'barKeys' => CRM_Utils_Array::value('barKeys', $rows, []),
- ];
- }
-
- // rotate the x labels.
- $chartData['xLabelAngle'] = CRM_Utils_Array::value('xLabelAngle', $rows, 0);
- if (!empty($rows['tip'])) {
- $chartData['tip'] = $rows['tip'];
- }
-
- // legend
- $chartData['xname'] = CRM_Utils_Array::value('xname', $rows);
- $chartData['yname'] = CRM_Utils_Array::value('yname', $rows);
-
- // carry some chart params if pass.
- foreach ([
- 'xSize',
- 'ySize',
- 'divName',
- ] as $f) {
- if (!empty($rows[$f])) {
- $chartData[$f] = $rows[$f];
- }
- }
-
- return self::buildChart($chartData, $chart);
- }
-
- /**
- * @param $rows
- * @param $chart
- * @param $interval
- * @param $chartInfo
- *
- * @return array
- */
- public static function reportChart($rows, $chart, $interval, &$chartInfo) {
- foreach ($interval as $key => $val) {
- $graph[$val] = $rows['value'][$key];
- }
-
- $chartData = [
- 'values' => $graph,
- 'legend' => $chartInfo['legend'],
- 'xname' => $chartInfo['xname'],
- 'yname' => $chartInfo['yname'],
- ];
-
- // rotate the x labels.
- $chartData['xLabelAngle'] = CRM_Utils_Array::value('xLabelAngle', $chartInfo, 20);
- if (!empty($chartInfo['tip'])) {
- $chartData['tip'] = $chartInfo['tip'];
- }
-
- // carry some chart params if pass.
- foreach ([
- 'xSize',
- 'ySize',
- 'divName',
- ] as $f) {
- if (!empty($rows[$f])) {
- $chartData[$f] = $rows[$f];
- }
- }
-
- return self::buildChart($chartData, $chart);
- }
-
- /**
- * @param array $params
- * @param $chart
- *
- * @return array
- */
- public static function buildChart(&$params, $chart) {
- $openFlashChart = [];
- if ($chart && is_array($params) && !empty($params)) {
- // build the chart objects.
- $chartObj = CRM_Utils_OpenFlashChart::$chart($params);
-
- $openFlashChart = [];
- if ($chartObj) {
- // calculate chart size.
- $xSize = CRM_Utils_Array::value('xSize', $params, 400);
- $ySize = CRM_Utils_Array::value('ySize', $params, 300);
- if ($chart == 'barChart') {
- $ySize = CRM_Utils_Array::value('ySize', $params, 250);
- $xSize = 60 * count($params['values']);
- // hack to show tooltip.
- if ($xSize < 200) {
- $xSize = (count($params['values']) > 1) ? 100 * count($params['values']) : 170;
- }
- elseif ($xSize > 600 && count($params['values']) > 1) {
- $xSize = (count($params['values']) + 400 / count($params['values'])) * count($params['values']);
- }
- }
-
- // generate unique id for this chart instance
- $uniqueId = md5(uniqid(rand(), TRUE));
-
- $openFlashChart["chart_{$uniqueId}"]['size'] = ['xSize' => $xSize, 'ySize' => $ySize];
- $openFlashChart["chart_{$uniqueId}"]['object'] = $chartObj;
-
- // assign chart data to template
- $template = CRM_Core_Smarty::singleton();
- $template->assign('uniqueId', $uniqueId);
- $template->assign("openFlashChartData", json_encode($openFlashChart));
- }
- }
-
- return $openFlashChart;
- }
-
-}
if ($isTestField) {
$isTestField->setDefaultValue('0');
}
+
+ $isTemplateField = $spec->getFieldByName('is_template');
+ if ($isTemplateField) {
+ $isTemplateField->setDefaultValue('0');
+ }
}
/**
$scope.addRoleOnTheFly = function(roles, newType) {
roles.push({name: newType.label_b_a, displaylabel: newType.label_a_b});
// Assume that the case role should be A-B but add both directions as options.
- $scope.relationshipTypeOptions.push({id: newType.label_a_b, text: newType.label_a_b});
+ $scope.relationshipTypeOptions.push({id: newType.label_a_b, text: newType.label_b_a});
if (newType.label_a_b != newType.label_b_a) {
- $scope.relationshipTypeOptions.push({id: newType.label_b_a, text: newType.label_b_a});
+ $scope.relationshipTypeOptions.push({id: newType.label_b_a, text: newType.label_a_b});
}
};
* API result array.
*
* @throws \API_Exception
+ * @throws \CiviCRM_API3_Exception
*/
function civicrm_api3_loc_block_create($params) {
$entities = [];
];
$params['amount'] = [
'api.required' => TRUE,
- 'title' => ts('Amount to refund'),
+ 'title' => ts('Amount to pay'),
'type' => CRM_Utils_Type::T_MONEY,
];
}
mailerJobsMax
maxFileSize
max_attachments
+max_attachments_backend
replyTo
secondDegRelPermissions
securityAlert
*/
function contribution_create_example() {
$params = [
- 'contact_id' => 31,
+ 'contact_id' => 32,
'receive_date' => '20120511',
'total_amount' => '100',
'financial_type_id' => 1,
'net_amount' => '95',
'source' => 'SSF',
'contribution_status_id' => 1,
- 'honor_contact_id' => 32,
+ 'honor_contact_id' => 33,
];
try{
'values' => [
'1' => [
'id' => '1',
- 'contact_id' => '31',
+ 'contact_id' => '32',
'financial_type_id' => '1',
'contribution_page_id' => '',
'payment_instrument_id' => '4',
'creditnote_id' => '',
'tax_amount' => '',
'revenue_recognition_date' => '',
+ 'is_template' => '',
'contribution_type_id' => '1',
],
],
*/
function contribution_create_example() {
$params = [
- 'contact_id' => 25,
+ 'contact_id' => 26,
'receive_date' => '2012-01-01',
'total_amount' => '100',
'financial_type_id' => 1,
'values' => [
'1' => [
'id' => '1',
- 'contact_id' => '25',
+ 'contact_id' => '26',
'financial_type_id' => '1',
'contribution_page_id' => '',
'payment_instrument_id' => '1',
'creditnote_id' => '',
'tax_amount' => '',
'revenue_recognition_date' => '',
+ 'is_template' => '',
'contribution_type_id' => '1',
],
],
*/
function contribution_create_example() {
$params = [
- 'contact_id' => 27,
+ 'contact_id' => 28,
'receive_date' => '20120511',
'total_amount' => '100',
'financial_type_id' => 1,
'contribution_status_id' => 1,
'soft_credit' => [
'1' => [
- 'contact_id' => 28,
+ 'contact_id' => 29,
'amount' => 50,
'soft_credit_type_id' => 3,
],
'values' => [
'1' => [
'id' => '1',
- 'contact_id' => '27',
+ 'contact_id' => '28',
'financial_type_id' => '1',
'contribution_page_id' => '',
'payment_instrument_id' => '4',
'creditnote_id' => '',
'tax_amount' => '',
'revenue_recognition_date' => '',
+ 'is_template' => '',
'contribution_type_id' => '1',
],
],
*/
function contribution_create_example() {
$params = [
- 'contact_id' => 29,
+ 'contact_id' => 30,
'receive_date' => '20120511',
'total_amount' => '100',
'financial_type_id' => 1,
'net_amount' => '95',
'source' => 'SSF',
'contribution_status_id' => 1,
- 'soft_credit_to' => 30,
+ 'soft_credit_to' => 31,
];
try{
'values' => [
'1' => [
'id' => '1',
- 'contact_id' => '29',
+ 'contact_id' => '30',
'financial_type_id' => '1',
'contribution_page_id' => '',
'payment_instrument_id' => '4',
'creditnote_id' => '',
'tax_amount' => '',
'revenue_recognition_date' => '',
+ 'is_template' => '',
'contribution_type_id' => '1',
],
],
'creditnote_id' => '',
'tax_amount' => '',
'revenue_recognition_date' => '',
+ 'is_template' => '',
'contribution_type_id' => '1',
],
],
*/
function contribution_create_example() {
$params = [
- 'contact_id' => 12,
+ 'contact_id' => 13,
'receive_date' => '20120511',
'total_amount' => '100',
'financial_type_id' => 1,
'values' => [
'1' => [
'id' => '1',
- 'contact_id' => '12',
+ 'contact_id' => '13',
'financial_type_id' => '1',
'contribution_page_id' => '',
'payment_instrument_id' => '1',
'creditnote_id' => '',
'tax_amount' => 0,
'revenue_recognition_date' => '',
+ 'is_template' => '',
'contribution_type_id' => '1',
'api.line_item.create' => [
'0' => [
- github : wmortada
name : William Mortada
- organization: Community IT Academy
+ organization: a-n The Artists Information Company
jira : wmortada
- name : Philipp Michael
/* Set/alter ICONS */
-#crm-container div#printer-friendly {
- float: right;
- position: relative;
- margin: -2em 0.5em 0 0;
-}
-/* For Joomla, margin 0 works correctly */
-#crm-container table#crm-content div#printer-friendly {
- margin: 0;
-}
-
#crm-container .order-icon {
height: 15px;
width: 10px;
.crm-container.crm-public .select2-results {
font-size: 14px;
}
+.crm-container.crm-public .select2-container * {
+ box-sizing: content-box;
+}
.crm-container.crm-public .select2-container .select2-choice {
padding: 5px 5px 5px 8px;
- height: 35px;
}
.crm-container.crm-public .select2-container-multi .select2-choices {
padding: 4px;
* https://github.com/civicrm/civicrm-joomla
* https://github.com/civicrm/civicrm-wordpress
+## CiviCRM 5.18.2
+
+Released October 9, 2019
+
+- **[Synopsis](release-notes/5.18.2.md#synopsis)**
+- **[Bugs resolved](release-notes/5.18.2.md#bugs)**
+- **[Credits](release-notes/5.18.2.md#credits)**
+- **[Feedback](release-notes/5.18.2.md#feedback)**
+
+
## CiviCRM 5.18.1
Released October 5, 2019
--- /dev/null
+# CiviCRM 5.18.2
+
+Released October 9, 2019
+
+- **[Synopsis](#synopsis)**
+- **[Bugs resolved](#bugs)**
+- **[Credits](#credits)**
+- **[Feedback](#feedback)**
+
+## <a name="synopsis"></a>Synopsis
+
+| *Does this version...?* | |
+|:--------------------------------------------------------------- |:-------:|
+| Fix security vulnerabilities? | no |
+| Change the database schema? | no |
+| Alter the API? | no |
+| Require attention to configuration options? | no |
+| Fix problems installing or upgrading to a previous version? | no |
+| Introduce features? | no |
+| **Fix bugs?** | **yes** |
+
+## <a name="bugs"></a>Bugs resolved
+
+* **_PDFLetter_: Fix a warning on the "Print/Merge Document" screen ([dev/core#1281](https://lab.civicrm.org/dev/core/issues/1281): [#15420](https://github.com/civicrm/civicrm-core/pull/15420))**
+* **_Export_: Wrong export list when selecting contact and also when using option "Exclude contacts with "do not mail" (et al)" ([dev/core#1293](https://lab.civicrm.org/dev/core/issues/1293): [#15439](https://github.com/civicrm/civicrm-core/pull/15439))**
+* **_Export_: Ensure that an export file is always generated - even if dataset is empty" ([dev/core#1293](https://lab.civicrm.org/dev/core/issues/1293): [#15440](https://github.com/civicrm/civicrm-core/pull/15440))**
+* **_Import_: Fix value-matching when using certain numerical identifiers ([dev/core#1285](https://lab.civicrm.org/dev/core/issues/1285): [#15453](https://github.com/civicrm/civicrm-core/pull/15453))**
+* **_Import_: "Contribution" import with custom fields may fail due to an underfined index ([dev/core#1269](https://lab.civicrm.org/dev/core/issues/1269): [#15447](https://github.com/civicrm/civicrm-core/pull/15447))**
+* **_Profiles_: Fix sorting by custom fields when using profile search results ([dev/core#1305](https://lab.civicrm.org/dev/core/issues/1305): [#15454](https://github.com/civicrm/civicrm-core/pull/15454))**
+
+
+## <a name="credits"></a>Credits
+
+This release was developed by the following authors and reviewers:
+
+Wikimedia Foundation - Eileen McNaughton; skherraz; tapash;
+Dave D; Australian Greens - Seamus Lee
+
+## <a name="feedback"></a>Feedback
+
+These release notes are edited by Tim Otten and Andrew Hunt. If you'd like to
+provide feedback on them, please login to https://chat.civicrm.org/civicrm and
+contact `@agh1`.
'title' => ts('Maximum Attachments'),
'is_domain' => 1,
'is_contact' => 0,
- 'description' => ts('Maximum number of files (documents, images, etc.) which can be attached to emails or activities.'),
+ 'description' => ts('Maximum number of files (documents, images, etc.) which can be attached to emails or activities. This setting applies to UI forms and limits the number of fields available on the form.'),
+ 'help_text' => NULL,
+ ],
+ 'max_attachments_backend' => [
+ 'group_name' => 'CiviCRM Preferences',
+ 'group' => 'core',
+ 'name' => 'max_attachments_backend',
+ 'legacy_key' => 'maxAttachmentsBackend',
+ 'type' => 'Integer',
+ 'quick_form_type' => 'Element',
+ 'html_type' => 'text',
+ 'html_attributes' => [
+ 'size' => 2,
+ 'maxlength' => 8,
+ ],
+ 'default' => CRM_Core_BAO_File::DEFAULT_MAX_ATTACHMENTS_BACKEND,
+ 'add' => '5.20',
+ 'title' => ts('Maximum Attachments For Backend Processes'),
+ 'is_domain' => 1,
+ 'is_contact' => 0,
+ 'description' => ts('Maximum number of files (documents, images, etc.) which can be processed during backend processing such as automated inbound email processing. This should be a big number higher than the other Maximum Attachments setting above. This setting here merely provides an upper limit to prevent attacks that might overload the server.'),
'help_text' => NULL,
],
'maxFileSize' => [
$group->visibility = 'Public Pages';
$group->is_active = 1;
$group->save();
- $group->buildClause();
- $group->save();
}
// 60 are for newsletter
$group->visibility = 'Public Pages';
$group->is_active = 1;
$group->save();
- $group->buildClause();
- $group->save();
}
// 60 are for newsletter
LOCK TABLES `civicrm_domain` WRITE;
/*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */;
-INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.19.alpha1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
+INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.20.alpha1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
/*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
UNLOCK TABLES;
<tr class="columnheader">
<td colspan="2">{ts}Sending Emails (includes contribution receipts and event confirmations){/ts}</td>
</tr>
- <tr class="even">
- <td class="tasklist nowrap"><a href="{crmURL p="civicrm/admin/setting/smtp" q="reset=1&civicrmDestination=`$destination`"}" title="{$linkTitle|escape}">{ts}Outbound Email{/ts}</a></td>
- <td>{ts}Settings for outbound email - either SMTP server, port and authentication or Sendmail path and argument.{/ts}</td>
- </tr>
<tr class="even">
<td class="tasklist nowrap"><a href="{crmURL p="civicrm/admin/options/from_email_address" q="reset=1&civicrmDestination=`$destination`"}" title="{$linkTitle|escape}">{ts}From Email Addresses{/ts}</a></td>
<td>{ts}Define general email address(es) that can be used as the FROM address when sending email to contacts from within CiviCRM (e.g. info@example.org){/ts}</td>
</tr>
+ <tr class="even">
+ <td class="tasklist nowrap"><a href="{crmURL p="civicrm/admin/setting/smtp" q="reset=1&civicrmDestination=`$destination`"}" title="{$linkTitle|escape}">{ts}Outbound Email{/ts}</a></td>
+ <td>{ts}Settings for outbound email - either SMTP server, port and authentication or Sendmail path and argument.{/ts}</td>
+ </tr>
<tr class="columnheader">
<td colspan="2">{ts}Online Contributions / Online Membership Signup / Online Event Registration{/ts}</td>
+--------------------------------------------------------------------+
*}
{include file="CRM/common/dashboard.tpl"}
-{include file="CRM/common/openFlashChart.tpl"}
+{include file="CRM/common/chart.tpl"}
{* Alerts for critical configuration settings. *}
{$communityMessages}
<div class="crm-submit-buttons crm-dashboard-controls">
{* Display monthly and yearly contributions using Google charts (Bar and Pie) *}
{if $hasContributions}
<div id="chartData">
-<table class="chart">
- <tr class="crm-contribution-form-block-open_flash_chart">
- <td>
+<table >
+ <tr class="crm-contribution-form-block-chart">
+ <td width="50%">
{if $hasByMonthChart}
{* display monthly chart *}
- <div id="open_flash_chart_by_month"></div>
+ <div id="chart_by_month"></div>
{else}
{ts}There were no contributions during the selected year.{/ts}
{/if}
</td>
- <td>
+ <td width="50%">
{* display yearly chart *}
- <div id="open_flash_chart_by_year"></div>
+ <div id="chart_by_year"></div>
</td>
</tr>
</table>
</div>
{/if}
-{if $hasOpenFlashChart}
-{include file="CRM/common/openFlashChart.tpl" contriChart=true}
+{if $hasChart}
+{include file="CRM/common/chart.tpl" contriChart=true}
{literal}
<script type="text/javascript">
CRM.$(function($) {
- var chartData = {/literal}{$openFlashChartData}{literal};
- $.each(chartData, function(chartID, chartValues) {
- createSWFObject(chartID, chartValues.divName, chartValues.size.xSize, chartValues.size.ySize, 'loadData');
- });
- });
+ var allData = {/literal}{$chartData}{literal};
- function loadData( chartID ) {
- var allData = {/literal}{$openFlashChartData}{literal};
- return JSON.stringify(allData[chartID].object);
- }
+ $.each( allData, function( chartID, chartValues ) {
+ var divName = "chart_" + chartID;
+ createChart( chartID, divName, 300, 300, allData[chartID].object );
+ });
- function byMonthOnClick( barIndex ) {
- var allData = {/literal}{$openFlashChartData}{literal};
- var url = eval( "allData.by_month.on_click_urls.url_" + barIndex );
- if ( url ) window.location.href = url;
- }
+ function byMonthOnClick( barIndex ) {
+ var url = allData.by_month.on_click_urls['url_' + barIndex];
+ if ( url ) window.location.href = url;
+ }
- function byYearOnClick( barIndex ) {
- var allData = {/literal}{$openFlashChartData}{literal};
- var url = eval( "allData.by_year.on_click_urls.url_" + barIndex );
- if ( url ) window.location.href = url;
- }
+ function byYearOnClick( barIndex ) {
+ var url = allData.by_year.on_click_urls['url_' + barIndex];
+ if ( url ) window.location.href = url;
+ }
- </script>
+ });
+</script>
{/literal}
{/if}
<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
<table class="form-layout-compressed">
<tr class="crm-contribution-contributionpage-settings-form-block-title"><td class="label">{$form.title.label} {if $action == 2}{include file='CRM/Core/I18n/Dialog.tpl' table='civicrm_contribution_page' field='title' id=$contributionPageID}{/if}</td><td>{$form.title.html}<br/>
+ <span class="description">{ts}This title will be displayed at the top of the page unless the frontend title field is filled out.<br />Please use only alphanumeric, spaces, hyphens and dashes for Title.{/ts}</td>
+ </tr>
+ <tr class="crm-contribution-contributionpage-settings-form-block-frontend-title"><td class="label">{$form.contribution_page_frontend_title.label} {if $action == 2}{include file='CRM/Core/I18n/Dialog.tpl' table='civicrm_contribution_page' field='frontend_title' id=$contributionPageID}{/if}</td><td>{$form.contribution_page_frontend_title.html}<br/>
<span class="description">{ts}This title will be displayed at the top of the page.<br />Please use only alphanumeric, spaces, hyphens and dashes for Title.{/ts}</td>
</tr>
<tr class="crm-contribution-contributionpage-settings-form-block-financial_type_id"><td class="label">{$form.financial_type_id.label}</td><td>{$form.financial_type_id.html}<br />
</div>
{else}
<table class="form-layout-compressed">
- {if $context eq 'standalone'}
<tr class="crm-pledge-form-contact-id">
<td class="label">{$form.contact_id.label}</td>
<td>{$form.contact_id.html}</td>
</tr>
- {else}
- <tr class="crm-pledge-form-block-displayName">
- <td class="font-size12pt right"><strong>{ts}Pledge by{/ts}</strong></td>
- <td class="font-size12pt"><strong>{$displayName}</strong></td>
- </tr>
- {/if}
<tr class="crm-pledge-form-block-amount">
<td class="label">{$form.amount.label}</td>
<td>
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*}
-{assign var=uploadURL value=$config->imageUploadURL|replace:'/persist/contribute/':'/persist/'|cat:'openFlashChart/'}
+{assign var=uploadURL value=$config->imageUploadURL|replace:'/persist/contribute/':'/persist/'}
{* Display weekly,Quarterly,monthly and yearly contributions using pChart (Bar and Pie) *}
{if $chartEnabled and $chartSupported}
-<div class='crm-flashchart'>
-<table class="chart">
- <tr>
- <td>
- {if $outputMode eq 'print' OR $outputMode eq 'pdf'}
- <img src="{$uploadURL|cat:$chartId}.png" />
- {else}
- <div id="open_flash_chart_{$uniqueId}"></div>
- {/if}
- </td>
- </tr>
-</table>
-</div>
-
-{if !$printOnly} {* NO print section starts *}
-{if !$section}
- {include file="CRM/common/openFlashChart.tpl" divId="open_flash_chart_$uniqueId"}
+ <div class='crm-chart'>
+ {if $outputMode eq 'print' OR $outputMode eq 'pdf'}
+ <img src="{$uploadURL|cat:$chartId}.png" />
+ {else}
+ <div id="chart_{$uniqueId}"></div>
+ {/if}
+ </div>
{/if}
-{literal}
-<script type="text/javascript">
- CRM.$(function($) {
- buildChart( );
-
- $("input[id$='submit_print'],input[id$='submit_pdf']").bind('click', function(e){
- // image creator php file path and append image name
- var url = CRM.url('civicrm/report/chart', 'name=' + '{/literal}{$chartId}{literal}' + '.png');
+{if !$printOnly} {* NO print section starts *}
+ {if !$section}
+ {include file="CRM/common/chart.tpl" divId="chart_$uniqueId"}
+ {/if}
+ {if $chartData}
+ {literal}
+ <script type="text/javascript">
+ CRM.$(function($) {
+ // Build all charts.
+ var allData = {/literal}{$chartData}{literal};
- //fetch object and 'POST' image
- swfobject.getObjectById("open_flash_chart_{/literal}{$uniqueId}{literal}").post_image(url, true, false);
- });
+ $.each( allData, function( chartID, chartValues ) {
+ var divName = {/literal}"chart_{$uniqueId}"{literal};
+ createChart( chartID, divName, chartValues.size.xSize, chartValues.size.ySize, allData[chartID].object );
+ });
- function buildChart( ) {
- var chartData = {/literal}{$openFlashChartData}{literal};
- $.each( chartData, function( chartID, chartValues ) {
- var divName = {/literal}"open_flash_chart_{$uniqueId}"{literal};
- var loadDataFunction = {/literal}"loadData{$uniqueId}"{literal};
+ $("input[id$='submit_print'],input[id$='submit_pdf']").bind('click', function(e){
+ // image creator php file path and append image name
+ var url = CRM.url('civicrm/report/chart', 'name=' + '{/literal}{$chartId}{literal}' + '.png');
- createSWFObject( chartID, divName, chartValues.size.xSize, chartValues.size.ySize, loadDataFunction );
+ //fetch object and 'POST' image
+ swfobject.getObjectById("chart_{/literal}{$uniqueId}{literal}").post_image(url, true, false);
+ });
});
- }
- });
- function loadData{/literal}{$uniqueId}{literal}( chartID ) {
- var allData = {/literal}{$openFlashChartData}{literal};
- return JSON.stringify(allData[chartID].object);
- }
-</script>
-{/literal}
-{/if}
+ </script>
+ {/literal}
+ {/if}
{/if}
</div>
{/if}
-{if isset($browserPrint) and $browserPrint}
-{* Javascript window.print link. Used for public pages where we can't do printer-friendly view. *}
-<div id="printer-friendly">
-<a href="#" onclick="window.print(); return false;" title="{ts}Print this page.{/ts}">
- <i class="crm-i fa-print"></i>
-</a>
-</div>
-{else}
-{* Printer friendly link/icon. *}
-<div id="printer-friendly">
-<a href="{$printerFriendly}" target='_blank' title="{ts}Printer-friendly view of this page.{/ts}">
- <i class="crm-i fa-print"></i>
-</a>
-</div>
-{/if}
-
{if $pageTitle}
<div class="crm-title">
<h1 class="title">{if $isDeleted}<del>{/if}{$pageTitle}{if $isDeleted}</del>{/if}</h1>
--- /dev/null
+{*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2019 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*}
+<script src="{$config->resourceBase}/bower_components/d3/d3.min.js"></script>
+<script src="{$config->resourceBase}/bower_components/crossfilter2/crossfilter.min.js"></script>
+<script src="{$config->resourceBase}/bower_components/dc-2.1.x/dc.min.js"></script>
+<style src="{$config->resourceBase}/bower_components/dc-2.1.x/dc.min.css"></style>
+{literal}
+<style>
+ .dc-chart path.domain {
+ fill: none;
+ stroke: black;
+ }
+</style>
+<script type="text/javascript">
+function createChart( chartID, divName, xSize, ySize, data ) {
+
+ var div = document.getElementById(divName);
+ if (!div) {
+ console.log("no element found for chart id ", divName);
+ return;
+ }
+
+ // Figure out suitable size based on container size.
+ // In some cases the containing element has no size. We should insist on a minimum size.
+ var w = Math.max(Math.min(div.clientWidth - 32, 800), 316);
+ var h = Math.min(400, parseInt(w / 2));
+
+ var chartNode = document.createElement('div');
+ var heading = document.createElement('h2');
+ heading.textContent = data.title;
+ heading.style.marginBottom = '1rem';
+ heading.style.textAlign = 'center';
+ div.style.width = w + 'px';
+ div.style.marginLeft = 'auto';
+ div.style.marginRight = 'auto';
+
+ var links = document.createElement('div');
+ links.style.textAlign = 'center';
+ links.style.marginBottom = '1rem';
+ var linkSVG = document.createElement('a');
+ linkSVG.href = '#';
+ linkSVG.textContent = 'Download chart (SVG)';
+ linkSVG.addEventListener('click', e => {
+ e.preventDefault();
+ e.stopPropagation();
+ // Create an image.
+ var svg = div.querySelector('svg');
+ var xml = new XMLSerializer().serializeToString(svg);
+ var image64 = 'data:image/svg+xml;base64,' + btoa(xml);
+
+ downloadImageUrl('image/svg+xml', image64, data.title.replace(/[^a-zA-Z0-9-]+/g, '') + '.svg');
+ });
+ function downloadImageUrl(mime, url, filename) {
+ var downloadLink = document.createElement('a');
+ downloadLink.download = filename;
+ downloadLink.href = url;
+ downloadLink.downloadurl = [mime, downloadLink.download, url].join(':');
+ document.body.append(downloadLink);
+ downloadLink.click();
+ document.body.removeChild(downloadLink);
+ }
+ var linkPNG = document.createElement('a');
+ linkPNG.href = '#';
+ linkPNG.textContent = 'Download chart (PNG)';
+ linkPNG.addEventListener('click', e => {
+ e.preventDefault();
+ e.stopPropagation();
+ // Create an image.
+
+ var canvas = document.createElement('canvas');
+ canvas.width = w;
+ canvas.height = h;
+ div.appendChild(canvas);
+
+ var svg = div.querySelector('svg');
+ var xml = new XMLSerializer().serializeToString(svg);
+ var svg64 = btoa(xml);
+ var b64Start = 'data:image/svg+xml;base64,';
+ var image64 = b64Start + svg64;
+
+ var img = document.createElement('img');
+ img.onload = function() {
+ canvas.getContext('2d').drawImage(img, 0, 0);
+ // canvas.style.display = 'block';
+ var imgURL = canvas.toDataURL('image/png');
+ downloadImageUrl('image/png', imgURL, data.title.replace(/[^a-zA-Z0-9-]+/g, '') + '.png');
+ div.removeChild(canvas);
+ };
+ img.src = image64;
+ });
+
+ links.appendChild(linkSVG);
+ links.appendChild(document.createTextNode(' | '));
+ links.appendChild(linkPNG);
+
+ var crossfilterData, ndx, dataDimension, dataGroup, chart;
+ ndx = crossfilter(data.values[0]);
+ dataDimension = ndx.dimension(d => d.label);
+ dataGroup = dataDimension.group().reduceSum(d => d.value);
+ var ordinals = data.values[0].map(d => d.label);
+
+ if (data.type === 'barchart') {
+ chart = dc.barChart(chartNode)
+ .width(w)
+ .height(h)
+ .dimension(dataDimension)
+ .group(dataGroup)
+ .gap(4) // px
+ .x(d3.scale.ordinal(ordinals).domain(ordinals))
+ .xUnits(dc.units.ordinal)
+ .margins({top: 10, right: 30, bottom: 30, left: 90})
+ .elasticY(true)
+ .renderLabel(false)
+ .renderHorizontalGridLines(true)
+ .title(item=> item.key + ': ' + item.value)
+ //.turnOnControls(true)
+ .renderTitle(true);
+ }
+ else if (data.type === 'piechart') {
+ chart = dc.pieChart(chartNode)
+ .width(w)
+ .height(h)
+ .radius(parseInt(h / 2) - 5) // define pie radius
+ .innerRadius(parseInt(h / 4) - 5) // optional
+ .externalRadiusPadding(5)
+ .legend(dc.legend().legendText(d => d.name).y(5))
+ .dimension(dataDimension)
+ .group(dataGroup)
+ .renderLabel(false)
+ .title(item=> item.key + ': ' + item.value)
+ .turnOnControls(true)
+ .renderTitle(true);
+ }
+ // Delay rendering so that animation looks good.
+ window.setTimeout(() => {
+ div.appendChild(heading);
+ div.appendChild(chartNode);
+ div.appendChild(links);
+
+ dc.renderAll();
+ }, 1500);
+}
+</script>
+{/literal}
</div>
{/if}
-{if $browserPrint}
-{* Javascript window.print link. Used for public pages where we can't do printer-friendly view. *}
-<div id="printer-friendly"><a href="#" onclick="window.print(); return false;" title="{ts}Print this page.{/ts}"><i class="crm-i fa-print"></i></a></div>
-{else}
-{* Printer friendly link/icon. *}
-<div id="printer-friendly"><a href="{$printerFriendly}" target='_blank' title="{ts}Printer-friendly view of this page.{/ts}"><i class="crm-i fa-print"></i></a></div>
-{/if}
-
{if $pageTitle}
<div class="crm-title">
<h1 class="title">{if $isDeleted}<del>{/if}{$pageTitle}{if $isDeleted}</del>{/if}</h1>
+++ /dev/null
-{*
- +--------------------------------------------------------------------+
- | CiviCRM version 5 |
- +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2019 |
- +--------------------------------------------------------------------+
- | This file is a part of CiviCRM. |
- | |
- | CiviCRM is free software; you can copy, modify, and distribute it |
- | under the terms of the GNU Affero General Public License |
- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
- | |
- | CiviCRM is distributed in the hope that it will be useful, but |
- | WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
- | See the GNU Affero General Public License for more details. |
- | |
- | You should have received a copy of the GNU Affero General Public |
- | License and the CiviCRM Licensing Exception along |
- | with this program; if not, contact CiviCRM LLC |
- | at info[AT]civicrm[DOT]org. If you have questions about the |
- | GNU Affero General Public License or the licensing of CiviCRM, |
- | see the CiviCRM license FAQ at http://civicrm.org/licensing |
- +--------------------------------------------------------------------+
-*}
-<script type="text/javascript" src="{$config->resourceBase}packages/OpenFlashChart/js/json/openflashchart.packed.js"></script>
-<script type="text/javascript" src="{$config->resourceBase}packages/OpenFlashChart/js/swfobject.js"></script>
-{literal}
-<script type="text/javascript">
- function createSWFObject( chartID, divName, xSize, ySize, loadDataFunction ) {
- var flashFilePath = {/literal}"{$config->resourceBase}packages/OpenFlashChart/open-flash-chart.swf"{literal};
-
- //create object.
- swfobject.embedSWF( flashFilePath, divName,
- xSize, ySize, "9.0.0",
- "expressInstall.swf",
- {"get-data":loadDataFunction, "id":chartID},
- null,
- {"wmode": 'transparent'}
- );
- }
- OFC = {};
- OFC.jquery = {
- name: "jQuery",
- image: function(src) { return "<img src='data:image/png;base64," + $('#'+src)[0].get_img_binary() + "' />"},
- popup: function(src) {
- var img_win = window.open('', 'Save Chart as Image');
- // HTML, HEAD, and BODY tags in JS literals obfuscated to avoid being parsed as DOM elements.
- var html = 'html', head = 'head', body = 'body';
- img_win.document.write('<' + html + '><' + head + '><title>Save Chart as Image<\/title><\/' + head + '><' + body + '>' + OFC.jquery.image(src) + ' <\/' + body + '><\/' + html + '>');
- img_win.document.close();
- }
- }
-
-function save_image( divName ) {
- var divId = {/literal}"{$contriChart}"{literal} ? 'open_flash_chart_'+divName : {/literal}"{$divId}"{literal};
- if( !divId ) {
- divId = 'open_flash_'+divName;
- }
- OFC.jquery.popup( divId );
-}
-
-</script>
-{/literal}
);
});
});
+
+ describe('when adding a role on-the-fly', function() {
+ beforeEach(inject(function ($controller) {
+ ctrl = $controller('CaseTypeCtrl', {$scope: scope, apiCalls: apiCalls});
+ }));
+
+ it('updates the case roles for unidirectional', function() {
+ // first simulate the ajax popup to create a new relationship type
+ var newType = {
+ "id": "33",
+ "name_a_b": "Some New Type is",
+ "label_a_b": "Some New Type is",
+ "name_b_a": "Some New Type for",
+ "label_b_a": "Some New Type for",
+ "description": "Some New Type",
+ "contact_type_a": "Individual",
+ "contact_type_b": "Individual",
+ "is_reserved": "0",
+ "is_active": "1"
+ };
+ apiCalls.relTypes.values.push(newType);
+
+ // now let the real code do what it does with the new type
+ scope.addRoleOnTheFly(scope.caseType.definition.caseRoles, newType);
+
+ expect(scope.caseType.definition.caseRoles).toEqual(
+ [
+ {
+ name: 'Homeless Services Coordinator',
+ creator: '1',
+ manager: '1',
+ displaylabel: 'Homeless Services Coordinator is'
+ },
+ {
+ name: 'Some New Type for',
+ displaylabel: 'Some New Type is'
+ }
+ ]
+ );
+
+ expect(scope.relationshipTypeOptions.slice(-2)).toEqual(
+ [
+ {
+ id: 'Some New Type is',
+ text: 'Some New Type for'
+ },
+ {
+ id: 'Some New Type for',
+ text: 'Some New Type is'
+ }
+ ]
+ );
+ });
+
+ it('updates the case roles for bidirectional', function() {
+ // first simulate the ajax popup to create a new relationship type
+ var newType = {
+ "id": "34",
+ "name_a_b": "Friend of",
+ "label_a_b": "Friend of",
+ "name_b_a": "Friend of",
+ "label_b_a": "Friend of",
+ "description": "Friend",
+ "contact_type_a": "Individual",
+ "contact_type_b": "Individual",
+ "is_reserved": "0",
+ "is_active": "1"
+ };
+ apiCalls.relTypes.values.push(newType);
+
+ // now let the real code do what it does with the new type
+ scope.addRoleOnTheFly(scope.caseType.definition.caseRoles, newType);
+
+ expect(scope.caseType.definition.caseRoles).toEqual(
+ [
+ {
+ name: 'Homeless Services Coordinator',
+ creator: '1',
+ manager: '1',
+ displaylabel: 'Homeless Services Coordinator is'
+ },
+ {
+ name: 'Friend of',
+ displaylabel: 'Friend of'
+ }
+ ]
+ );
+
+ expect(scope.relationshipTypeOptions.slice(-1)).toEqual(
+ [
+ {
+ id: 'Friend of',
+ text: 'Friend of'
+ }
+ ]
+ );
+
+ // Check that it did NOT add two entries for this bidirectional type
+ expect(scope.relationshipTypeOptions.slice(-2,-1)).not.toEqual(
+ [
+ {
+ id: 'Friend of',
+ text: 'Friend of'
+ }
+ ]
+ );
+ });
+ });
});
describe('crmAddName', function () {
}
/**
- * Test checking if contribution recurr object can allow for changes to financial types.
+ * Test checking if contribution recur object can allow for changes to financial types.
*
*/
public function testSupportFinancialTypeChange() {
$this->assertEquals('XAU', $dao->currency, 'Edit clobbered recur currency');
}
+ /**
+ * Check test contributions aren't picked up as template for non-test recurs
+ *
+ */
+ public function testGetTemplateContributionMatchTest1() {
+ $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', $this->_params);
+ // Create a first contrib
+ $firstContrib = $this->callAPISuccess('Contribution', 'create', [
+ 'contribution_recur_id' => $contributionRecur['id'],
+ 'total_amount' => '3.00',
+ 'financial_type_id' => 1,
+ 'payment_instrument_id' => 1,
+ 'currency' => 'USD',
+ 'contact_id' => $this->individualCreate(),
+ 'contribution_status_id' => 1,
+ 'receive_date' => 'yesterday',
+ ]);
+ // Create a test contrib - should not be picked up as template for non-test recur
+ $this->callAPISuccess('Contribution', 'create', [
+ 'contribution_recur_id' => $contributionRecur['id'],
+ 'total_amount' => '3.00',
+ 'financial_type_id' => 1,
+ 'payment_instrument_id' => 1,
+ 'currency' => 'USD',
+ 'contact_id' => $this->individualCreate(),
+ 'contribution_status_id' => 1,
+ 'receive_date' => 'yesterday',
+ 'is_test' => 1,
+ ]);
+ $fetchedTemplate = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution($contributionRecur['id']);
+ $this->assertEquals($firstContrib['id'], $fetchedTemplate['id']);
+ }
+
+ /**
+ * Check non-test contributions aren't picked up as template for test recurs
+ *
+ */
+ public function testGetTemplateContributionMatchTest() {
+ $params = $this->_params;
+ $params['is_test'] = 1;
+ $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', $params);
+ // Create a first test contrib
+ $firstContrib = $this->callAPISuccess('Contribution', 'create', [
+ 'contribution_recur_id' => $contributionRecur['id'],
+ 'total_amount' => '3.00',
+ 'financial_type_id' => 1,
+ 'payment_instrument_id' => 1,
+ 'currency' => 'USD',
+ 'contact_id' => $this->individualCreate(),
+ 'contribution_status_id' => 1,
+ 'receive_date' => 'yesterday',
+ 'is_test' => 1,
+ ]);
+ // Create a non-test contrib - should not be picked up as template for non-test recur
+ // This shouldn't occur - a live contrib against a test recur, but that's not the point...
+ $this->callAPISuccess('Contribution', 'create', [
+ 'contribution_recur_id' => $contributionRecur['id'],
+ 'total_amount' => '3.00',
+ 'financial_type_id' => 1,
+ 'payment_instrument_id' => 1,
+ 'currency' => 'USD',
+ 'contact_id' => $this->individualCreate(),
+ 'contribution_status_id' => 1,
+ 'receive_date' => 'yesterday',
+ 'is_test' => 0,
+ ]);
+ $fetchedTemplate = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution($contributionRecur['id']);
+ $this->assertEquals($firstContrib['id'], $fetchedTemplate['id']);
+ }
+
+ /**
+ * Test that is_template contribution is used where available
+ *
+ */
+ public function testGetTemplateContributionNewTemplate() {
+ $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', $this->_params);
+ // Create the template
+ $templateContrib = $this->callAPISuccess('Contribution', 'create', [
+ 'contribution_recur_id' => $contributionRecur['id'],
+ 'total_amount' => '3.00',
+ 'financial_type_id' => 1,
+ 'payment_instrument_id' => 1,
+ 'currency' => 'USD',
+ 'contact_id' => $this->individualCreate(),
+ 'contribution_status_id' => 1,
+ 'receive_date' => 'yesterday',
+ 'is_template' => 1,
+ ]);
+ // Create another normal contrib
+ $this->callAPISuccess('Contribution', 'create', [
+ 'contribution_recur_id' => $contributionRecur['id'],
+ 'total_amount' => '3.00',
+ 'financial_type_id' => 1,
+ 'payment_instrument_id' => 1,
+ 'currency' => 'USD',
+ 'contact_id' => $this->individualCreate(),
+ 'contribution_status_id' => 1,
+ 'receive_date' => 'yesterday',
+ ]);
+ $fetchedTemplate = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution($contributionRecur['id']);
+ // Fetched template should be the is_template, not the latest contrib
+ $this->assertEquals($fetchedTemplate['id'], $templateContrib['id']);
+ }
+
}
$values['contribution_status_id'] = 'just say no';
$this->runImport($values, CRM_Import_Parser::DUPLICATE_UPDATE, CRM_Import_Parser::ERROR);
$this->callAPISuccessGetCount('Contribution', ['contact_id' => $contactID], 2);
+
+ // Per https://lab.civicrm.org/dev/core/issues/1285 it's a bit arguable but Ok we can support id...
+ $values['contribution_status_id'] = 3;
+ $this->runImport($values, CRM_Import_Parser::DUPLICATE_UPDATE, NULL);
+ $this->callAPISuccessGetCount('Contribution', ['contact_id' => $contactID, 'contribution_status_id' => 3], 1);
+
}
/**
}
/**
- * Test getPartialPaymentWithType function.
+ * Test testGetContributionBalance function.
*/
- public function testGetPartialPaymentWithType() {
+ public function testGetContributionBalance() {
//create the contribution that isn't paid yet
$contactId = $this->individualCreate();
$params = [
];
$this->callAPISuccess('Payment', 'create', $params);
//amount owed should be one cent
- $amountOwed = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($contribution['id'], 'contribution')['amount_owed'];
+ $amountOwed = CRM_Contribute_BAO_Contribution::getContributionBalance($contribution['id']);
$this->assertTrue(0.01 == $amountOwed, 'Amount does not match');
}
$params['contact_id'] = $contactId;
- $location = CRM_Core_BAO_Location::create($params);
-
- $locBlockId = CRM_Utils_Array::value('id', $location);
+ $locBlockId = CRM_Core_BAO_Location::create($params);
//Now check DB for contact
$searchParams = [
$compareParams = ['phone' => '9833910234'];
$this->assertDBCompareValues('CRM_Core_DAO_Phone', $searchParams, $compareParams);
- //delete the location block
- CRM_Core_BAO_Location::deleteLocBlock($locBlockId);
$this->contactDelete($contactId);
}
//create location block.
//with various element of location block
//like address, phone, email, im.
- $location = CRM_Core_BAO_Location::create($params, NULL, TRUE);
- $locBlockId = CRM_Utils_Array::value('id', $location);
+ $locBlockId = CRM_Core_BAO_Location::create($params, NULL, TRUE)['id'];
//update event record with location block id
$eventParams = [
$this->contactDelete($this->_contactId);
}
- /**
- * DeleteLocBlock() method
- * delete the location block
- * created with various elements.
- */
- public function testDeleteLocBlock() {
- $this->_contactId = $this->individualCreate();
- //create test event record.
- $event = $this->eventCreate();
- $params['location'][1] = [
- 'location_type_id' => 1,
- 'is_primary' => 1,
- 'address' => [
- 'street_address' => 'Saint Helier St',
- 'supplemental_address_1' => 'Hallmark Ct',
- 'supplemental_address_2' => 'Jersey Village',
- 'supplemental_address_3' => 'My Town',
- 'city' => 'Newark',
- 'postal_code' => '01903',
- 'country_id' => 1228,
- 'state_province_id' => 1029,
- 'geo_code_1' => '18.219023',
- 'geo_code_2' => '-105.00973',
- ],
- 'email' => [
- '1' => ['email' => 'john.smith@example.org'],
- ],
- 'phone' => [
- '1' => [
- 'phone_type_id' => 1,
- 'phone' => '303443689',
- ],
- '2' => [
- 'phone_type_id' => 2,
- 'phone' => '9833910234',
- ],
- ],
- 'im' => [
- '1' => [
- 'name' => 'jane.doe',
- 'provider_id' => 1,
- ],
- ],
- ];
- $params['entity_id'] = $event['id'];
- $params['entity_table'] = 'civicrm_event';
-
- //create location block.
- //with various elements
- //like address, phone, email, im.
- $location = CRM_Core_BAO_Location::create($params, NULL, TRUE);
- $locBlockId = CRM_Utils_Array::value('id', $location);
- //update event record with location block id
- $eventParams = [
- 'id' => $event['id'],
- 'loc_block_id' => $locBlockId,
- ];
- CRM_Event_BAO_Event::add($eventParams);
-
- //delete the location block
- CRM_Core_BAO_Location::deleteLocBlock($locBlockId);
-
- //Now check DB for location elements.
- //Now check DB for Address
- $this->assertDBNull('CRM_Core_DAO_Address', 'Saint Helier St', 'id', 'street_address',
- 'Database check, Address deleted successfully.'
- );
- //Now check DB for Email
- $this->assertDBNull('CRM_Core_DAO_Email', 'john.smith@example.org', 'id', 'email',
- 'Database check, Email deleted successfully.'
- );
- //Now check DB for Phone
- $this->assertDBNull('CRM_Core_DAO_Phone', '303443689', 'id', 'phone',
- 'Database check, Phone deleted successfully.'
- );
- //Now check DB for Mobile
- $this->assertDBNull('CRM_Core_DAO_Phone', '9833910234', 'id', 'phone',
- 'Database check, Mobile deleted successfully.'
- );
- //Now check DB for IM
- $this->assertDBNull('CRM_Core_DAO_IM', 'jane.doe', 'id', 'name',
- 'Database check, IM deleted successfully.'
- );
-
- //cleanup DB by deleting the record.
- $this->eventDelete($event['id']);
- $this->contactDelete($this->_contactId);
-
- //Now check DB for Event
- $this->assertDBNull('CRM_Event_DAO_Event', $event['id'], 'id', 'id',
- 'Database check, Event deleted successfully.'
- );
- }
-
/**
* GetValues() method
* get the values of various location elements
$this->assertEquals(CRM_Contact_BAO_Contact::getMasterDisplayName($this->masterAddressID), $row['Home-Master Address Belongs To']);
}
+ /**
+ * Test merging same address when specifying fields.
+ *
+ * @throws \CRM_Core_Exception
+ * @throws \League\Csv\Exception
+ */
+ public function testMergeSameAddressSpecifyFields() {
+ $this->setUpContactSameAddressExportData();
+ $this->doExportTest(['mergeSameAddress' => TRUE, 'fields' => [['contact_type' => 'Individual', 'name' => 'master_id', 'location_type_id' => 1]]]);
+ }
+
/**
* Test the merge same address option.
*
$this->assertCount(2, $this->csv);
}
+ /**
+ * Test exporting when no rows are retrieved.
+ *
+ * @throws \CRM_Core_Exception
+ * @throws \League\Csv\Exception
+ */
+ public function testExportNoRows() {
+ $contactA = $this->callAPISuccess('contact', 'create', [
+ 'first_name' => 'John',
+ 'last_name' => 'Doe',
+ 'contact_type' => 'Individual',
+ ]);
+ $this->doExportTest([
+ 'selectAll' => TRUE,
+ 'ids' => [$contactA['id']],
+ 'exportParams' => [
+ 'postal_mailing_export' => [
+ 'postal_mailing_export' => TRUE,
+ ],
+ 'mergeSameAddress' => TRUE,
+ ],
+ ]);
+ $this->assertEquals('Contact ID', $this->csv->getHeader()[0]);
+ }
+
/**
* Test that deceased and do not mail contacts are removed from contacts before
*
'contact_type' => 'Individual',
], $reason));
+ // Create another contact not included in the exporrt set.
+ $this->callAPISuccess('contact', 'create', array_merge([
+ 'first_name' => 'Janet',
+ 'last_name' => 'Doe',
+ 'contact_type' => 'Individual',
+ 'api.address.create' => ['supplemental_address_1' => 'An address'],
+ ], $reason));
+
+ // Create another contact not included in the exporrt set.
+ $this->callAPISuccess('contact', 'create', array_merge([
+ 'first_name' => 'Janice',
+ 'last_name' => 'Doe',
+ 'contact_type' => 'Individual',
+ ], $reason));
+
//create address for contact A
$this->callAPISuccess('address', 'create', [
'contact_id' => $contactA['id'],
--- /dev/null
+<?php
+
+/**
+ * Class CRM_Utils_Mail_EmailProcessorInboundTest
+ * @group headless
+ */
+class CRM_Utils_Mail_EmailProcessorInboundTest extends CiviUnitTestCase {
+
+ /**
+ * MailSettings record id.
+ *
+ * @var int
+ */
+ protected $mailSettingsId;
+
+ public function setUp() {
+ parent::setUp();
+ CRM_Utils_File::cleanDir(__DIR__ . '/data/mail');
+ mkdir(__DIR__ . '/data/mail');
+ // Note this is configured for Inbound Email Processing (not bounces)
+ // but otherwise is the same as bounces.
+ $this->mailSettingsId = $this->callAPISuccess('MailSettings', 'create', [
+ 'name' => 'local',
+ 'protocol' => 'Localdir',
+ 'source' => __DIR__ . '/data/mail',
+ 'domain' => 'example.com',
+ // a little weird - is_default=0 means for inbound email processing
+ 'is_default' => '0',
+ 'domain_id' => 1,
+ ])['id'];
+ }
+
+ public function tearDown() {
+ CRM_Utils_File::cleanDir(__DIR__ . '/data/mail');
+ $this->callAPISuccess('MailSettings', 'delete', [
+ 'id' => $this->mailSettingsId,
+ ]);
+ parent::tearDown();
+ }
+
+ /**
+ * Fetch activities with many attachments
+ *
+ * In particular the default limit for the UI is 3, which is how this came up
+ * because it was also being used as a limit for backend processes. So we
+ * test 4, which is bigger than 3 (unless running on a 2-bit CPU).
+ */
+ public function testFetchActivitiesWithManyAttachments() {
+ $mail = 'test_message_many_attachments.eml';
+
+ // paranoid check that settings are the standard defaults
+ $currentUIMax = Civi::settings()->get('max_attachments');
+ $currentBackendMax = Civi::settings()->get('max_attachments_backend');
+ if ($currentUIMax > 3) {
+ Civi::settings()->set('max_attachments', 3);
+ }
+ if ($currentBackendMax < CRM_Core_BAO_File::DEFAULT_MAX_ATTACHMENTS_BACKEND) {
+ Civi::settings()->set('max_attachments_backend', CRM_Core_BAO_File::DEFAULT_MAX_ATTACHMENTS_BACKEND);
+ }
+
+ // create some contacts
+ $senderContactId = $this->individualCreate([], 1);
+ $senderContact = $this->callAPISuccess('Contact', 'getsingle', [
+ 'id' => $senderContactId,
+ ]);
+ $recipientContactId = $this->individualCreate([], 2);
+ $recipientContact = $this->callAPISuccess('Contact', 'getsingle', [
+ 'id' => $recipientContactId,
+ ]);
+
+ $templateFillData = [
+ 'the_date' => date('r'),
+ 'from_name' => $senderContact['display_name'],
+ 'from_email' => $senderContact['email'],
+ 'to_email' => $recipientContact['email'],
+ ];
+
+ // Retrieve the template and insert our data like current dates
+ $file_contents = file_get_contents(__DIR__ . '/data/inbound/' . $mail);
+ foreach ($templateFillData as $field => $value) {
+ $file_contents = str_replace("%%{$field}%%", $value, $file_contents);
+ }
+ // put it in the mail dir
+ file_put_contents(__DIR__ . '/data/mail/' . $mail, $file_contents);
+
+ // run the job
+ $this->callAPISuccess('job', 'fetch_activities', []);
+
+ // check that file was removed from mail dir
+ $this->assertFalse(file_exists(__DIR__ . '/data/mail/' . $mail));
+
+ // get the filed activity, by sender contact id
+ $activities = $this->callAPISuccess('Activity', 'get', [
+ 'source_contact_id' => $senderContact['id'],
+ ]);
+ $this->assertEquals(1, $activities['count']);
+
+ // check subject
+ $activity = $activities['values'][$activities['id']];
+ $this->assertEquals('Testing 4 attachments', $activity['subject']);
+
+ // Check target is our recipient
+ $targets = $this->callAPISuccess('ActivityContact', 'get', [
+ 'activity_id' => $activity['id'],
+ 'record_type_id' => 'Activity Targets',
+ ]);
+ $this->assertEquals($recipientContact['id'], $targets['values'][$targets['id']]['contact_id']);
+
+ // Check we have 4 attachments
+ $attachments = $this->callAPISuccess('Attachment', 'get', [
+ 'entity_id' => $activity['id'],
+ 'entity_table' => 'civicrm_activity',
+ ]);
+ $this->assertEquals(4, $attachments['count']);
+
+ // reset in case it was different from defaults
+ Civi::settings()->set('max_attachments', $currentUIMax);
+ Civi::settings()->set('max_attachments_backend', $currentBackendMax);
+ }
+
+}
--- /dev/null
+MIME-Version: 1.0\r
+Date: %%the_date%%\r
+Message-ID: <CAL+tpUmRn2J7zcjUAv4WXMTJZcEV67V2_Ktu77Ha_MGmth0CmQ@mail.gmail.com>\r
+Subject: Testing 4 attachments\r
+From: %%from_name%% <%%from_email%%>\r
+To: %%to_email%%\r
+Content-Type: multipart/mixed; boundary="000000000000a2ad5f059325db35"\r
+\r
+--000000000000a2ad5f059325db35\r
+Content-Type: multipart/alternative; boundary="000000000000a2ad5a059325db33"\r
+\r
+--000000000000a2ad5a059325db33\r
+Content-Type: text/plain; charset="UTF-8"\r
+\r
+test\r
+\r
+--000000000000a2ad5a059325db33\r
+Content-Type: text/html; charset="UTF-8"\r
+\r
+<div dir="ltr">test<br></div>\r
+\r
+--000000000000a2ad5a059325db33--\r
+--000000000000a2ad5f059325db35\r
+Content-Type: image/gif; name="c.gif"\r
+Content-Disposition: attachment; filename="c.gif"\r
+Content-Transfer-Encoding: base64\r
+X-Attachment-Id: f_k0v4qdju2\r
+Content-ID: <f_k0v4qdju2>\r
+\r
+R0lGODlhPwA+APcAAAAAAAAAMwAAZgAAmQAAzAAA/wArAAArMwArZgArmQArzAAr/wBVAABVMwBV\r
+ZgBVmQBVzABV/wCAAACAMwCAZgCAmQCAzACA/wCqAACqMwCqZgCqmQCqzACq/wDVAADVMwDVZgDV\r
+mQDVzADV/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMrADMrMzMrZjMrmTMr\r
+zDMr/zNVADNVMzNVZjNVmTNVzDNV/zOAADOAMzOAZjOAmTOAzDOA/zOqADOqMzOqZjOqmTOqzDOq\r
+/zPVADPVMzPVZjPVmTPVzDPV/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2Yr\r
+AGYrM2YrZmYrmWYrzGYr/2ZVAGZVM2ZVZmZVmWZVzGZV/2aAAGaAM2aAZmaAmWaAzGaA/2aqAGaq\r
+M2aqZmaqmWaqzGaq/2bVAGbVM2bVZmbVmWbVzGbV/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kA\r
+ZpkAmZkAzJkA/5krAJkrM5krZpkrmZkrzJkr/5lVAJlVM5lVZplVmZlVzJlV/5mAAJmAM5mAZpmA\r
+mZmAzJmA/5mqAJmqM5mqZpmqmZmqzJmq/5nVAJnVM5nVZpnVmZnVzJnV/5n/AJn/M5n/Zpn/mZn/\r
+zJn//8wAAMwAM8wAZswAmcwAzMwA/8wrAMwrM8wrZswrmcwrzMwr/8xVAMxVM8xVZsxVmcxVzMxV\r
+/8yAAMyAM8yAZsyAmcyAzMyA/8yqAMyqM8yqZsyqmcyqzMyq/8zVAMzVM8zVZszVmczVzMzV/8z/\r
+AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8rAP8rM/8rZv8rmf8rzP8r//9VAP9V\r
+M/9VZv9Vmf9VzP9V//+AAP+AM/+AZv+Amf+AzP+A//+qAP+qM/+qZv+qmf+qzP+q///VAP/VM//V\r
+Zv/Vmf/VzP/V////AP//M///Zv//mf//zP///wAAAAAAAAAAAAAAACH5BAEAAPwALAAAAAA/AD4A\r
+AAjCAPcJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmTKFOqXMmypcuX\r
+IgHInAnT4MybOGvi3JmzJc+fNFcCHQpAJdCCP1HyVLjU5E6GT0tGhdpzZNWGV0NmXTgVZFesN62G\r
+jbi1Y1muY7WmfXh2Y9uEbzPGPTgXY92BXz/eFbjXYl6Ef/XODSz4bVOnh/EmRkx08cnGhKVClqmT\r
+aE2CSS9r3sy5s+fPoEOLHk26tOnTqFPXDAgAOw==\r
+--000000000000a2ad5f059325db35\r
+Content-Type: image/gif; name="b.gif"\r
+Content-Disposition: attachment; filename="b.gif"\r
+Content-Transfer-Encoding: base64\r
+X-Attachment-Id: f_k0v4qdjj1\r
+Content-ID: <f_k0v4qdjj1>\r
+\r
+R0lGODlhPwA+APcAAAAAAAAAMwAAZgAAmQAAzAAA/wArAAArMwArZgArmQArzAAr/wBVAABVMwBV\r
+ZgBVmQBVzABV/wCAAACAMwCAZgCAmQCAzACA/wCqAACqMwCqZgCqmQCqzACq/wDVAADVMwDVZgDV\r
+mQDVzADV/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMrADMrMzMrZjMrmTMr\r
+zDMr/zNVADNVMzNVZjNVmTNVzDNV/zOAADOAMzOAZjOAmTOAzDOA/zOqADOqMzOqZjOqmTOqzDOq\r
+/zPVADPVMzPVZjPVmTPVzDPV/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2Yr\r
+AGYrM2YrZmYrmWYrzGYr/2ZVAGZVM2ZVZmZVmWZVzGZV/2aAAGaAM2aAZmaAmWaAzGaA/2aqAGaq\r
+M2aqZmaqmWaqzGaq/2bVAGbVM2bVZmbVmWbVzGbV/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kA\r
+ZpkAmZkAzJkA/5krAJkrM5krZpkrmZkrzJkr/5lVAJlVM5lVZplVmZlVzJlV/5mAAJmAM5mAZpmA\r
+mZmAzJmA/5mqAJmqM5mqZpmqmZmqzJmq/5nVAJnVM5nVZpnVmZnVzJnV/5n/AJn/M5n/Zpn/mZn/\r
+zJn//8wAAMwAM8wAZswAmcwAzMwA/8wrAMwrM8wrZswrmcwrzMwr/8xVAMxVM8xVZsxVmcxVzMxV\r
+/8yAAMyAM8yAZsyAmcyAzMyA/8yqAMyqM8yqZsyqmcyqzMyq/8zVAMzVM8zVZszVmczVzMzV/8z/\r
+AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8rAP8rM/8rZv8rmf8rzP8r//9VAP9V\r
+M/9VZv9Vmf9VzP9V//+AAP+AM/+AZv+Amf+AzP+A//+qAP+qM/+qZv+qmf+qzP+q///VAP/VM//V\r
+Zv/Vmf/VzP/V////AP//M///Zv//mf//zP///wAAAAAAAAAAAAAAACH5BAEAAPwALAAAAAA/AD4A\r
+AAjCAPcJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmTKFOqXMmypcuX\r
+IgHInAnT4MybOGvi3JmzJc+fNFcCHQpAJdCCP1HyVLjU5E6GT0tGhdpzZNWGV0NmXTgVZFesN62G\r
+jbi1Y1muY7WmfXh2Y9uEbzPGPTgXY92BXz/eFbjXYl6Ef/XODSz4bVOnh/EmRkx08cnGhKVClqmT\r
+aE2CSS9r3sy5s+fPoEOLHk26tOnTqFPXDAgAOw==\r
+--000000000000a2ad5f059325db35\r
+Content-Type: image/gif; name="d.gif"\r
+Content-Disposition: attachment; filename="d.gif"\r
+Content-Transfer-Encoding: base64\r
+X-Attachment-Id: f_k0v4qdk73\r
+Content-ID: <f_k0v4qdk73>\r
+\r
+R0lGODlhPwA+APcAAAAAAAAAMwAAZgAAmQAAzAAA/wArAAArMwArZgArmQArzAAr/wBVAABVMwBV\r
+ZgBVmQBVzABV/wCAAACAMwCAZgCAmQCAzACA/wCqAACqMwCqZgCqmQCqzACq/wDVAADVMwDVZgDV\r
+mQDVzADV/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMrADMrMzMrZjMrmTMr\r
+zDMr/zNVADNVMzNVZjNVmTNVzDNV/zOAADOAMzOAZjOAmTOAzDOA/zOqADOqMzOqZjOqmTOqzDOq\r
+/zPVADPVMzPVZjPVmTPVzDPV/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2Yr\r
+AGYrM2YrZmYrmWYrzGYr/2ZVAGZVM2ZVZmZVmWZVzGZV/2aAAGaAM2aAZmaAmWaAzGaA/2aqAGaq\r
+M2aqZmaqmWaqzGaq/2bVAGbVM2bVZmbVmWbVzGbV/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kA\r
+ZpkAmZkAzJkA/5krAJkrM5krZpkrmZkrzJkr/5lVAJlVM5lVZplVmZlVzJlV/5mAAJmAM5mAZpmA\r
+mZmAzJmA/5mqAJmqM5mqZpmqmZmqzJmq/5nVAJnVM5nVZpnVmZnVzJnV/5n/AJn/M5n/Zpn/mZn/\r
+zJn//8wAAMwAM8wAZswAmcwAzMwA/8wrAMwrM8wrZswrmcwrzMwr/8xVAMxVM8xVZsxVmcxVzMxV\r
+/8yAAMyAM8yAZsyAmcyAzMyA/8yqAMyqM8yqZsyqmcyqzMyq/8zVAMzVM8zVZszVmczVzMzV/8z/\r
+AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8rAP8rM/8rZv8rmf8rzP8r//9VAP9V\r
+M/9VZv9Vmf9VzP9V//+AAP+AM/+AZv+Amf+AzP+A//+qAP+qM/+qZv+qmf+qzP+q///VAP/VM//V\r
+Zv/Vmf/VzP/V////AP//M///Zv//mf//zP///wAAAAAAAAAAAAAAACH5BAEAAPwALAAAAAA/AD4A\r
+AAjCAPcJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmTKFOqXMmypcuX\r
+IgHInAnT4MybOGvi3JmzJc+fNFcCHQpAJdCCP1HyVLjU5E6GT0tGhdpzZNWGV0NmXTgVZFesN62G\r
+jbi1Y1muY7WmfXh2Y9uEbzPGPTgXY92BXz/eFbjXYl6Ef/XODSz4bVOnh/EmRkx08cnGhKVClqmT\r
+aE2CSS9r3sy5s+fPoEOLHk26tOnTqFPXDAgAOw==\r
+--000000000000a2ad5f059325db35\r
+Content-Type: image/gif; name="a.gif"\r
+Content-Disposition: attachment; filename="a.gif"\r
+Content-Transfer-Encoding: base64\r
+X-Attachment-Id: f_k0v4qdiv0\r
+Content-ID: <f_k0v4qdiv0>\r
+\r
+R0lGODlhPwA+APcAAAAAAAAAMwAAZgAAmQAAzAAA/wArAAArMwArZgArmQArzAAr/wBVAABVMwBV\r
+ZgBVmQBVzABV/wCAAACAMwCAZgCAmQCAzACA/wCqAACqMwCqZgCqmQCqzACq/wDVAADVMwDVZgDV\r
+mQDVzADV/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMrADMrMzMrZjMrmTMr\r
+zDMr/zNVADNVMzNVZjNVmTNVzDNV/zOAADOAMzOAZjOAmTOAzDOA/zOqADOqMzOqZjOqmTOqzDOq\r
+/zPVADPVMzPVZjPVmTPVzDPV/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2Yr\r
+AGYrM2YrZmYrmWYrzGYr/2ZVAGZVM2ZVZmZVmWZVzGZV/2aAAGaAM2aAZmaAmWaAzGaA/2aqAGaq\r
+M2aqZmaqmWaqzGaq/2bVAGbVM2bVZmbVmWbVzGbV/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kA\r
+ZpkAmZkAzJkA/5krAJkrM5krZpkrmZkrzJkr/5lVAJlVM5lVZplVmZlVzJlV/5mAAJmAM5mAZpmA\r
+mZmAzJmA/5mqAJmqM5mqZpmqmZmqzJmq/5nVAJnVM5nVZpnVmZnVzJnV/5n/AJn/M5n/Zpn/mZn/\r
+zJn//8wAAMwAM8wAZswAmcwAzMwA/8wrAMwrM8wrZswrmcwrzMwr/8xVAMxVM8xVZsxVmcxVzMxV\r
+/8yAAMyAM8yAZsyAmcyAzMyA/8yqAMyqM8yqZsyqmcyqzMyq/8zVAMzVM8zVZszVmczVzMzV/8z/\r
+AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8rAP8rM/8rZv8rmf8rzP8r//9VAP9V\r
+M/9VZv9Vmf9VzP9V//+AAP+AM/+AZv+Amf+AzP+A//+qAP+qM/+qZv+qmf+qzP+q///VAP/VM//V\r
+Zv/Vmf/VzP/V////AP//M///Zv//mf//zP///wAAAAAAAAAAAAAAACH5BAEAAPwALAAAAAA/AD4A\r
+AAjCAPcJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmTKFOqXMmypcuX\r
+IgHInAnT4MybOGvi3JmzJc+fNFcCHQpAJdCCP1HyVLjU5E6GT0tGhdpzZNWGV0NmXTgVZFesN62G\r
+jbi1Y1muY7WmfXh2Y9uEbzPGPTgXY92BXz/eFbjXYl6Ef/XODSz4bVOnh/EmRkx08cnGhKVClqmT\r
+aE2CSS9r3sy5s+fPoEOLHk26tOnTqFPXDAgAOw==\r
+--000000000000a2ad5f059325db35--\r
--- /dev/null
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2019 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ */
+
+use Civi\Api4\Event;
+
+/**
+ * @group headless
+ */
+class EventTest extends \api\v4\UnitTestCase {
+
+ /**
+ * Test that the event api filters out templates by default.
+ *
+ * @throws \Civi\API\Exception\UnauthorizedException
+ */
+ public function testTemplateFilterByDefault() {
+ Event::create()->setValues(['template_title' => 'Big Event', 'is_template' => 1, 'start_date' => 'now', 'event_type_id' => 'Meeting'])->execute();
+ Event::create()->setValues(['title' => 'Bigger Event', 'start_date' => 'now', 'event_type_id' => 'Meeting'])->execute();
+ $this->assertEquals(1, Event::get()->selectRowCount()->execute()->count());
+ }
+
+}
</html>
<add>4.7</add>
</field>
+ <field>
+ <name>is_template</name>
+ <title>Is a Template Contribution</title>
+ <type>boolean</type>
+ <default>0</default>
+ <import>true</import>
+ <comment>Shows this is a template for recurring contributions.</comment>
+ <html>
+ <type>CheckBox</type>
+ </html>
+ <add>5.20</add>
+ </field>
</table>
<comment>if true - billing block is required for online contribution page</comment>
<add>4.6</add>
</field>
+ <field>
+ <name>frontend_title</name>
+ <title>Public Title</title>
+ <type>varchar</type>
+ <length>255</length>
+ <localizable>true</localizable>
+ <default>NULL</default>
+ <comment>Contribution Page Public title</comment>
+ <html>
+ <type>Text</type>
+ </html>
+ <add>5.20</add>
+ <uniqueName>contribution_page_frontend_title</uniqueName>
+ </field>
</table>
<comment>Last 4 digits of credit card</comment>
<add>4.7</add>
</field>
+ <field>
+ <name>order_reference</name>
+ <uniqueName>financial_trxn_order_reference</uniqueName>
+ <title>Order Reference</title>
+ <type>varchar</type>
+ <length>255</length>
+ <html>
+ <type>Text</type>
+ <size>25</size>
+ </html>
+ <comment>Payment Processor external order reference</comment>
+ <add>5.20</add>
+ </field>
</table>
<?xml version="1.0" encoding="iso-8859-1" ?>
<version>
- <version_no>5.19.alpha1</version_no>
+ <version_no>5.20.alpha1</version_no>
</version>