From 73cab19e6c9aaeaf7125827327a961330c216d31 Mon Sep 17 00:00:00 2001 From: Kevin Cristiano <kcristiano@tadpole.cc> Date: Sun, 14 Jan 2018 15:47:41 -0500 Subject: [PATCH] civicrm-47 Update to 4.7.29 --- civicrm/CRM/Contribute/BAO/Contribution.php | 15 +++- .../CRM/Contribute/BAO/Contribution/Utils.php | 16 +++- .../Contribute/Form/Contribution/Confirm.php | 20 +++-- .../CRM/Contribute/Form/ContributionBase.php | 3 + civicrm/CRM/Core/InnoDBIndexer.php | 4 + civicrm/CRM/Group/Form/Edit.php | 5 ++ civicrm/CRM/Price/BAO/LineItem.php | 9 ++- civicrm/CRM/Price/Page/Field.php | 2 +- civicrm/CRM/Price/Page/Option.php | 2 +- civicrm/CRM/Upgrade/Form.php | 4 +- civicrm/CRM/Upgrade/Incremental/General.php | 36 ++------- .../Upgrade/Incremental/sql/4.7.29.mysql.tpl | 1 + civicrm/CRM/Utils/Check/Component/Env.php | 51 ++++++------ civicrm/CRM/Utils/Rule.php | 10 ++- civicrm/CRM/Utils/SQL.php | 2 +- civicrm/Civi/Core/SettingsBag.php | 8 +- civicrm/api/v3/Contribution.php | 3 + civicrm/civicrm-version.php | 2 +- civicrm/install/index.php | 33 +++----- civicrm/release-notes.md | 10 +++ civicrm/release-notes/4.7.29.md | 79 +++++++++++++++++++ civicrm/sql/civicrm_data.mysql | 2 +- civicrm/sql/civicrm_generated.mysql | 2 +- civicrm/templates/CRM/common/version.tpl | 2 +- civicrm/vendor/autoload.php | 2 +- civicrm/vendor/composer/autoload_real.php | 14 ++-- civicrm/vendor/composer/autoload_static.php | 10 +-- 27 files changed, 228 insertions(+), 119 deletions(-) create mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.7.29.mysql.tpl create mode 100644 civicrm/release-notes/4.7.29.md diff --git a/civicrm/CRM/Contribute/BAO/Contribution.php b/civicrm/CRM/Contribute/BAO/Contribution.php index 79fdeb3ffb..6e485a5922 100644 --- a/civicrm/CRM/Contribute/BAO/Contribution.php +++ b/civicrm/CRM/Contribute/BAO/Contribution.php @@ -129,6 +129,10 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { if (!empty($params['skipCleanMoney'])) { unset($moneyFields[0]); } + else { + // @todo put a deprecated here - this should be done in the form layer. + $params['skipCleanMoney'] = FALSE; + } foreach ($moneyFields as $field) { if (isset($params[$field])) { @@ -4205,6 +4209,11 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) public static function checkTaxAmount($params, $isLineItem = FALSE) { $taxRates = CRM_Core_PseudoConstant::getTaxRates(); + // This function should be only called after standardisation (removal of + // thousand separator & using a decimal point for cents separator. + // However, we don't know if that is always true :-( + // There is a deprecation notice tho :-) + $unknownIfMoneyIsClean = empty($params['skipCleanMoney']) && !$isLineItem; // Update contribution. if (!empty($params['id'])) { // CRM-19126 and CRM-19152 If neither total or financial_type_id are set on an update @@ -4251,7 +4260,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) empty($params['skipLineItem']) && !$isLineItem ) { $taxRateParams = $taxRates[$params['financial_type_id']]; - $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount(CRM_Utils_Array::value('total_amount', $params), $taxRateParams); + $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount(CRM_Utils_Array::value('total_amount', $params), $taxRateParams, $unknownIfMoneyIsClean); $params['tax_amount'] = round($taxAmount['tax_amount'], 2); // Get Line Item on update of contribution @@ -4283,9 +4292,9 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) } else { // update line item of contrbution - if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && $isLineItem) { + if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && $isLineItem) { $taxRate = $taxRates[$params['financial_type_id']]; - $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($params['line_total'], $taxRate); + $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($params['line_total'], $taxRate, $unknownIfMoneyIsClean); $params['tax_amount'] = round($taxAmount['tax_amount'], 2); } } diff --git a/civicrm/CRM/Contribute/BAO/Contribution/Utils.php b/civicrm/CRM/Contribute/BAO/Contribution/Utils.php index 3930addfda..ce9caf1ab3 100644 --- a/civicrm/CRM/Contribute/BAO/Contribution/Utils.php +++ b/civicrm/CRM/Contribute/BAO/Contribution/Utils.php @@ -114,6 +114,9 @@ class CRM_Contribute_BAO_Contribution_Utils { $contributionParams['payment_instrument_id'] = $paymentParams['payment_instrument_id'] = $form->_paymentProcessor['payment_instrument_id']; } + // @todo this is the wrong place for this - it should be done as close to form submission + // as possible + $paymentParams['amount'] = CRM_Utils_Rule::cleanMoney($paymentParams['amount']); $contribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution( $form, $paymentParams, @@ -468,15 +471,24 @@ LIMIT 1 * Amount of field. * @param float $taxRate * Tax rate of selected financial account for field. + * @param bool $ugWeDoNotKnowIfItNeedsCleaning_Help + * This should ALWAYS BE FALSE and then be removed. A 'clean' money string uses a standardised format + * such as '1000.99' for one thousand $/Euro/CUR and ninety nine cents/units. + * However, we are in the habit of not necessarily doing that so need to grandfather in + * the new expectation. * * @return array * array of tax amount * */ - public static function calculateTaxAmount($amount, $taxRate) { + public static function calculateTaxAmount($amount, $taxRate, $ugWeDoNotKnowIfItNeedsCleaning_Help = FALSE) { $taxAmount = array(); + if ($ugWeDoNotKnowIfItNeedsCleaning_Help) { + Civi::log()->warning('Deprecated function, make sure money is in usable format before calling this.', array('civi.tag' => 'deprecated')); + $amount = CRM_Utils_Rule::cleanMoney($amount); + } // There can not be any rounding at this stage - as this is prior to quantity multiplication - $taxAmount['tax_amount'] = ($taxRate / 100) * CRM_Utils_Rule::cleanMoney($amount); + $taxAmount['tax_amount'] = ($taxRate / 100) * $amount; return $taxAmount; } diff --git a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php index abddc63b47..3a7028a46f 100644 --- a/civicrm/CRM/Contribute/Form/Contribution/Confirm.php +++ b/civicrm/CRM/Contribute/Form/Contribution/Confirm.php @@ -158,7 +158,6 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr * * @param array $params * @param int $financialTypeID - * @param float $nonDeductibleAmount * @param bool $pending * @param array $paymentProcessorOutcome * @param string $receiptDate @@ -167,13 +166,11 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr * @return array */ public static function getContributionParams( - $params, $financialTypeID, $nonDeductibleAmount, $pending, + $params, $financialTypeID, $pending, $paymentProcessorOutcome, $receiptDate, $recurringContributionID) { $contributionParams = array( 'financial_type_id' => $financialTypeID, 'receive_date' => (CRM_Utils_Array::value('receive_date', $params)) ? CRM_Utils_Date::processDate($params['receive_date']) : date('YmdHis'), - 'non_deductible_amount' => $nonDeductibleAmount, - 'total_amount' => $params['amount'], 'tax_amount' => CRM_Utils_Array::value('tax_amount', $params), 'amount_level' => CRM_Utils_Array::value('amount_level', $params), 'invoice_id' => $params['invoiceID'], @@ -202,10 +199,6 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr ); } - // CRM-4038: for non-en_US locales, CRM_Contribute_BAO_Contribution::add() expects localised amounts - $contributionParams['non_deductible_amount'] = trim(CRM_Utils_Money::format($contributionParams['non_deductible_amount'], ' ')); - $contributionParams['total_amount'] = trim(CRM_Utils_Money::format($contributionParams['total_amount'], ' ')); - if ($recurringContributionID) { $contributionParams['contribution_recur_id'] = $recurringContributionID; } @@ -299,7 +292,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr // lineItem isn't set until Register postProcess $this->_lineItem = $this->get('lineItem'); $this->_ccid = $this->get('ccid'); - $this->_paymentProcessor = $this->get('paymentProcessor'); + $this->_params = $this->controller->exportValues('Main'); $this->_params['ip_address'] = CRM_Utils_System::ipAddress(); $this->_params['amount'] = $this->get('amount'); @@ -950,7 +943,6 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $params['is_recur'] = $isRecur; $params['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $contributionParams); $recurringContributionID = self::processRecurringContribution($form, $params, $contactID, $financialType); - $nonDeductibleAmount = self::getNonDeductibleAmount($params, $financialType, $online, $form); $now = date('YmdHis'); $receiptDate = CRM_Utils_Array::value('receipt_date', $params); @@ -960,10 +952,15 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr if (isset($params['amount'])) { $contributionParams = array_merge(self::getContributionParams( - $params, $financialType->id, $nonDeductibleAmount, TRUE, + $params, $financialType->id, TRUE, $result, $receiptDate, $recurringContributionID), $contributionParams ); + $contributionParams['non_deductible_amount'] = self::getNonDeductibleAmount($params, $financialType, $online, $form); + $contributionParams['skipCleanMoney'] = TRUE; + // @todo this is the wrong place for this - it should be done as close to form submission + // as possible + $contributionParams['total_amount'] = $params['amount']; $contribution = CRM_Contribute_BAO_Contribution::add($contributionParams); $invoiceSettings = Civi::settings()->get('contribution_invoice_settings'); @@ -1988,6 +1985,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr } $priceFields = $priceFields[$priceSetID]['fields']; + $lineItems = array(); CRM_Price_BAO_PriceSet::processAmount($priceFields, $paramsProcessedForForm, $lineItems, 'civicrm_contribution'); $form->_lineItem = array($priceSetID => $lineItems); $membershipPriceFieldIDs = array(); diff --git a/civicrm/CRM/Contribute/Form/ContributionBase.php b/civicrm/CRM/Contribute/Form/ContributionBase.php index 216c8149e2..933128ea32 100644 --- a/civicrm/CRM/Contribute/Form/ContributionBase.php +++ b/civicrm/CRM/Contribute/Form/ContributionBase.php @@ -294,6 +294,9 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form { $this->_fields = $this->get('fields'); $this->_bltID = $this->get('bltID'); $this->_paymentProcessor = $this->get('paymentProcessor'); + if (!$this->_paymentProcessor) { + $this->_paymentProcessor = array('object' => Civi\Payment\System::singleton()->getById(0)); + } $this->_priceSetId = $this->get('priceSetId'); $this->_priceSet = $this->get('priceSet'); diff --git a/civicrm/CRM/Core/InnoDBIndexer.php b/civicrm/CRM/Core/InnoDBIndexer.php index 5c2c8fb44d..6d7ae283d4 100644 --- a/civicrm/CRM/Core/InnoDBIndexer.php +++ b/civicrm/CRM/Core/InnoDBIndexer.php @@ -91,6 +91,10 @@ class CRM_Core_InnoDBIndexer { * Specification of the setting (per *.settings.php). */ public static function onToggleFts($oldValue, $newValue, $metadata) { + if (empty($oldValue) && empty($newValue)) { + return; + } + $indexer = CRM_Core_InnoDBIndexer::singleton(); $indexer->setActive($newValue); $indexer->fixSchemaDifferences(); diff --git a/civicrm/CRM/Group/Form/Edit.php b/civicrm/CRM/Group/Form/Edit.php index 95c0df5cb0..55b9478a0e 100644 --- a/civicrm/CRM/Group/Form/Edit.php +++ b/civicrm/CRM/Group/Form/Edit.php @@ -378,6 +378,11 @@ WHERE title = %1 $params['group_organization'] = $this->_groupOrganizationID; } + // CRM-21431 If all group_type are unchecked, the change will not be saved otherwise. + if (!isset($params['group_type'])) { + $params['group_type'] = array(); + } + $params['is_reserved'] = CRM_Utils_Array::value('is_reserved', $params, FALSE); $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params, diff --git a/civicrm/CRM/Price/BAO/LineItem.php b/civicrm/CRM/Price/BAO/LineItem.php index 505642d602..1a90a9d3e8 100644 --- a/civicrm/CRM/Price/BAO/LineItem.php +++ b/civicrm/CRM/Price/BAO/LineItem.php @@ -341,6 +341,11 @@ WHERE li.contribution_id = %1"; * this is * lineItem array) * @param string $amount_override + * Amount override must be in format 1000.00 - ie no thousand separator & if + * a decimal point is used it should be a decimal + * + * @todo - this parameter is only used for partial payments. It's unclear why a partial + * payment would change the line item price. */ public static function format($fid, $params, $fields, &$values, $amount_override = NULL) { if (empty($params["price_{$fid}"])) { @@ -364,10 +369,6 @@ WHERE li.contribution_id = %1"; foreach ($params["price_{$fid}"] as $oid => $qty) { $price = $amount_override === NULL ? $options[$oid]['amount'] : $amount_override; - // lets clean the price in case it is not yet cleant - // CRM-10974 - $price = CRM_Utils_Rule::cleanMoney($price); - $participantsPerField = CRM_Utils_Array::value('count', $options[$oid], 0); $values[$oid] = array( diff --git a/civicrm/CRM/Price/Page/Field.php b/civicrm/CRM/Price/Page/Field.php index 536195af8f..68ebdc7e4a 100644 --- a/civicrm/CRM/Price/Page/Field.php +++ b/civicrm/CRM/Price/Page/Field.php @@ -149,7 +149,7 @@ class CRM_Price_Page_Field extends CRM_Core_Page { $getTaxDetails = TRUE; } if (isset($priceField[$priceFieldBAO->id]['tax_rate'])) { - $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($priceField[$priceFieldBAO->id]['price'], $priceField[$priceFieldBAO->id]['tax_rate']); + $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($priceField[$priceFieldBAO->id]['price'], $priceField[$priceFieldBAO->id]['tax_rate'], TRUE); $priceField[$priceFieldBAO->id]['tax_amount'] = $taxAmount['tax_amount']; } } diff --git a/civicrm/CRM/Price/Page/Option.php b/civicrm/CRM/Price/Page/Option.php index 0724ebec9b..eab7c0c560 100644 --- a/civicrm/CRM/Price/Page/Option.php +++ b/civicrm/CRM/Price/Page/Option.php @@ -158,7 +158,7 @@ class CRM_Price_Page_Option extends CRM_Core_Page { if ($invoicing && isset($customOption[$id]['tax_rate'])) { $getTaxDetails = TRUE; } - $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($customOption[$id]['amount'], $customOption[$id]['tax_rate']); + $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($customOption[$id]['amount'], $customOption[$id]['tax_rate'], TRUE); $customOption[$id]['tax_amount'] = $taxAmount['tax_amount']; } if (!empty($values['financial_type_id'])) { diff --git a/civicrm/CRM/Upgrade/Form.php b/civicrm/CRM/Upgrade/Form.php index 76aa53a26f..10b87ead2e 100644 --- a/civicrm/CRM/Upgrade/Form.php +++ b/civicrm/CRM/Upgrade/Form.php @@ -48,9 +48,9 @@ class CRM_Upgrade_Form extends CRM_Core_Form { const MINIMUM_UPGRADABLE_VERSION = '4.0.8'; /** - * Minimum php version we support + * Minimum php version required to run (equal to or lower than the minimum install version) */ - const MINIMUM_PHP_VERSION = '5.3.4'; + const MINIMUM_PHP_VERSION = '5.4'; protected $_config; diff --git a/civicrm/CRM/Upgrade/Incremental/General.php b/civicrm/CRM/Upgrade/Incremental/General.php index a2add64131..56a80610d2 100644 --- a/civicrm/CRM/Upgrade/Incremental/General.php +++ b/civicrm/CRM/Upgrade/Incremental/General.php @@ -41,25 +41,19 @@ class CRM_Upgrade_Incremental_General { /** * The recommended PHP version. */ - const MIN_RECOMMENDED_PHP_VER = '5.6'; + const RECOMMENDED_PHP_VER = '7.0'; /** * The previous recommended PHP version. */ - const PREVIOUS_MIN_RECOMMENDED_PHP_VER = '5.5'; + const MIN_RECOMMENDED_PHP_VER = '5.6'; /** * The minimum PHP version required to install Civi. * * @see install/index.php */ - const MIN_INSTALL_PHP_VER = '5.3.4'; - - /** - * The minimum PHP version required to avoid known - * limits or defects. - */ - const MIN_DEFECT_PHP_VER = '5.3.23'; + const MIN_INSTALL_PHP_VER = '5.4'; /** * Compute any messages which should be displayed before upgrade. @@ -73,25 +67,11 @@ class CRM_Upgrade_Incremental_General { $dateFormat = Civi::Settings()->get('dateformatshortdate'); if (version_compare(phpversion(), self::MIN_RECOMMENDED_PHP_VER) < 0) { $preUpgradeMessage .= '<p>'; - // CRM-20941 PHP 5.3 end date of End of 2017, PHP 5.4 End date End of Feb 2018 Recommend anyone on PHP 5.5 to move up to 5.6 or later e.g. 7.0 - if (version_compare(phpversion(), self::PREVIOUS_MIN_RECOMMENDED_PHP_VER) >= 0) { - $preUpgradeMessage .= ts('You may proceed with the upgrade and CiviCRM %1 will continue working normally, but future releases will require PHP %2 or above. We recommend you use the most recent php version you can.', array( - 1 => $latestVer, - 2 => self::MIN_RECOMMENDED_PHP_VER, - )); - } - elseif (version_compare(phpversion(), 5.5) < 0) { - $date = CRM_Utils_Date::customFormat('2018-02-28', $dateFormat); - if (version_compare(phpversion(), 5.4) < 0) { - $date = CRM_Utils_Date::customFormat('2017-12-31', $dateFormat); - } - $preUpgradeMessage .= ts('You may proceed with the upgrade and CiviCRM %1 will continue working normally, but PHP %2 will not work in releases published after %3. We recommend you use the most recent php version you can. For more explanation see <a href="%4">the announcement</a>.', array( - 1 => $currentVer, - 2 => phpversion(), - 3 => $date, - 4 => 'https://civicrm.org/blog/totten/end-of-zombies-php-53-and-54', - )); - } + $preUpgradeMessage .= ts('You may proceed with the upgrade and CiviCRM %1 will continue working normally, but future releases will require PHP %2 or above. We recommend PHP version %3.', array( + 1 => $latestVer, + 2 => self::MIN_RECOMMENDED_PHP_VER, + 3 => self::RECOMMENDED_PHP_VER, + )); $preUpgradeMessage .= '</p>'; } diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.7.29.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.7.29.mysql.tpl new file mode 100644 index 0000000000..444a0ba0e1 --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/4.7.29.mysql.tpl @@ -0,0 +1 @@ +{* file to handle db changes in 4.7.29 during upgrade *} diff --git a/civicrm/CRM/Utils/Check/Component/Env.php b/civicrm/CRM/Utils/Check/Component/Env.php index 54b92ac6f7..294547dac5 100644 --- a/civicrm/CRM/Utils/Check/Component/Env.php +++ b/civicrm/CRM/Utils/Check/Component/Env.php @@ -37,57 +37,62 @@ class CRM_Utils_Check_Component_Env extends CRM_Utils_Check_Component { */ public function checkPhpVersion() { $messages = array(); + $phpVersion = phpversion(); - if (version_compare(phpversion(), CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER) >= 0) { + if (version_compare($phpVersion, CRM_Upgrade_Incremental_General::RECOMMENDED_PHP_VER) >= 0) { $messages[] = new CRM_Utils_Check_Message( __FUNCTION__, - ts('This system uses PHP version %1 which meets or exceeds the minimum recommendation of %2.', + ts('This system uses PHP version %1 which meets or exceeds the recommendation of %2.', array( - 1 => phpversion(), - 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER, + 1 => $phpVersion, + 2 => CRM_Upgrade_Incremental_General::RECOMMENDED_PHP_VER, )), ts('PHP Up-to-Date'), \Psr\Log\LogLevel::INFO, 'fa-server' ); } - elseif (version_compare(phpversion(), CRM_Upgrade_Incremental_General::PREVIOUS_MIN_RECOMMENDED_PHP_VER) >= 0) { + elseif (version_compare($phpVersion, CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER) >= 0) { $messages[] = new CRM_Utils_Check_Message( __FUNCTION__, - ts('This system uses PHP version %1. While this meets the minimum requirements for CiviCRM to function, upgrading to PHP version %2 or newer is recommended for maximum compatibility.', + ts('This system uses PHP version %1. This meets the minimum recommendations and you do not need to upgrade immediately, but the preferred version is %2.', array( - 1 => phpversion(), - 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER, - 3 => CRM_Upgrade_Incremental_General::MIN_DEFECT_PHP_VER, + 1 => $phpVersion, + 2 => CRM_Upgrade_Incremental_General::RECOMMENDED_PHP_VER, )), ts('PHP Out-of-Date'), \Psr\Log\LogLevel::NOTICE, 'fa-server' ); } - else { - $date = ''; - $dateFormat = Civi::Settings()->get('dateformatshortdate'); - if (version_compare(phpversion(), 5.4) < 0) { - $date = CRM_Utils_Date::customFormat('2017-12-31', $dateFormat); - } - elseif (version_compare(phpversion(), 5.5) < 0) { - $date = CRM_Utils_Date::customFormat('2018-02-28', $dateFormat); - } + elseif (version_compare($phpVersion, CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER) >= 0) { $messages[] = new CRM_Utils_Check_Message( __FUNCTION__, - ts('This system uses PHP version %1. CiviCRM can be installed on this version. However PHP version %1 will not work in releases published after %2, and version %3 is recommended. For more explanation see <a href="%4"> the announcement</a>', + ts('This system uses PHP version %1. This meets the minimum requirements for CiviCRM to function but is not recommended. At least PHP version %2 is recommended; the preferrred version is %3.', array( - 1 => phpversion(), - 2 => $date, - 3 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER, - 4 => 'https://civicrm.org/blog/totten/end-of-zombies-php-53-and-54', + 1 => $phpVersion, + 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER, + 3 => CRM_Upgrade_Incremental_General::RECOMMENDED_PHP_VER, )), ts('PHP Out-of-Date'), \Psr\Log\LogLevel::WARNING, 'fa-server' ); } + else { + $messages[] = new CRM_Utils_Check_Message( + __FUNCTION__, + ts('This system uses PHP version %1. To ensure the continued operation of CiviCRM, upgrade your server now. At least PHP version %2 is recommended; the preferrred version is %3.', + array( + 1 => $phpVersion, + 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER, + 3 => CRM_Upgrade_Incremental_General::RECOMMENDED_PHP_VER, + )), + ts('PHP Out-of-Date'), + \Psr\Log\LogLevel::ERROR, + 'fa-server' + ); + } return $messages; } diff --git a/civicrm/CRM/Utils/Rule.php b/civicrm/CRM/Utils/Rule.php index c9a92fa967..0168e63c78 100644 --- a/civicrm/CRM/Utils/Rule.php +++ b/civicrm/CRM/Utils/Rule.php @@ -502,9 +502,15 @@ class CRM_Utils_Rule { } /** - * @param $value + * Strip thousand separator from a money string. + * + * Note that this should be done at the form layer. Once we are processing + * money at the BAO or processor layer we should be working with something that + * is already in a normalised format. + * + * @param string $value * - * @return mixed + * @return string */ public static function cleanMoney($value) { // first remove all white space diff --git a/civicrm/CRM/Utils/SQL.php b/civicrm/CRM/Utils/SQL.php index a82614e465..dba0c9ebe8 100644 --- a/civicrm/CRM/Utils/SQL.php +++ b/civicrm/CRM/Utils/SQL.php @@ -80,7 +80,7 @@ class CRM_Utils_SQL { // CRM-21455 MariaDB 10.2 does not support ANY_VALUE $version = CRM_Core_DAO::singleValueQuery('SELECT VERSION()'); - if (stripos('mariadb', $version) !== FALSE) { + if (stripos($version, 'mariadb') !== FALSE) { return FALSE; } diff --git a/civicrm/Civi/Core/SettingsBag.php b/civicrm/Civi/Core/SettingsBag.php index 2aee1eb1c2..66a663e93b 100644 --- a/civicrm/Civi/Core/SettingsBag.php +++ b/civicrm/Civi/Core/SettingsBag.php @@ -352,9 +352,11 @@ class SettingsBag { } $dao->find(TRUE); - // string comparison with 0 always return true, so to be ensure the type use === - // ref - https://stackoverflow.com/questions/8671942/php-string-comparasion-to-0-integer-returns-true - if (isset($metadata['on_change']) && !($value === 0 && ($dao->value === NULL || unserialize($dao->value) == 0))) { + // Call 'on_change' listeners. It would be nice to only fire when there's + // a genuine change in the data. However, PHP developers have mixed + // expectations about whether 0, '0', '', NULL, and FALSE represent the same + // value, so there's no universal way to determine if a change is genuine. + if (isset($metadata['on_change'])) { foreach ($metadata['on_change'] as $callback) { call_user_func( \Civi\Core\Resolver::singleton()->get($callback), diff --git a/civicrm/api/v3/Contribution.php b/civicrm/api/v3/Contribution.php index 6ed8f2a93e..027725ff58 100644 --- a/civicrm/api/v3/Contribution.php +++ b/civicrm/api/v3/Contribution.php @@ -45,6 +45,9 @@ function civicrm_api3_contribution_create(&$params) { $values = array(); _civicrm_api3_custom_format_params($params, $values, 'Contribution'); $params = array_merge($params, $values); + // The BAO should not clean money - it should be done in the form layer & api wrapper + // (although arguably the api should expect pre-cleaned it seems to do some cleaning.) + $params['skipCleanMoney'] = TRUE; if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) { if (empty($params['id'])) { diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php index dfe26c0bf4..473b0949fb 100644 --- a/civicrm/civicrm-version.php +++ b/civicrm/civicrm-version.php @@ -1,6 +1,6 @@ <?php function civicrmVersion( ) { - return array( 'version' => '4.7.28', + return array( 'version' => '4.7.29', 'cms' => 'Wordpress', 'revision' => '' ); } diff --git a/civicrm/install/index.php b/civicrm/install/index.php index b32c4f530d..1176379200 100644 --- a/civicrm/install/index.php +++ b/civicrm/install/index.php @@ -595,12 +595,9 @@ class InstallRequirements { $this->errors = NULL; - // See also: CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER - $this->requirePHPVersion('5.3.4', array( + $this->requirePHPVersion(array( ts("PHP Configuration"), ts("PHP5 installed"), - NULL, - ts("PHP version %1", array(1 => phpversion())), )); // Check that we can identify the root folder successfully @@ -860,36 +857,30 @@ class InstallRequirements { } /** - * @param $minVersion - * @param $testDetails - * @param null $maxVersion + * @param array $testDetails + * @return bool */ - public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) { + public function requirePHPVersion($testDetails) { $this->testing($testDetails); $phpVersion = phpversion(); - $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0; - $belowMaxVersion = $maxVersion ? version_compare($phpVersion, $maxVersion) < 0 : TRUE; + $aboveMinVersion = version_compare($phpVersion, CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER) >= 0; - if ($aboveMinVersion && $belowMaxVersion) { - if (version_compare(phpversion(), CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER) < 0) { - $testDetails[2] = ts('This webserver is running an outdated version of PHP (%1). It is strongly recommended to upgrade to PHP %2 or later, as older versions can present a security risk.', array( - 1 => phpversion(), + if ($aboveMinVersion) { + if (version_compare($phpVersion, CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER) < 0) { + $testDetails[2] = ts('This webserver is running an outdated version of PHP (%1). It is strongly recommended to upgrade to PHP %2 or later, as older versions can present a security risk. The preferred version is %3.', array( + 1 => $phpVersion, 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER, + 3 => CRM_Upgrade_Incremental_General::RECOMMENDED_PHP_VER, )); $this->warning($testDetails); } return TRUE; } - if (!$testDetails[2]) { - if (!$aboveMinVersion) { - $testDetails[2] = ts("You need PHP version %1 or later, only %2 is installed. Please upgrade your server, or ask your web-host to do so.", array(1 => $minVersion, 2 => $phpVersion)); - } - else { - $testDetails[2] = ts("PHP version %1 is not supported. PHP version earlier than %2 is required. You might want to downgrade your server, or ask your web-host to do so.", array(1 => $maxVersion, 2 => $phpVersion)); - } + if (empty($testDetails[2])) { + $testDetails[2] = ts("You need PHP version %1 or later, only %2 is installed. Please upgrade your server, or ask your web-host to do so.", array(1 => CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER, 2 => $phpVersion)); } $this->error($testDetails); diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md index 9777c84c6c..9edaae7353 100644 --- a/civicrm/release-notes.md +++ b/civicrm/release-notes.md @@ -14,6 +14,16 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress +## CiviCRM 4.7.29 + +Released December 20, 2017 + +- **[Synopsis](release-notes/4.7.29.md#synopsis)** +- **[Features](release-notes/4.7.29.md#features)** +- **[Bugs resolved](release-notes/4.7.29.md#bugs)** +- **[Credits](release-notes/4.7.29.md#credits)** +- **[Feedback](release-notes/4.7.29.md#feedback)** + ## CiviCRM 4.7.28 Released December 6, 2017 diff --git a/civicrm/release-notes/4.7.29.md b/civicrm/release-notes/4.7.29.md new file mode 100644 index 0000000000..5aba623c9b --- /dev/null +++ b/civicrm/release-notes/4.7.29.md @@ -0,0 +1,79 @@ +# CiviCRM 4.7.29 + +Released December 20, 2017 + +- **[Synopsis](#synopsis)** +- **[Features](#features)** +- **[Bugs resolved](#bugs)** +- **[Miscellany](#misc)** +- **[Credits](#credits)** +- **[Feedback](#feedback)** + +## <a name="synopsis"></a>Synopsis + +| *Does this version...?* | | +|:----------------------------------------------------------- |:-------:| +| Fix security vulnerabilities? | no | +| Change the database schema? | no | +| Alter the API? | no | +| Require attention to configuration options? | no | +| Fix problems installing or upgrading to a previous version? | no | +| **Introduce features?** | **yes** | +| **Fix bugs?** | **yes** | + +## <a name="features"></a>Features + +### Core CiviCRM + +- **[CRM-20941](https://issues.civicrm.org/jira/browse/CRM-20941) Increase minimum PHP required to install CiviCRM + ([11416](https://github.com/civicrm/civicrm-core/pull/11416))** + + Increases the minimum PHP version required to install CiviCRM 4.7.29 to be 5.4 as per the [announcement blog post](https://civicrm.org/blog/totten/end-of-zombies-php-53-and-54) + +## <a name="bugs"></a>Bugs resolved + +### Core CiviCRM + +- **[CRM-21445](https://issues.civicrm.org/jira/browse/CRM-20941) Ensure "Pay Later" processor is set so a fatal isn't thrown + ([11427](https://github.com/civicrm/civicrm-core/pull/11427))** + + Ensures that the pay later payment processor is set to that a fatal error isn't thrown + +- **[CRM-21431](https://issues.civicrm.org/jira/browse/CRM-21431) Fix removing of group types + ([11436](https://github.com/civicrm/civicrm-core/pull/11436))** + + Fixes an issue where unchecking both the ACL and Mailing list box when editing a group didn't actually remove those types + +- **[CRM-21568](https://issues.civicrm.org/jira/browse/CRM-21568) Move the determination of values of empty from settingsbag to InnodbIndxer + ([11423](https://github.com/civicrm/civicrm-core/pull/11423))** + + Fixes an issue where string '0' wasn't being treated as false. So the checking of whether there is an empty value is now done in the on change listener for the full text search switcher + +- **[CRM-21562](https://issues.civicrm.org/jira/browse/CRM-21562) Fix line item mis-saving when using a ',' as the thousand separator + ([11412](https://github.com/civicrm/civicrm-core/pull/11412))** + + Fixes an issue for currencies which use a ',' as the thousand separator the line item was being incorrectly saved by a significant margin. + +- **[CRM-21534](https://issues.civicrm.org/jira/browse/CRM-21534) Fix issue where checking if server was a MariaDB server wasn't working correctly + ([11413](https://github.com/civicrm/civicrm-core/pull/11413))** + + Fixes an issue where the check to see if the MySQL server was a MariaDB instance wasn't working right. This lead to hard crashes as queries were being incorrectly re-written + +## <a name="credits"></a>Credits + +This release was developed by the following code authors: + +Australian Greens - Seamus Lee; CiviCRM - Coleman Watts, Tim Otten; +Coop SymbioTIC - Mathieu Lutfy; Wikimedia Foundation - Eileen McNaughton + +Most authors also reviewed code for this release; in addition, the following +reviewers contributed their comments: + +Ben Mango; JMA Consulting - Monish Deb; Megaphone Technology Consulting - Jon +Goldberg; Richard van Oosterhout + +## <a name="feedback"></a>Feedback + +These release notes are edited by Andrew Hunt. If you'd like to provide +feedback on them, please login to https://chat.civicrm.org/civicrm and contact +`@agh1`. diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql index 9e4af9d28b..d5589f24a0 100644 --- a/civicrm/sql/civicrm_data.mysql +++ b/civicrm/sql/civicrm_data.mysql @@ -23948,4 +23948,4 @@ INSERT INTO `civicrm_report_instance` VALUES ( @domainID, 'Survey Details', 'survey/detail', 'Detailed report for canvassing, phone-banking, walk lists or other surveys.', 'access CiviReport', 'a:39:{s:6:"fields";a:2:{s:9:"sort_name";s:1:"1";s:6:"result";s:1:"1";}s:22:"assignee_contact_id_op";s:2:"eq";s:25:"assignee_contact_id_value";s:0:"";s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:17:"street_number_min";s:0:"";s:17:"street_number_max";s:0:"";s:16:"street_number_op";s:3:"lte";s:19:"street_number_value";s:0:"";s:14:"street_name_op";s:3:"has";s:17:"street_name_value";s:0:"";s:15:"postal_code_min";s:0:"";s:15:"postal_code_max";s:0:"";s:14:"postal_code_op";s:3:"lte";s:17:"postal_code_value";s:0:"";s:7:"city_op";s:3:"has";s:10:"city_value";s:0:"";s:20:"state_province_id_op";s:2:"in";s:23:"state_province_id_value";a:0:{}s:13:"country_id_op";s:2:"in";s:16:"country_id_value";a:0:{}s:12:"survey_id_op";s:2:"in";s:15:"survey_id_value";a:0:{}s:12:"status_id_op";s:2:"eq";s:15:"status_id_value";s:1:"1";s:11:"custom_1_op";s:2:"in";s:14:"custom_1_value";a:0:{}s:11:"custom_2_op";s:2:"in";s:14:"custom_2_value";a:0:{}s:17:"custom_3_relative";s:1:"0";s:13:"custom_3_from";s:0:"";s:11:"custom_3_to";s:0:"";s:11:"description";s:75:"Detailed report for canvassing, phone-banking, walk lists or other surveys.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviReport";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}'); -UPDATE civicrm_domain SET version = '4.7.28'; +UPDATE civicrm_domain SET version = '4.7.29'; diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql index b5d3272108..e67d6d0af5 100644 --- a/civicrm/sql/civicrm_generated.mysql +++ b/civicrm/sql/civicrm_generated.mysql @@ -399,7 +399,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_domain` WRITE; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; -INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.7.28',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); +INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.7.29',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */; UNLOCK TABLES; diff --git a/civicrm/templates/CRM/common/version.tpl b/civicrm/templates/CRM/common/version.tpl index 21f4f3f3ef..e9b84c35cf 100644 --- a/civicrm/templates/CRM/common/version.tpl +++ b/civicrm/templates/CRM/common/version.tpl @@ -1 +1 @@ -4.7.28 \ No newline at end of file +4.7.29 \ No newline at end of file diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php index 616bd0f712..633ea9eb7a 100644 --- a/civicrm/vendor/autoload.php +++ b/civicrm/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInit1ebc8b5f142ef547147d855925aa5948::getLoader(); +return ComposerAutoloaderInit5cdee2268f29abd76073fe42de4e8d15::getLoader(); diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php index ebaeeb3c7f..86a01c7ba7 100644 --- a/civicrm/vendor/composer/autoload_real.php +++ b/civicrm/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit1ebc8b5f142ef547147d855925aa5948 +class ComposerAutoloaderInit5cdee2268f29abd76073fe42de4e8d15 { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInit1ebc8b5f142ef547147d855925aa5948 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit1ebc8b5f142ef547147d855925aa5948', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit5cdee2268f29abd76073fe42de4e8d15', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit1ebc8b5f142ef547147d855925aa5948', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit5cdee2268f29abd76073fe42de4e8d15', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; array_push($includePaths, get_include_path()); @@ -31,7 +31,7 @@ class ComposerAutoloaderInit1ebc8b5f142ef547147d855925aa5948 if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit1ebc8b5f142ef547147d855925aa5948::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit5cdee2268f29abd76073fe42de4e8d15::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -52,19 +52,19 @@ class ComposerAutoloaderInit1ebc8b5f142ef547147d855925aa5948 $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit1ebc8b5f142ef547147d855925aa5948::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit5cdee2268f29abd76073fe42de4e8d15::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire1ebc8b5f142ef547147d855925aa5948($fileIdentifier, $file); + composerRequire5cdee2268f29abd76073fe42de4e8d15($fileIdentifier, $file); } return $loader; } } -function composerRequire1ebc8b5f142ef547147d855925aa5948($fileIdentifier, $file) +function composerRequire5cdee2268f29abd76073fe42de4e8d15($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php index a130f3d531..d327aa0382 100644 --- a/civicrm/vendor/composer/autoload_static.php +++ b/civicrm/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit1ebc8b5f142ef547147d855925aa5948 +class ComposerStaticInit5cdee2268f29abd76073fe42de4e8d15 { public static $files = array ( 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', @@ -344,10 +344,10 @@ class ComposerStaticInit1ebc8b5f142ef547147d855925aa5948 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit1ebc8b5f142ef547147d855925aa5948::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit1ebc8b5f142ef547147d855925aa5948::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit1ebc8b5f142ef547147d855925aa5948::$prefixesPsr0; - $loader->classMap = ComposerStaticInit1ebc8b5f142ef547147d855925aa5948::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit5cdee2268f29abd76073fe42de4e8d15::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit5cdee2268f29abd76073fe42de4e8d15::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInit5cdee2268f29abd76073fe42de4e8d15::$prefixesPsr0; + $loader->classMap = ComposerStaticInit5cdee2268f29abd76073fe42de4e8d15::$classMap; }, null, ClassLoader::class); } -- GitLab