From aa6d176929b82431218b4f2f5d53d1bd95a49d59 Mon Sep 17 00:00:00 2001 From: Kevin Cristiano <kcristiano@kcristiano.com> Date: Fri, 26 Jan 2024 08:23:36 -0500 Subject: [PATCH] civicrm release-5.69.3 --- civicrm.php | 4 +- civicrm/CRM/Admin/Form/Setting/Mail.php | 1 + civicrm/CRM/Contact/Form/Contact.php | 2 +- .../CRM/Contribute/Form/Contribution/Main.php | 4 +- civicrm/CRM/Mailing/BAO/Mailing.php | 26 +- civicrm/CRM/Mailing/Form/Unsubscribe.php | 2 +- civicrm/CRM/Mailing/Page/Unsubscribe.php | 42 ++- .../CRM/Mailing/Service/ListUnsubscribe.php | 85 ++++++ civicrm/CRM/Mailing/xml/Menu/Mailing.xml | 2 +- civicrm/CRM/Utils/Check/Component/Mailing.php | 46 +++ civicrm/CRM/Utils/Check/Message.php | 3 + civicrm/CRM/Utils/System/Base.php | 2 +- civicrm/Civi/Test/LocalHttpClient.php | 276 ++++++++++++++++++ .../Civi/Test/LocalHttpClient/ClassProps.php | 40 +++ .../Civi/Test/LocalHttpClient/SuperGlobal.php | 37 +++ civicrm/ang/crmStatusPage/StatusPageCtrl.js | 2 +- civicrm/civicrm-version.php | 2 +- civicrm/ext/afform/admin/info.xml | 4 +- civicrm/ext/afform/core/info.xml | 4 +- civicrm/ext/afform/html/info.xml | 4 +- civicrm/ext/afform/mock/info.xml | 4 +- civicrm/ext/authx/info.xml | 4 +- civicrm/ext/civi_campaign/info.xml | 4 +- civicrm/ext/civi_case/info.xml | 4 +- civicrm/ext/civi_contribute/info.xml | 4 +- civicrm/ext/civi_event/info.xml | 4 +- civicrm/ext/civi_mail/info.xml | 4 +- civicrm/ext/civi_member/info.xml | 4 +- civicrm/ext/civi_pledge/info.xml | 4 +- civicrm/ext/civi_report/info.xml | 4 +- civicrm/ext/civicrm_admin_ui/info.xml | 4 +- civicrm/ext/civicrm_search_ui/info.xml | 4 +- civicrm/ext/civigrant/info.xml | 4 +- civicrm/ext/civiimport/info.xml | 4 +- civicrm/ext/ckeditor4/info.xml | 4 +- .../ext/contributioncancelactions/info.xml | 4 +- civicrm/ext/elavon/info.xml | 4 +- civicrm/ext/eventcart/info.xml | 4 +- civicrm/ext/ewaysingle/info.xml | 4 +- civicrm/ext/financialacls/info.xml | 4 +- civicrm/ext/flexmailer/info.xml | 4 +- .../Civi/FlexMailer/FlexMailerSystemTest.php | 6 +- civicrm/ext/greenwich/info.xml | 4 +- civicrm/ext/legacycustomsearches/info.xml | 4 +- civicrm/ext/message_admin/info.xml | 4 +- civicrm/ext/oauth-client/info.xml | 4 +- civicrm/ext/payflowpro/info.xml | 4 +- civicrm/ext/recaptcha/info.xml | 4 +- civicrm/ext/scheduled_communications/info.xml | 4 +- civicrm/ext/search_kit/info.xml | 4 +- civicrm/ext/sequentialcreditnotes/info.xml | 4 +- civicrm/ext/standaloneusers/info.xml | 4 +- civicrm/ext/user_dashboard/info.xml | 4 +- civicrm/js/version.json | 2 +- civicrm/release-notes.md | 9 + civicrm/release-notes/5.69.3.md | 49 ++++ civicrm/settings/Mailing.setting.php | 24 ++ civicrm/sql/civicrm_data.mysql | 2 +- civicrm/sql/civicrm_generated.mysql | 2 +- .../CRM/Contribute/Form/Contribution/Main.tpl | 2 +- civicrm/templates/CRM/Price/Page/LineItem.tpl | 5 +- civicrm/vendor/autoload.php | 2 +- civicrm/vendor/composer/autoload_real.php | 14 +- civicrm/vendor/composer/autoload_static.php | 12 +- civicrm/vendor/composer/installed.php | 4 +- civicrm/xml/version.xml | 2 +- 66 files changed, 729 insertions(+), 122 deletions(-) create mode 100644 civicrm/CRM/Mailing/Service/ListUnsubscribe.php create mode 100644 civicrm/CRM/Utils/Check/Component/Mailing.php create mode 100644 civicrm/Civi/Test/LocalHttpClient.php create mode 100644 civicrm/Civi/Test/LocalHttpClient/ClassProps.php create mode 100644 civicrm/Civi/Test/LocalHttpClient/SuperGlobal.php create mode 100644 civicrm/release-notes/5.69.3.md diff --git a/civicrm.php b/civicrm.php index cd768d1bde..493058e427 100644 --- a/civicrm.php +++ b/civicrm.php @@ -2,7 +2,7 @@ /** * Plugin Name: CiviCRM * Description: CiviCRM - Growing and Sustaining Relationships - * Version: 5.69.2 + * Version: 5.69.3 * Requires at least: 4.9 * Requires PHP: 7.3 * Author: CiviCRM LLC @@ -36,7 +36,7 @@ if (!defined('ABSPATH')) { } // Set version here: changing it forces Javascript and CSS to reload. -define('CIVICRM_PLUGIN_VERSION', '5.69.2'); +define('CIVICRM_PLUGIN_VERSION', '5.69.3'); // Store reference to this file. if (!defined('CIVICRM_PLUGIN_FILE')) { diff --git a/civicrm/CRM/Admin/Form/Setting/Mail.php b/civicrm/CRM/Admin/Form/Setting/Mail.php index 4b49514c34..358c87f81f 100644 --- a/civicrm/CRM/Admin/Form/Setting/Mail.php +++ b/civicrm/CRM/Admin/Form/Setting/Mail.php @@ -29,6 +29,7 @@ class CRM_Admin_Form_Setting_Mail extends CRM_Admin_Form_Setting { // dev/core#1768 Make this interval configurable. 'civimail_sync_interval' => CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, 'replyTo' => CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, + 'civimail_unsubscribe_methods' => CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, ]; /** diff --git a/civicrm/CRM/Contact/Form/Contact.php b/civicrm/CRM/Contact/Form/Contact.php index 99d0761d00..d66616d09a 100644 --- a/civicrm/CRM/Contact/Form/Contact.php +++ b/civicrm/CRM/Contact/Form/Contact.php @@ -365,7 +365,7 @@ class CRM_Contact_Form_Contact extends CRM_Core_Form { // the buildForm adds the contact_sub_type to the form we need to look in _submitValues for it - submitValues // is a un-sanitised version of what is in the form submission (_POST) whereas `getSubmittedValues()` retrieves // 'allowed' POSTED values - ie values which match available fields, with some localization handling. - CRM_Custom_Form_CustomData::preProcess($this, NULL, $this->isSubmitted() ? ($this->_submitValues['contact_sub_type'] ?? []) : $this->getContactValue('contact_sub_type'), + CRM_Custom_Form_CustomData::preProcess($this, NULL, $this->isSubmitted() ? ($this->_submitValues['contact_sub_type'] ?? []) : $this->getContactValue('contact_sub_type') ?? $this->_contactSubType, 1, $this->_contactType, $this->getContactID() ); $this->assign('customValueCount', $this->_customValueCount); diff --git a/civicrm/CRM/Contribute/Form/Contribution/Main.php b/civicrm/CRM/Contribute/Form/Contribution/Main.php index 8b5544e590..a39d1b0665 100644 --- a/civicrm/CRM/Contribute/Form/Contribution/Main.php +++ b/civicrm/CRM/Contribute/Form/Contribution/Main.php @@ -1852,9 +1852,9 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu return 0; } if (!$this->isQuickConfig()) { - return CRM_Member_BAO_MembershipType::getMembershipType($membershipTypeID)['auto_renew']; + return CRM_Member_BAO_MembershipType::getMembershipType($membershipTypeID)['auto_renew'] ?? 0; } - $membershipTypeAutoRenewOption = CRM_Member_BAO_MembershipType::getMembershipType($membershipTypeID)['auto_renew']; + $membershipTypeAutoRenewOption = CRM_Member_BAO_MembershipType::getMembershipType($membershipTypeID)['auto_renew'] ?? 0; if ($membershipTypeAutoRenewOption === 2 || $membershipTypeAutoRenewOption === 0) { // It is not possible to override never or always at the membership block leve. return $membershipTypeAutoRenewOption; diff --git a/civicrm/CRM/Mailing/BAO/Mailing.php b/civicrm/CRM/Mailing/BAO/Mailing.php index c476818874..ad551aeb11 100644 --- a/civicrm/CRM/Mailing/BAO/Mailing.php +++ b/civicrm/CRM/Mailing/BAO/Mailing.php @@ -2439,19 +2439,19 @@ LEFT JOIN civicrm_mailing_group g ON g.mailing_id = m.id public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) { if ($event->action === 'create') { $params = &$event->params; - $params['created_id'] ??= CRM_Core_Session::singleton()->getLoggedInContactID(); - $params['override_verp'] ??= !Civi::settings()->get('track_civimail_replies'); - $params['visibility'] ??= 'Public Pages'; - $params['dedupe_email'] ??= Civi::settings()->get('dedupe_email_default'); - $params['open_tracking'] ??= Civi::settings()->get('open_tracking_default'); - $params['url_tracking'] ??= Civi::settings()->get('url_tracking_default'); - $params['header_id'] ??= CRM_Mailing_PseudoConstant::defaultComponent('Header', ''); - $params['footer_id'] ??= CRM_Mailing_PseudoConstant::defaultComponent('Footer', ''); - $params['optout_id'] ??= CRM_Mailing_PseudoConstant::defaultComponent('OptOut', ''); - $params['reply_id'] ??= CRM_Mailing_PseudoConstant::defaultComponent('Reply', ''); - $params['resubscribe_id'] ??= CRM_Mailing_PseudoConstant::defaultComponent('Resubscribe', ''); - $params['unsubscribe_id'] ??= CRM_Mailing_PseudoConstant::defaultComponent('Unsubscribe', ''); - $params['mailing_type'] ??= 'standalone'; + $params['created_id'] = $params['created_id'] ?? CRM_Core_Session::singleton()->getLoggedInContactID(); + $params['override_verp'] = $params['override_verp'] ?? !Civi::settings()->get('track_civimail_replies'); + $params['visibility'] = $params['visibility'] ?? 'Public Pages'; + $params['dedupe_email'] = $params['dedupe_email'] ?? Civi::settings()->get('dedupe_email_default'); + $params['open_tracking'] = $params['open_tracking'] ?? Civi::settings()->get('open_tracking_default'); + $params['url_tracking'] = $params['url_tracking'] ?? Civi::settings()->get('url_tracking_default'); + $params['header_id'] = $params['header_id'] ?? CRM_Mailing_PseudoConstant::defaultComponent('Header', ''); + $params['footer_id'] = $params['footer_id'] ?? CRM_Mailing_PseudoConstant::defaultComponent('Footer', ''); + $params['optout_id'] = $params['optout_id'] ?? CRM_Mailing_PseudoConstant::defaultComponent('OptOut', ''); + $params['reply_id'] = $params['reply_id'] ?? CRM_Mailing_PseudoConstant::defaultComponent('Reply', ''); + $params['resubscribe_id'] = $params['resubscribe_id'] ?? CRM_Mailing_PseudoConstant::defaultComponent('Resubscribe', ''); + $params['unsubscribe_id'] = $params['unsubscribe_id'] ?? CRM_Mailing_PseudoConstant::defaultComponent('Unsubscribe', ''); + $params['mailing_type'] = $params['mailing_type'] ?? 'standalone'; } if ($event->action === 'delete' && $event->id) { // Delete all file attachments diff --git a/civicrm/CRM/Mailing/Form/Unsubscribe.php b/civicrm/CRM/Mailing/Form/Unsubscribe.php index f0a8e0d1f9..6abca91f81 100644 --- a/civicrm/CRM/Mailing/Form/Unsubscribe.php +++ b/civicrm/CRM/Mailing/Form/Unsubscribe.php @@ -64,7 +64,7 @@ class CRM_Mailing_Form_Unsubscribe extends CRM_Core_Form { ); } - list($displayName, $email) = CRM_Mailing_Event_BAO_MailingEventQueue::getContactInfo($queue_id); + [$displayName, $email] = CRM_Mailing_Event_BAO_MailingEventQueue::getContactInfo($queue_id); $this->assign('display_name', $displayName); $nameMasked = ''; $names = explode(' ', $displayName); diff --git a/civicrm/CRM/Mailing/Page/Unsubscribe.php b/civicrm/CRM/Mailing/Page/Unsubscribe.php index 349ee59d2a..218fe4c828 100644 --- a/civicrm/CRM/Mailing/Page/Unsubscribe.php +++ b/civicrm/CRM/Mailing/Page/Unsubscribe.php @@ -14,7 +14,7 @@ * @package CRM * @copyright CiviCRM LLC https://civicrm.org/licensing */ -class CRM_Mailing_Page_Unsubscribe extends CRM_Mailing_Page_Common { +class CRM_Mailing_Page_Unsubscribe extends CRM_Core_Page { /** * Run page. @@ -25,8 +25,44 @@ class CRM_Mailing_Page_Unsubscribe extends CRM_Mailing_Page_Common { * @throws Exception */ public function run() { - $this->_type = 'unsubscribe'; - return parent::run(); + $isOneClick = ($_SERVER['REQUEST_METHOD'] === 'POST' && CRM_Utils_Request::retrieve('List-Unsubscribe', 'String') === 'One-Click'); + if ($isOneClick) { + $this->handleOneClick(); + return NULL; + } + + $wrapper = new CRM_Utils_Wrapper(); + return $wrapper->run('CRM_Mailing_Form_Unsubscribe', $this->_title); + } + + /** + * + * Pre-condition: Validated the _job_id, _queue_id, _hash. + * Post-condition: Unsubscribed + * + * @link https://datatracker.ietf.org/doc/html/rfc8058 + * @return void + */ + public function handleOneClick(): void { + $jobId = CRM_Utils_Request::retrieve('jid', 'Integer'); + $queueId = CRM_Utils_Request::retrieve('qid', 'Integer'); + $hash = CRM_Utils_Request::retrieve('h', 'String'); + + $q = CRM_Mailing_Event_BAO_MailingEventQueue::verify(NULL, $queueId, $hash); + if (!$q) { + CRM_Utils_System::sendResponse( + new \GuzzleHttp\Psr7\Response(400, [], ts("Invalid request: bad parameters")) + ); + } + + $groups = CRM_Mailing_Event_BAO_MailingEventUnsubscribe::unsub_from_mailing($jobId, $queueId, $hash); + if (!empty($groups)) { + CRM_Mailing_Event_BAO_MailingEventUnsubscribe::send_unsub_response($queueId, $groups, FALSE, $jobId); + } + + CRM_Utils_System::sendResponse( + new \GuzzleHttp\Psr7\Response(200, [], 'OK') + ); } } diff --git a/civicrm/CRM/Mailing/Service/ListUnsubscribe.php b/civicrm/CRM/Mailing/Service/ListUnsubscribe.php new file mode 100644 index 0000000000..f7f8910563 --- /dev/null +++ b/civicrm/CRM/Mailing/Service/ListUnsubscribe.php @@ -0,0 +1,85 @@ +<?php + +/** + * Apply a full range of `List-Unsubscribe` header options. + * + * @service civi.mailing.listUnsubscribe + * @link https://datatracker.ietf.org/doc/html/rfc8058 + */ +class CRM_Mailing_Service_ListUnsubscribe extends \Civi\Core\Service\AutoService implements \Symfony\Component\EventDispatcher\EventSubscriberInterface { + + /** + * @var string|null + */ + private $urlFlags = NULL; + + public static function getMethods(): array { + return [ + 'mailto' => ts('Mailto'), + 'http' => ts('HTTP(S) Web-Form'), + 'oneclick' => ts('HTTP(S) One-Click'), + ]; + } + + public static function getSubscribedEvents() { + return [ + '&hook_civicrm_alterMailParams' => ['alterMailParams', 1000], + ]; + } + + /** + * @see \CRM_Utils_Hook::alterMailParams() + */ + public function alterMailParams(&$params, $context = NULL): void { + // FIXME: Flexmailer (BasicHeaders) and BAO (getVerpAndUrlsAndHeaders) separately define + // `List-Unsubscribe: <mailto:....>`. And they have separate invocations of alterMailParams. + // + // This code is a little ugly because it anticipates serving both code-paths. + // But the BAO path should be properly killed. Doing so will allow you cleanup this code more. + + if (!in_array($context, ['civimail', 'flexmailer'])) { + return; + } + + $methods = Civi::settings()->get('civimail_unsubscribe_methods'); + if ($methods === ['mailto']) { + return; + } + + $sep = preg_quote(Civi::settings()->get('verpSeparator'), ';'); + $regex = ";^<mailto:[^>]*u{$sep}(\d+){$sep}(\d+){$sep}(\w*)@(.+)>$;"; + if (!preg_match($regex, $params['List-Unsubscribe'], $m)) { + \Civi::log()->warning('Failed to set final value of List-Unsubscribe'); + return; + } + + if ($this->urlFlags === NULL) { + $this->urlFlags = 'a'; + if (in_array('oneclick', $methods) && empty(parse_url(CIVICRM_UF_BASEURL, PHP_URL_PORT))) { + // Yahoo etal require HTTPS for one-click URLs. Cron-runs can be a bit inconsistent wrt HTTP(S), + // so we force-SSL for most production-style sites. + $this->urlFlags .= 's'; + } + } + + $listUnsubscribe = []; + if (in_array('mailto', $methods)) { + $listUnsubscribe[] = $params['List-Unsubscribe']; + } + if (array_intersect(['http', 'oneclick'], $methods)) { + $listUnsubscribe[] = '<' . Civi::url('frontend://civicrm/mailing/unsubscribe', $this->urlFlags)->addQuery([ + 'reset' => 1, + 'jid' => $m[1], + 'qid' => $m[2], + 'h' => $m[3], + ]) . '>'; + } + + if (in_array('oneclick', $methods)) { + $params['headers']['List-Unsubscribe-Post'] = 'List-Unsubscribe=One-Click'; + } + $params['headers']['List-Unsubscribe'] = implode(', ', $listUnsubscribe); + unset($params['List-Unsubscribe']); + } + +} diff --git a/civicrm/CRM/Mailing/xml/Menu/Mailing.xml b/civicrm/CRM/Mailing/xml/Menu/Mailing.xml index f3267235d3..7942323fad 100644 --- a/civicrm/CRM/Mailing/xml/Menu/Mailing.xml +++ b/civicrm/CRM/Mailing/xml/Menu/Mailing.xml @@ -115,7 +115,7 @@ <item> <path>civicrm/mailing/unsubscribe</path> <title>Unsubscribe</title> - <page_callback>CRM_Mailing_Form_Unsubscribe</page_callback> + <page_callback>CRM_Mailing_Page_Unsubscribe</page_callback> <access_arguments>access CiviMail subscribe/unsubscribe pages</access_arguments> <is_public>true</is_public> <weight>640</weight> diff --git a/civicrm/CRM/Utils/Check/Component/Mailing.php b/civicrm/CRM/Utils/Check/Component/Mailing.php new file mode 100644 index 0000000000..b7288fb8f0 --- /dev/null +++ b/civicrm/CRM/Utils/Check/Component/Mailing.php @@ -0,0 +1,46 @@ +<?php +/* + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC. All rights reserved. | + | | + | This work is published under the GNU AGPLv3 license with some | + | permitted exceptions and without any warranty. For full license | + | and copyright information, see https://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +/** + * + * @package CRM + * @copyright CiviCRM LLC https://civicrm.org/licensing + */ +class CRM_Utils_Check_Component_Mailing extends CRM_Utils_Check_Component { + + /** + * @return CRM_Utils_Check_Message[] + */ + public function checkUnsubscribeMethods() { + if (!\CRM_Core_Component::isEnabled('CiviMail')) { + return []; + } + + $methods = Civi::settings()->get('civimail_unsubscribe_methods'); + if (in_array('oneclick', $methods)) { + return []; + } + + // OK, all guards passed. Show message. + $message = new CRM_Utils_Check_Message( + __FUNCTION__, + '<p>' . ts('Beginning in 2024, some web-mail services (Google and Yahoo) will require that large mailing-lists support another unsubscribe method: "HTTP One-Click" (RFC 8058). Please review the documentation and update the settings.') . '</p>', + ts('CiviMail: Enable One-Click Unsubscribe'), + \Psr\Log\LogLevel::NOTICE, + 'fa-server' + ); + $message->addAction(ts('Learn more'), FALSE, 'href', ['url' => 'https://civicrm.org/redirect/unsubscribe-one-click'], 'fa-info-circle'); + $message->addAction(ts('Update settings'), FALSE, 'href', ['path' => 'civicrm/admin/mail', 'query' => 'reset=1'], 'fa-wrench'); + + return [$message]; + } + +} diff --git a/civicrm/CRM/Utils/Check/Message.php b/civicrm/CRM/Utils/Check/Message.php index 8aae42516f..deb4a4b6cb 100644 --- a/civicrm/CRM/Utils/Check/Message.php +++ b/civicrm/CRM/Utils/Check/Message.php @@ -155,6 +155,9 @@ class CRM_Utils_Check_Message { * Currently supports: api3 or href * @param array $params * Params to be passed to CRM.api3 or CRM.url depending on type + * Ex: ['MyApiEntity', 'MyApiAction', [...params...]] + * Ex: ['path' => 'civicrm/admin/foo', 'query' => 'reset=1'] + * Ex: ['url' => 'https://example.com/more/info'] * @param string $icon * Fa-icon class for the button */ diff --git a/civicrm/CRM/Utils/System/Base.php b/civicrm/CRM/Utils/System/Base.php index 8559f220b2..a5cbcaf780 100644 --- a/civicrm/CRM/Utils/System/Base.php +++ b/civicrm/CRM/Utils/System/Base.php @@ -977,7 +977,7 @@ abstract class CRM_Utils_System_Base { CRM_Utils_System::setHttpHeader($name, implode(', ', (array) $values)); } echo $response->getBody(); - CRM_Utils_System::civiExit(); + CRM_Utils_System::civiExit(0, ['response' => $response]); } /** diff --git a/civicrm/Civi/Test/LocalHttpClient.php b/civicrm/Civi/Test/LocalHttpClient.php new file mode 100644 index 0000000000..f7e9d01da8 --- /dev/null +++ b/civicrm/Civi/Test/LocalHttpClient.php @@ -0,0 +1,276 @@ +<?php + +namespace Civi\Test; + +use Civi\Test\LocalHttpClient\ClassProps; +use Civi\Test\LocalHttpClient\SuperGlobal; +use GuzzleHttp\Psr7\Response; +use Psr\Http\Client\ClientInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * (Experimental) Send HTTP-style requests directly to CRM_Core_Invoke (PSR-18 ClientInterface). + * This allows you to process many requests within the same PHP process, which can be useful for + * headless unit-testing. + * + * $c = new LocalHttpClient(['reboot' => FALSE]); + * $response = $c->sendRequest(new Request('GET', '/civicrm/foo?reset=1&bar=100')); + * $response = $c->sendRequest(new Request('GET', '/civicrm/whiz?reset=1&bang=200')); + * + * In theory, this could be the basis for headless HTTP testing with client-libraries like Guzzle, Mink, or BrowserKit. + * + * WHY: CiviCRM predates the PSR HTTP OOP conventions -- many things are built with $_GET, $_REQUEST, etc. + * To simulate an HTTP request to these, we swap-in and swap-out values for $_GET, $_REQUEST, etc. + * Consequently, there is some limited isolation between the parent/requester and child/requestee. + * + * NOTE: You can improve the isolation more with `reboot=>TRUE`. This will swap (and reinitialize) + * the CiviCRM runtime-config and service-container. However, there is no comprehensive option to + * swap all static properties (other classes), so some data may still leak between requester+requestee. + * + * NOTE: This is primarily intended for use in headless testing (CIVICRM_UF=UnitTests). It may + * or may not be quirky with real UFs. + * + * @link https://www.php-fig.org/psr/psr-18/ + */ +class LocalHttpClient implements ClientInterface { + + /** + * List of scopes which should be backed-up, (re)populated, (re)set for the duration of the subrequest. + * + * @var array + * Ex: ['_GET' => new SuperGlobal('_GET')] + */ + protected $scopes; + + /** + * List of scopes which should be inherited/extended within the subrequest. + * + * @var array + * Ex: ['_COOKIE', '_SERVER'] + */ + protected $inherit; + + /** + * Whether to generate the HTML <HEAD>er + * + * @var bool + */ + protected $htmlHeader; + + /** + * @param array $options + * - reboot (bool): TRUE if you want to re-bootstrap CiviCRM (config/container) on each request + * Default: FALSE + * - htmlHeader (bool): TRUE if you want the generated page to include the full HTML header + * This may become standard (non-optional). It's opt-out to help debug/work-around some early + * quirks when first using LocalHttpClient in CI. + * - globals (string[]): List of (super)globals that should be backed-up, populated, used, and restored. + * Default: ['_GET', '_POST', '_COOKIE', '_FILES', '_SERVER', '_REQUEST'] + * - inherit (string[]): When populating these (super)globals, build on top of the existing values. + * Default: ['_COOKIE', '_SERVER'] + */ + public function __construct(array $options = []) { + $defaultOptions = [ + 'reboot' => FALSE, + 'htmlHeader' => TRUE, + 'globals' => ['_GET', '_POST', '_COOKIE', '_FILES', '_SERVER', '_REQUEST'], + 'inherit' => ['_COOKIE', '_SERVER'], + ]; + $options = array_merge($defaultOptions, $options); + + $this->inherit = $options['inherit']; + $this->htmlHeader = $options['htmlHeader']; + $this->scopes = []; + + foreach ($options['globals'] as $scopeName) { + $this->scopes[$scopeName] = new SuperGlobal($scopeName); + } + + if ($options['reboot']) { + $classes = [ + \Civi::class, + \CRM_Core_Config::class, + \CRM_Utils_Hook::class, + \Civi\Core\Resolver::class, + \CRM_Queue_Service::class, + \CRM_Utils_System::class, + \CRM_Utils_Cache::class, + ]; + foreach ($classes as $class) { + $this->scopes[$class] = new ClassProps($class); + } + } + } + + public function sendRequest(RequestInterface $request): ResponseInterface { + $backup = $this->getAllValues(); + try { + $this->initScopes($request); + + $var = \CRM_Core_Config::singleton()->userFrameworkURLVar; + if (!isset($_GET[$var])) { + $_GET[$var] = ltrim($request->getUri()->getPath(), '/'); + } + $body = $this->invoke($_GET[$var]); + // FIXME: There's probably a way to instrument CRM_Utils_System_UnitTests to do this better. + return new Response(200, [], $body); + } + catch (\CRM_Core_Exception_PrematureExitException $e) { + if (isset($e->errorData['response'])) { + return $e->errorData['response']; + } + // FIXME: There are some things which emit PrematureExitException but don't provide the $response object. + // We should probably revise \CRM_Utils_System::redirect() and returnJsonResponse() + else { + throw $e; + } + } + finally { + $this->restoreAllValues($backup); + } + } + + protected function initScopes(RequestInterface $request) { + foreach ($this->scopes as $scopeName => $scope) { + if (!in_array($scopeName, $this->inherit)) { + $scope->unsetKeys(array_keys($scope->getValues())); + } + + $method = 'initValues' . $scopeName; + $initValues = is_callable([$this, $method]) ? $this->$method($request) : []; + $scope->setValues($initValues); + } + if (in_array('CRM_Core_Config', $this->scopes)) { + \CRM_Core_Config::singleton(); + } + } + + /** + * Map data from the request to $_GET. + * + * @param \Psr\Http\Message\RequestInterface $request + * @return array + */ + protected function initValues_GET(RequestInterface $request): array { + $result = []; + parse_str($request->getUri()->getQuery() ?: '', $result); + return $result; + } + + /** + * Map data from the request to $_POST. + * + * @param \Psr\Http\Message\RequestInterface $request + * @return array + */ + protected function initValues_POST(RequestInterface $request): array { + $result = []; + if ($request->getMethod() === 'POST') { + $contentTypes = $request->getHeader('Content-Type'); + if (in_array('application/x-www-form-urlencoded', $contentTypes) || empty($contentTypes)) { + $body = (string) $request->getBody(); + parse_str($body, $result); + } + } + return $result; + } + + /** + * Map data from the request to $_REQUEST. + * + * @param \Psr\Http\Message\RequestInterface $request + * @return array + */ + protected function initValues_REQUEST(RequestInterface $request): array { + $sources = ['g' => '_GET', 'p' => '_POST', 'c' => '_COOKIE']; + + if (ini_get('request_order')) { + $order = strtolower(ini_get('request_order')); + } + elseif (ini_get('variables_order')) { + $order = strtolower(ini_get('variables_order')); + } + else { + $order = 'gpc'; + } + + $result = []; + for ($i = 0; $i < strlen($order); $i++) { + if (isset($sources[$order[$i]])) { + $scope = $this->scopes[$sources[$order[$i]]]; + $result = array_merge($result, $scope->getValues()); + } + } + return $result; + } + + protected function initValues_SERVER(RequestInterface $request): array { + $uri = $request->getUri(); + + $result = []; + $result['REQUEST_METHOD'] = $request->getMethod(); + $result['REQUEST_URI'] = $uri->getPath(); + if ($uri->getQuery()) { + $result['REQUEST_URI'] .= '?' . $uri->getQuery(); + } + if ($uri->getHost()) { + $result['HTTP_HOST'] = $uri->getHost(); + if ($uri->getPort()) { + $result['HTTP_HOST'] .= ':' . $uri->getPort(); + $result['SERVER_PORT'] = $uri->getPort(); + } + $result['SERVER_NAME'] = $uri->getHost(); + } + $result['HTTP_USER_AGENT'] = __CLASS__; + return $result; + } + + protected function invoke(string $route): ?string { + if ($this->htmlHeader) { + \CRM_Core_Resources::singleton()->addCoreResources('html-header'); + } + + ob_start(); + try { + $pageContent = \CRM_Core_Invoke::_invoke(explode('/', $route)); + } + finally { + $printedContent = ob_get_clean(); + } + + if (empty($pageContent) && !empty($printedContent)) { + $pageContent = $printedContent; + } + + $locale = \CRM_Core_I18n::getLocale(); + $lang = substr($locale, 0, 2); + $dir = \CRM_Core_I18n::isLanguageRTL($locale) ? 'rtl' : 'ltr'; + $head = $this->htmlHeader ? \CRM_Core_Region::instance('html-header')->render('') : ''; + + return <<<PAGETPL +<!DOCTYPE html> +<html lang="$lang" dir="$dir"> +<head>$head</head> +<body class="civicrm-unittest-body">$pageContent</body> +</html> +PAGETPL; + } + + public function getAllValues(): array { + $backup = []; + foreach ($this->scopes as $scopeName => $scope) { + $backup[$scopeName] = $scope->getValues(); + } + return $backup; + } + + protected function restoreAllValues(array &$backup): void { + foreach ($this->scopes as $scopeName => $scope) { + $extraKeys = array_diff(array_keys($scope->getValues()), array_keys($backup[$scopeName])); + $scope->unsetKeys($extraKeys); + $scope->setValues($backup[$scopeName]); + } + } + +} diff --git a/civicrm/Civi/Test/LocalHttpClient/ClassProps.php b/civicrm/Civi/Test/LocalHttpClient/ClassProps.php new file mode 100644 index 0000000000..736c18ffdd --- /dev/null +++ b/civicrm/Civi/Test/LocalHttpClient/ClassProps.php @@ -0,0 +1,40 @@ +<?php +namespace Civi\Test\LocalHttpClient; + +use Civi\Test\Invasive; + +/** + * @internal + */ +class ClassProps { + + /** + * @var \ReflectionClass + */ + protected $class; + + public function __construct(string $class) { + $this->class = new \ReflectionClass($class); + } + + public function getValues() { + return $this->class->getStaticProperties() ?: []; + } + + public function setValues(iterable $values): void { + foreach ($values as $key => $value) { + // In PHP 7.3, setStaticPropertyValue() fails for private properties. + // $this->class->setStaticPropertyValue($key, $value); + Invasive::set([$this->class->getName(), $key], $value); + } + } + + public function unsetKeys(iterable $keys): void { + foreach ($keys as $key) { + // In PHP 7.3, setStaticPropertyValue() fails for private properties. + // $this->class->setStaticPropertyValue($key, NULL); + Invasive::set([$this->class->getName(), $key], NULL); + } + } + +} diff --git a/civicrm/Civi/Test/LocalHttpClient/SuperGlobal.php b/civicrm/Civi/Test/LocalHttpClient/SuperGlobal.php new file mode 100644 index 0000000000..437f10af1e --- /dev/null +++ b/civicrm/Civi/Test/LocalHttpClient/SuperGlobal.php @@ -0,0 +1,37 @@ +<?php +namespace Civi\Test\LocalHttpClient; + +/** + * @internal + */ +class SuperGlobal { + + /** + * @var string + */ + protected $name; + + /** + * @param string $name + */ + public function __construct(string $name) { + $this->name = $name; + } + + public function getValues() { + return $GLOBALS[$this->name]; + } + + public function setValues(iterable $values): void { + foreach ($values as $key => $value) { + $GLOBALS[$this->name][$key] = $value; + } + } + + public function unsetKeys(iterable $keys): void { + foreach ($keys as $key) { + unset($GLOBALS[$this->name][$key]); + } + } + +} diff --git a/civicrm/ang/crmStatusPage/StatusPageCtrl.js b/civicrm/ang/crmStatusPage/StatusPageCtrl.js index 5dad04fc59..2d6d75f61f 100644 --- a/civicrm/ang/crmStatusPage/StatusPageCtrl.js +++ b/civicrm/ang/crmStatusPage/StatusPageCtrl.js @@ -51,7 +51,7 @@ function run() { switch (action.type) { case 'href': - window.location = CRM.url(action.params.path, action.params.query, action.params.mode); + window.location = action.params.url ? action.params.url : CRM.url(action.params.path, action.params.query, action.params.mode); break; case 'api3': diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php index 803b154382..362820b041 100644 --- a/civicrm/civicrm-version.php +++ b/civicrm/civicrm-version.php @@ -1,7 +1,7 @@ <?php /** @deprecated */ function civicrmVersion( ) { - return array( 'version' => '5.69.2', + return array( 'version' => '5.69.3', 'cms' => 'Wordpress', 'revision' => '' ); } diff --git a/civicrm/ext/afform/admin/info.xml b/civicrm/ext/afform/admin/info.xml index fd44926b3d..3762b1ff97 100644 --- a/civicrm/ext/afform/admin/info.xml +++ b/civicrm/ext/afform/admin/info.xml @@ -12,8 +12,8 @@ <url desc="Chat">https://chat.civicrm.org/civicrm/channels/dev-afform</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>beta</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/afform/core/info.xml b/civicrm/ext/afform/core/info.xml index 5a8c0e747b..fcf0b28f5e 100644 --- a/civicrm/ext/afform/core/info.xml +++ b/civicrm/ext/afform/core/info.xml @@ -12,8 +12,8 @@ <url desc="Chat">https://chat.civicrm.org/civicrm/channels/dev-afform</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <compatibility> <ver>5.69</ver> </compatibility> diff --git a/civicrm/ext/afform/html/info.xml b/civicrm/ext/afform/html/info.xml index 3c4f105ab2..dada7a31a7 100644 --- a/civicrm/ext/afform/html/info.xml +++ b/civicrm/ext/afform/html/info.xml @@ -12,8 +12,8 @@ <url desc="Chat">https://chat.civicrm.org/civicrm/channels/dev-afform</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>alpha</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/afform/mock/info.xml b/civicrm/ext/afform/mock/info.xml index ac698c4727..795b178102 100644 --- a/civicrm/ext/afform/mock/info.xml +++ b/civicrm/ext/afform/mock/info.xml @@ -11,8 +11,8 @@ <urls> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <tags> <tag>mgmt:hidden</tag> </tags> diff --git a/civicrm/ext/authx/info.xml b/civicrm/ext/authx/info.xml index 921c9e6f18..5f0ef54f69 100644 --- a/civicrm/ext/authx/info.xml +++ b/civicrm/ext/authx/info.xml @@ -14,8 +14,8 @@ <url desc="Issues">https://lab.civicrm.org/dev/core/-/issues</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>mgmt:required</tag> diff --git a/civicrm/ext/civi_campaign/info.xml b/civicrm/ext/civi_campaign/info.xml index a8a9372e66..355cf41c72 100644 --- a/civicrm/ext/civi_campaign/info.xml +++ b/civicrm/ext/civi_campaign/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/campaign/what-is-civicampaign/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civi_case/info.xml b/civicrm/ext/civi_case/info.xml index e0fd52eb2d..f2a0fff4c2 100644 --- a/civicrm/ext/civi_case/info.xml +++ b/civicrm/ext/civi_case/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/case-management/what-is-civicase/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civi_contribute/info.xml b/civicrm/ext/civi_contribute/info.xml index 3f201436df..f01beb6924 100644 --- a/civicrm/ext/civi_contribute/info.xml +++ b/civicrm/ext/civi_contribute/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/contributions/what-is-civicontribute/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civi_event/info.xml b/civicrm/ext/civi_event/info.xml index 7185d36e42..ffcd3900c5 100644 --- a/civicrm/ext/civi_event/info.xml +++ b/civicrm/ext/civi_event/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/events/what-is-civievent</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civi_mail/info.xml b/civicrm/ext/civi_mail/info.xml index e03fb4c40a..aa0114e164 100644 --- a/civicrm/ext/civi_mail/info.xml +++ b/civicrm/ext/civi_mail/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/email/what-is-civimail/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civi_member/info.xml b/civicrm/ext/civi_member/info.xml index 1f78fd8167..4499c7671b 100644 --- a/civicrm/ext/civi_member/info.xml +++ b/civicrm/ext/civi_member/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/membership/what-is-civimember/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civi_pledge/info.xml b/civicrm/ext/civi_pledge/info.xml index a8ab9b1279..bb400f8b5f 100644 --- a/civicrm/ext/civi_pledge/info.xml +++ b/civicrm/ext/civi_pledge/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/pledges/what-is-civipledge/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civi_report/info.xml b/civicrm/ext/civi_report/info.xml index e42793d098..b9fa72fcf4 100644 --- a/civicrm/ext/civi_report/info.xml +++ b/civicrm/ext/civi_report/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/reporting/what-is-civireport/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>component</tag> diff --git a/civicrm/ext/civicrm_admin_ui/info.xml b/civicrm/ext/civicrm_admin_ui/info.xml index 42da1f2468..df1c2c867c 100644 --- a/civicrm/ext/civicrm_admin_ui/info.xml +++ b/civicrm/ext/civicrm_admin_ui/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://lab.civicrm.org/dev/core/-/issues</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>beta</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/civicrm_search_ui/info.xml b/civicrm/ext/civicrm_search_ui/info.xml index 55908928e7..f025e92455 100644 --- a/civicrm/ext/civicrm_search_ui/info.xml +++ b/civicrm/ext/civicrm_search_ui/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://lab.civicrm.org/dev/core/-/issues</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>alpha</develStage> <requires> <ext>org.civicrm.search_kit</ext> diff --git a/civicrm/ext/civigrant/info.xml b/civicrm/ext/civigrant/info.xml index a8a22d1c37..f66d8f9941 100644 --- a/civicrm/ext/civigrant/info.xml +++ b/civicrm/ext/civigrant/info.xml @@ -12,8 +12,8 @@ <url desc="Documentation">https://docs.civicrm.org/user/en/latest/grants/what-is-civigrant/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/civiimport/info.xml b/civicrm/ext/civiimport/info.xml index af06112910..968163f372 100644 --- a/civicrm/ext/civiimport/info.xml +++ b/civicrm/ext/civiimport/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://civicrm.org</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>alpha</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/ckeditor4/info.xml b/civicrm/ext/ckeditor4/info.xml index e619949d1c..b1a57717b6 100644 --- a/civicrm/ext/ckeditor4/info.xml +++ b/civicrm/ext/ckeditor4/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://github.com/civicrm/civicrm-core/</url> <url desc="Licensing">https://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/contributioncancelactions/info.xml b/civicrm/ext/contributioncancelactions/info.xml index 675f8d2c67..25113898e1 100644 --- a/civicrm/ext/contributioncancelactions/info.xml +++ b/civicrm/ext/contributioncancelactions/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://civicrm.org</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/elavon/info.xml b/civicrm/ext/elavon/info.xml index bd9b0fdddc..b1c63a816a 100644 --- a/civicrm/ext/elavon/info.xml +++ b/civicrm/ext/elavon/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://lab.civicrm.org</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/eventcart/info.xml b/civicrm/ext/eventcart/info.xml index 381bb5b05d..7df0d6a3b4 100644 --- a/civicrm/ext/eventcart/info.xml +++ b/civicrm/ext/eventcart/info.xml @@ -12,8 +12,8 @@ <url desc="Main Extension Page">https://github.com/civicrm/civicrm-core/tree/master/ext/eventcart</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <tags> <tag>mgmt:hidden</tag> </tags> diff --git a/civicrm/ext/ewaysingle/info.xml b/civicrm/ext/ewaysingle/info.xml index 2d2bf431b6..99447186b4 100644 --- a/civicrm/ext/ewaysingle/info.xml +++ b/civicrm/ext/ewaysingle/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://github.com/civicrm/civicrm-core/blob/master/ext/ewaysingle</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <tags> <tag>mgmt:hidden</tag> </tags> diff --git a/civicrm/ext/financialacls/info.xml b/civicrm/ext/financialacls/info.xml index 3dc506da21..e2d4b8dfab 100644 --- a/civicrm/ext/financialacls/info.xml +++ b/civicrm/ext/financialacls/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://FIXME</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/flexmailer/info.xml b/civicrm/ext/flexmailer/info.xml index 1fc9314c69..036f9bb28d 100644 --- a/civicrm/ext/flexmailer/info.xml +++ b/civicrm/ext/flexmailer/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://civicrm.stackexchange.com/</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <comments> FlexMailer is an email delivery engine which replaces the internal guts diff --git a/civicrm/ext/flexmailer/tests/phpunit/Civi/FlexMailer/FlexMailerSystemTest.php b/civicrm/ext/flexmailer/tests/phpunit/Civi/FlexMailer/FlexMailerSystemTest.php index d91e6ec490..679b4b6426 100644 --- a/civicrm/ext/flexmailer/tests/phpunit/Civi/FlexMailer/FlexMailerSystemTest.php +++ b/civicrm/ext/flexmailer/tests/phpunit/Civi/FlexMailer/FlexMailerSystemTest.php @@ -75,13 +75,13 @@ class FlexMailerSystemTest extends \CRM_Mailing_BaseMailingSystemTest { * @see CRM_Utils_Hook::alterMailParams */ public function hook_alterMailParams(&$params, $context = NULL) { - $this->counts['hook_alterMailParams'] = 1; - $this->assertEquals('flexmailer', $context); + $this->counts["hook_alterMailParams::$context"] = 1; } public function tearDown(): void { parent::tearDown(); - $this->assertNotEmpty($this->counts['hook_alterMailParams']); + $this->assertNotEmpty($this->counts['hook_alterMailParams::flexmailer']); + $this->assertEmpty($this->counts['hook_alterMailParams::civimail'] ?? NULL); foreach (FlexMailer::getEventTypes() as $event => $class) { $this->assertTrue( $this->counts[$class] > 0, diff --git a/civicrm/ext/greenwich/info.xml b/civicrm/ext/greenwich/info.xml index 475525e8ec..15b35f61e5 100644 --- a/civicrm/ext/greenwich/info.xml +++ b/civicrm/ext/greenwich/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://civicrm.org</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <tags> <tag>mgmt:hidden</tag> </tags> diff --git a/civicrm/ext/legacycustomsearches/info.xml b/civicrm/ext/legacycustomsearches/info.xml index 7ff4a1d888..3948283af2 100644 --- a/civicrm/ext/legacycustomsearches/info.xml +++ b/civicrm/ext/legacycustomsearches/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://FIXME</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/message_admin/info.xml b/civicrm/ext/message_admin/info.xml index f72d3766cf..b8bd023d17 100644 --- a/civicrm/ext/message_admin/info.xml +++ b/civicrm/ext/message_admin/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://civicrm.org</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>alpha</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/oauth-client/info.xml b/civicrm/ext/oauth-client/info.xml index 22c8170196..e8e73931d5 100644 --- a/civicrm/ext/oauth-client/info.xml +++ b/civicrm/ext/oauth-client/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://lab.civicrm.org/dev/core/-/issues</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/payflowpro/info.xml b/civicrm/ext/payflowpro/info.xml index d49749d23b..5d9b36d5cb 100644 --- a/civicrm/ext/payflowpro/info.xml +++ b/civicrm/ext/payflowpro/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://lab.civicrm.org</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/recaptcha/info.xml b/civicrm/ext/recaptcha/info.xml index 9d82903a1e..548b52d5f0 100644 --- a/civicrm/ext/recaptcha/info.xml +++ b/civicrm/ext/recaptcha/info.xml @@ -12,8 +12,8 @@ <url desc="Main Extension Page">https://github.com/civicrm/civicrm-core/tree/master/ext/recaptcha</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <tags> <tag>mgmt:hidden</tag> </tags> diff --git a/civicrm/ext/scheduled_communications/info.xml b/civicrm/ext/scheduled_communications/info.xml index 7750124795..4659c4d5f7 100644 --- a/civicrm/ext/scheduled_communications/info.xml +++ b/civicrm/ext/scheduled_communications/info.xml @@ -12,8 +12,8 @@ <url desc="Chat">https://chat.civicrm.org/civicrm/channels/search-improvements</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>beta</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/search_kit/info.xml b/civicrm/ext/search_kit/info.xml index f9071bcb40..b64fb79767 100644 --- a/civicrm/ext/search_kit/info.xml +++ b/civicrm/ext/search_kit/info.xml @@ -14,8 +14,8 @@ <url desc="Issues">https://lab.civicrm.org/dev/report/-/issues</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>stable</develStage> <tags> <tag>mgmt:required</tag> diff --git a/civicrm/ext/sequentialcreditnotes/info.xml b/civicrm/ext/sequentialcreditnotes/info.xml index c1abec7e72..b64cbf4cfe 100644 --- a/civicrm/ext/sequentialcreditnotes/info.xml +++ b/civicrm/ext/sequentialcreditnotes/info.xml @@ -14,8 +14,8 @@ <url desc="Support">https://lab.civicrm.org/extensions/sequentialcreditnotes</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <tags> <tag>mgmt:hidden</tag> </tags> diff --git a/civicrm/ext/standaloneusers/info.xml b/civicrm/ext/standaloneusers/info.xml index 03439363c6..083bf03bab 100644 --- a/civicrm/ext/standaloneusers/info.xml +++ b/civicrm/ext/standaloneusers/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://FIXME</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>alpha</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/ext/user_dashboard/info.xml b/civicrm/ext/user_dashboard/info.xml index c587ec6056..20b53aa576 100644 --- a/civicrm/ext/user_dashboard/info.xml +++ b/civicrm/ext/user_dashboard/info.xml @@ -14,8 +14,8 @@ <url desc="Support">http://FIXME</url> <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url> </urls> - <releaseDate>2024-01-11</releaseDate> - <version>5.69.2</version> + <releaseDate>2024-01-25</releaseDate> + <version>5.69.3</version> <develStage>alpha</develStage> <compatibility> <ver>5.69</ver> diff --git a/civicrm/js/version.json b/civicrm/js/version.json index 01750314f6..ff623e264c 100644 --- a/civicrm/js/version.json +++ b/civicrm/js/version.json @@ -1 +1 @@ -"5.69.2" +"5.69.3" diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md index 7729a3d403..75fc12be41 100644 --- a/civicrm/release-notes.md +++ b/civicrm/release-notes.md @@ -15,6 +15,15 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress +## CiviCRM 5.69.3 + +Released January 26, 2024 + +- **[Synopsis](release-notes/5.69.3.md#synopsis)** +- **[Bugs resolved](release-notes/5.69.3.md#bugs)** +- **[Credits](release-notes/5.69.3.md#credits)** +- **[Feedback](release-notes/5.69.3.md#feedback)** + ## CiviCRM 5.69.2 Released January 11, 2024 diff --git a/civicrm/release-notes/5.69.3.md b/civicrm/release-notes/5.69.3.md new file mode 100644 index 0000000000..ac4014acd1 --- /dev/null +++ b/civicrm/release-notes/5.69.3.md @@ -0,0 +1,49 @@ +# CiviCRM 5.69.3 + +Released January 26, 2024 + +- **[Synopsis](#synopsis)** +- **[Bugs resolved](#bugs)** +- **[Credits](#credits)** +- **[Feedback](#feedback)** + +## <a name="synopsis"></a>Synopsis + +| *Does this version...?* | | +| --------------------------------------------------------------- | -------- | +| Change the database schema? | no | +| Alter the API? | no | +| **Require attention to configuration options?** | **yes** | +| Fix problems installing or upgrading to a previous version? | no | +| **Introduce features?** | **yes** | +| **Fix bugs?** | **yes** | +| Fix security vulnerabilities? | no | + +## <a name="bugs"></a>Bugs resolved + +* **_CiviMail_: Add support for "HTTP One-Click" unsubscribes ([dev/core#4641](https://lab.civicrm.org/dev/core/-/issues/4641): [#28964](https://github.com/civicrm/civicrm-core/pull/28964), [#29086](https://github.com/civicrm/civicrm-core/pull/29086))** + + CiviMail users with large mailing lists should consider enabling this new option. [More info](https://civicrm.org/redirect/unsubscribe-one-click) + +* **_CiviContribute_: Fix error viewing contributions when "Tax and Invoicing" is enabled ([#28994](https://github.com/civicrm/civicrm-core/pull/28994), [#29000](https://github.com/civicrm/civicrm-core/pull/29000))** +* **_CiviContribute_: Fix focus-handling for "Other Amount" ([dev/core#4912](https://lab.civicrm.org/dev/core/-/issues/4912): [#29016](https://github.com/civicrm/civicrm-core/pull/29016))** +* **_CiviMember_: Fix handling of "Auto Renew" checkbox in certain configurations ([#29069](https://github.com/civicrm/civicrm-core/pull/29069))** +* **_Custom Fields_: Fix for custom fields when creating new (subtyped) contacts ([dev/core#4910](https://lab.civicrm.org/dev/core/-/issues/4910): [#29003](https://github.com/civicrm/civicrm-core/pull/29003))** +* **_PHP 7.3_: Restore compatibility with PHP 7.3 ([#29074](https://github.com/civicrm/civicrm-core/pull/29074))** + +## <a name="credits"></a>Credits + +This release was developed by the following authors and reviewers: + +Wikimedia Foundation - Eileen McNaughton; tresero; Tadpole Collective - Kevin Cristiano; +Skvare - Mark Hanna; pbarmak; Megaphone Technology Consulting - Jon Goldberg; Makoa - Usha +F. Matisson; lkuttner; JMA Consulting - Seamus Lee; iank; Humanists UK - Andrew West;; +Fuzion - Peter Davis; Dave D; Coop SymbioTIC - Shane Bill; CiviDesk - Yashodha Chaku; +CiviCRM - Tim Otten, Coleman Watts, Josh Gowans; Christian Wach; Chabadrichmond; +Australian Greens - John Twyman; Artful Robot - Rich Lott; Agileware - Justin Freeman + +## <a name="feedback"></a>Feedback + +These release notes are edited by Tim Otten and Andie 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/settings/Mailing.setting.php b/civicrm/settings/Mailing.setting.php index d000dc47fd..15e127bce9 100644 --- a/civicrm/settings/Mailing.setting.php +++ b/civicrm/settings/Mailing.setting.php @@ -18,6 +18,8 @@ * Settings metadata file */ +$unsubLearnMore = '<br/>' . ts('(<a %1">Learn more</a>)', [1 => 'href="https://civicrm.org/redirect/unsubscribe-one-click" target="_blank"']); + return [ 'profile_double_optin' => [ 'group_name' => 'Mailing Preferences', @@ -91,6 +93,28 @@ return [ 'is_contact' => 0, 'help_text' => NULL, ], + 'civimail_unsubscribe_methods' => [ + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'civimail_unsubscribe_methods', + 'type' => 'Array', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => [ + 'multiple' => 1, + 'class' => 'crm-select2', + ], + 'default' => version_compare(CRM_Utils_System::version(), '5.72', '<=') ? ['mailto'] : ['mailto', 'http', 'oneclick'], + 'add' => '5.69', + 'title' => ts('Unsubscribe Methods'), + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => ts("These methods will be offered to email clients for semi-automated unsubscribes. Support for each depends on the recipient's email client.") . $unsubLearnMore, + 'help_text' => NULL, + 'pseudoconstant' => [ + 'callback' => 'CRM_Mailing_Service_ListUnsubscribe::getMethods', + ], + ], 'replyTo' => [ 'group_name' => 'Mailing Preferences', 'group' => 'mailing', diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql index 4c73ac3040..d77cb76bf3 100644 --- a/civicrm/sql/civicrm_data.mysql +++ b/civicrm/sql/civicrm_data.mysql @@ -21703,4 +21703,4 @@ INSERT INTO `civicrm_report_instance` ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) 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 = '5.69.2'; +UPDATE civicrm_domain SET version = '5.69.3'; diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql index a70d269fee..0246c63aed 100644 --- a/civicrm/sql/civicrm_generated.mysql +++ b/civicrm/sql/civicrm_generated.mysql @@ -2976,7 +2976,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_domain` WRITE; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES - (1,'Default Domain Name',NULL,'5.69.2',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); + (1,'Default Domain Name',NULL,'5.69.3',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/Contribute/Form/Contribution/Main.tpl b/civicrm/templates/CRM/Contribute/Form/Contribution/Main.tpl index 84f8490e06..d44bd2b600 100644 --- a/civicrm/templates/CRM/Contribute/Form/Contribution/Main.tpl +++ b/civicrm/templates/CRM/Contribute/Form/Contribution/Main.tpl @@ -22,7 +22,7 @@ element = document.Main.elements[i]; if ( element.type == 'radio' && element.name === mainPriceFieldName ) { if (element.value == '0' ) { - element.click(); + element.checked = true; } else { element.checked = false; diff --git a/civicrm/templates/CRM/Price/Page/LineItem.tpl b/civicrm/templates/CRM/Price/Page/LineItem.tpl index 8635cf9028..e714491211 100644 --- a/civicrm/templates/CRM/Price/Page/LineItem.tpl +++ b/civicrm/templates/CRM/Price/Page/LineItem.tpl @@ -72,7 +72,7 @@ <td></td> <td></td> {/if} - <td class="right">{$line.line_total+$line.tax_amount|crmMoney:$currency}</td> + <td class="right">{assign var=totalWithTax value=$line.line_total+$line.tax_amount}{$totalWithTax|crmMoney:$currency}</td> {/if} {if $pricesetFieldsCount} <td class="right">{$line.participant_count}</td> @@ -92,7 +92,8 @@ {ts}Contribution Total{/ts}: {elseif $context EQ "Event"} {if $totalTaxAmount} - {ts}Event SubTotal: {$totalAmount-$totalTaxAmount|crmMoney:$currency}{/ts}<br /> + {assign var=eventSubTotal value=$totalAmount-$totalTaxAmount} + {ts 1=$eventSubTotal|crmMoney:$currency}Event SubTotal: %1{/ts}<br /> {/if} {ts}Total Amount{/ts}: {elseif $context EQ "Membership"} diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php index 7d254f595f..4d99ded32f 100644 --- a/civicrm/vendor/autoload.php +++ b/civicrm/vendor/autoload.php @@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) { require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit0fcbe1ec640ae9fe693b02538241f085::getLoader(); +return ComposerAutoloaderInite36d44b412c906747bbbe03020d7d072::getLoader(); diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php index 9109da8966..9ba5ef25b5 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 ComposerAutoloaderInit0fcbe1ec640ae9fe693b02538241f085 +class ComposerAutoloaderInite36d44b412c906747bbbe03020d7d072 { private static $loader; @@ -24,22 +24,22 @@ class ComposerAutoloaderInit0fcbe1ec640ae9fe693b02538241f085 require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit0fcbe1ec640ae9fe693b02538241f085', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInite36d44b412c906747bbbe03020d7d072', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit0fcbe1ec640ae9fe693b02538241f085', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInite36d44b412c906747bbbe03020d7d072', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); set_include_path(implode(PATH_SEPARATOR, $includePaths)); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInite36d44b412c906747bbbe03020d7d072::getInitializer($loader)); $loader->register(true); - $includeFiles = \Composer\Autoload\ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085::$files; + $includeFiles = \Composer\Autoload\ComposerStaticInite36d44b412c906747bbbe03020d7d072::$files; foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire0fcbe1ec640ae9fe693b02538241f085($fileIdentifier, $file); + composerRequiree36d44b412c906747bbbe03020d7d072($fileIdentifier, $file); } return $loader; @@ -51,7 +51,7 @@ class ComposerAutoloaderInit0fcbe1ec640ae9fe693b02538241f085 * @param string $file * @return void */ -function composerRequire0fcbe1ec640ae9fe693b02538241f085($fileIdentifier, $file) +function composerRequiree36d44b412c906747bbbe03020d7d072($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php index 6c7aa78c9f..e75a9e1d8e 100644 --- a/civicrm/vendor/composer/autoload_static.php +++ b/civicrm/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085 +class ComposerStaticInite36d44b412c906747bbbe03020d7d072 { public static $files = array ( 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', @@ -713,11 +713,11 @@ class ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085::$prefixesPsr0; - $loader->fallbackDirsPsr0 = ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085::$fallbackDirsPsr0; - $loader->classMap = ComposerStaticInit0fcbe1ec640ae9fe693b02538241f085::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInite36d44b412c906747bbbe03020d7d072::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInite36d44b412c906747bbbe03020d7d072::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInite36d44b412c906747bbbe03020d7d072::$prefixesPsr0; + $loader->fallbackDirsPsr0 = ComposerStaticInite36d44b412c906747bbbe03020d7d072::$fallbackDirsPsr0; + $loader->classMap = ComposerStaticInite36d44b412c906747bbbe03020d7d072::$classMap; }, null, ClassLoader::class); } diff --git a/civicrm/vendor/composer/installed.php b/civicrm/vendor/composer/installed.php index b25cdac267..52232eb15b 100644 --- a/civicrm/vendor/composer/installed.php +++ b/civicrm/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'civicrm/civicrm-core', 'pretty_version' => '5.69.x-dev', 'version' => '5.69.9999999.9999999-dev', - 'reference' => 'b74e1246ea7d980ff89773c5f22186b95fc4d3bb', + 'reference' => 'c3f742eff3a4248f26ed499e5ea61b2deee461e9', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -40,7 +40,7 @@ 'civicrm/civicrm-core' => array( 'pretty_version' => '5.69.x-dev', 'version' => '5.69.9999999.9999999-dev', - 'reference' => 'b74e1246ea7d980ff89773c5f22186b95fc4d3bb', + 'reference' => 'c3f742eff3a4248f26ed499e5ea61b2deee461e9', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/civicrm/xml/version.xml b/civicrm/xml/version.xml index e0fb9ccfbc..36efda8d5e 100644 --- a/civicrm/xml/version.xml +++ b/civicrm/xml/version.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="iso-8859-1" ?> <version> - <version_no>5.69.2</version_no> + <version_no>5.69.3</version_no> </version> -- GitLab