From 588185fbb70131c6f9cec6d2605f2c65755c23f3 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 12:18:15 -0700 Subject: [PATCH 01/42] Fix for CRM-18399: "My billing address is the same as above" option goes away when selecting other payment options. --- CRM/Core/Payment/Form.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CRM/Core/Payment/Form.php b/CRM/Core/Payment/Form.php index bafe1ae2a6c8..2a6e2f6915ba 100644 --- a/CRM/Core/Payment/Form.php +++ b/CRM/Core/Payment/Form.php @@ -225,6 +225,19 @@ public static function getPaymentTypeLabel($paymentProcessor) { */ public static function buildPaymentForm(&$form, $processor, $billing_profile_id, $isBackOffice) { //if the form has address fields assign to the template so the js can decide what billing fields to show + if ($form instanceof CRM_Financial_Form_Payment) { + $contribution_form = new CRM_Contribute_Form_Contribution_Main(); + $contribution_form->controller = new CRM_Contribute_Controller_Contribution(); + $contribution_form->preProcess(); + $contribution_form->buildCustom($contribution_form->_values['custom_pre_id'], 'customPre'); + if (!empty($contribution_form->_fields) && !empty($contribution_form->_values['custom_pre_id'])) { + $profileAddressFields = array(); + foreach ($contribution_form->_fields as $key => $value) { + CRM_Core_BAO_UFField::assignAddressField($key, $profileAddressFields, array('uf_group_id' => $contribution_form->_values['custom_pre_id'])); + } + $form->set('profileAddressFields', $profileAddressFields); + } + } $profileAddressFields = $form->get('profileAddressFields'); if (!empty($profileAddressFields)) { $form->assign('profileAddressFields', $profileAddressFields); From 1002e47982d0253dd7b40d319fdfc1ddaaf5ff36 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 12:59:25 -0700 Subject: [PATCH 02/42] Fix CRM-18418: Checked Payment Option is unset when selecting "Other" amount --- templates/CRM/common/paymentBlock.tpl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/templates/CRM/common/paymentBlock.tpl b/templates/CRM/common/paymentBlock.tpl index 73e05bba0e63..e5775bc0f112 100644 --- a/templates/CRM/common/paymentBlock.tpl +++ b/templates/CRM/common/paymentBlock.tpl @@ -113,10 +113,19 @@ } } } + var $billingcheckbox = $('#billingcheckbox'); + if ($billingcheckbox) { + if ($billingcheckbox.prop("checked")) { + CRM.vars.billingcheckbox = true; + } + } // Processors like pp-express will hide the form submit buttons, so re-show them when switching $('.crm-submit-buttons', $form).show().find('input').prop('disabled', true); CRM.loadPage(dataUrl, {target: '#billing-payment-block'}); + if ($('#billingcheckbox') && CRM.vars.billingcheckbox) { + $('#billingcheckbox').prop('checked', true); + } } $('.crm-group.payment_options-group').show(); From 4f36d2fc8d548668932913472ad93b3a56798740 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 15:08:03 -0700 Subject: [PATCH 03/42] CRM-18515 - Allow Payment Processor with same name when using multi-domain. --- CRM/Admin/Form/PaymentProcessor.php | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/CRM/Admin/Form/PaymentProcessor.php b/CRM/Admin/Form/PaymentProcessor.php index a0367bb24bf1..191a2519ada7 100644 --- a/CRM/Admin/Form/PaymentProcessor.php +++ b/CRM/Admin/Form/PaymentProcessor.php @@ -176,7 +176,8 @@ public function buildQuickForm($check = FALSE) { $attributes['name'], TRUE ); - $this->addRule('name', ts('Name already exists in Database.'), 'objectExists', array( + $this->registerRule('paymentProcessorNameExists', 'callback', 'paymentProcessorNameExists', 'CRM_Admin_Form_PaymentProcessor'); + $this->addRule('name', ts('Name already exists in Database.'), 'paymentProcessorNameExists', array( 'CRM_Financial_DAO_PaymentProcessor', $this->_id, )); @@ -400,4 +401,34 @@ public function updatePaymentProcessor(&$values, $domainID, $test) { civicrm_api3('PaymentProcessor', 'create', $params); } + /** + * Check if there is a record with the same name in the db. + * + * @param string $value + * The value of the field we are checking. + * @param array $options + * The daoName and fieldName (optional ). + * + * @return bool + * true if object exists + */ + public static function paymentProcessorNameExists($value, $options) { + $fieldName = 'name'; + $daoName = CRM_Utils_Array::value(0, $options); + $daoID = CRM_Utils_Array::value(1, $options); + $domain_id = CRM_Core_Config::domainID(); + $object = new $daoName(); + $object->$fieldName = $value; + $object->domain_id = $domain_id; + + $config = CRM_Core_Config::singleton(); + + if ($object->find(TRUE)) { + return ($daoID && $object->id == $daoID) ? TRUE : FALSE; + } + else { + return TRUE; + } + } + } From bf922610ec224e31d84831f408d3f8734e739fbf Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 16:21:24 -0700 Subject: [PATCH 04/42] Revert "CRM-18515 - Allow Payment Processor with same name when using multi-domain." This reverts commit 4f36d2fc8d548668932913472ad93b3a56798740. --- CRM/Admin/Form/PaymentProcessor.php | 33 +---------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/CRM/Admin/Form/PaymentProcessor.php b/CRM/Admin/Form/PaymentProcessor.php index 191a2519ada7..a0367bb24bf1 100644 --- a/CRM/Admin/Form/PaymentProcessor.php +++ b/CRM/Admin/Form/PaymentProcessor.php @@ -176,8 +176,7 @@ public function buildQuickForm($check = FALSE) { $attributes['name'], TRUE ); - $this->registerRule('paymentProcessorNameExists', 'callback', 'paymentProcessorNameExists', 'CRM_Admin_Form_PaymentProcessor'); - $this->addRule('name', ts('Name already exists in Database.'), 'paymentProcessorNameExists', array( + $this->addRule('name', ts('Name already exists in Database.'), 'objectExists', array( 'CRM_Financial_DAO_PaymentProcessor', $this->_id, )); @@ -401,34 +400,4 @@ public function updatePaymentProcessor(&$values, $domainID, $test) { civicrm_api3('PaymentProcessor', 'create', $params); } - /** - * Check if there is a record with the same name in the db. - * - * @param string $value - * The value of the field we are checking. - * @param array $options - * The daoName and fieldName (optional ). - * - * @return bool - * true if object exists - */ - public static function paymentProcessorNameExists($value, $options) { - $fieldName = 'name'; - $daoName = CRM_Utils_Array::value(0, $options); - $daoID = CRM_Utils_Array::value(1, $options); - $domain_id = CRM_Core_Config::domainID(); - $object = new $daoName(); - $object->$fieldName = $value; - $object->domain_id = $domain_id; - - $config = CRM_Core_Config::singleton(); - - if ($object->find(TRUE)) { - return ($daoID && $object->id == $daoID) ? TRUE : FALSE; - } - else { - return TRUE; - } - } - } From 3e9d4e10bdcec4fa17f99bf016afabf4a1162e06 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 16:21:24 -0700 Subject: [PATCH 05/42] Revert "Fix CRM-18418: Checked Payment Option is unset when selecting "Other" amount" This reverts commit 1002e47982d0253dd7b40d319fdfc1ddaaf5ff36. --- templates/CRM/common/paymentBlock.tpl | 9 --------- 1 file changed, 9 deletions(-) diff --git a/templates/CRM/common/paymentBlock.tpl b/templates/CRM/common/paymentBlock.tpl index e5775bc0f112..73e05bba0e63 100644 --- a/templates/CRM/common/paymentBlock.tpl +++ b/templates/CRM/common/paymentBlock.tpl @@ -113,19 +113,10 @@ } } } - var $billingcheckbox = $('#billingcheckbox'); - if ($billingcheckbox) { - if ($billingcheckbox.prop("checked")) { - CRM.vars.billingcheckbox = true; - } - } // Processors like pp-express will hide the form submit buttons, so re-show them when switching $('.crm-submit-buttons', $form).show().find('input').prop('disabled', true); CRM.loadPage(dataUrl, {target: '#billing-payment-block'}); - if ($('#billingcheckbox') && CRM.vars.billingcheckbox) { - $('#billingcheckbox').prop('checked', true); - } } $('.crm-group.payment_options-group').show(); From 9a440bbfac266b8a0de17b9c25615452afd5f4b9 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 16:21:24 -0700 Subject: [PATCH 06/42] Revert "Fix for CRM-18399: "My billing address is the same as above" option goes away when selecting other payment options." This reverts commit 588185fbb70131c6f9cec6d2605f2c65755c23f3. --- CRM/Core/Payment/Form.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/CRM/Core/Payment/Form.php b/CRM/Core/Payment/Form.php index 2a6e2f6915ba..bafe1ae2a6c8 100644 --- a/CRM/Core/Payment/Form.php +++ b/CRM/Core/Payment/Form.php @@ -225,19 +225,6 @@ public static function getPaymentTypeLabel($paymentProcessor) { */ public static function buildPaymentForm(&$form, $processor, $billing_profile_id, $isBackOffice) { //if the form has address fields assign to the template so the js can decide what billing fields to show - if ($form instanceof CRM_Financial_Form_Payment) { - $contribution_form = new CRM_Contribute_Form_Contribution_Main(); - $contribution_form->controller = new CRM_Contribute_Controller_Contribution(); - $contribution_form->preProcess(); - $contribution_form->buildCustom($contribution_form->_values['custom_pre_id'], 'customPre'); - if (!empty($contribution_form->_fields) && !empty($contribution_form->_values['custom_pre_id'])) { - $profileAddressFields = array(); - foreach ($contribution_form->_fields as $key => $value) { - CRM_Core_BAO_UFField::assignAddressField($key, $profileAddressFields, array('uf_group_id' => $contribution_form->_values['custom_pre_id'])); - } - $form->set('profileAddressFields', $profileAddressFields); - } - } $profileAddressFields = $form->get('profileAddressFields'); if (!empty($profileAddressFields)) { $form->assign('profileAddressFields', $profileAddressFields); From 6bcc9797885084f3a5cef57a0451b490575faf83 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 16:23:25 -0700 Subject: [PATCH 07/42] CRM-18515 - Allow Payment Processor with same name when using multi-domain. --- CRM/Admin/Form/PaymentProcessor.php | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/CRM/Admin/Form/PaymentProcessor.php b/CRM/Admin/Form/PaymentProcessor.php index a0367bb24bf1..191a2519ada7 100644 --- a/CRM/Admin/Form/PaymentProcessor.php +++ b/CRM/Admin/Form/PaymentProcessor.php @@ -176,7 +176,8 @@ public function buildQuickForm($check = FALSE) { $attributes['name'], TRUE ); - $this->addRule('name', ts('Name already exists in Database.'), 'objectExists', array( + $this->registerRule('paymentProcessorNameExists', 'callback', 'paymentProcessorNameExists', 'CRM_Admin_Form_PaymentProcessor'); + $this->addRule('name', ts('Name already exists in Database.'), 'paymentProcessorNameExists', array( 'CRM_Financial_DAO_PaymentProcessor', $this->_id, )); @@ -400,4 +401,34 @@ public function updatePaymentProcessor(&$values, $domainID, $test) { civicrm_api3('PaymentProcessor', 'create', $params); } + /** + * Check if there is a record with the same name in the db. + * + * @param string $value + * The value of the field we are checking. + * @param array $options + * The daoName and fieldName (optional ). + * + * @return bool + * true if object exists + */ + public static function paymentProcessorNameExists($value, $options) { + $fieldName = 'name'; + $daoName = CRM_Utils_Array::value(0, $options); + $daoID = CRM_Utils_Array::value(1, $options); + $domain_id = CRM_Core_Config::domainID(); + $object = new $daoName(); + $object->$fieldName = $value; + $object->domain_id = $domain_id; + + $config = CRM_Core_Config::singleton(); + + if ($object->find(TRUE)) { + return ($daoID && $object->id == $daoID) ? TRUE : FALSE; + } + else { + return TRUE; + } + } + } From b8ace2411534e798c1d3b0b0a21d020c87d89255 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 15:08:03 -0700 Subject: [PATCH 08/42] CRM-18515 - Allow Payment Processor with same name when using multi-domain. --- CRM/Admin/Form/PaymentProcessor.php | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/CRM/Admin/Form/PaymentProcessor.php b/CRM/Admin/Form/PaymentProcessor.php index a0367bb24bf1..191a2519ada7 100644 --- a/CRM/Admin/Form/PaymentProcessor.php +++ b/CRM/Admin/Form/PaymentProcessor.php @@ -176,7 +176,8 @@ public function buildQuickForm($check = FALSE) { $attributes['name'], TRUE ); - $this->addRule('name', ts('Name already exists in Database.'), 'objectExists', array( + $this->registerRule('paymentProcessorNameExists', 'callback', 'paymentProcessorNameExists', 'CRM_Admin_Form_PaymentProcessor'); + $this->addRule('name', ts('Name already exists in Database.'), 'paymentProcessorNameExists', array( 'CRM_Financial_DAO_PaymentProcessor', $this->_id, )); @@ -400,4 +401,34 @@ public function updatePaymentProcessor(&$values, $domainID, $test) { civicrm_api3('PaymentProcessor', 'create', $params); } + /** + * Check if there is a record with the same name in the db. + * + * @param string $value + * The value of the field we are checking. + * @param array $options + * The daoName and fieldName (optional ). + * + * @return bool + * true if object exists + */ + public static function paymentProcessorNameExists($value, $options) { + $fieldName = 'name'; + $daoName = CRM_Utils_Array::value(0, $options); + $daoID = CRM_Utils_Array::value(1, $options); + $domain_id = CRM_Core_Config::domainID(); + $object = new $daoName(); + $object->$fieldName = $value; + $object->domain_id = $domain_id; + + $config = CRM_Core_Config::singleton(); + + if ($object->find(TRUE)) { + return ($daoID && $object->id == $daoID) ? TRUE : FALSE; + } + else { + return TRUE; + } + } + } From c276e3d6af514420ae3727d58b55322f3dea09b6 Mon Sep 17 00:00:00 2001 From: Web Access Date: Wed, 4 May 2016 18:54:00 +0530 Subject: [PATCH 09/42] CRM-18151 --- tests/karma/unit/crmMailingRadioDateSpec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/karma/unit/crmMailingRadioDateSpec.js b/tests/karma/unit/crmMailingRadioDateSpec.js index f3628b5141b3..defda31a0324 100644 --- a/tests/karma/unit/crmMailingRadioDateSpec.js +++ b/tests/karma/unit/crmMailingRadioDateSpec.js @@ -88,9 +88,10 @@ describe('crmMailingRadioDate', function() { var now = new Date(); var month = '' + (now.getMonth() + 1); + var day = '' + (now.getDate() + 1); var year = (now.getFullYear() + 1); + if (day.length < 2) day = '0' + day; if (month.length < 2) month = '0' + month; - var day = "01"; var minutes = "30"; var hours = "09"; var datenow = [year, month, day].join('-'); @@ -103,8 +104,7 @@ describe('crmMailingRadioDate', function() { expect($rootScope.myForm.$valid).toBe(true); expect(element.find('.radio-now').prop('checked')).toBe(false); expect(element.find('.radio-at').prop('checked')).toBe(true); - // expect(element.find('.crm-form-date').datepicker('getDate').toDateString()).toEqual(ndate.toDateString()); - expect(element.find('.crm-form-date').datepicker('getDate').getUTCDate()).toEqual(ndate.getUTCDate()); + expect(element.find('.crm-form-date').datepicker('getDate').toDateString()).toEqual(ndate.toDateString()); expect(element.find('.crm-hidden-date').val()).toEqual(currentDate); }); From b715aa08355e282a90527075cf423367cddc80c5 Mon Sep 17 00:00:00 2001 From: eileen Date: Tue, 26 Apr 2016 10:36:43 +1200 Subject: [PATCH 10/42] CRM-18193 logging schema: fix mismatch between comment & code convention Comment suggests 'c_' to identify a non-CRM connection + timestamp to the hour + connection_id but code used 'con_' I think the shorter version in comment is better as there is more real information space --- CRM/Logging/Schema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Logging/Schema.php b/CRM/Logging/Schema.php index 99dcc2d64546..402a77df526a 100644 --- a/CRM/Logging/Schema.php +++ b/CRM/Logging/Schema.php @@ -874,7 +874,7 @@ public function triggerInfo(&$info, $tableName = NULL, $force = FALSE) { // We tried setting the @uniqueID in the trigger but it was unreliable. // An external interaction could split over 2 connections & it seems worth blocking the revert on // these reports & adding extra permissioning to the api for this. - $connectionSQLString = "COALESCE(@uniqueID, LEFT(CONCAT('con_', unix_timestamp()/3600, CONNECTION_ID()), 17))"; + $connectionSQLString = "COALESCE(@uniqueID, LEFT(CONCAT('c_', unix_timestamp()/3600, CONNECTION_ID()), 17))"; } else { // The log tables have not yet been converted to have varchar(17) fields for log_conn_id. From f9d88182cf969e67476cbd42800a0163348e6f27 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 26 Apr 2016 12:24:21 -0700 Subject: [PATCH 11/42] CRM-18469, CRM-17984 - getTree - No more pass by reference --- CRM/Activity/Form/Activity.php | 2 +- CRM/Case/Form/CaseView.php | 2 +- CRM/Case/Form/CustomData.php | 2 +- CRM/Contact/Form/CustomData.php | 6 +++--- CRM/Contact/Form/Search/Custom/ActivitySearch.php | 2 +- CRM/Contact/Page/Inline/CustomData.php | 2 +- CRM/Event/Form/ParticipantView.php | 2 +- CRM/Grant/Form/GrantView.php | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CRM/Activity/Form/Activity.php b/CRM/Activity/Form/Activity.php index 9e74fffb5682..32dc72b26cc7 100644 --- a/CRM/Activity/Form/Activity.php +++ b/CRM/Activity/Form/Activity.php @@ -379,7 +379,7 @@ public function preProcess() { if ($this->_action & CRM_Core_Action::VIEW) { // Get the tree of custom fields. - $this->_groupTree = &CRM_Core_BAO_CustomGroup::getTree('Activity', $this, + $this->_groupTree = CRM_Core_BAO_CustomGroup::getTree('Activity', $this, $this->_activityId, 0, $this->_activityTypeId ); } diff --git a/CRM/Case/Form/CaseView.php b/CRM/Case/Form/CaseView.php index a597724c53ad..886e3ef27f05 100644 --- a/CRM/Case/Form/CaseView.php +++ b/CRM/Case/Form/CaseView.php @@ -161,7 +161,7 @@ public function preProcess() { $entitySubType = !empty($values['case_type_id']) ? $values['case_type_id'] : NULL; $this->assign('caseTypeID', $entitySubType); - $groupTree = &CRM_Core_BAO_CustomGroup::getTree('Case', + $groupTree = CRM_Core_BAO_CustomGroup::getTree('Case', $this, $this->_caseID, NULL, diff --git a/CRM/Case/Form/CustomData.php b/CRM/Case/Form/CustomData.php index b5c633e16389..81419825fc68 100644 --- a/CRM/Case/Form/CustomData.php +++ b/CRM/Case/Form/CustomData.php @@ -65,7 +65,7 @@ public function preProcess() { $this->_subTypeID = CRM_Utils_Request::retrieve('subType', 'Positive', $this, TRUE); $this->_contactID = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE); - $groupTree = &CRM_Core_BAO_CustomGroup::getTree('Case', + $groupTree = CRM_Core_BAO_CustomGroup::getTree('Case', $this, $this->_entityID, $this->_groupID, diff --git a/CRM/Contact/Form/CustomData.php b/CRM/Contact/Form/CustomData.php index b38d740313d3..24feb13a81e1 100644 --- a/CRM/Contact/Form/CustomData.php +++ b/CRM/Contact/Form/CustomData.php @@ -230,7 +230,7 @@ public function setDefaultValues() { if ($this->_cdType || $this->_multiRecordDisplay == 'single') { if ($this->_copyValueId) { // cached tree is fetched - $groupTree = &CRM_Core_BAO_CustomGroup::getTree($this->_type, + $groupTree = CRM_Core_BAO_CustomGroup::getTree($this->_type, $this, $this->_entityId, $this->_groupID @@ -253,7 +253,7 @@ public function setDefaultValues() { return $customDefaultValue; } - $groupTree = &CRM_Core_BAO_CustomGroup::getTree($this->_contactType, + $groupTree = CRM_Core_BAO_CustomGroup::getTree($this->_contactType, $this, $this->_tableID, $this->_groupID, @@ -262,7 +262,7 @@ public function setDefaultValues() { if (empty($_POST['hidden_custom_group_count'])) { // custom data building in edit mode (required to handle multi-value) - $groupTree = &CRM_Core_BAO_CustomGroup::getTree($this->_contactType, $this, $this->_tableID, + $groupTree = CRM_Core_BAO_CustomGroup::getTree($this->_contactType, $this, $this->_tableID, $this->_groupID, $this->_contactSubType ); $customValueCount = CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, TRUE, $this->_groupID, NULL, NULL, $this->_tableID); diff --git a/CRM/Contact/Form/Search/Custom/ActivitySearch.php b/CRM/Contact/Form/Search/Custom/ActivitySearch.php index 6b4da6304df9..d7b8ba87fc93 100644 --- a/CRM/Contact/Form/Search/Custom/ActivitySearch.php +++ b/CRM/Contact/Form/Search/Custom/ActivitySearch.php @@ -70,7 +70,7 @@ public function __construct(&$formValues) { ); //Add custom fields to columns array for inclusion in export - $groupTree = &CRM_Core_BAO_CustomGroup::getTree('Activity', $form, NULL, + $groupTree = CRM_Core_BAO_CustomGroup::getTree('Activity', $form, NULL, NULL, '', NULL ); diff --git a/CRM/Contact/Page/Inline/CustomData.php b/CRM/Contact/Page/Inline/CustomData.php index f3098df758f5..5d8d31bd477f 100644 --- a/CRM/Contact/Page/Inline/CustomData.php +++ b/CRM/Contact/Page/Inline/CustomData.php @@ -51,7 +51,7 @@ public function run() { //custom groups Inline $entityType = CRM_Contact_BAO_Contact::getContactType($contactId); $entitySubType = CRM_Contact_BAO_Contact::getContactSubType($contactId); - $groupTree = &CRM_Core_BAO_CustomGroup::getTree($entityType, $this, $contactId, + $groupTree = CRM_Core_BAO_CustomGroup::getTree($entityType, $this, $contactId, $cgId, $entitySubType ); $details = CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, FALSE, NULL, NULL, NULL, $contactId); diff --git a/CRM/Event/Form/ParticipantView.php b/CRM/Event/Form/ParticipantView.php index 34ead01720e8..ee52b4b3c747 100644 --- a/CRM/Event/Form/ParticipantView.php +++ b/CRM/Event/Form/ParticipantView.php @@ -140,7 +140,7 @@ public function preProcess() { foreach ($allRoleIDs as $k => $v) { $roleGroupTree = CRM_Core_BAO_CustomGroup::getTree('Participant', $this, $participantID, NULL, $v, $roleCustomDataTypeID); - $eventGroupTree = &CRM_Core_BAO_CustomGroup::getTree('Participant', $this, $participantID, NULL, + $eventGroupTree = CRM_Core_BAO_CustomGroup::getTree('Participant', $this, $participantID, NULL, $values[$participantID]['event_id'], $eventNameCustomDataTypeID ); $eventTypeID = CRM_Core_DAO::getFieldValue("CRM_Event_DAO_Event", $values[$participantID]['event_id'], 'event_type_id', 'id'); diff --git a/CRM/Grant/Form/GrantView.php b/CRM/Grant/Form/GrantView.php index fecced4a2ac8..ba7cb835f211 100644 --- a/CRM/Grant/Form/GrantView.php +++ b/CRM/Grant/Form/GrantView.php @@ -117,7 +117,7 @@ public function preProcess() { $this->assign('attachment', $attachment); $grantType = CRM_Core_DAO::getFieldValue("CRM_Grant_DAO_Grant", $this->_id, "grant_type_id"); - $groupTree = &CRM_Core_BAO_CustomGroup::getTree("Grant", $this, $this->_id, 0, $grantType); + $groupTree = CRM_Core_BAO_CustomGroup::getTree("Grant", $this, $this->_id, 0, $grantType); CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, FALSE, NULL, NULL, NULL, $this->_id); $this->assign('id', $this->_id); From df95dc2da6c005d6e1f2da52b086f3fab636fd58 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sat, 23 Apr 2016 15:12:30 -0400 Subject: [PATCH 12/42] CRM-18006 - Specify db engine for civicrm_install_canary table --- Civi/Core/InstallationCanary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Civi/Core/InstallationCanary.php b/Civi/Core/InstallationCanary.php index 3fd967bcbd3b..e94dbe857547 100644 --- a/Civi/Core/InstallationCanary.php +++ b/Civi/Core/InstallationCanary.php @@ -53,7 +53,7 @@ public static function check(SystemInstallEvent $event) { throw new \CRM_Core_Exception("Found installation canary. This suggests that something went wrong with tracking installation process. Please post to forum or JIRA."); } \Civi::log()->info('Creating canary table'); - \CRM_Core_DAO::executeQuery('CREATE TABLE civicrm_install_canary (id int(10) unsigned NOT NULL)'); + \CRM_Core_DAO::executeQuery('CREATE TABLE civicrm_install_canary (id int(10) unsigned NOT NULL) ENGINE=InnoDB'); } } From 0033724e989d51bb5d1fd0ec59ff3225b869867c Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 25 Apr 2016 16:13:07 -0700 Subject: [PATCH 13/42] CRM-18006 - civicrm_install_canary - Ensure ENGINE is InnoDB This should resolve warnings on systems where MyISAM was default engine. --- CRM/Upgrade/Incremental/php/FourSeven.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CRM/Upgrade/Incremental/php/FourSeven.php b/CRM/Upgrade/Incremental/php/FourSeven.php index 94ed0dfb1b50..971c58486bf2 100644 --- a/CRM/Upgrade/Incremental/php/FourSeven.php +++ b/CRM/Upgrade/Incremental/php/FourSeven.php @@ -183,6 +183,13 @@ public function upgrade_4_7_4($rev) { $this->addTask('Add Contact Deleted by Merge Activity Type', 'addDeletedByMergeActivityType'); } + public function upgrade_4_7_7($rev) { + // https://issues.civicrm.org/jira/browse/CRM-18006 + if (CRM_Core_DAO::checkTableExists('civicrm_install_canary')) { + CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_install_canary ENGINE=InnoDB'); + } + } + /** * CRM-16354 * From 31a83984282dc5e189e80c2aacebffd0791a747f Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Tue, 26 Apr 2016 16:58:21 -0400 Subject: [PATCH 14/42] CRM-16846 - Fix missing upgrade steps --- CRM/Upgrade/Incremental/php/FourSeven.php | 26 +++++++++ CRM/Upgrade/Incremental/sql/4.7.1.mysql.tpl | 31 ----------- CRM/Upgrade/Incremental/sql/4.7.2.mysql.tpl | 28 ---------- CRM/Upgrade/Incremental/sql/4.7.4.mysql.tpl | 4 -- CRM/Upgrade/Incremental/sql/4.7.7.mysql.tpl | 62 +++++++++++++++++++++ 5 files changed, 88 insertions(+), 63 deletions(-) diff --git a/CRM/Upgrade/Incremental/php/FourSeven.php b/CRM/Upgrade/Incremental/php/FourSeven.php index 971c58486bf2..bd1c17560afa 100644 --- a/CRM/Upgrade/Incremental/php/FourSeven.php +++ b/CRM/Upgrade/Incremental/php/FourSeven.php @@ -151,6 +151,7 @@ public function upgrade_4_7_beta6($rev) { * @param string $rev */ public function upgrade_4_7_1($rev) { + $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); $this->addTask('Add Index to civicrm_contribution creditnote_id field', 'addIndexContributionCreditNoteID'); } @@ -160,6 +161,7 @@ public function upgrade_4_7_1($rev) { * @param string $rev */ public function upgrade_4_7_2($rev) { + $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); $this->addTask('Fix Index on civicrm_financial_item combined entity_id + entity_table', 'addCombinedIndexFinancialItemEntityIDEntityType'); $this->addTask('enable financial account relationships for chargeback & refund', 'addRefundAndChargeBackAccountsIfNotExist'); $this->addTask('Add Index to civicrm_contribution.source', 'addIndexContributionSource'); @@ -171,6 +173,7 @@ public function upgrade_4_7_2($rev) { * @param string $rev */ public function upgrade_4_7_3($rev) { + $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); $this->addTask('Add Index to civicrm_contribution.total_amount', 'addIndexContributionAmount'); } @@ -180,16 +183,39 @@ public function upgrade_4_7_3($rev) { * @param string $rev */ public function upgrade_4_7_4($rev) { + $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); $this->addTask('Add Contact Deleted by Merge Activity Type', 'addDeletedByMergeActivityType'); } + /** + * Upgrade function. + * + * @param string $rev + */ public function upgrade_4_7_7($rev) { + $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); // https://issues.civicrm.org/jira/browse/CRM-18006 if (CRM_Core_DAO::checkTableExists('civicrm_install_canary')) { CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_install_canary ENGINE=InnoDB'); } } + /* + * Important! All upgrade functions MUST call the 'runSql' task. + * Uncomment and use the following template for a new upgrade version + * (change the x in the function name): + */ + + // /** + // * Upgrade function. + // * + // * @param string $rev + // */ + // public function upgrade_4_7_x($rev) { + // $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); + // // Additional tasks here... + // } + /** * CRM-16354 * diff --git a/CRM/Upgrade/Incremental/sql/4.7.1.mysql.tpl b/CRM/Upgrade/Incremental/sql/4.7.1.mysql.tpl index 3dc0b34d14ae..65ea99d5a178 100644 --- a/CRM/Upgrade/Incremental/sql/4.7.1.mysql.tpl +++ b/CRM/Upgrade/Incremental/sql/4.7.1.mysql.tpl @@ -1,32 +1 @@ {* file to handle db changes in 4.7.1 during upgrade *} -# CRM-17852 - Misspeled state names in Estonia/Lithuania - -#Estonia - -SET @EstoniaCountryId = (SELECT id FROM civicrm_country cc WHERE cc.name = 'Estonia'); - -UPDATE civicrm_state_province SET name = 'Harjumaa' where name='Harjumsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Hiiumaa' where name='Hitumea' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Ida-Virumaa' where name='Ida-Virumsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Jõgevamaa' where name='Jogevamsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Järvamaa' where name='Jarvamsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Läänemaa' where name='Lasnemsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Lääne-Virumaa' where name='Laane-Virumaa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Põlvamaa' where name='Polvamea' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Pärnumaa' where name='Parnumsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Raplamaa' where name='Raplamsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Saaremaa' where name='Saaremsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Tartumaa' where name='Tartumsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Viljandimaa' where name='Viljandimsa' AND country_id = @EstoniaCountryId; -UPDATE civicrm_state_province SET name = 'Võrumaa' where name='Vorumaa' AND country_id = @EstoniaCountryId; - -#Lithuania - -SET @LithuaniaCountryId = (SELECT id FROM civicrm_country cc WHERE cc.name = 'Lithuania'); - -UPDATE civicrm_state_province SET name = 'Klaipėdos Apskritis' where name='Klaipedos Apskritis' AND country_id = @LithuaniaCountryId; -UPDATE civicrm_state_province SET name = 'Marijampolės Apskritis' where name='Marijampoles Apskritis' AND country_id = @LithuaniaCountryId; -UPDATE civicrm_state_province SET name = 'Panevėžio Apskritis' where name='Panevezio Apskritis' AND country_id = @LithuaniaCountryId; -UPDATE civicrm_state_province SET name = 'Šiaulių Apskritis' where name='Sisuliu Apskritis' AND country_id = @LithuaniaCountryId; -UPDATE civicrm_state_province SET name = 'Tauragės Apskritis' where name='Taurages Apskritis' AND country_id = @LithuaniaCountryId; -UPDATE civicrm_state_province SET name = 'Telšių Apskritis' where name='Telsiu Apskritis' AND country_id = @LithuaniaCountryId; diff --git a/CRM/Upgrade/Incremental/sql/4.7.2.mysql.tpl b/CRM/Upgrade/Incremental/sql/4.7.2.mysql.tpl index 2e87e38e6570..8a258e453a68 100644 --- a/CRM/Upgrade/Incremental/sql/4.7.2.mysql.tpl +++ b/CRM/Upgrade/Incremental/sql/4.7.2.mysql.tpl @@ -1,29 +1 @@ {* file to handle db changes in 4.7.2 during upgrade *} -# CRM-18014 - Missspeled county names in Sweden - -#Sweden - -SET @SwedenCountryId = (SELECT id FROM civicrm_country cc WHERE cc.name = 'Sweden'); - -UPDATE civicrm_state_province SET name = 'Blekinge län' where name='Blekinge lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Dalarnas län' where name='Dalarnas lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Gävleborgs län' where name='Gavleborge lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Gotlands län' where name='Gotlands lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Hallands län' where name='Hallands lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Jämtlands län' where name='Jamtlande lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Jönköpings län' where name='Jonkopings lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Kalmar län' where name='Kalmar lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Kronobergs län' where name='Kronoberge lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Norrbottens län' where name='Norrbottena lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Örebro län' where name='Orebro lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Östergötlands län' where name='Ostergotlands lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Skåne län' where name='Skane lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Södermanlands län' where name='Sodermanlands lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Stockholms län' where name='Stockholms lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Uppsala län' where name='Uppsala lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Värmlands län' where name='Varmlanda lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Västerbottens län' where name='Vasterbottens lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Västernorrlands län' where name='Vasternorrlands lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Västmanlands län' where name='Vastmanlanda lan' AND country_id = @SwedenCountryId; -UPDATE civicrm_state_province SET name = 'Västra Götalands län' where name='Vastra Gotalands lan' AND country_id = @SwedenCountryId; - diff --git a/CRM/Upgrade/Incremental/sql/4.7.4.mysql.tpl b/CRM/Upgrade/Incremental/sql/4.7.4.mysql.tpl index 4755bbea29d9..1079b1ad157a 100644 --- a/CRM/Upgrade/Incremental/sql/4.7.4.mysql.tpl +++ b/CRM/Upgrade/Incremental/sql/4.7.4.mysql.tpl @@ -1,5 +1 @@ {* file to handle db changes in 4.7.4 during upgrade *} -{include file='../CRM/Upgrade/4.7.4.msg_template/civicrm_msg_template.tpl'} - --- CRM-18037 - update preferred mail format to set as default -UPDATE `civicrm_contact` SET `preferred_mail_format` = 'Both' WHERE `preferred_mail_format` IS NULL; diff --git a/CRM/Upgrade/Incremental/sql/4.7.7.mysql.tpl b/CRM/Upgrade/Incremental/sql/4.7.7.mysql.tpl index a6430c44a570..ce446ac804e6 100644 --- a/CRM/Upgrade/Incremental/sql/4.7.7.mysql.tpl +++ b/CRM/Upgrade/Incremental/sql/4.7.7.mysql.tpl @@ -1,4 +1,66 @@ {* file to handle db changes in 4.7.7 during upgrade *} +# CRM-17852 - Misspeled state names in Estonia/Lithuania +#Estonia + +SET @EstoniaCountryId = (SELECT id FROM civicrm_country cc WHERE cc.name = 'Estonia'); + +UPDATE civicrm_state_province SET name = 'Harjumaa' where name='Harjumsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Hiiumaa' where name='Hitumea' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Ida-Virumaa' where name='Ida-Virumsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Jõgevamaa' where name='Jogevamsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Järvamaa' where name='Jarvamsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Läänemaa' where name='Lasnemsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Lääne-Virumaa' where name='Laane-Virumaa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Põlvamaa' where name='Polvamea' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Pärnumaa' where name='Parnumsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Raplamaa' where name='Raplamsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Saaremaa' where name='Saaremsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Tartumaa' where name='Tartumsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Viljandimaa' where name='Viljandimsa' AND country_id = @EstoniaCountryId; +UPDATE civicrm_state_province SET name = 'Võrumaa' where name='Vorumaa' AND country_id = @EstoniaCountryId; + +#Lithuania + +SET @LithuaniaCountryId = (SELECT id FROM civicrm_country cc WHERE cc.name = 'Lithuania'); + +UPDATE civicrm_state_province SET name = 'Klaipėdos Apskritis' where name='Klaipedos Apskritis' AND country_id = @LithuaniaCountryId; +UPDATE civicrm_state_province SET name = 'Marijampolės Apskritis' where name='Marijampoles Apskritis' AND country_id = @LithuaniaCountryId; +UPDATE civicrm_state_province SET name = 'Panevėžio Apskritis' where name='Panevezio Apskritis' AND country_id = @LithuaniaCountryId; +UPDATE civicrm_state_province SET name = 'Šiaulių Apskritis' where name='Sisuliu Apskritis' AND country_id = @LithuaniaCountryId; +UPDATE civicrm_state_province SET name = 'Tauragės Apskritis' where name='Taurages Apskritis' AND country_id = @LithuaniaCountryId; +UPDATE civicrm_state_province SET name = 'Telšių Apskritis' where name='Telsiu Apskritis' AND country_id = @LithuaniaCountryId; + +# CRM-18014 - Missspeled county names in Sweden + +SET @SwedenCountryId = (SELECT id FROM civicrm_country cc WHERE cc.name = 'Sweden'); + +UPDATE civicrm_state_province SET name = 'Blekinge län' where name='Blekinge lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Dalarnas län' where name='Dalarnas lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Gävleborgs län' where name='Gavleborge lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Gotlands län' where name='Gotlands lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Hallands län' where name='Hallands lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Jämtlands län' where name='Jamtlande lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Jönköpings län' where name='Jonkopings lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Kalmar län' where name='Kalmar lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Kronobergs län' where name='Kronoberge lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Norrbottens län' where name='Norrbottena lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Örebro län' where name='Orebro lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Östergötlands län' where name='Ostergotlands lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Skåne län' where name='Skane lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Södermanlands län' where name='Sodermanlands lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Stockholms län' where name='Stockholms lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Uppsala län' where name='Uppsala lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Värmlands län' where name='Varmlanda lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Västerbottens län' where name='Vasterbottens lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Västernorrlands län' where name='Vasternorrlands lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Västmanlands län' where name='Vastmanlanda lan' AND country_id = @SwedenCountryId; +UPDATE civicrm_state_province SET name = 'Västra Götalands län' where name='Vastra Gotalands lan' AND country_id = @SwedenCountryId; + +{include file='../CRM/Upgrade/4.7.4.msg_template/civicrm_msg_template.tpl'} + +-- CRM-18037 - update preferred mail format to set as default +UPDATE `civicrm_contact` SET `preferred_mail_format` = 'Both' WHERE `preferred_mail_format` IS NULL; + -- Fix weight interchange of `Extensions` and `Connections` navigation menu SELECT @parent_id := id from `civicrm_navigation` where name = 'System Settings' AND domain_id = {$domainID}; UPDATE From ecba2dac43145edd865cf3a95d7451c7594278e7 Mon Sep 17 00:00:00 2001 From: eileenmcnaugton Date: Wed, 27 Apr 2016 19:37:02 +1200 Subject: [PATCH 15/42] CRM-18469, CRM-17984 - getTree regression on multiple integers separated by the cnrtl char --- CRM/Core/BAO/CustomGroup.php | 7 ++++++- .../phpunit/CRM/Core/BAO/CustomGroupTest.php | 21 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CRM/Core/BAO/CustomGroup.php b/CRM/Core/BAO/CustomGroup.php index d56c7ed18bdd..837bde7f1b4f 100644 --- a/CRM/Core/BAO/CustomGroup.php +++ b/CRM/Core/BAO/CustomGroup.php @@ -363,7 +363,12 @@ public static function getTree( $subTypes = array(); } else { - $subTypes = explode(',', $subTypes); + if (stristr(',', $subTypes)) { + $subTypes = explode(',', $subTypes); + } + else { + $subTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($subTypes, CRM_Core_DAO::VALUE_SEPARATOR)); + } } } diff --git a/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php b/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php index ac6962f058d7..3d35f4425184 100644 --- a/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php +++ b/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php @@ -72,6 +72,25 @@ public function testGetTreeContactSubType() { $this->fail('There is no such thing as a small kind bank'); } + /** + * Test calling getTree with contact subtype data. + * + * Note that the function seems to support a range of formats so 3 are tested. Yay for + * inconsistency. + */ + public function testGetTreeCampaignSubType() { + $this->campaignCreate(); + $this->campaignCreate(); + $customGroup = $this->CustomGroupCreate(array( + 'extends' => 'Campaign', + 'extends_entity_column_value' => '12' + )); + $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id'])); + $result1 = CRM_Core_BAO_CustomGroup::getTree('Campaign', NULL, NULL, NULL, '12'); + $this->assertEquals('Custom Field', $result1[$customGroup['id']]['fields'][$customField['id']]['label']); + $this->customGroupDelete($customGroup['id']); + } + /** * Test calling getTree with contact subtype data. */ @@ -84,7 +103,7 @@ public function testGetTreeActivitySubType() { } /** - * Test retrieve() with Empty Params + * Test retrieve() with Empty Params. */ public function testRetrieveEmptyParams() { $params = array(); From a808dea0d2d411761e72e1c38c15d5eed0362572 Mon Sep 17 00:00:00 2001 From: eileenmcnaugton Date: Wed, 27 Apr 2016 20:13:41 +1200 Subject: [PATCH 16/42] Further custom tree regression fix, where the label does not match the name the name is the key to use --- CRM/Core/BAO/CustomGroup.php | 2 +- tests/phpunit/CRM/Core/BAO/CustomGroupTest.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CRM/Core/BAO/CustomGroup.php b/CRM/Core/BAO/CustomGroup.php index 837bde7f1b4f..0d76d4672fdb 100644 --- a/CRM/Core/BAO/CustomGroup.php +++ b/CRM/Core/BAO/CustomGroup.php @@ -658,7 +658,7 @@ protected static function validateSubTypeByEntity($entityType, $subType) { throw new CRM_Core_Exception('Invalid Entity Filter'); } $subTypes = civicrm_api3('Contact', 'getoptions', array('field' => 'contact_sub_type')); - if (!in_array($subType, $subTypes['values'])) { + if (!isset($subTypes['values'][$subType])) { // Same comments about fail hard as above. throw new CRM_Core_Exception('Invalid Filter'); } diff --git a/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php b/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php index 3d35f4425184..efd65a52070c 100644 --- a/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php +++ b/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php @@ -53,14 +53,14 @@ public function testGetTree() { * inconsistency. */ public function testGetTreeContactSubType() { - $this->callAPISuccess('ContactType', 'create', array('name' => 'Big Bank', 'parent_id' => 'Organization')); - $customGroup = $this->CustomGroupCreate(array('extends' => 'Organization', 'extends_entity_column_value' => array('Big Bank'))); + $this->callAPISuccess('ContactType', 'create', array('name' => 'Big Bank', 'label' => 'biggee', 'parent_id' => 'Organization')); + $customGroup = $this->CustomGroupCreate(array('extends' => 'Organization', 'extends_entity_column_value' => array('Big_Bank'))); $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id'])); - $result1 = CRM_Core_BAO_CustomGroup::getTree('Organization', NULL, NULL, NULL, array('Big Bank')); + $result1 = CRM_Core_BAO_CustomGroup::getTree('Organization', NULL, NULL, NULL, array('Big_Bank')); $this->assertEquals('Custom Field', $result1[$customGroup['id']]['fields'][$customField['id']]['label']); - $result = CRM_Core_BAO_CustomGroup::getTree('Organization', NULL, NULL, NULL, CRM_Core_DAO::VALUE_SEPARATOR . 'Big Bank' . CRM_Core_DAO::VALUE_SEPARATOR); + $result = CRM_Core_BAO_CustomGroup::getTree('Organization', NULL, NULL, NULL, CRM_Core_DAO::VALUE_SEPARATOR . 'Big_Bank' . CRM_Core_DAO::VALUE_SEPARATOR); $this->assertEquals($result1, $result); - $result = CRM_Core_BAO_CustomGroup::getTree('Organization', NULL, NULL, NULL, 'Big Bank'); + $result = CRM_Core_BAO_CustomGroup::getTree('Organization', NULL, NULL, NULL, 'Big_Bank'); $this->assertEquals($result1, $result); try { CRM_Core_BAO_CustomGroup::getTree('Organization', NULL, NULL, NULL, array('Small Kind Bank')); From e527e895d1ead6495bbe61c487bc271b0f00aaa1 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 27 Apr 2016 11:52:47 -0700 Subject: [PATCH 17/42] CRM-17984 - CustomGroupTest - Fix style errors There were problems in this line: * The missing comma (required by Drupal style) * The use of literal CtrlA causes phpcs to produce invalid output --- tests/phpunit/CRM/Core/BAO/CustomGroupTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php b/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php index efd65a52070c..9e07753e5f2c 100644 --- a/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php +++ b/tests/phpunit/CRM/Core/BAO/CustomGroupTest.php @@ -79,11 +79,12 @@ public function testGetTreeContactSubType() { * inconsistency. */ public function testGetTreeCampaignSubType() { + $sep = CRM_Core_DAO::VALUE_SEPARATOR; $this->campaignCreate(); $this->campaignCreate(); $customGroup = $this->CustomGroupCreate(array( 'extends' => 'Campaign', - 'extends_entity_column_value' => '12' + 'extends_entity_column_value' => "{$sep}1{$sep}2{$sep}", )); $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id'])); $result1 = CRM_Core_BAO_CustomGroup::getTree('Campaign', NULL, NULL, NULL, '12'); From dc08df84f716ebb1292d7642652c70a1181b340a Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Mon, 25 Apr 2016 17:16:49 +0200 Subject: [PATCH 18/42] First WIP for AJAX cleanup. --- CRM/Activity/Page/AJAX.php | 121 ++++++++++--------------------------- CRM/Core/Page/AJAX.php | 27 ++++++++- CRM/Custom/Page/AJAX.php | 22 +++---- CRM/Group/Page/AJAX.php | 19 +----- CRM/Mailing/Page/AJAX.php | 23 +------ CRM/Utils/Type.php | 2 +- 6 files changed, 69 insertions(+), 145 deletions(-) diff --git a/CRM/Activity/Page/AJAX.php b/CRM/Activity/Page/AJAX.php index 4035106c8443..783f262c47f7 100644 --- a/CRM/Activity/Page/AJAX.php +++ b/CRM/Activity/Page/AJAX.php @@ -37,27 +37,23 @@ */ class CRM_Activity_Page_AJAX { public static function getCaseActivity() { + // Should those params be passed through the getSanitizedParams method? $caseID = CRM_Utils_Type::escape($_GET['caseID'], 'Integer'); $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer'); $userID = CRM_Utils_Type::escape($_GET['userID'], 'Integer'); $context = CRM_Utils_Type::escape(CRM_Utils_Array::value('context', $_GET), 'String'); - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; + $optionalParameters = array( + 'source_contact_id' => 'Integer', + 'status_id' => 'Integer', + 'activity_deleted' => 'Boolean', + 'activity_type_id' => 'Integer', + 'activity_date_low' => 'String', + 'activity_date_high' => 'String', + ); - $params = $_GET; - if ($sort && $sortOrder) { - $params['sortBy'] = $sort . ' ' . $sortOrder; - } - $params['page'] = ($offset / $rowCount) + 1; - $params['rp'] = $rowCount; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); + $params += CRM_Core_Page_AJAX::getSanitizedParams(array(), $optionalParameters); // get the activities related to given case $activities = CRM_Case_BAO_Case::getCaseActivity($caseID, $params, $contactID, $context, $userID); @@ -66,31 +62,15 @@ public static function getCaseActivity() { } public static function getCaseGlobalRelationships() { - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; - - $params = $_GET; - - // CRM-14466 initialize variable to avoid php notice. - $sortSQL = ""; - if ($sort && $sortOrder) { - $sortSQL = $sort . ' ' . $sortOrder; - } + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); // get the activities related to given case $globalGroupInfo = array(); // get the total row count - $relGlobalTotalCount = CRM_Case_BAO_Case::getGlobalContacts($globalGroupInfo, NULL, FALSE, TRUE, NULL, NULL); + CRM_Case_BAO_Case::getGlobalContacts($globalGroupInfo, NULL, FALSE, TRUE, NULL, NULL); // limit the rows - $relGlobal = CRM_Case_BAO_Case::getGlobalContacts($globalGroupInfo, $sortSQL, $showLinks = TRUE, FALSE, $offset, $rowCount); + $relGlobal = CRM_Case_BAO_Case::getGlobalContacts($globalGroupInfo, $params['sortBy'], $showLinks = TRUE, FALSE, $params['offset'], $params['rp']); $relationships = array(); // after sort we can update username fields to be a url @@ -103,12 +83,10 @@ public static function getCaseGlobalRelationships() { array_push($relationships, $relationship); } - $params['total'] = count($relationships); - $globalRelationshipsDT = array(); $globalRelationshipsDT['data'] = $relationships; - $globalRelationshipsDT['recordsTotal'] = $params['total']; - $globalRelationshipsDT['recordsFiltered'] = $params['total']; + $globalRelationshipsDT['recordsTotal'] = count($relationships); + $globalRelationshipsDT['recordsFiltered'] = count($relationships); CRM_Utils_JSON::output($globalRelationshipsDT); } @@ -117,17 +95,7 @@ public static function getCaseClientRelationships() { $caseID = CRM_Utils_Type::escape($_GET['caseID'], 'Integer'); $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer'); - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; - - $params = $_GET; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); // Retrieve ALL client relationships $relClient = CRM_Contact_BAO_Relationship::getRelationship($contactID, @@ -148,9 +116,9 @@ public static function getCaseClientRelationships() { // sort clientRelationships array using jquery call params foreach ($clientRelationships as $key => $row) { - $sortArray[$key] = $row[$sort]; + $sortArray[$key] = $row[$params['_raw_values']['sort'][0]]; } - $sort_type = "SORT_" . strtoupper($sortOrder); + $sort_type = "SORT_" . strtoupper($params['_raw_values']['order'][0]); array_multisort($sortArray, constant($sort_type), $clientRelationships); $relationships = array(); @@ -166,12 +134,10 @@ public static function getCaseClientRelationships() { array_push($relationships, $relationship); } - $params['total'] = count($relationships); - $clientRelationshipsDT = array(); $clientRelationshipsDT['data'] = $relationships; - $clientRelationshipsDT['recordsTotal'] = $params['total']; - $clientRelationshipsDT['recordsFiltered'] = $params['total']; + $clientRelationshipsDT['recordsTotal'] = count($relationships); + $clientRelationshipsDT['recordsFiltered'] = count($relationships); CRM_Utils_JSON::output($clientRelationshipsDT); } @@ -181,17 +147,7 @@ public static function getCaseRoles() { $caseID = CRM_Utils_Type::escape($_GET['caseID'], 'Integer'); $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer'); - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; - - $params = $_GET; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); $caseRelationships = CRM_Case_BAO_Case::getCaseRoles($contactID, $caseID); $caseTypeName = CRM_Case_BAO_Case::getCaseType($caseID, 'name'); @@ -241,9 +197,9 @@ public static function getCaseRoles() { // sort clientRelationships array using jquery call params foreach ($caseRelationships as $key => $row) { - $sortArray[$key] = $row[$sort]; + $sortArray[$key] = $row[$params['_raw_values']['sort'][0]]; } - $sort_type = "SORT_" . strtoupper($sortOrder); + $sort_type = "SORT_" . strtoupper($params['_raw_values']['order'][0]); array_multisort($sortArray, constant($sort_type), $caseRelationships); $relationships = array(); @@ -434,29 +390,16 @@ public static function _convertToCaseActivity($params) { } public static function getContactActivity() { - $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer'); - $context = CRM_Utils_Type::escape(CRM_Utils_Array::value('context', $_GET), 'String'); - - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; - - $params = $_GET; - if ($sort && $sortOrder) { - $params['sortBy'] = $sort . ' ' . $sortOrder; - } + $requiredParameters = array( + 'cid' => 'Integer', + ); - $params['page'] = ($offset / $rowCount) + 1; - $params['rp'] = $rowCount; + $optionalParameters = array( + 'context' => 'String', + ); - $params['contact_id'] = $contactID; - $params['context'] = $context; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); + $params += CRM_Core_Page_AJAX::getSanitizedParams($requiredParameters, $optionalParameters); // get the contact activities $activities = CRM_Activity_BAO_Activity::getContactActivitySelector($params); diff --git a/CRM/Core/Page/AJAX.php b/CRM/Core/Page/AJAX.php index 9777e8f5d177..cfc7e8d909be 100644 --- a/CRM/Core/Page/AJAX.php +++ b/CRM/Core/Page/AJAX.php @@ -215,7 +215,9 @@ public static function setJsHeaders($ttl = NULL) { } public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRowCount = 25, $defaultSort = NULL, $defaultsortOrder = 'asc') { - $params = array(); + $params = array( + '_raw_values' => array(), + ); $sortMapper = array(); foreach ($_GET['columns'] as $key => $value) { @@ -230,12 +232,33 @@ public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRow if ($sort) { $params['sortBy'] = "`{$sort}` {$sortOrder}"; + + $params['_raw_values']['sort'][0] = $sort; + $params['_raw_values']['order'][0] = $sortOrder; } - $params['page'] = ($offset / $rowCount) + 1; + $params['offset'] = $offset; $params['rp'] = $rowCount; + $params['page'] = ($offset / $rowCount) + 1; + + return $params; + } + + public static function getSanitizedParams($requiredParams = array(), $optionalParams = array()) { + $params = array(); + + foreach ($requiredParams as $param => $type) { + $params[$param] = CRM_Utils_Type::escape(CRM_Utils_Array::value($param, $_GET), $type); + } + + foreach ($optionalParams as $param => $type) { + if (CRM_Utils_Array::value($param, $_GET)) { + $params[$param] = CRM_Utils_Type::escape(CRM_Utils_Array::value($param, $_GET), $type); + } + } return $params; + } } diff --git a/CRM/Custom/Page/AJAX.php b/CRM/Custom/Page/AJAX.php index 59b5cf28e0d1..1bd938996f71 100644 --- a/CRM/Custom/Page/AJAX.php +++ b/CRM/Custom/Page/AJAX.php @@ -111,19 +111,11 @@ public static function fixOrdering() { * */ public static function getMultiRecordFieldList() { - $params = $_GET; - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 10; - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(0, 10); + $params['cid'] = CRM_Utils_Type::escape($_GET['cid'], 'Integer'); + $params['cgid'] = CRM_Utils_Type::escape($_GET['cgid'], 'Integer'); - $params['page'] = ($offset / $rowCount) + 1; - $params['rp'] = $rowCount; $contactType = CRM_Contact_BAO_Contact::getContactType($params['cid']); $obj = new CRM_Profile_Page_MultipleRecordFieldsListing(); @@ -133,9 +125,11 @@ public static function getMultiRecordFieldList() { $obj->_contactType = $contactType; $obj->_DTparams['offset'] = ($params['page'] - 1) * $params['rp']; $obj->_DTparams['rowCount'] = $params['rp']; - if ($sort && $sortOrder) { - $sort = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $sort, 'column_name', 'label'); - $obj->_DTparams['sort'] = $sort . ' ' . $sortOrder; + if (isset($params['_raw_values']['sort'][0])) { + // Will this work when CiviCRM is translated, as searching happens on the label column? + // I can't find a place where the sort is added, but it should use the name, not the label. + $sort = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $params['_raw_values']['sort'][0], 'column_name', 'label'); + $obj->_DTparams['sort'] = $sort . ' ' . $params['_raw_values']['order'][0]; } list($fields, $attributes) = $obj->browse(); diff --git a/CRM/Group/Page/AJAX.php b/CRM/Group/Page/AJAX.php index 045e6119148e..2050348fa90b 100644 --- a/CRM/Group/Page/AJAX.php +++ b/CRM/Group/Page/AJAX.php @@ -50,24 +50,7 @@ public static function getGroupList() { CRM_Utils_JSON::output($groups); } else { - - $sortMapper = array(); - $columns = CRM_Utils_Array::value('columns', $params, array()); - foreach ($columns as $key => $value) { - $sortMapper[$key] = $value['data']; - } - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; - - if ($sort && $sortOrder) { - $params['sortBy'] = $sort . ' ' . $sortOrder; - } - - $params['page'] = ($offset / $rowCount) + 1; - $params['rp'] = $rowCount; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); // get group list $groups = CRM_Contact_BAO_Group::getGroupListSelector($params); diff --git a/CRM/Mailing/Page/AJAX.php b/CRM/Mailing/Page/AJAX.php index 72341aca53ed..3e7f9746df29 100644 --- a/CRM/Mailing/Page/AJAX.php +++ b/CRM/Mailing/Page/AJAX.php @@ -61,27 +61,8 @@ public static function template() { * Retrieve contact mailings. */ public static function getContactMailings() { - $contactID = CRM_Utils_Type::escape($_GET['contact_id'], 'Integer'); - - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; - - $params = $_GET; - if ($sort && $sortOrder) { - $params['sortBy'] = $sort . ' ' . $sortOrder; - } - - $params['page'] = ($offset / $rowCount) + 1; - $params['rp'] = $rowCount; - - $params['contact_id'] = $contactID; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); + $params += CRM_Core_Page_AJAX::getSanitizedParams(array('contact_id' => 'Integer')); // get the contact mailings $mailings = CRM_Mailing_BAO_Mailing::getContactMailingSelector($params); diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index 25bf54ff2127..50c242df8d59 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -258,7 +258,7 @@ public static function escape($data, $type, $abort = TRUE) { case 'MysqlColumnNameLoose': if (CRM_Utils_Rule::mysqlColumnNameLoose($data)) { - return str_replace('`', '', $data); + return str_replace('`', '``', $data); } break; From 0e63a819187123f5475d4d7a0b05b3e98a9d3b7b Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Mon, 25 Apr 2016 23:44:24 +0200 Subject: [PATCH 19/42] Extra ajax fixes. --- CRM/Contact/Page/AJAX.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CRM/Contact/Page/AJAX.php b/CRM/Contact/Page/AJAX.php index cd9712308888..e4c8d7527581 100644 --- a/CRM/Contact/Page/AJAX.php +++ b/CRM/Contact/Page/AJAX.php @@ -892,8 +892,10 @@ public static function flipDupePairs($prevNextId = NULL) { INNER JOIN civicrm_prevnext_cache old on cpc.id = old.id SET cpc.entity_id1 = cpc.entity_id2, cpc.entity_id2 = old.entity_id1 "; if (is_array($prevNextId) && !CRM_Utils_Array::crmIsEmptyArray($prevNextId)) { + foreach ($prevNextId as $id) { + CRM_Utils_Type::escape($id, 'Positive'); + } $prevNextId = implode(', ', $prevNextId); - $prevNextId = CRM_Utils_Type::escape($prevNextId, 'String'); $query .= "WHERE cpc.id IN ({$prevNextId}) AND cpc.is_selected = 1"; } else { @@ -991,8 +993,10 @@ public static function toggleDedupeSelect() { //check pnid is_array or integer $whereClause = NULL; if (is_array($pnid) && !CRM_Utils_Array::crmIsEmptyArray($pnid)) { + foreach ($pnid as $id) { + CRM_Utils_Type::escape($id, 'Positive'); + } $pnid = implode(', ', $pnid); - $pnid = CRM_Utils_Type::escape($pnid, 'String'); $whereClause = " id IN ( {$pnid} ) "; } else { From 1888fc57bf3065ec97b538a643e9454bc59ddc1d Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 26 Apr 2016 07:50:23 +0200 Subject: [PATCH 20/42] Made correct distinction between validate and escape. --- CRM/Activity/Page/AJAX.php | 18 +++++++++--------- CRM/Core/Page/AJAX.php | 14 +++++++------- CRM/Utils/Type.php | 24 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/CRM/Activity/Page/AJAX.php b/CRM/Activity/Page/AJAX.php index 783f262c47f7..21164501e693 100644 --- a/CRM/Activity/Page/AJAX.php +++ b/CRM/Activity/Page/AJAX.php @@ -37,23 +37,23 @@ */ class CRM_Activity_Page_AJAX { public static function getCaseActivity() { - // Should those params be passed through the getSanitizedParams method? - $caseID = CRM_Utils_Type::escape($_GET['caseID'], 'Integer'); - $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer'); - $userID = CRM_Utils_Type::escape($_GET['userID'], 'Integer'); - $context = CRM_Utils_Type::escape(CRM_Utils_Array::value('context', $_GET), 'String'); + // Should those params be passed through the validateParams method? + $caseID = CRM_Utils_Type::validate($_GET['caseID'], 'Integer'); + $contactID = CRM_Utils_Type::validate($_GET['cid'], 'Integer'); + $userID = CRM_Utils_Type::validate($_GET['userID'], 'Integer'); + $context = CRM_Utils_Type::validate(CRM_Utils_Array::value('context', $_GET), 'String'); $optionalParameters = array( 'source_contact_id' => 'Integer', 'status_id' => 'Integer', 'activity_deleted' => 'Boolean', 'activity_type_id' => 'Integer', - 'activity_date_low' => 'String', - 'activity_date_high' => 'String', + 'activity_date_low' => 'Date', + 'activity_date_high' => 'Date', ); $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); - $params += CRM_Core_Page_AJAX::getSanitizedParams(array(), $optionalParameters); + $params += CRM_Core_Page_AJAX::validateParams(array(), $optionalParameters); // get the activities related to given case $activities = CRM_Case_BAO_Case::getCaseActivity($caseID, $params, $contactID, $context, $userID); @@ -399,7 +399,7 @@ public static function getContactActivity() { ); $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); - $params += CRM_Core_Page_AJAX::getSanitizedParams($requiredParameters, $optionalParameters); + $params += CRM_Core_Page_AJAX::validateParams($requiredParameters, $optionalParameters); // get the contact activities $activities = CRM_Activity_BAO_Activity::getContactActivitySelector($params); diff --git a/CRM/Core/Page/AJAX.php b/CRM/Core/Page/AJAX.php index cfc7e8d909be..3a4559878662 100644 --- a/CRM/Core/Page/AJAX.php +++ b/CRM/Core/Page/AJAX.php @@ -224,11 +224,11 @@ public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRow $sortMapper[$key] = CRM_Utils_Type::escape($value['data'], 'MysqlColumnName'); }; - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : $defaultOffset; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : $defaultRowCount; + $offset = isset($_GET['start']) ? CRM_Utils_Type::validate($_GET['start'], 'Integer') : $defaultOffset; + $rowCount = isset($_GET['length']) ? CRM_Utils_Type::validate($_GET['length'], 'Integer') : $defaultRowCount; // Why is the number of order by columns limited to 1? - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : $defaultSort; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'MysqlOrderByDirection') : $defaultsortOrder; + $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::validate($_GET['order'][0]['column'], 'Integer'), $sortMapper) : $defaultSort; + $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::validate($_GET['order'][0]['dir'], 'MysqlOrderByDirection') : $defaultsortOrder; if ($sort) { $params['sortBy'] = "`{$sort}` {$sortOrder}"; @@ -244,16 +244,16 @@ public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRow return $params; } - public static function getSanitizedParams($requiredParams = array(), $optionalParams = array()) { + public static function validateParams($requiredParams = array(), $optionalParams = array()) { $params = array(); foreach ($requiredParams as $param => $type) { - $params[$param] = CRM_Utils_Type::escape(CRM_Utils_Array::value($param, $_GET), $type); + $params[$param] = CRM_Utils_Type::validate(CRM_Utils_Array::value($param, $_GET), $type); } foreach ($optionalParams as $param => $type) { if (CRM_Utils_Array::value($param, $_GET)) { - $params[$param] = CRM_Utils_Type::escape(CRM_Utils_Array::value($param, $_GET), $type); + $params[$param] = CRM_Utils_Type::validate(CRM_Utils_Array::value($param, $_GET), $type); } } diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index 50c242df8d59..81e8274f91f1 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -377,6 +377,30 @@ public static function validate($data, $type, $abort = TRUE, $name = 'One of par } break; + case 'MysqlColumnNameLoose': + if (CRM_Utils_Rule::mysqlColumnNameLoose($data)) { + return data; + } + break; + + case 'MysqlColumnName': + if (CRM_Utils_Rule::mysqlColumnName($data)) { + return $data; + } + break; + + case 'MysqlOrderByDirection': + if (CRM_Utils_Rule::mysqlOrderByDirection($data)) { + return $data; + } + break; + + case 'MysqlOrderBy': + if (CRM_Utils_Rule::mysqlOrderBy($data)) { + return $data; + } + break; + default: CRM_Core_Error::fatal("Cannot recognize $type for $data"); break; From 89262ef0dffd4b8a797e3c423138edd181a213b3 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 26 Apr 2016 07:51:22 +0200 Subject: [PATCH 21/42] Just discovered CRM_Utils_Type::escapeAll --- CRM/Contact/Page/AJAX.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CRM/Contact/Page/AJAX.php b/CRM/Contact/Page/AJAX.php index e4c8d7527581..fa3902b4ee5c 100644 --- a/CRM/Contact/Page/AJAX.php +++ b/CRM/Contact/Page/AJAX.php @@ -892,9 +892,7 @@ public static function flipDupePairs($prevNextId = NULL) { INNER JOIN civicrm_prevnext_cache old on cpc.id = old.id SET cpc.entity_id1 = cpc.entity_id2, cpc.entity_id2 = old.entity_id1 "; if (is_array($prevNextId) && !CRM_Utils_Array::crmIsEmptyArray($prevNextId)) { - foreach ($prevNextId as $id) { - CRM_Utils_Type::escape($id, 'Positive'); - } + CRM_Utils_Type::escapeAll($prevNextId, 'Positive'); $prevNextId = implode(', ', $prevNextId); $query .= "WHERE cpc.id IN ({$prevNextId}) AND cpc.is_selected = 1"; } @@ -993,9 +991,7 @@ public static function toggleDedupeSelect() { //check pnid is_array or integer $whereClause = NULL; if (is_array($pnid) && !CRM_Utils_Array::crmIsEmptyArray($pnid)) { - foreach ($pnid as $id) { - CRM_Utils_Type::escape($id, 'Positive'); - } + CRM_Utils_Type::escapeAll($pnid, 'Positive'); $pnid = implode(', ', $pnid); $whereClause = " id IN ( {$pnid} ) "; } From 2fe5b4f9745c688cfc69cc946f85e1af79daad75 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 26 Apr 2016 14:10:49 +0200 Subject: [PATCH 22/42] Added tests + validate and escape checks for mysql order by. --- CRM/Utils/Rule.php | 19 +++++++++ CRM/Utils/Type.php | 58 ++++++++++++++++++++++++++-- tests/phpunit/CRM/Utils/TypeTest.php | 20 ++++++++++ 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/CRM/Utils/Rule.php b/CRM/Utils/Rule.php index 08cbcc4a0b4f..73b978967bcb 100644 --- a/CRM/Utils/Rule.php +++ b/CRM/Utils/Rule.php @@ -143,6 +143,25 @@ public static function mysqlOrderByDirection($str) { return TRUE; } + /** + * Validate that a string is valid order by clause. + * + * @param $str + * @return bool + */ + public static function mysqlOrderBy($str) { + // Making a regex for a comma separated list is quite hard and not readable + // at all, so we split and loop over. + $parts = explode(',', $str); + foreach ($parts as $part) { + if (!preg_match('/^(([\w_]+)((\.)([\w_]+))?( (asc|desc))?)$/i', trim($part))) { + return FALSE; + } + } + + return TRUE; + } + /** * @param $str * diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index 81e8274f91f1..7f9ddafddba4 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -152,6 +152,18 @@ public static function escapeAll($data, $type, $abort = TRUE) { return $data; } + /** + * Helper function to call validate on arrays + * + * @see validate + */ + public static function validateAll($data, $type, $abort = TRUE) { + foreach ($data as $key => $value) { + $data[$key] = CRM_Utils_Type::validate($value, $type, $abort); + } + return $data; + } + /** * Verify that a variable is of a given type, and apply a bit of processing. * @@ -258,19 +270,35 @@ public static function escape($data, $type, $abort = TRUE) { case 'MysqlColumnNameLoose': if (CRM_Utils_Rule::mysqlColumnNameLoose($data)) { - return str_replace('`', '``', $data); + $parts = explode('.', str_replace('`', '``', $data)); + $data = '`'.implode('`.`', $parts).'`'; + + return $data; } break; case 'MysqlColumnName': if (CRM_Utils_Rule::mysqlColumnName($data)) { + $parts = explode('.', $data); + $data = '`'.implode('`.`', $parts).'`'; + return $data; } break; case 'MysqlOrderByDirection': if (CRM_Utils_Rule::mysqlOrderByDirection($data)) { - return $data; + return strtolower($data); + } + break; + + case 'MysqlOrderBy': + if (CRM_Utils_Rule::mysqlOrderBy($data)) { + $parts = explode(',', $data); + foreach ($parts as &$part) { + $part = preg_replace_callback('/(?:([\w_]+)(?:(?:\.)([\w_]+))?(?: (asc|desc))?)/i', array('CRM_Utils_Type', 'mysqlOrderByCallback'), trim($part)); + } + return implode(', ', $parts); } break; @@ -391,7 +419,7 @@ public static function validate($data, $type, $abort = TRUE, $name = 'One of par case 'MysqlOrderByDirection': if (CRM_Utils_Rule::mysqlOrderByDirection($data)) { - return $data; + return strtolower($data); } break; @@ -414,4 +442,28 @@ public static function validate($data, $type, $abort = TRUE, $name = 'One of par return NULL; } + /** + * preg_replace_callback for MysqlOrderBy escape. + */ + public static function mysqlOrderByCallback($matches) { + $output = ''; + + // Column or table name. + if (isset($matches[1])) { + $output .= '`' . $matches[1] . '`'; + } + + // Column name in case there is a table. + if (isset($matches[2]) && $matches[2]) { + $output .= '.`' . $matches[2] . '`'; + } + + // Sort order. + if (isset($matches[3]) && $matches[3]) { + $output .= ' ' . $matches[3]; + } + + return $output; + } + } diff --git a/tests/phpunit/CRM/Utils/TypeTest.php b/tests/phpunit/CRM/Utils/TypeTest.php index 679841fb472d..ae131aa268ad 100644 --- a/tests/phpunit/CRM/Utils/TypeTest.php +++ b/tests/phpunit/CRM/Utils/TypeTest.php @@ -37,6 +37,16 @@ public function validateDataProvider() { array(-10, 'Positive', NULL), array('-10', 'Positive', NULL), array('-10foo', 'Positive', NULL), + array('civicrm_column_name', 'MysqlColumnName', 'civicrm_column_name'), + array('table.civicrm_column_name', 'MysqlColumnName', 'table.civicrm_column_name'), + array('table.civicrm_column_name.toomanydots', 'MysqlColumnName', NULL), + array('invalid-column-name', 'MysqlColumnName', NULL), + array('column_name, sleep(5)', 'MysqlColumnName', NULL), + array('asc', 'MysqlOrderByDirection', 'asc'), + array('DESC', 'MysqlOrderByDirection', 'desc'), + array('DESCc', 'MysqlOrderByDirection', NULL), + array('table.civicrm_column_name desc', 'MysqlOrderBy', 'table.civicrm_column_name desc'), + array('table.civicrm_column_name desc,other_column,another_column desc', 'MysqlOrderBy', 'table.civicrm_column_name desc, other_column, another_column desc'), ); } @@ -75,6 +85,16 @@ public function escapeDataProvider() { array('-3', 'ContactReference', NULL), // Escape function is meant for sql, not xss array('

Hello

', 'Memo', '

Hello

'), + array('civicrm_column_name', 'MysqlColumnName', '`civicrm_column_name`'), + array('table.civicrm_column_name', 'MysqlColumnName', '`table`.`civicrm_column_name`'), + array('table.civicrm_column_name.toomanydots', 'MysqlColumnName', NULL), + array('invalid-column-name', 'MysqlColumnName', NULL), + array('column_name, sleep(5)', 'MysqlColumnName', NULL), + array('asc', 'MysqlOrderByDirection', 'asc'), + array('DESC', 'MysqlOrderByDirection', 'desc'), + array('DESCc', 'MysqlOrderByDirection', NULL), + array('table.civicrm_column_name desc', 'MysqlOrderBy', '`table`.`civicrm_column_name` desc'), + array('table.civicrm_column_name desc,other_column,another_column desc', 'MysqlOrderBy', '`table`.`civicrm_column_name` desc, `other_column`, `another_column` desc'), ); } From 2ac464d5babb8d7f4c14f4a64055d38668d66ca5 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 26 Apr 2016 14:11:55 +0200 Subject: [PATCH 23/42] Adapted CRM_Utils_Sort code to use the validation and escaping. --- CRM/Utils/Sort.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CRM/Utils/Sort.php b/CRM/Utils/Sort.php index 1801f97a4eef..789dba32d65f 100644 --- a/CRM/Utils/Sort.php +++ b/CRM/Utils/Sort.php @@ -121,7 +121,7 @@ public function __construct(&$vars, $defaultSortOrder = NULL) { foreach ($vars as $weight => $value) { $this->_vars[$weight] = array( - 'name' => $value['sort'], + 'name' => CRM_Utils_Type::validate($value['sort'], 'MysqlColumnName'), 'direction' => CRM_Utils_Array::value('direction', $value), 'title' => $value['name'], ); @@ -152,11 +152,11 @@ public function orderBy() { $this->_vars[$this->_currentSortID]['direction'] == self::DONTCARE ) { $this->_vars[$this->_currentSortID]['name'] = str_replace(' ', '_', $this->_vars[$this->_currentSortID]['name']); - return $this->_vars[$this->_currentSortID]['name'] . ' asc'; + return CRM_Utils_Type::validate($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' asc'; } else { $this->_vars[$this->_currentSortID]['name'] = str_replace(' ', '_', $this->_vars[$this->_currentSortID]['name']); - return $this->_vars[$this->_currentSortID]['name'] . ' desc'; + return CRM_Utils_Type::validate($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' desc'; } } From 1e6ec670d994697d3112a8fcecc88963a7cfb1c1 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 26 Apr 2016 14:32:55 +0200 Subject: [PATCH 24/42] Typo fix in tests. --- tests/phpunit/CRM/Utils/TypeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/CRM/Utils/TypeTest.php b/tests/phpunit/CRM/Utils/TypeTest.php index ae131aa268ad..b8371cdd0581 100644 --- a/tests/phpunit/CRM/Utils/TypeTest.php +++ b/tests/phpunit/CRM/Utils/TypeTest.php @@ -46,7 +46,7 @@ public function validateDataProvider() { array('DESC', 'MysqlOrderByDirection', 'desc'), array('DESCc', 'MysqlOrderByDirection', NULL), array('table.civicrm_column_name desc', 'MysqlOrderBy', 'table.civicrm_column_name desc'), - array('table.civicrm_column_name desc,other_column,another_column desc', 'MysqlOrderBy', 'table.civicrm_column_name desc, other_column, another_column desc'), + array('table.civicrm_column_name desc,other_column, another_column desc', 'MysqlOrderBy', 'table.civicrm_column_name desc,other_column, another_column desc'), ); } From 5c829c335264d895e4a523d902bba2a59abe02d0 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Wed, 27 Apr 2016 14:26:50 +0200 Subject: [PATCH 25/42] Removed unnecessary parts of the Mysql regexes. --- CRM/Utils/Rule.php | 4 ++-- CRM/Utils/Type.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CRM/Utils/Rule.php b/CRM/Utils/Rule.php index 73b978967bcb..eeb97a291404 100644 --- a/CRM/Utils/Rule.php +++ b/CRM/Utils/Rule.php @@ -120,7 +120,7 @@ public static function mysqlColumnName($str) { // // MySQL permits column names that don't match this (eg containing spaces), // but CiviCRM won't create those ... - if (!preg_match('/^[\w_]+(\.[\w_]+)?$/i', $str)) { + if (!preg_match('/^[\w]+(\.[\w]+)?$/i', $str)) { return FALSE; } @@ -154,7 +154,7 @@ public static function mysqlOrderBy($str) { // at all, so we split and loop over. $parts = explode(',', $str); foreach ($parts as $part) { - if (!preg_match('/^(([\w_]+)((\.)([\w_]+))?( (asc|desc))?)$/i', trim($part))) { + if (!preg_match('/^(([\w]+)((\.)([\w]+))?( (asc|desc))?)$/i', trim($part))) { return FALSE; } } diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index 7f9ddafddba4..8bbdb8cb6166 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -296,7 +296,7 @@ public static function escape($data, $type, $abort = TRUE) { if (CRM_Utils_Rule::mysqlOrderBy($data)) { $parts = explode(',', $data); foreach ($parts as &$part) { - $part = preg_replace_callback('/(?:([\w_]+)(?:(?:\.)([\w_]+))?(?: (asc|desc))?)/i', array('CRM_Utils_Type', 'mysqlOrderByCallback'), trim($part)); + $part = preg_replace_callback('/(?:([\w]+)(?:(?:\.)([\w]+))?(?: (asc|desc))?)/i', array('CRM_Utils_Type', 'mysqlOrderByCallback'), trim($part)); } return implode(', ', $parts); } From 7e3df0ef8707e6034fbccbd77deb018f1dda8d83 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Wed, 27 Apr 2016 18:22:12 +0200 Subject: [PATCH 26/42] Fixed incorrect regexes for . names + added warning in mysqlColumnNameLoose method. --- CRM/Utils/Rule.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CRM/Utils/Rule.php b/CRM/Utils/Rule.php index eeb97a291404..00af967bd3af 100644 --- a/CRM/Utils/Rule.php +++ b/CRM/Utils/Rule.php @@ -93,9 +93,13 @@ public static function variable($str) { * @return bool */ public static function mysqlColumnNameLoose($str) { - // check the length. - // This check can be incorrect for the
. format, which can be + // Check the length. + // This check is incorrect for the
. format, which can be // a problem. + // But is quit difficult to check, as a dot is also a valid character in a + // column name. In that case backticks are needed, which will + // be escaped in the escape function, which lead to an icorrect name... + // So this function assumes there is only a column name. if (empty($str) || strlen($str) > 64) { return FALSE; } @@ -111,16 +115,16 @@ public static function mysqlColumnNameLoose($str) { * @return bool */ public static function mysqlColumnName($str) { - // Check the length. - if (empty($str) || strlen($str) > 64) { + // Check not empty. + if (empty($str)) { return FALSE; } - // Make sure it only contains valid characters (alphanumeric and underscores). + // Ensure it only contains valid characters (alphanumeric and underscores). // // MySQL permits column names that don't match this (eg containing spaces), // but CiviCRM won't create those ... - if (!preg_match('/^[\w]+(\.[\w]+)?$/i', $str)) { + if (!preg_match('/^\w{1,64}(\.\w{1,64})?$/i', $str)) { return FALSE; } @@ -154,7 +158,7 @@ public static function mysqlOrderBy($str) { // at all, so we split and loop over. $parts = explode(',', $str); foreach ($parts as $part) { - if (!preg_match('/^(([\w]+)((\.)([\w]+))?( (asc|desc))?)$/i', trim($part))) { + if (!preg_match('/^((\w{1,64})((\.)(\w{1,64}))?( (asc|desc))?)$/i', trim($part))) { return FALSE; } } From cd899be3f37ac8bdace78895359bd17a1677b911 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Fri, 29 Apr 2016 07:45:10 +0200 Subject: [PATCH 27/42] Removed obsolete MysqlColumnNameLoose validate and escape check. --- CRM/Utils/Rule.php | 20 -------------------- CRM/Utils/Type.php | 15 --------------- 2 files changed, 35 deletions(-) diff --git a/CRM/Utils/Rule.php b/CRM/Utils/Rule.php index 00af967bd3af..3251d26bbefb 100644 --- a/CRM/Utils/Rule.php +++ b/CRM/Utils/Rule.php @@ -87,26 +87,6 @@ public static function variable($str) { return TRUE; } - /** - * @param $str - * - * @return bool - */ - public static function mysqlColumnNameLoose($str) { - // Check the length. - // This check is incorrect for the
. format, which can be - // a problem. - // But is quit difficult to check, as a dot is also a valid character in a - // column name. In that case backticks are needed, which will - // be escaped in the escape function, which lead to an icorrect name... - // So this function assumes there is only a column name. - if (empty($str) || strlen($str) > 64) { - return FALSE; - } - - return TRUE; - } - /** * Validate an acceptable column name for sorting results. * diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index 8bbdb8cb6166..7eb4da56f4f6 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -268,15 +268,6 @@ public static function escape($data, $type, $abort = TRUE) { } break; - case 'MysqlColumnNameLoose': - if (CRM_Utils_Rule::mysqlColumnNameLoose($data)) { - $parts = explode('.', str_replace('`', '``', $data)); - $data = '`'.implode('`.`', $parts).'`'; - - return $data; - } - break; - case 'MysqlColumnName': if (CRM_Utils_Rule::mysqlColumnName($data)) { $parts = explode('.', $data); @@ -405,12 +396,6 @@ public static function validate($data, $type, $abort = TRUE, $name = 'One of par } break; - case 'MysqlColumnNameLoose': - if (CRM_Utils_Rule::mysqlColumnNameLoose($data)) { - return data; - } - break; - case 'MysqlColumnName': if (CRM_Utils_Rule::mysqlColumnName($data)) { return $data; From 5ada14523d4731c8d0e7869168fa9af958adc11d Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Fri, 29 Apr 2016 07:50:35 +0200 Subject: [PATCH 28/42] Added tests for
. 64 character limit. --- tests/phpunit/CRM/Utils/TypeTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpunit/CRM/Utils/TypeTest.php b/tests/phpunit/CRM/Utils/TypeTest.php index b8371cdd0581..4e51944f3133 100644 --- a/tests/phpunit/CRM/Utils/TypeTest.php +++ b/tests/phpunit/CRM/Utils/TypeTest.php @@ -42,6 +42,11 @@ public function validateDataProvider() { array('table.civicrm_column_name.toomanydots', 'MysqlColumnName', NULL), array('invalid-column-name', 'MysqlColumnName', NULL), array('column_name, sleep(5)', 'MysqlColumnName', NULL), + array(str_repeat('a', 64), 'MysqlColumnName', str_repeat('a', 64)), + array(str_repeat('a', 65), 'MysqlColumnName', NULL), + array(str_repeat('a', 64) . '.' . str_repeat('a', 64), 'MysqlColumnName', str_repeat('a', 64) . '.' . str_repeat('a', 64)), + array(str_repeat('a', 64) . '.' . str_repeat('a', 65), 'MysqlColumnName', NULL), + array(str_repeat('a', 65) . '.' . str_repeat('a', 64), 'MysqlColumnName', NULL), array('asc', 'MysqlOrderByDirection', 'asc'), array('DESC', 'MysqlOrderByDirection', 'desc'), array('DESCc', 'MysqlOrderByDirection', NULL), From 695a37629b5403c9626543c1b8f8219d9e4b6583 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Fri, 29 Apr 2016 08:00:42 +0200 Subject: [PATCH 29/42] Style fixes. --- CRM/Core/Page/AJAX.php | 4 ++-- CRM/Utils/Type.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CRM/Core/Page/AJAX.php b/CRM/Core/Page/AJAX.php index 3a4559878662..d99e2b19ac56 100644 --- a/CRM/Core/Page/AJAX.php +++ b/CRM/Core/Page/AJAX.php @@ -233,8 +233,8 @@ public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRow if ($sort) { $params['sortBy'] = "`{$sort}` {$sortOrder}"; - $params['_raw_values']['sort'][0] = $sort; - $params['_raw_values']['order'][0] = $sortOrder; + $params['_raw_values']['sort'][0] = $sort; + $params['_raw_values']['order'][0] = $sortOrder; } $params['offset'] = $offset; diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index 7eb4da56f4f6..44e8f17a07e8 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -271,7 +271,7 @@ public static function escape($data, $type, $abort = TRUE) { case 'MysqlColumnName': if (CRM_Utils_Rule::mysqlColumnName($data)) { $parts = explode('.', $data); - $data = '`'.implode('`.`', $parts).'`'; + $data = '`' . implode('`.`', $parts) . '`'; return $data; } From a22b0f6dd0659544df4d0f86930cbe5cbbac07d5 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Fri, 29 Apr 2016 21:01:30 +0200 Subject: [PATCH 30/42] Added forgotten changes. --- CRM/Core/Page/AJAX.php | 4 ++-- CRM/Utils/Sort.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CRM/Core/Page/AJAX.php b/CRM/Core/Page/AJAX.php index d99e2b19ac56..7c4537eecd45 100644 --- a/CRM/Core/Page/AJAX.php +++ b/CRM/Core/Page/AJAX.php @@ -221,7 +221,7 @@ public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRow $sortMapper = array(); foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = CRM_Utils_Type::escape($value['data'], 'MysqlColumnName'); + $sortMapper[$key] = CRM_Utils_Type::validate($value['data'], 'MysqlColumnName'); }; $offset = isset($_GET['start']) ? CRM_Utils_Type::validate($_GET['start'], 'Integer') : $defaultOffset; @@ -231,7 +231,7 @@ public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRow $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::validate($_GET['order'][0]['dir'], 'MysqlOrderByDirection') : $defaultsortOrder; if ($sort) { - $params['sortBy'] = "`{$sort}` {$sortOrder}"; + $params['sortBy'] = "{$sort} {$sortOrder}"; $params['_raw_values']['sort'][0] = $sort; $params['_raw_values']['order'][0] = $sortOrder; diff --git a/CRM/Utils/Sort.php b/CRM/Utils/Sort.php index 789dba32d65f..e20e75d44296 100644 --- a/CRM/Utils/Sort.php +++ b/CRM/Utils/Sort.php @@ -152,11 +152,11 @@ public function orderBy() { $this->_vars[$this->_currentSortID]['direction'] == self::DONTCARE ) { $this->_vars[$this->_currentSortID]['name'] = str_replace(' ', '_', $this->_vars[$this->_currentSortID]['name']); - return CRM_Utils_Type::validate($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' asc'; + return CRM_Utils_Type::escape($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' asc'; } else { $this->_vars[$this->_currentSortID]['name'] = str_replace(' ', '_', $this->_vars[$this->_currentSortID]['name']); - return CRM_Utils_Type::validate($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' desc'; + return CRM_Utils_Type::escape($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' desc'; } } From 1e504b38fdadf59284a633d994605a0e153138f9 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Fri, 29 Apr 2016 21:04:31 +0200 Subject: [PATCH 31/42] Fixed incorrect parameter. --- CRM/Activity/Page/AJAX.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CRM/Activity/Page/AJAX.php b/CRM/Activity/Page/AJAX.php index 21164501e693..b91804d8aa0e 100644 --- a/CRM/Activity/Page/AJAX.php +++ b/CRM/Activity/Page/AJAX.php @@ -401,6 +401,11 @@ public static function getContactActivity() { $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); $params += CRM_Core_Page_AJAX::validateParams($requiredParameters, $optionalParameters); + // To be consistent, the cid parameter should be renamed to contact_id in + // the template file, see templates/CRM/Activity/Selector/Selector.tpl + $params['contact_id'] = $params['cid']; + unset($params['cid']); + // get the contact activities $activities = CRM_Activity_BAO_Activity::getContactActivitySelector($params); From c4beefdc5514ac8fbe68d1d3c1f6475f318a3dee Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 3 May 2016 16:34:03 +0200 Subject: [PATCH 32/42] Fixed forgotten rename. --- CRM/Mailing/Page/AJAX.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Mailing/Page/AJAX.php b/CRM/Mailing/Page/AJAX.php index 3e7f9746df29..855967c01cab 100644 --- a/CRM/Mailing/Page/AJAX.php +++ b/CRM/Mailing/Page/AJAX.php @@ -62,7 +62,7 @@ public static function template() { */ public static function getContactMailings() { $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); - $params += CRM_Core_Page_AJAX::getSanitizedParams(array('contact_id' => 'Integer')); + $params += CRM_Core_Page_AJAX::validateParams(array('contact_id' => 'Integer')); // get the contact mailings $mailings = CRM_Mailing_BAO_Mailing::getContactMailingSelector($params); From cf12857328790e86097bba7e72ba8681b555df33 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 3 May 2016 16:37:30 +0200 Subject: [PATCH 33/42] Parially revert 19b8532d55bb35d3d471bbe859e5ca080e85324f to ensure queries are not broken. --- CRM/Utils/Sort.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CRM/Utils/Sort.php b/CRM/Utils/Sort.php index e20e75d44296..2b5765f23598 100644 --- a/CRM/Utils/Sort.php +++ b/CRM/Utils/Sort.php @@ -152,11 +152,11 @@ public function orderBy() { $this->_vars[$this->_currentSortID]['direction'] == self::DONTCARE ) { $this->_vars[$this->_currentSortID]['name'] = str_replace(' ', '_', $this->_vars[$this->_currentSortID]['name']); - return CRM_Utils_Type::escape($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' asc'; + return $this->_vars[$this->_currentSortID]['name'] . ' asc'; } else { $this->_vars[$this->_currentSortID]['name'] = str_replace(' ', '_', $this->_vars[$this->_currentSortID]['name']); - return CRM_Utils_Type::escape($this->_vars[$this->_currentSortID]['name'], 'MysqlColumnName') . ' desc'; + return $this->_vars[$this->_currentSortID]['name'] . ' desc'; } } From 0ef3b8a677d5fb49c312dbe024144dc080be420d Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Tue, 3 May 2016 21:19:08 +0200 Subject: [PATCH 34/42] PHP warning fix. --- CRM/Core/Page/AJAX.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CRM/Core/Page/AJAX.php b/CRM/Core/Page/AJAX.php index 7c4537eecd45..84185152f176 100644 --- a/CRM/Core/Page/AJAX.php +++ b/CRM/Core/Page/AJAX.php @@ -220,9 +220,11 @@ public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRow ); $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = CRM_Utils_Type::validate($value['data'], 'MysqlColumnName'); - }; + if (isset($_GET['columns'])) { + foreach ($_GET['columns'] as $key => $value) { + $sortMapper[$key] = CRM_Utils_Type::validate($value['data'], 'MysqlColumnName'); + }; + } $offset = isset($_GET['start']) ? CRM_Utils_Type::validate($_GET['start'], 'Integer') : $defaultOffset; $rowCount = isset($_GET['length']) ? CRM_Utils_Type::validate($_GET['length'], 'Integer') : $defaultRowCount; From f49c1e978660078fcfaf6251361d6691376f2466 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Wed, 4 May 2016 07:41:13 +0200 Subject: [PATCH 35/42] Fixed issue with ajax calls on custom field table tab on contact. --- CRM/Custom/Page/AJAX.php | 9 +++------ CRM/Profile/Page/MultipleRecordFieldsListing.php | 1 + .../CRM/Profile/Page/MultipleRecordFieldsListing.tpl | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CRM/Custom/Page/AJAX.php b/CRM/Custom/Page/AJAX.php index 1bd938996f71..7bb96f7d2456 100644 --- a/CRM/Custom/Page/AJAX.php +++ b/CRM/Custom/Page/AJAX.php @@ -125,11 +125,8 @@ public static function getMultiRecordFieldList() { $obj->_contactType = $contactType; $obj->_DTparams['offset'] = ($params['page'] - 1) * $params['rp']; $obj->_DTparams['rowCount'] = $params['rp']; - if (isset($params['_raw_values']['sort'][0])) { - // Will this work when CiviCRM is translated, as searching happens on the label column? - // I can't find a place where the sort is added, but it should use the name, not the label. - $sort = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $params['_raw_values']['sort'][0], 'column_name', 'label'); - $obj->_DTparams['sort'] = $sort . ' ' . $params['_raw_values']['order'][0]; + if ($params['sortBy']) { + $obj->_DTparams['sort'] = $params['sortBy']; } list($fields, $attributes) = $obj->browse(); @@ -143,7 +140,7 @@ public static function getMultiRecordFieldList() { $fieldName = array('data' => $fieldName, 'cellClass' => $attributes[$fieldId][$id]['class']); } if (is_numeric($fieldId)) { - $fName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $fieldId, 'label'); + $fName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $fieldId, 'column_name'); CRM_Utils_Array::crmReplaceKey($value, $fieldId, $fName); } } diff --git a/CRM/Profile/Page/MultipleRecordFieldsListing.php b/CRM/Profile/Page/MultipleRecordFieldsListing.php index c27eb1953f96..88410a1d2f24 100644 --- a/CRM/Profile/Page/MultipleRecordFieldsListing.php +++ b/CRM/Profile/Page/MultipleRecordFieldsListing.php @@ -428,6 +428,7 @@ public function browse() { if (!empty($fieldIDs)) { foreach ($fieldIDs as $fieldID) { $headers[$fieldID] = ($this->_pageViewType == 'profileDataView') ? $customGroupInfo[$fieldID]['fieldLabel'] : $fieldLabels[$fieldID]['label']; + $headerAttr[$fieldID]['columnName'] = $fieldLabels[$fieldID]['column_name']; } } $this->assign('dateFields', $dateFields); diff --git a/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl b/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl index 5f6f091b5857..4e3824e19bcf 100644 --- a/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl +++ b/templates/CRM/Profile/Page/MultipleRecordFieldsListing.tpl @@ -40,7 +40,7 @@ {if $pageViewType eq 'customDataView'} {foreach from=$headers key=recId item=head} - From 9337f53209d9603ac3c6b614b7bdc2a876050db6 Mon Sep 17 00:00:00 2001 From: KarinG Date: Mon, 25 Apr 2016 13:49:07 -0600 Subject: [PATCH 36/42] CRM-18110-test added test. --- .../CRM/Contribute/Form/ContributionTest.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/phpunit/CRM/Contribute/Form/ContributionTest.php b/tests/phpunit/CRM/Contribute/Form/ContributionTest.php index c4bdeb1b45dd..35c0cbd89db0 100644 --- a/tests/phpunit/CRM/Contribute/Form/ContributionTest.php +++ b/tests/phpunit/CRM/Contribute/Form/ContributionTest.php @@ -617,6 +617,29 @@ public function testSubmitWithNoteCreditCard() { $this->assertEquals($note['note'], 'Super cool and interesting stuff'); } + /** + * Test that if a negative contribution is entered it does not get reset to $0 + */ + public function testEnterNegativeContribution() { + $form = new CRM_Contribute_Form_Contribution(); + $form->testSubmit(array( + 'total_amount' => -5, + 'financial_type_id' => 1, + 'receive_date' => '04/24/2016', + 'receive_date_time' => '11:27PM', + 'contact_id' => $this->_individualId, + 'payment_instrument_id' => array_search('Check', $this->paymentInstruments), + 'contribution_status_id' => 1, + ), + CRM_Core_Action::ADD); + $this->callAPISuccessGetCount('Contribution', array('contact_id' => $this->_individualId), 1); + + $contribution = $this->callAPISuccessGetSingle('Contribution', array( + 'contact_id' => $this->_individualId, + )); + $this->assertEquals(-5, $contribution['total_amount']); + } + /** * Test the submit function on the contribution page. */ From 9f88902d3c0b07e66ff90b2e397fe7c0e0036cda Mon Sep 17 00:00:00 2001 From: yashodha Date: Wed, 4 May 2016 15:08:04 +0530 Subject: [PATCH 37/42] CRM-18154: Profile custom field option: 'Include in multi-record listing' un-ticked, but still persists ---------------------------------------- * CRM-18154: Profile custom field option: "Include in multi-record listing" un-ticked, but still persists https://issues.civicrm.org/jira/browse/CRM-18154 --- CRM/Custom/Form/Field.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Custom/Form/Field.php b/CRM/Custom/Form/Field.php index 9550971ba5a5..c3d7d85eb85f 100644 --- a/CRM/Custom/Form/Field.php +++ b/CRM/Custom/Form/Field.php @@ -507,7 +507,7 @@ public function buildQuickForm() { ); // is active ? - $this->add('checkbox', 'is_active', ts('Active?')); + $this->add('advcheckbox', 'is_active', ts('Active?')); // is active ? $this->add('checkbox', 'is_view', ts('View Only?')); From bc94abb2e3164d8bf19d3f246a2ee8f76c1cb6da Mon Sep 17 00:00:00 2001 From: yashodha Date: Thu, 5 May 2016 13:14:35 +0530 Subject: [PATCH 38/42] CRM-18154: change checkbox to advcheckbox to ensure unsetting works fine ---------------------------------------- * CRM-18154: Profile custom field option: "Include in multi-record listing" un-ticked, but still persists https://issues.civicrm.org/jira/browse/CRM-18154 --- CRM/Custom/Form/Field.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CRM/Custom/Form/Field.php b/CRM/Custom/Form/Field.php index c3d7d85eb85f..81676a071db2 100644 --- a/CRM/Custom/Form/Field.php +++ b/CRM/Custom/Form/Field.php @@ -486,7 +486,7 @@ public function buildQuickForm() { $this->addRule('weight', ts('is a numeric field'), 'numeric'); // is required ? - $this->add('checkbox', 'is_required', ts('Required?')); + $this->add('advcheckbox', 'is_required', ts('Required?')); // checkbox / radio options per line $this->add('text', 'options_per_line', ts('Options Per Line')); @@ -510,10 +510,10 @@ public function buildQuickForm() { $this->add('advcheckbox', 'is_active', ts('Active?')); // is active ? - $this->add('checkbox', 'is_view', ts('View Only?')); + $this->add('advcheckbox', 'is_view', ts('View Only?')); // is searchable ? - $this->addElement('checkbox', + $this->addElement('advcheckbox', 'is_searchable', ts('Is this Field Searchable?'), NULL, array('onclick' => "showSearchRange(this)") From 9894faee27e6c147d5b7760c56b99f01e37553d3 Mon Sep 17 00:00:00 2001 From: Herb vd Dool Date: Sun, 10 Apr 2016 18:21:27 -0400 Subject: [PATCH 39/42] added getUFLocale, setUFLocale methods to Backdrop class because language object and language_list are different in Backdrop --- CRM/Utils/System/Backdrop.php | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/CRM/Utils/System/Backdrop.php b/CRM/Utils/System/Backdrop.php index f09017102ead..72c177ebe008 100644 --- a/CRM/Utils/System/Backdrop.php +++ b/CRM/Utils/System/Backdrop.php @@ -403,6 +403,57 @@ public function userLoginFinalize($params = array()) { user_login_finalize($params); } + /** + * @inheritDoc + */ + public function getUFLocale() { + // return CiviCRM’s xx_YY locale that either matches Drupal’s Chinese locale + // (for CRM-6281), Drupal’s xx_YY or is retrieved based on Drupal’s xx + // sometimes for CLI based on order called, this might not be set and/or empty + global $language; + + if (empty($language)) { + return NULL; + } + + if ($language->langcode == 'zh-hans') { + return 'zh_CN'; + } + + if ($language->langcode == 'zh-hant') { + return 'zh_TW'; + } + + if (preg_match('/^.._..$/', $language->langcode)) { + return $language->langcode; + } + + return CRM_Core_I18n_PseudoConstant::longForShort(substr($language->langcode, 0, 2)); + } + + /** + * @inheritDoc + */ + public function setUFLocale($civicrm_language) { + global $language; + + $langcode = substr($civicrm_language, 0, 2); + $languages = language_list(FALSE, TRUE); + + if (isset($languages[$langcode])) { + $language = $languages[$langcode]; + + // Config must be re-initialized to reset the base URL + // otherwise links will have the wrong language prefix/domain. + $config = CRM_Core_Config::singleton(); + $config->free(); + + return TRUE; + } + + return FALSE; + } + /** * Determine the native ID of the CMS user. * From 22f38e15b53762565c890e388ded9d5cee74f0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20T=C3=A9tard?= Date: Mon, 18 Apr 2016 16:11:31 +0200 Subject: [PATCH 40/42] =?UTF-8?q?CRM-18432:=20In=20CiviMail=E2=80=99s=20up?= =?UTF-8?q?dateEmailResetDate(),=20exec=20the=20main=20query.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In CRM_Mailing_Event_BAO_Delivered::updateEmailResetDate(), call for CRM_Core_DAO::executeQuery($query), so the temporary table can be filled. --- CRM/Mailing/Event/BAO/Delivered.php | 1 + 1 file changed, 1 insertion(+) diff --git a/CRM/Mailing/Event/BAO/Delivered.php b/CRM/Mailing/Event/BAO/Delivered.php index 4b43cd5fa297..ee20d437b1f8 100644 --- a/CRM/Mailing/Event/BAO/Delivered.php +++ b/CRM/Mailing/Event/BAO/Delivered.php @@ -304,6 +304,7 @@ public static function updateEmailResetDate($minDays = 3, $maxDays = 7) { AND (civicrm_email.reset_date IS NULL OR civicrm_email.reset_date < civicrm_mailing_job.start_date) GROUP BY civicrm_email.id "; + CRM_Core_DAO::executeQuery($query); $query = " UPDATE civicrm_email e From e77ccb21e424989b9e96c9ac80177c5e30a5e6c2 Mon Sep 17 00:00:00 2001 From: "Laryn - CEDC.org" Date: Fri, 6 May 2016 13:27:17 -0500 Subject: [PATCH 41/42] Simple spelling fix --- CRM/Mailing/BAO/Mailing.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Mailing/BAO/Mailing.php b/CRM/Mailing/BAO/Mailing.php index a863b10ff14f..d3c6853636f8 100644 --- a/CRM/Mailing/BAO/Mailing.php +++ b/CRM/Mailing/BAO/Mailing.php @@ -749,7 +749,7 @@ private function getPreparedTemplates() { /** * Retrieve a ref to an array that holds the email and text templates for this email * assembles the complete template including the header and footer - * that the user has uploaded or declared (if they have dome that) + * that the user has uploaded or declared (if they have done that) * * @return array * reference to an assoc array From a579dd830e5e56c2ccca5cab4538c457cc0ca4b1 Mon Sep 17 00:00:00 2001 From: Darrick Servis Date: Sat, 7 May 2016 15:08:03 -0700 Subject: [PATCH 42/42] CRM-18515 - Allow Payment Processor with same name when using multi-domain. --- CRM/Admin/Form/PaymentProcessor.php | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/CRM/Admin/Form/PaymentProcessor.php b/CRM/Admin/Form/PaymentProcessor.php index a0367bb24bf1..191a2519ada7 100644 --- a/CRM/Admin/Form/PaymentProcessor.php +++ b/CRM/Admin/Form/PaymentProcessor.php @@ -176,7 +176,8 @@ public function buildQuickForm($check = FALSE) { $attributes['name'], TRUE ); - $this->addRule('name', ts('Name already exists in Database.'), 'objectExists', array( + $this->registerRule('paymentProcessorNameExists', 'callback', 'paymentProcessorNameExists', 'CRM_Admin_Form_PaymentProcessor'); + $this->addRule('name', ts('Name already exists in Database.'), 'paymentProcessorNameExists', array( 'CRM_Financial_DAO_PaymentProcessor', $this->_id, )); @@ -400,4 +401,34 @@ public function updatePaymentProcessor(&$values, $domainID, $test) { civicrm_api3('PaymentProcessor', 'create', $params); } + /** + * Check if there is a record with the same name in the db. + * + * @param string $value + * The value of the field we are checking. + * @param array $options + * The daoName and fieldName (optional ). + * + * @return bool + * true if object exists + */ + public static function paymentProcessorNameExists($value, $options) { + $fieldName = 'name'; + $daoName = CRM_Utils_Array::value(0, $options); + $daoID = CRM_Utils_Array::value(1, $options); + $domain_id = CRM_Core_Config::domainID(); + $object = new $daoName(); + $object->$fieldName = $value; + $object->domain_id = $domain_id; + + $config = CRM_Core_Config::singleton(); + + if ($object->find(TRUE)) { + return ($daoID && $object->id == $daoID) ? TRUE : FALSE; + } + else { + return TRUE; + } + } + }
{ts}{$head}{/ts}