From 6eb0f9b12572ac20caef48420f57324bfe7febf7 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Thu, 16 Feb 2023 14:24:39 +1300 Subject: [PATCH] CiviCRM 5.58.1 update Note we have some recent patches that are included. These are mostly ones merged to civicrm-core since forking for 5.58. One is in 5.58 now so is listed for completeness & 2 minor ones are not yet merged upstream |pr|status|notes| |[25565](https://github.com/civicrm/civicrm-core/pull/25565)|merged to master(5.60)|Supports T327963 - activity types for thank you| |[25516](https://github.com/civicrm/civicrm-core/pull/25516)|merged to master(5.60)|Helps import - filter imported searches| |[25527](https://github.com/civicrm/civicrm-core/pull/25527)|not yet merged| but performance fix for dedupe searches (the name & address ones Sandra is doing) |[25433](https://github.com/civicrm/civicrm-core/pull/25433)|merged to rc (5.59)|fix for search kit display| |[25482](https://github.com/civicrm/civicrm-core/pull/25482)|Already in 5.58.1|Fix for search kit display| |[25418](https://github.com/civicrm/civicrm-core/pull/25418)|Merged to rc (5.59)|Permanent imap timout fix| |[25226](https://github.com/civicrm/civicrm-core/pull/25226)|Merged to rc (5.59)|ReportInstance api - in our install| |[25568](https://github.com/civicrm/civicrm-core/pull/25568)|not yet merged|Helps with new import code, reduces chance of crash| |[24515](https://github.com/civicrm/civicrm-core/pull/25415)|Merged to rc (5.59)| Fix to stop CI from breaking, replaces our hack| List of cherry picked commits from the above 18d82af27b9 (HEAD -> master) Filter expired searches from search kit results a75b98cb47a Add test to is_current on SavedSearch, fix e4d69230ad1 Increase timeout on imap 89ab855619f Do not crash the whole SearchKit UI if one entity fails 0142e5dd18c Fix performance on deciding which tables to query cd710af9733 dev/core#4117 Add is_current to UserJob, Search 2fa17fb88ae Make activity_type_id available to links, test 2d2bd93cda8 (dev/core#4088) ClassScanner - Move unit-test registration e3e669d4556 Add Report Instance apiv4 Bug: T329681 Change-Id: I839d1bbfabfe3558094f7445a4281f237b609fed --- .../civicrm/CRM/Activity/Selector/Search.php | 4 + .../modules/civicrm/CRM/Contact/Tokens.php | 5 +- .../CRM/Contribute/Form/Task/Invoice.php | 5 +- .../civicrm/CRM/Core/BAO/MessageTemplate.php | 20 +- .../civicrm/CRM/Core/BAO/PdfFormat.php | 1 + .../civicrm/CRM/Core/BAO/SchemaHandler.php | 43 +++ .../all/modules/civicrm/CRM/Core/DAO.php | 2 +- .../modules/civicrm/CRM/Core/EntityTokens.php | 8 +- .../CRM/Dedupe/BAO/DedupeRuleGroup.php | 43 +-- .../Event/Form/ManageEvent/Registration.php | 3 +- .../civicrm/CRM/Extension/ClassLoader.php | 7 +- .../all/modules/civicrm/CRM/Report/Form.php | 15 +- .../CRM/Utils/Check/Component/Timestamps.php | 2 +- .../all/modules/civicrm/CRM/Utils/File.php | 7 +- .../all/modules/civicrm/CRM/Utils/Hook.php | 4 + .../Provider/IsCurrentFieldSpecProvider.php | 36 ++- .../civicrm/Civi/Core/ClassScanner.php | 6 - .../civicrm/Civi/Test/Api4TestTrait.php | 306 ++++++++++++++++++ .../civicrm/Civi/Test/CiviTestListener.php | 1 + .../Civi/Test/CiviTestListenerPHPUnit7.php | 1 + .../Civi/Test/Legacy/CiviTestListener.php | 1 + .../all/modules/civicrm/civicrm-version.php | 2 +- .../sites/all/modules/civicrm/composer.lock | 12 +- .../all/modules/civicrm/drupal/civicrm.info | 2 +- .../civicrm_contact_ref.info | 2 +- .../civicrm_engage/civicrm_engage.info | 2 +- .../civicrm_group_roles.info | 2 +- .../civicrm_member_roles.info | 2 +- .../civicrm_og_sync/civicrm_og_sync.info | 2 +- .../modules/civicrm_rules/civicrm_rules.info | 2 +- .../modules/civicrmtheme/civicrmtheme.info | 2 +- .../modules/civicrm/ext/afform/admin/info.xml | 2 +- .../modules/civicrm/ext/afform/core/info.xml | 2 +- .../Civi/Afform/AfformContactSummaryTest.php | 18 +- .../modules/civicrm/ext/afform/html/info.xml | 2 +- .../modules/civicrm/ext/afform/mock/info.xml | 2 +- .../all/modules/civicrm/ext/authx/info.xml | 2 +- .../civicrm/ext/civicrm_admin_ui/info.xml | 2 +- .../modules/civicrm/ext/civigrant/info.xml | 2 +- .../modules/civicrm/ext/civiimport/info.xml | 2 +- .../modules/civicrm/ext/ckeditor4/info.xml | 2 +- .../ext/contributioncancelactions/info.xml | 2 +- .../all/modules/civicrm/ext/elavon/info.xml | 2 +- .../modules/civicrm/ext/eventcart/info.xml | 2 +- .../modules/civicrm/ext/ewaysingle/info.xml | 2 +- .../civicrm/ext/financialacls/info.xml | 2 +- .../modules/civicrm/ext/flexmailer/info.xml | 2 +- .../modules/civicrm/ext/greenwich/info.xml | 2 +- .../civicrm/ext/legacycustomsearches/info.xml | 2 +- .../civicrm/ext/message_admin/info.xml | 2 +- .../modules/civicrm/ext/oauth-client/info.xml | 2 +- .../modules/civicrm/ext/payflowpro/info.xml | 2 +- .../modules/civicrm/ext/recaptcha/info.xml | 2 +- .../ext/search_kit/Civi/Search/Admin.php | 10 +- .../crmSearchAdminSearchListing.component.js | 2 +- .../modules/civicrm/ext/search_kit/info.xml | 2 +- .../api/v4/SearchDisplay/SearchRunTest.php | 3 +- .../SearchRunWithCustomFieldTest.php | 3 +- .../ext/sequentialcreditnotes/info.xml | 2 +- .../civicrm/mixin/scan-classes@1/mixin.php | 6 +- .../all/modules/civicrm/release-notes.md | 10 + .../modules/civicrm/release-notes/5.58.1.md | 53 +++ .../modules/civicrm/sql/civicrm_data.mysql | 2 +- .../civicrm/sql/civicrm_generated.mysql | 2 +- .../all/modules/civicrm/vendor/autoload.php | 2 +- .../civicrm/vendor/composer/autoload_real.php | 14 +- .../vendor/composer/autoload_static.php | 12 +- .../civicrm/vendor/composer/include_paths.php | 2 +- .../civicrm/vendor/composer/installed.json | 14 +- .../civicrm/vendor/composer/installed.php | 10 +- .../civicrm/vendor/dompdf/dompdf/VERSION | 2 +- .../vendor/dompdf/dompdf/src/Image/Cache.php | 23 +- .../sites/all/modules/civicrm/xml/version.xml | 2 +- 73 files changed, 640 insertions(+), 146 deletions(-) create mode 100644 drupal/sites/all/modules/civicrm/Civi/Test/Api4TestTrait.php create mode 100644 drupal/sites/all/modules/civicrm/release-notes/5.58.1.md diff --git a/drupal/sites/all/modules/civicrm/CRM/Activity/Selector/Search.php b/drupal/sites/all/modules/civicrm/CRM/Activity/Selector/Search.php index 14215f6adc..b41f921145 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Activity/Selector/Search.php +++ b/drupal/sites/all/modules/civicrm/CRM/Activity/Selector/Search.php @@ -303,6 +303,10 @@ public function &getRows($action, $offset, $rowCount, $sort, $output = NULL) { 'id' => $result->activity_id, 'cid' => $contactId, 'cxt' => $this->_context, + // Parameter for hook locked in by CRM_Activity_Selector_SearchTest + // Any additional parameters added should follow apiv4 style + // and be added to the test. + 'activity_type_id' => $row['activity_type_id'], ], ts('more'), FALSE, diff --git a/drupal/sites/all/modules/civicrm/CRM/Contact/Tokens.php b/drupal/sites/all/modules/civicrm/CRM/Contact/Tokens.php index 4dc0cc9236..a99da6faff 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Contact/Tokens.php +++ b/drupal/sites/all/modules/civicrm/CRM/Contact/Tokens.php @@ -397,14 +397,17 @@ protected function getTokenMetadata(): array { foreach ($metadata as $field) { if ($entity === 'website') { // It's not the primary - it's 'just one of them' - so the name is _first not _primary + $field['name'] = 'website_first.' . $field['name']; $this->addFieldToTokenMetadata($tokensMetadata, $field, $exposedFields, 'website_first'); } else { + $field['name'] = $entity . '_primary.' . $field['name']; $this->addFieldToTokenMetadata($tokensMetadata, $field, $exposedFields, $entity . '_primary'); $field['label'] .= ' (' . ts('Billing') . ')'; // Set audience to sysadmin in case adding them to UI annoys people. If people ask to see this // in the UI we could set to 'user'. $field['audience'] = 'sysadmin'; + $field['name'] = $entity . '_billing.' . $field['name']; $this->addFieldToTokenMetadata($tokensMetadata, $field, $exposedFields, $entity . '_billing'); } } @@ -453,13 +456,11 @@ protected function getContact(int $contactId, array $requiredFields, bool $getAl if ($fieldSpec['table_name'] === 'civicrm_website') { $tableAlias = 'website_first'; $joins[$tableAlias] = $fieldSpec['entity']; - $prefix = $tableAlias . '.'; } if ($fieldSpec['table_name'] === 'civicrm_openid') { // We could start to deprecate this one maybe..... I've made it un-advertised. $tableAlias = 'openid_primary'; $joins[$tableAlias] = $fieldSpec['entity']; - $prefix = $tableAlias . '.'; } if ($fieldSpec['type'] === 'Custom') { $customFields['custom_' . $fieldSpec['custom_field_id']] = $fieldSpec['name']; diff --git a/drupal/sites/all/modules/civicrm/CRM/Contribute/Form/Task/Invoice.php b/drupal/sites/all/modules/civicrm/CRM/Contribute/Form/Task/Invoice.php index c2beedce0f..c67b0a10ff 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Contribute/Form/Task/Invoice.php +++ b/drupal/sites/all/modules/civicrm/CRM/Contribute/Form/Task/Invoice.php @@ -233,10 +233,9 @@ public static function printPDF($contribIDs, &$params, $contactIds) { $refundedStatusId = CRM_Utils_Array::key('Refunded', $contributionStatusID); $cancelledStatusId = CRM_Utils_Array::key('Cancelled', $contributionStatusID); $pendingStatusId = CRM_Utils_Array::key('Pending', $contributionStatusID); - $pdfFormat = CRM_Core_BAO_PdfFormat::getByName('default_invoice_pdf_format'); - + $pdfFormat = CRM_Core_BAO_MessageTemplate::getPDFFormatForTemplate('contribution_invoice_receipt'); foreach ($elementDetails as $contributionID => $detail) { - $input = $ids = []; + $input = []; if (in_array($detail['contact'], $excludedContactIDs)) { continue; } diff --git a/drupal/sites/all/modules/civicrm/CRM/Core/BAO/MessageTemplate.php b/drupal/sites/all/modules/civicrm/CRM/Core/BAO/MessageTemplate.php index bdb9a9d644..12fe6914c7 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Core/BAO/MessageTemplate.php +++ b/drupal/sites/all/modules/civicrm/CRM/Core/BAO/MessageTemplate.php @@ -203,7 +203,7 @@ public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) { */ public static function getMessageTemplates($all = TRUE, $isSMS = FALSE) { - $messageTemplates = \Civi\Api4\MessageTemplate::get() + $messageTemplates = MessageTemplate::get() ->addSelect('id', 'msg_title') ->addWhere('is_active', '=', TRUE) ->addWhere('is_sms', '=', $isSMS); @@ -218,6 +218,24 @@ public static function getMessageTemplates($all = TRUE, $isSMS = FALSE) { return $msgTpls; } + /** + * Get the appropriate pdf format for the given template. + * + * @param string $workflow + * + * @return array + * @throws \CRM_Core_Exception + */ + public static function getPDFFormatForTemplate(string $workflow): array { + $pdfFormatID = MessageTemplate::get(FALSE) + ->addWhere('workflow_name', '=', $workflow) + ->addSelect('pdf_format_id') + ->execute()->first()['pdf_format_id'] ?? 0; + // Get by ID will fall back to retrieving the default values if + // it does not find the appropriate ones - hence passing in 0 works. + return CRM_Core_BAO_PdfFormat::getById($pdfFormatID); + } + /** * Revert a message template to its default subject+text+HTML state. * diff --git a/drupal/sites/all/modules/civicrm/CRM/Core/BAO/PdfFormat.php b/drupal/sites/all/modules/civicrm/CRM/Core/BAO/PdfFormat.php index cfe2ebfb01..0113ec6224 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Core/BAO/PdfFormat.php +++ b/drupal/sites/all/modules/civicrm/CRM/Core/BAO/PdfFormat.php @@ -230,6 +230,7 @@ public static function &getPdfFormat($field, $val) { * (reference) associative array of name/value pairs */ public static function &getByName($name) { + CRM_Core_Error::deprecatedFunctionWarning('none'); return self::getPdfFormat('name', $name); } diff --git a/drupal/sites/all/modules/civicrm/CRM/Core/BAO/SchemaHandler.php b/drupal/sites/all/modules/civicrm/CRM/Core/BAO/SchemaHandler.php index 0ee0b27c4c..240ada234a 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Core/BAO/SchemaHandler.php +++ b/drupal/sites/all/modules/civicrm/CRM/Core/BAO/SchemaHandler.php @@ -906,6 +906,49 @@ public static function getInUseCollation(): string { return \Civi::$statics[__CLASS__][__FUNCTION__]; } + /** + * Get estimated number of rows in the given tables. + * + * Note that this query is less precise than SELECT(*) - especially on + * larger tables but performs significantly better. + * See https://dba.stackexchange.com/questions/184685/why-is-count-slow-when-explain-knows-the-answer + * + * @param array $tables + * e.g ['civicrm_contact', 'civicrm_activity'] + * + * @return array + * e.g ['civicrm_contact' => 200000, 'civicrm_activity' => 100000] + */ + public static function getRowCountForTables(array $tables): array { + $cachedResults = Civi::$statics[__CLASS__][__FUNCTION__] ?? []; + // Compile list of tables not already cached. + $tablesToCheck = array_keys(array_diff_key(array_flip($tables), $cachedResults)); + $result = CRM_Core_DAO::executeQuery(' + SELECT TABLE_ROWS as row_count, TABLE_NAME as table_name FROM information_schema.TABLES WHERE + TABLE_NAME IN("' . implode('","', $tablesToCheck) . '") + AND TABLE_SCHEMA = DATABASE()' + ); + while ($result->fetch()) { + $cachedResults[$result->table_name] = (int) $result->row_count; + } + Civi::$statics[__CLASS__][__FUNCTION__] = $cachedResults; + return array_intersect_key($cachedResults, array_fill_keys($tables, TRUE)); + } + + /** + * Get estimated number of rows in the given table. + * + * @see self::getRowCountForTables + * + * @param string $tableName + * + * @return int + * The approximate number of rows in the table. This is also 0 if the table does not exist. + */ + public static function getRowCountForTable(string $tableName): int { + return self::getRowCountForTables([$tableName])[$tableName] ?? 0; + } + /** * Does the database support utf8mb4. * diff --git a/drupal/sites/all/modules/civicrm/CRM/Core/DAO.php b/drupal/sites/all/modules/civicrm/CRM/Core/DAO.php index f5f376fa12..7abc731765 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Core/DAO.php +++ b/drupal/sites/all/modules/civicrm/CRM/Core/DAO.php @@ -1100,7 +1100,7 @@ public static function checkFieldExists($tableName, $columnName, $i18nRewrite = } /** - * Scans all the tables using a slow query and table name. + * Gets the names of all the tables in the schema. * * @return array */ diff --git a/drupal/sites/all/modules/civicrm/CRM/Core/EntityTokens.php b/drupal/sites/all/modules/civicrm/CRM/Core/EntityTokens.php index af3ba17efd..9672f08c14 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Core/EntityTokens.php +++ b/drupal/sites/all/modules/civicrm/CRM/Core/EntityTokens.php @@ -611,7 +611,8 @@ public function getActiveTokens(TokenValueEvent $e) { * @param string $prefix */ protected function addFieldToTokenMetadata(array &$tokensMetadata, array $field, array $exposedFields, string $prefix = ''): void { - if ($field['type'] !== 'Custom' && !in_array($field['name'], $exposedFields, TRUE)) { + $isExposed = in_array(str_replace($prefix . '.', '', $field['name']), $exposedFields, TRUE); + if ($field['type'] !== 'Custom' && !$isExposed) { return; } $field['audience'] = $field['audience'] ?? 'user'; @@ -635,8 +636,9 @@ protected function addFieldToTokenMetadata(array &$tokensMetadata, array $field, $tokensMetadata[$tokenName] = $field; return; } - $tokenName = $prefix ? ($prefix . '.' . $field['name']) : $field['name']; - if (in_array($field['name'], $exposedFields, TRUE)) { + $tokenName = $field['name']; + // Presumably this line can not be reached unless isExposed = TRUE. + if ($isExposed) { if ( ($field['options'] || !empty($field['suffixes'])) // At the time of writing currency didn't have a label option - this may have changed. diff --git a/drupal/sites/all/modules/civicrm/CRM/Dedupe/BAO/DedupeRuleGroup.php b/drupal/sites/all/modules/civicrm/CRM/Dedupe/BAO/DedupeRuleGroup.php index 5e6f1d80b7..dc25dc02b4 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Dedupe/BAO/DedupeRuleGroup.php +++ b/drupal/sites/all/modules/civicrm/CRM/Dedupe/BAO/DedupeRuleGroup.php @@ -263,7 +263,7 @@ public function fillTable() { $query = "{$insertClause} {$query} {$groupByClause} ON DUPLICATE KEY UPDATE weight = weight + VALUES(weight)"; $dao = CRM_Core_DAO::executeQuery($query); - // FIXME: we need to be more acurate with affected rows, especially for insert vs duplicate insert. + // FIXME: we need to be more accurate with affected rows, especially for insert vs duplicate insert. // And that will help optimize further. $affectedRows = $dao->affectedRows(); @@ -337,28 +337,31 @@ public static function isQuerySetInclusive($tableQueries, $threshold, $exclWeigh } /** - * sort queries by number of records for the table associated with them. - * @param $tableQueries + * Sort queries by number of records for the table associated with them. + * + * @param array $tableQueries */ - public static function orderByTableCount(&$tableQueries) { - static $tableCount = []; - - $tempArray = []; - foreach ($tableQueries as $key => $query) { - $table = explode(".", $key); - $table = $table[0]; - if (!array_key_exists($table, $tableCount)) { - $query = "SELECT COUNT(*) FROM {$table}"; - $tableCount[$table] = CRM_Core_DAO::singleValueQuery($query); - } - $tempArray[$key] = $tableCount[$table]; - } + public static function orderByTableCount(array &$tableQueries): void { + uksort($tableQueries, 'self::isTableBigger'); + } - asort($tempArray); - foreach ($tempArray as $key => $count) { - $tempArray[$key] = $tableQueries[$key]; + /** + * Is the table extracted from the first string larger than the second string. + * + * @param string $a + * e.g civicrm_contact.first_name + * @param string $b + * e.g civicrm_address.street_address + * + * @return int + */ + private static function isTableBigger(string $a, string $b): int { + $tableA = explode('.', $a)[0]; + $tableB = explode('.', $b)[0]; + if ($tableA === $tableB) { + return 0; } - $tableQueries = $tempArray; + return CRM_Core_BAO_SchemaHandler::getRowCountForTable($tableA) <=> CRM_Core_BAO_SchemaHandler::getRowCountForTable($tableB); } /** diff --git a/drupal/sites/all/modules/civicrm/CRM/Event/Form/ManageEvent/Registration.php b/drupal/sites/all/modules/civicrm/CRM/Event/Form/ManageEvent/Registration.php index babb08cc9f..4a76047396 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Event/Form/ManageEvent/Registration.php +++ b/drupal/sites/all/modules/civicrm/CRM/Event/Form/ManageEvent/Registration.php @@ -444,7 +444,8 @@ public static function formRule($values, $files, $form) { if (($values['registration_link_text'] ?? '') === '') { $errorMsg['registration_link_text'] = ts('Please enter Registration Link Text'); } - if (($values['confirm_title'] ?? '') === '') { + // Check if the confirm text is set if we have enabled the confirmation page or page is monetary which forces the confirm page. + if (($values['confirm_title'] ?? '') === '' && (!empty($values['is_confirm_enabled']) || CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $form->_id, 'is_monetary'))) { $errorMsg['confirm_title'] = ts('Please enter a Title for the registration Confirmation Page'); } if (($values['thankyou_title'] ?? '') === '') { diff --git a/drupal/sites/all/modules/civicrm/CRM/Extension/ClassLoader.php b/drupal/sites/all/modules/civicrm/CRM/Extension/ClassLoader.php index 9ca81638bf..7f84b083a9 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Extension/ClassLoader.php +++ b/drupal/sites/all/modules/civicrm/CRM/Extension/ClassLoader.php @@ -179,7 +179,12 @@ private static function loadExtension(\Composer\Autoload\ClassLoader $loader, CR * @return string */ protected function getCacheFile() { - $envId = \CRM_Core_Config_Runtime::getId(); + $envId = md5(implode(',', array_merge( + [\CRM_Core_Config_Runtime::getId()], + array_column($this->mapper->getActiveModuleFiles(), 'prefix') + // dev/core#4055 - When toggling ext's on systems with opcode caching, you may get stale reads for a moment. + // New cache key ensures new data-set. + ))); $file = \Civi::paths()->getPath("[civicrm.compile]/CachedExtLoader.{$envId}.php"); return $file; } diff --git a/drupal/sites/all/modules/civicrm/CRM/Report/Form.php b/drupal/sites/all/modules/civicrm/CRM/Report/Form.php index 37a08a2e41..432d3f1ed2 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Report/Form.php +++ b/drupal/sites/all/modules/civicrm/CRM/Report/Form.php @@ -3770,14 +3770,18 @@ public function legacySlowGroupFilterClause($field, $value, $op) { } CRM_Contact_BAO_GroupContactCache::check($smartGroups); - + $aclFilter = NULL; + $selectWhereClauses = array_filter(CRM_Contact_BAO_Group::getSelectWhereClause('group')); + $aclFilter = implode(' AND ', $selectWhereClauses); + $aclFilter = !empty($aclFilter) ? ' AND ' . $aclFilter : ''; $smartGroupQuery = ''; if (!empty($smartGroups)) { $smartGroups = implode(',', $smartGroups); $smartGroupQuery = " UNION DISTINCT SELECT DISTINCT smartgroup_contact.contact_id FROM civicrm_group_contact_cache smartgroup_contact - WHERE smartgroup_contact.group_id IN ({$smartGroups}) "; + INNER JOIN `civicrm_group` AS `group` ON `group`.id = smartgroup_contact.group_id + WHERE smartgroup_contact.group_id IN ({$smartGroups}) {$aclFilter}"; } $sqlOp = $this->getSQLOperator($op); @@ -3796,7 +3800,8 @@ public function legacySlowGroupFilterClause($field, $value, $op) { return " {$contactAlias}.id {$sqlOp} ( SELECT DISTINCT {$this->_aliases['civicrm_group']}.contact_id FROM civicrm_group_contact {$this->_aliases['civicrm_group']} - WHERE {$clause} AND {$this->_aliases['civicrm_group']}.status = 'Added' + INNER JOIN `civicrm_group` AS `group` ON `group`.id = {$this->_aliases['civicrm_group']}.group_id + WHERE {$clause} AND {$this->_aliases['civicrm_group']}.status = 'Added' {$aclFilter} {$smartGroupQuery} ) "; } @@ -3950,6 +3955,10 @@ public function buildPermissionClause() { $ret = []; foreach ($this->selectedTables() as $tableName) { $baoName = str_replace('_DAO_', '_BAO_', (CRM_Core_DAO_AllCoreTables::getClassForTable($tableName) ?? '')); + // Do not include CiviCRM group add Select Where clause because we don't necessarily join here for reports with optimisedGroupFilters + if ($baoName === 'CRM_Contact_BAO_Group') { + continue; + } if ($baoName && class_exists($baoName) && !empty($this->_columns[$tableName]['alias'])) { $tableAlias = $this->_columns[$tableName]['alias']; $clauses = array_filter($baoName::getSelectWhereClause($tableAlias)); diff --git a/drupal/sites/all/modules/civicrm/CRM/Utils/Check/Component/Timestamps.php b/drupal/sites/all/modules/civicrm/CRM/Utils/Check/Component/Timestamps.php index 0514ee4ca8..c2240cf179 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Utils/Check/Component/Timestamps.php +++ b/drupal/sites/all/modules/civicrm/CRM/Utils/Check/Component/Timestamps.php @@ -58,7 +58,7 @@ public function checkTimezoneAPIs() { 1 => 'target="_blank" href="https://dev.mysql.com/doc/refman/8.0/en/mysql-tzinfo-to-sql.html"', ]), ts('MySQL Timezone Problem'), - \Psr\Log\LogLevel::WARNING, + \Psr\Log\LogLevel::NOTICE, 'fa-clock-o' ); } diff --git a/drupal/sites/all/modules/civicrm/CRM/Utils/File.php b/drupal/sites/all/modules/civicrm/CRM/Utils/File.php index bc882aa8f4..a822f32c6f 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Utils/File.php +++ b/drupal/sites/all/modules/civicrm/CRM/Utils/File.php @@ -352,8 +352,7 @@ public static function stripComments($string) { * @return bool */ public static function isExtensionSafe($ext) { - static $extensions = NULL; - if (!$extensions) { + if (!isset(Civi::$statics[__CLASS__]['file_extensions'])) { $extensions = CRM_Core_OptionGroup::values('safe_file_extension', TRUE); // make extensions to lowercase @@ -370,9 +369,11 @@ public static function isExtensionSafe($ext) { unset($extensions['html']); unset($extensions['htm']); } + Civi::$statics[__CLASS__]['file_extensions'] = $extensions; } + $restricted = CRM_Utils_Constant::value('CIVICRM_RESTRICTED_UPLOADS', '/(php|php\d|phtml|phar|pl|py|cgi|asp|js|sh|exe|pcgi\d)/i'); // support lower and uppercase file extensions - return (bool) isset($extensions[strtolower($ext)]); + return (bool) isset(Civi::$statics[__CLASS__]['file_extensions'][strtolower($ext)]) && !preg_match($restricted, strtolower($ext)); } /** diff --git a/drupal/sites/all/modules/civicrm/CRM/Utils/Hook.php b/drupal/sites/all/modules/civicrm/CRM/Utils/Hook.php index edd44148f5..90c73f3dab 100644 --- a/drupal/sites/all/modules/civicrm/CRM/Utils/Hook.php +++ b/drupal/sites/all/modules/civicrm/CRM/Utils/Hook.php @@ -309,6 +309,10 @@ public function runHooks( * @param $moduleList */ public function requireCiviModules(&$moduleList) { + foreach ($GLOBALS['CIVICRM_FORCE_MODULES'] ?? [] as $prefix) { + $moduleList[$prefix] = $prefix; + } + $civiModules = CRM_Core_PseudoConstant::getModuleExtensions(); foreach ($civiModules as $civiModule) { if (!file_exists($civiModule['filePath'] ?? '')) { diff --git a/drupal/sites/all/modules/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php b/drupal/sites/all/modules/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php index c031c6c2f9..29ce637ad8 100644 --- a/drupal/sites/all/modules/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php +++ b/drupal/sites/all/modules/civicrm/Civi/Api4/Service/Spec/Provider/IsCurrentFieldSpecProvider.php @@ -31,7 +31,7 @@ class IsCurrentFieldSpecProvider extends \Civi\Core\Service\AutoService implemen /** * @param \Civi\Api4\Service\Spec\RequestSpec $spec */ - public function modifySpec(RequestSpec $spec) { + public function modifySpec(RequestSpec $spec): void { $field = new FieldSpec('is_current', $spec->getEntity(), 'Boolean'); $field->setLabel(ts('Is Current')) ->setTitle(ts('Current')) @@ -39,27 +39,42 @@ public function modifySpec(RequestSpec $spec) { ->setColumnName('is_current') ->setDescription(ts('Is active with a non-past end-date')) ->setType('Extra') - ->setSqlRenderer([__CLASS__, 'renderIsCurrentSql']); + ->setSqlRenderer([__CLASS__, $this->getRenderer($field->getEntity())]); $spec->addFieldSpec($field); } + /** + * Get the function to render the sql. + * + * @param string $entity + * + * @return string + */ + private function getRenderer(string $entity): string { + if (in_array($entity, ['UserJob', 'SavedSearch'])) { + return 'renderNonExpiredSql'; + } + return 'renderIsCurrentSql'; + } + /** * @param string $entity * @param string $action * * @return bool */ - public function applies($entity, $action) { + public function applies($entity, $action): bool { if ($action !== 'get') { return FALSE; } // TODO: If we wanted this to not be a hard-coded list, we could always return TRUE here // and then in the `modifySpec` function check for the 3 fields `is_active`, `start_date`, and `end_date` - return in_array($entity, ['Relationship', 'RelationshipCache', 'Event', 'Campaign'], TRUE); + return in_array($entity, ['Relationship', 'RelationshipCache', 'Event', 'Campaign', 'SavedSearch', 'UserJob'], TRUE); } /** * @param array $field + * * return string */ public static function renderIsCurrentSql(array $field): string { @@ -71,4 +86,17 @@ public static function renderIsCurrentSql(array $field): string { return "IF($isActive = 1 AND ($startDate <= '$todayStart' OR $startDate IS NULL) AND ($endDate >= '$todayEnd' OR $endDate IS NULL), '1', '0')"; } + /** + * Render the sql clause to filter on expires date. + * + * @param array $field + * + * return string + */ + public static function renderNonExpiredSql(array $field): string { + $endDate = substr_replace($field['sql_name'], 'expires_date', -11, -1); + $todayEnd = date('Ymd'); + return "IF($endDate >= '$todayEnd' OR $endDate IS NULL, 1, 0)"; + } + } diff --git a/drupal/sites/all/modules/civicrm/Civi/Core/ClassScanner.php b/drupal/sites/all/modules/civicrm/Civi/Core/ClassScanner.php index c1e8eefbc7..7863d07edf 100644 --- a/drupal/sites/all/modules/civicrm/Civi/Core/ClassScanner.php +++ b/drupal/sites/all/modules/civicrm/Civi/Core/ClassScanner.php @@ -143,12 +143,6 @@ private static function scanCoreClasses(): array { static::scanFolders($classes, $civicrmRoot, 'CRM/*/WorkflowMessage', '_'); static::scanFolders($classes, $civicrmRoot, 'CRM/*/Import', '_'); static::scanFolders($classes, $civicrmRoot, 'Civi', '\\', ';\\\(Security|Test)\\\;'); - if (\CRM_Utils_Constant::value('CIVICRM_UF') === 'UnitTests') { - if (strpos(get_include_path(), $civicrmRoot . 'tests/phpunit') !== FALSE) { - static::scanFolders($classes, $civicrmRoot . 'tests/phpunit', 'CRM/*/WorkflowMessage', '_'); - static::scanFolders($classes, $civicrmRoot . 'tests/phpunit', 'Civi/*/WorkflowMessage', '\\'); - } - } $cache->set($cacheKey, $classes, static::TTL); return $classes; diff --git a/drupal/sites/all/modules/civicrm/Civi/Test/Api4TestTrait.php b/drupal/sites/all/modules/civicrm/Civi/Test/Api4TestTrait.php new file mode 100644 index 0000000000..eaded65524 --- /dev/null +++ b/drupal/sites/all/modules/civicrm/Civi/Test/Api4TestTrait.php @@ -0,0 +1,306 @@ +saveTestRecords($entityName, ['records' => [$values]])->single(); + } + + /** + * Saves one or more test records, supplying default values. + * + * Test records will be automatically deleted during tearDown. + * + * @param string $entityName + * @param array $saveParams + * @return \Civi\Api4\Generic\Result + * @throws \CRM_Core_Exception + * @throws \Civi\API\Exception\NotImplementedException + */ + public function saveTestRecords(string $entityName, array $saveParams): Result { + $saveParams += [ + 'checkPermissions' => FALSE, + 'defaults' => [], + ]; + $idField = CoreUtil::getIdFieldName($entityName); + foreach ($saveParams['records'] as &$record) { + $record += $saveParams['defaults']; + if (empty($record[$idField])) { + $this->getRequiredValuesToCreate($entityName, $record); + } + } + // Unset for clarity as it leaks from the foreach & is a reference. + unset($record); + $saved = civicrm_api4($entityName, 'save', $saveParams); + foreach ($saved as $item) { + $this->testRecords[] = [$entityName, [[$idField, '=', $item[$idField]]]]; + } + return $saved; + } + + /** + * Generate some random lowercase letters + * @param int $len + * @return string + */ + protected function randomLetters(int $len = 10): string { + return \CRM_Utils_String::createRandom($len, implode('', range('a', 'z'))); + } + + /** + * Get the required fields for the api entity + action. + * + * @param string $entity + * @param array $values + * + * @return array + * @throws \CRM_Core_Exception + */ + public function getRequiredValuesToCreate(string $entity, array &$values = []): array { + $requiredFields = civicrm_api4($entity, 'getfields', [ + 'action' => 'create', + 'loadOptions' => TRUE, + 'where' => [ + ['type', 'IN', ['Field', 'Extra']], + ['OR', + [ + ['required', '=', TRUE], + // Include conditionally-required fields only if they don't create a circular FK reference + ['AND', [['required_if', 'IS NOT EMPTY'], ['fk_entity', '!=', $entity]]], + ], + ], + ['default_value', 'IS EMPTY'], + ['readonly', 'IS EMPTY'], + ], + ], 'name'); + + $extraValues = []; + foreach ($requiredFields as $fieldName => $requiredField) { + if (!isset($values[$fieldName])) { + $extraValues[$fieldName] = $this->getRequiredValue($requiredField); + } + } + + // Hack in some extra per-entity values that couldn't be determined by metadata. + // Try to keep this to a minimum and improve metadata as a first-resort. + + switch ($entity) { + case 'UFField': + $extraValues['field_name'] = 'activity_campaign_id'; + break; + + case 'Translation': + $extraValues['entity_table'] = 'civicrm_msg_template'; + $extraValues['entity_field'] = 'msg_subject'; + $extraValues['entity_id'] = $this->getFkID('MessageTemplate'); + break; + + case 'Case': + $extraValues['creator_id'] = $this->getFkID('Contact'); + break; + + case 'CaseContact': + // Prevent "already exists" error from using an existing contact id + $extraValues['contact_id'] = $this->createTestRecord('Contact')['id']; + break; + + case 'CaseType': + $extraValues['definition'] = [ + 'activityTypes' => [ + [ + 'name' => 'Open Case', + 'max_instances' => 1, + ], + [ + 'name' => 'Follow up', + ], + ], + 'activitySets' => [ + [ + 'name' => 'standard_timeline', + 'label' => 'Standard Timeline', + 'timeline' => 1, + 'activityTypes' => [ + [ + 'name' => 'Open Case', + 'status' => 'Completed', + ], + [ + 'name' => 'Follow up', + 'reference_activity' => 'Open Case', + 'reference_offset' => 3, + 'reference_select' => 'newest', + ], + ], + ], + ], + 'timelineActivityTypes' => [ + [ + 'name' => 'Open Case', + 'status' => 'Completed', + ], + [ + 'name' => 'Follow up', + 'reference_activity' => 'Open Case', + 'reference_offset' => 3, + 'reference_select' => 'newest', + ], + ], + 'caseRoles' => [ + [ + 'name' => 'Parent of', + 'creator' => 1, + 'manager' => 1, + ], + ], + ]; + break; + } + + $values += $extraValues; + return $values; + } + + /** + * Attempt to get a value using field option, defaults, FKEntity, or a random + * value based on the data type. + * + * @param array $field + * + * @return mixed + * @throws \CRM_Core_Exception + */ + private function getRequiredValue(array $field) { + if (!empty($field['options'])) { + return key($field['options']); + } + if (!empty($field['fk_entity'])) { + return $this->getFkID($field['fk_entity']); + } + if (isset($field['default_value'])) { + return $field['default_value']; + } + if ($field['name'] === 'contact_id') { + return $this->getFkID('Contact'); + } + if ($field['name'] === 'entity_id') { + // What could possibly go wrong with this? + switch ($field['table_name'] ?? NULL) { + case 'civicrm_financial_item': + return $this->getFkID(\Civi\Api4\Service\Spec\Provider\FinancialItemCreationSpecProvider::DEFAULT_ENTITY); + + default: + return $this->getFkID('Contact'); + } + } + + $randomValue = $this->getRandomValue($field['data_type']); + + if ($randomValue) { + return $randomValue; + } + + throw new \CRM_Core_Exception('Could not provide default value'); + } + + protected function deleteTestRecords(): void { + // Delete all test records in reverse order to prevent fk constraints + foreach (array_reverse($this->testRecords) as $record) { + $params = ['checkPermissions' => FALSE, 'where' => $record[1]]; + + // Set useTrash param if it exists + $entityClass = CoreUtil::getApiClass($record[0]); + $deleteAction = $entityClass::delete(); + if (property_exists($deleteAction, 'useTrash')) { + $params['useTrash'] = FALSE; + } + + civicrm_api4($record[0], 'delete', $params); + } + } + + /** + * Get an ID for the appropriate entity. + * + * @param string $fkEntity + * + * @return int + * + * @throws \CRM_Core_Exception + */ + private function getFkID(string $fkEntity): int { + $params = ['checkPermissions' => FALSE]; + // Be predictable about what type of contact we select + if ($fkEntity === 'Contact') { + $params['where'] = [['contact_type', '=', 'Individual']]; + } + $entityList = civicrm_api4($fkEntity, 'get', $params); + // If no existing entities, create one + if ($entityList->count() < 1) { + return $this->createTestRecord($fkEntity)['id']; + } + + return $entityList->last()['id']; + } + + /** + * @param $dataType + * + * @return int|null|string + * + * @noinspection PhpUnhandledExceptionInspection + * @noinspection PhpDocMissingThrowsInspection + */ + private function getRandomValue($dataType) { + switch ($dataType) { + case 'Boolean': + return TRUE; + + case 'Integer': + return random_int(1, 2000); + + case 'String': + return $this->randomLetters(); + + case 'Text': + return $this->randomLetters(100); + + case 'Money': + return sprintf('%d.%2d', random_int(0, 2000), random_int(10, 99)); + + case 'Date': + return '20100102'; + + case 'Timestamp': + return 'now'; + } + + return NULL; + } + +} diff --git a/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListener.php b/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListener.php index 6e3b4cdc08..fbd6fd8878 100644 --- a/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListener.php +++ b/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListener.php @@ -121,6 +121,7 @@ protected function bootHeadless($test) { \CRM_Core_Session::singleton()->set('userID', NULL); // ugh, performance $config = \CRM_Core_Config::singleton(TRUE, TRUE); + $config->userSystem->setMySQLTimeZone(); if (property_exists($config->userPermissionClass, 'permissions')) { $config->userPermissionClass->permissions = NULL; diff --git a/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListenerPHPUnit7.php b/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListenerPHPUnit7.php index 8b4b9af92e..c29c572e81 100644 --- a/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListenerPHPUnit7.php +++ b/drupal/sites/all/modules/civicrm/Civi/Test/CiviTestListenerPHPUnit7.php @@ -114,6 +114,7 @@ protected function bootHeadless($test) { \CRM_Core_Session::singleton()->set('userID', NULL); // ugh, performance $config = \CRM_Core_Config::singleton(TRUE, TRUE); + $config->userSystem->setMySQLTimeZone(); if (property_exists($config->userPermissionClass, 'permissions')) { $config->userPermissionClass->permissions = NULL; diff --git a/drupal/sites/all/modules/civicrm/Civi/Test/Legacy/CiviTestListener.php b/drupal/sites/all/modules/civicrm/Civi/Test/Legacy/CiviTestListener.php index 93fb4ac8fb..4889da722b 100644 --- a/drupal/sites/all/modules/civicrm/Civi/Test/Legacy/CiviTestListener.php +++ b/drupal/sites/all/modules/civicrm/Civi/Test/Legacy/CiviTestListener.php @@ -111,6 +111,7 @@ protected function bootHeadless($test) { \CRM_Core_Session::singleton()->set('userID', NULL); // ugh, performance $config = \CRM_Core_Config::singleton(TRUE, TRUE); + $config->userSystem->setMySQLTimeZone(); if (property_exists($config->userPermissionClass, 'permissions')) { $config->userPermissionClass->permissions = NULL; diff --git a/drupal/sites/all/modules/civicrm/civicrm-version.php b/drupal/sites/all/modules/civicrm/civicrm-version.php index 24edc2ccfd..371fc18c70 100644 --- a/drupal/sites/all/modules/civicrm/civicrm-version.php +++ b/drupal/sites/all/modules/civicrm/civicrm-version.php @@ -1,7 +1,7 @@ '5.58.0', + return array( 'version' => '5.58.1', 'cms' => 'Drupal', 'revision' => '' ); } diff --git a/drupal/sites/all/modules/civicrm/composer.lock b/drupal/sites/all/modules/civicrm/composer.lock index a7dada33e2..13078911fa 100644 --- a/drupal/sites/all/modules/civicrm/composer.lock +++ b/drupal/sites/all/modules/civicrm/composer.lock @@ -612,16 +612,16 @@ }, { "name": "dompdf/dompdf", - "version": "v2.0.2", + "version": "v2.0.3", "source": { "type": "git", "url": "https://github.com/dompdf/dompdf.git", - "reference": "ad4c631bf8897fc1ca7b566468a969cfd71a558a" + "reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/dompdf/zipball/ad4c631bf8897fc1ca7b566468a969cfd71a558a", - "reference": "ad4c631bf8897fc1ca7b566468a969cfd71a558a", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/e8d2d5e37e8b0b30f0732a011295ab80680d7e85", + "reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85", "shasum": "" }, "require": { @@ -668,9 +668,9 @@ "homepage": "https://github.com/dompdf/dompdf", "support": { "issues": "https://github.com/dompdf/dompdf/issues", - "source": "https://github.com/dompdf/dompdf/tree/v2.0.2" + "source": "https://github.com/dompdf/dompdf/tree/v2.0.3" }, - "time": "2023-01-31T13:30:40+00:00" + "time": "2023-02-07T12:51:48+00:00" }, { "name": "ezyang/htmlpurifier", diff --git a/drupal/sites/all/modules/civicrm/drupal/civicrm.info b/drupal/sites/all/modules/civicrm/drupal/civicrm.info index 2449ec4c42..be8b868bc3 100644 --- a/drupal/sites/all/modules/civicrm/drupal/civicrm.info +++ b/drupal/sites/all/modules/civicrm/drupal/civicrm.info @@ -1,6 +1,6 @@ name = CiviCRM description = Constituent relationship management system. Allows sites to manage contacts, relationships and groups, and track contact activities, contributions, memberships and events. See the CiviCRM website for more information. -version = 7.x-5.58.0 +version = 7.x-5.58.1 package = CiviCRM core = 7.x project = civicrm diff --git a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_contact_ref/civicrm_contact_ref.info b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_contact_ref/civicrm_contact_ref.info index 228adc054a..7e38c4ed74 100644 --- a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_contact_ref/civicrm_contact_ref.info +++ b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_contact_ref/civicrm_contact_ref.info @@ -1,6 +1,6 @@ name = CiviCRM Contact Reference Field description = Makes a CiviCRM Contact Reference Field. -version = 7.x-5.58.0 +version = 7.x-5.58.1 core = 7.x package = CiviCRM project = civicrm diff --git a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_engage/civicrm_engage.info b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_engage/civicrm_engage.info index 4d165c1f1c..ffcc667509 100755 --- a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_engage/civicrm_engage.info +++ b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_engage/civicrm_engage.info @@ -1,6 +1,6 @@ name = CiviEngage description = DEPRECATED Walklist and Phone-banking support for CiviCRM. This module will not be ported to Drupal 8. Please see: https://civicrm.org/blog/jamie/civicrmengage-is-dead-long-live-civicrmengage -version = 7.x-5.58.0 +version = 7.x-5.58.1 core = 7.x package = CiviCRM project = civicrm diff --git a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_group_roles/civicrm_group_roles.info b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_group_roles/civicrm_group_roles.info index 4496fa3cad..1eded875c5 100644 --- a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_group_roles/civicrm_group_roles.info +++ b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_group_roles/civicrm_group_roles.info @@ -1,6 +1,6 @@ name = CiviGroup Roles Sync description = Sync Drupal Roles to CiviCRM Groups. -version = 7.x-5.58.0 +version = 7.x-5.58.1 core = 7.x package = CiviCRM project = civicrm diff --git a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_member_roles/civicrm_member_roles.info b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_member_roles/civicrm_member_roles.info index 7f94a9bccb..479c67aaa2 100644 --- a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_member_roles/civicrm_member_roles.info +++ b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_member_roles/civicrm_member_roles.info @@ -1,6 +1,6 @@ name = CiviMember Roles Sync description = Synchronize CiviCRM Contacts with Membership Status to a specified Drupal Role both automatically and manually. -version = 7.x-5.58.0 +version = 7.x-5.58.1 core = 7.x package = CiviCRM project = civicrm diff --git a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_og_sync/civicrm_og_sync.info b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_og_sync/civicrm_og_sync.info index 0472ce56b2..fabc1e484e 100644 --- a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_og_sync/civicrm_og_sync.info +++ b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_og_sync/civicrm_og_sync.info @@ -1,6 +1,6 @@ name = CiviCRM OG Sync description = Synchronize Organic Groups and CiviCRM Groups and ACL's. More information at: https://docs.civicrm.org/sysadmin/en/latest/integration/drupal/#civicrm-organic-groups-sync -version = 7.x-5.58.0 +version = 7.x-5.58.1 core = 7.x package = CiviCRM project = civicrm diff --git a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_rules/civicrm_rules.info b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_rules/civicrm_rules.info index 7ab03d70f7..db35b29772 100644 --- a/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_rules/civicrm_rules.info +++ b/drupal/sites/all/modules/civicrm/drupal/modules/civicrm_rules/civicrm_rules.info @@ -1,6 +1,6 @@ name = CiviCRM Rules Integration description = Integrate CiviCRM and Drupal Rules Module. Expose Contact, Contribution and other Objects along with Form / Page Operations. -version = 7.x-5.58.0 +version = 7.x-5.58.1 core = 7.x package = CiviCRM project = civicrm diff --git a/drupal/sites/all/modules/civicrm/drupal/modules/civicrmtheme/civicrmtheme.info b/drupal/sites/all/modules/civicrm/drupal/modules/civicrmtheme/civicrmtheme.info index 384e1124c6..33ecfaf6d3 100644 --- a/drupal/sites/all/modules/civicrm/drupal/modules/civicrmtheme/civicrmtheme.info +++ b/drupal/sites/all/modules/civicrm/drupal/modules/civicrmtheme/civicrmtheme.info @@ -1,6 +1,6 @@ name = CiviCRM Theme description = Define alternate themes for CiviCRM. -version = 7.x-5.58.0 +version = 7.x-5.58.1 core = 7.x package = CiviCRM project = civicrm diff --git a/drupal/sites/all/modules/civicrm/ext/afform/admin/info.xml b/drupal/sites/all/modules/civicrm/ext/afform/admin/info.xml index b1fc0efe10..31c7ec80ac 100644 --- a/drupal/sites/all/modules/civicrm/ext/afform/admin/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/afform/admin/info.xml @@ -13,7 +13,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-01-09 - 5.58.0 + 5.58.1 beta 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/afform/core/info.xml b/drupal/sites/all/modules/civicrm/ext/afform/core/info.xml index e8247b5e43..38db7d63bc 100644 --- a/drupal/sites/all/modules/civicrm/ext/afform/core/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/afform/core/info.xml @@ -13,7 +13,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-01-09 - 5.58.0 + 5.58.1 beta 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php b/drupal/sites/all/modules/civicrm/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php index 21aafaeb5f..aa8817b792 100644 --- a/drupal/sites/all/modules/civicrm/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php +++ b/drupal/sites/all/modules/civicrm/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php @@ -1,15 +1,19 @@ installMe(__DIR__)->install('org.civicrm.search_kit')->apply(); + public function setUpHeadless(): CiviEnvBuilder { + return Test::headless()->installMe(__DIR__)->install('org.civicrm.search_kit')->apply(); } public function tearDown(): void { Afform::revert(FALSE)->addWhere('name', 'IN', $this->formNames)->execute(); - parent::tearDown(); + $this->deleteTestRecords(); } public function testAfformContactSummaryTab(): void { diff --git a/drupal/sites/all/modules/civicrm/ext/afform/html/info.xml b/drupal/sites/all/modules/civicrm/ext/afform/html/info.xml index 38c79d2e1b..b4852505eb 100644 --- a/drupal/sites/all/modules/civicrm/ext/afform/html/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/afform/html/info.xml @@ -13,7 +13,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-01-09 - 5.58.0 + 5.58.1 alpha 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/afform/mock/info.xml b/drupal/sites/all/modules/civicrm/ext/afform/mock/info.xml index 15cc1c62cc..1801f0ad37 100644 --- a/drupal/sites/all/modules/civicrm/ext/afform/mock/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/afform/mock/info.xml @@ -12,7 +12,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-01-09 - 5.58.0 + 5.58.1 mgmt:hidden diff --git a/drupal/sites/all/modules/civicrm/ext/authx/info.xml b/drupal/sites/all/modules/civicrm/ext/authx/info.xml index b33d350433..47b654cd16 100644 --- a/drupal/sites/all/modules/civicrm/ext/authx/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/authx/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-02-11 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/civicrm_admin_ui/info.xml b/drupal/sites/all/modules/civicrm/ext/civicrm_admin_ui/info.xml index 824a80e055..6aeef831e4 100644 --- a/drupal/sites/all/modules/civicrm/ext/civicrm_admin_ui/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/civicrm_admin_ui/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2022-01-02 - 5.58.0 + 5.58.1 alpha 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/civigrant/info.xml b/drupal/sites/all/modules/civicrm/ext/civigrant/info.xml index 02faef117e..1545bb4905 100644 --- a/drupal/sites/all/modules/civicrm/ext/civigrant/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/civigrant/info.xml @@ -13,7 +13,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-11-11 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/civiimport/info.xml b/drupal/sites/all/modules/civicrm/ext/civiimport/info.xml index a14b4566de..877c1b2b03 100644 --- a/drupal/sites/all/modules/civicrm/ext/civiimport/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/civiimport/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2022-08-11 - 5.58.0 + 5.58.1 alpha 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/ckeditor4/info.xml b/drupal/sites/all/modules/civicrm/ext/ckeditor4/info.xml index f8b075b332..2fe1dd6c96 100644 --- a/drupal/sites/all/modules/civicrm/ext/ckeditor4/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/ckeditor4/info.xml @@ -15,7 +15,7 @@ https://www.gnu.org/licenses/agpl-3.0.html 2021-05-23 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/contributioncancelactions/info.xml b/drupal/sites/all/modules/civicrm/ext/contributioncancelactions/info.xml index a93b4514a5..f3b7ea1fd1 100644 --- a/drupal/sites/all/modules/civicrm/ext/contributioncancelactions/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/contributioncancelactions/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-10-12 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/elavon/info.xml b/drupal/sites/all/modules/civicrm/ext/elavon/info.xml index d97c229a39..4477e1f043 100644 --- a/drupal/sites/all/modules/civicrm/ext/elavon/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/elavon/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2022-08-05 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/eventcart/info.xml b/drupal/sites/all/modules/civicrm/ext/eventcart/info.xml index b675a63654..b84e15f037 100644 --- a/drupal/sites/all/modules/civicrm/ext/eventcart/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/eventcart/info.xml @@ -13,7 +13,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-08-03 - 5.58.0 + 5.58.1 mgmt:hidden diff --git a/drupal/sites/all/modules/civicrm/ext/ewaysingle/info.xml b/drupal/sites/all/modules/civicrm/ext/ewaysingle/info.xml index 6c5d857922..e5fac2c140 100644 --- a/drupal/sites/all/modules/civicrm/ext/ewaysingle/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/ewaysingle/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-10-07 - 5.58.0 + 5.58.1 mgmt:hidden diff --git a/drupal/sites/all/modules/civicrm/ext/financialacls/info.xml b/drupal/sites/all/modules/civicrm/ext/financialacls/info.xml index 65029056bb..47ce98a29a 100644 --- a/drupal/sites/all/modules/civicrm/ext/financialacls/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/financialacls/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-08-27 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/flexmailer/info.xml b/drupal/sites/all/modules/civicrm/ext/flexmailer/info.xml index 6a0f469e4e..7a71dddabf 100644 --- a/drupal/sites/all/modules/civicrm/ext/flexmailer/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/flexmailer/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-08-05 - 5.58.0 + 5.58.1 stable FlexMailer is an email delivery engine which replaces the internal guts diff --git a/drupal/sites/all/modules/civicrm/ext/greenwich/info.xml b/drupal/sites/all/modules/civicrm/ext/greenwich/info.xml index e063c2102d..c98060aa5b 100644 --- a/drupal/sites/all/modules/civicrm/ext/greenwich/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/greenwich/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-07-21 - 5.58.0 + 5.58.1 mgmt:hidden diff --git a/drupal/sites/all/modules/civicrm/ext/legacycustomsearches/info.xml b/drupal/sites/all/modules/civicrm/ext/legacycustomsearches/info.xml index fd2c926acf..59ee823f8c 100644 --- a/drupal/sites/all/modules/civicrm/ext/legacycustomsearches/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/legacycustomsearches/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-07-25 - 5.58.0 + 5.58.1 stable mgmt:hidden diff --git a/drupal/sites/all/modules/civicrm/ext/message_admin/info.xml b/drupal/sites/all/modules/civicrm/ext/message_admin/info.xml index 59bf012b17..a8e835b4a0 100644 --- a/drupal/sites/all/modules/civicrm/ext/message_admin/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/message_admin/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-06-12 - 5.58.0 + 5.58.1 alpha 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/oauth-client/info.xml b/drupal/sites/all/modules/civicrm/ext/oauth-client/info.xml index aa0093af19..e5063c1c3b 100644 --- a/drupal/sites/all/modules/civicrm/ext/oauth-client/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/oauth-client/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-10-23 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/payflowpro/info.xml b/drupal/sites/all/modules/civicrm/ext/payflowpro/info.xml index a2ce72e813..00b3b400ec 100644 --- a/drupal/sites/all/modules/civicrm/ext/payflowpro/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/payflowpro/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-04-13 - 5.58.0 + 5.58.1 stable 5.58 diff --git a/drupal/sites/all/modules/civicrm/ext/recaptcha/info.xml b/drupal/sites/all/modules/civicrm/ext/recaptcha/info.xml index 4595946a29..ef978c7f7a 100644 --- a/drupal/sites/all/modules/civicrm/ext/recaptcha/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/recaptcha/info.xml @@ -13,7 +13,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-04-03 - 5.58.0 + 5.58.1 mgmt:hidden diff --git a/drupal/sites/all/modules/civicrm/ext/search_kit/Civi/Search/Admin.php b/drupal/sites/all/modules/civicrm/ext/search_kit/Civi/Search/Admin.php index 5a482bf996..ee85568afd 100644 --- a/drupal/sites/all/modules/civicrm/ext/search_kit/Civi/Search/Admin.php +++ b/drupal/sites/all/modules/civicrm/ext/search_kit/Civi/Search/Admin.php @@ -145,11 +145,11 @@ public static function getSchema(): array { $entity['addPath'] = $paths['add']; } try { - $getFields = civicrm_api4($entity['name'], 'getFields', [ - 'select' => ['name', 'title', 'label', 'description', 'type', 'options', 'input_type', 'input_attrs', 'data_type', 'serialize', 'entity', 'fk_entity', 'readonly', 'operators', 'suffixes', 'nullable'], - 'where' => [['deprecated', '=', FALSE], ['name', 'NOT IN', ['api_key', 'hash']]], - 'orderBy' => ['label'], - ]); + $getFields = civicrm_api4($entity['name'], 'getFields', [ + 'select' => ['name', 'title', 'label', 'description', 'type', 'options', 'input_type', 'input_attrs', 'data_type', 'serialize', 'entity', 'fk_entity', 'readonly', 'operators', 'suffixes', 'nullable'], + 'where' => [['deprecated', '=', FALSE], ['name', 'NOT IN', ['api_key', 'hash']]], + 'orderBy' => ['label'], + ]); } catch (\CRM_Core_Exception $e) { \Civi::log()->warning('Entity could not be loaded', ['entity' => $entity['name']]); diff --git a/drupal/sites/all/modules/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js b/drupal/sites/all/modules/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js index 69d59c8010..c9b75271f1 100644 --- a/drupal/sites/all/modules/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js +++ b/drupal/sites/all/modules/civicrm/ext/search_kit/ang/crmSearchAdmin/searchListing/crmSearchAdminSearchListing.component.js @@ -56,7 +56,7 @@ ['Group AS group', 'LEFT', ['id', '=', 'group.saved_search_id']], ['EntityTag AS entity_tag', 'LEFT', ['entity_tag.entity_table', '=', '"civicrm_saved_search"'], ['id', '=', 'entity_tag.entity_id']], ], - where: [['api_entity', 'IS NOT NULL']], + where: [['api_entity', 'IS NOT NULL'], ['is_current', '=', true]], groupBy: ['id'] } }; diff --git a/drupal/sites/all/modules/civicrm/ext/search_kit/info.xml b/drupal/sites/all/modules/civicrm/ext/search_kit/info.xml index 45d85fb36c..ebab5ba583 100644 --- a/drupal/sites/all/modules/civicrm/ext/search_kit/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/search_kit/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-01-06 - 5.58.0 + 5.58.1 stable mgmt:required diff --git a/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunTest.php b/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunTest.php index 819d3b879f..985d000248 100644 --- a/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunTest.php +++ b/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunTest.php @@ -14,6 +14,7 @@ use Civi\Api4\SavedSearch; use Civi\Api4\SearchDisplay; use Civi\Api4\UFMatch; +use Civi\Test\CiviEnvBuilder; use Civi\Test\TransactionalInterface; /** @@ -22,7 +23,7 @@ class SearchRunTest extends Api4TestBase implements TransactionalInterface { use \Civi\Test\ACLPermissionTrait; - public function setUpHeadless() { + public function setUpHeadless(): CiviEnvBuilder { // Civi\Test has many helpers, like install(), uninstall(), sql(), and sqlFile(). // See: https://docs.civicrm.org/dev/en/latest/testing/phpunit/#civitest return \Civi\Test::headless() diff --git a/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunWithCustomFieldTest.php b/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunWithCustomFieldTest.php index 0e5bf67769..9497758b10 100644 --- a/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunWithCustomFieldTest.php +++ b/drupal/sites/all/modules/civicrm/ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunWithCustomFieldTest.php @@ -10,13 +10,14 @@ use Civi\Api4\Contact; use Civi\Api4\CustomField; use Civi\Api4\CustomGroup; +use Civi\Test\CiviEnvBuilder; /** * @group headless */ class SearchRunWithCustomFieldTest extends CustomTestBase { - public function setUpHeadless() { + public function setUpHeadless(): CiviEnvBuilder { return \Civi\Test::headless() ->installMe(__DIR__) ->apply(); diff --git a/drupal/sites/all/modules/civicrm/ext/sequentialcreditnotes/info.xml b/drupal/sites/all/modules/civicrm/ext/sequentialcreditnotes/info.xml index 86f8b93090..5ed5ee2a77 100644 --- a/drupal/sites/all/modules/civicrm/ext/sequentialcreditnotes/info.xml +++ b/drupal/sites/all/modules/civicrm/ext/sequentialcreditnotes/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2020-01-28 - 5.58.0 + 5.58.1 mgmt:hidden diff --git a/drupal/sites/all/modules/civicrm/mixin/scan-classes@1/mixin.php b/drupal/sites/all/modules/civicrm/mixin/scan-classes@1/mixin.php index fc070c215f..f23dabaf52 100644 --- a/drupal/sites/all/modules/civicrm/mixin/scan-classes@1/mixin.php +++ b/drupal/sites/all/modules/civicrm/mixin/scan-classes@1/mixin.php @@ -54,10 +54,8 @@ \Civi\Core\ClassScanner::scanFolders($all, $baseDir, 'CRM', '_'); \Civi\Core\ClassScanner::scanFolders($all, $baseDir, 'Civi', '\\'); if (defined('CIVICRM_TEST')) { - // Bug T327360 - // https://lab.civicrm.org/dev/core/-/issues/4088 - // \Civi\Core\ClassScanner::scanFolders($all, "$baseDir/tests/phpunit", 'CRM', '_'); - // \Civi\Core\ClassScanner::scanFolders($all, "$baseDir/tests/phpunit", 'Civi', '\\'); + \Civi\Core\ClassScanner::scanFolders($all, "$baseDir/tests/phpunit", 'CRM', '_'); + \Civi\Core\ClassScanner::scanFolders($all, "$baseDir/tests/phpunit", 'Civi', '\\'); } $cache->set($cacheKey, $all, \Civi\Core\ClassScanner::TTL); } diff --git a/drupal/sites/all/modules/civicrm/release-notes.md b/drupal/sites/all/modules/civicrm/release-notes.md index 36908d4d8d..e154f37420 100644 --- a/drupal/sites/all/modules/civicrm/release-notes.md +++ b/drupal/sites/all/modules/civicrm/release-notes.md @@ -15,6 +15,16 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress +## CiviCRM 5.58.1 + +Released February 15, 2023 + +- **[Synopsis](release-notes/5.58.1.md#synopsis)** +- **[Security advisories](release-notes/5.58.1.md#security)** +- **[Bugs resolved](release-notes/5.58.1.md#bugs)** +- **[Credits](release-notes/5.58.1.md#credits)** +- **[Feedback](release-notes/5.58.1.md#feedback)** + ## CiviCRM 5.58.0 Released February 1, 2023 diff --git a/drupal/sites/all/modules/civicrm/release-notes/5.58.1.md b/drupal/sites/all/modules/civicrm/release-notes/5.58.1.md new file mode 100644 index 0000000000..db065998ce --- /dev/null +++ b/drupal/sites/all/modules/civicrm/release-notes/5.58.1.md @@ -0,0 +1,53 @@ +# CiviCRM 5.58.1 + +Released February 15, 2023 + +- **[Synopsis](#synopsis)** +- **[Security advisories](#security)** +- **[Bugs resolved](#bugs)** +- **[Credits](#credits)** +- **[Feedback](#feedback)** + +## Synopsis + +| *Does this version...?* | | +| --------------------------------------------------------------- | -------- | +| Change the database schema? | no | +| Alter the API? | no | +| Require attention to configuration options? | no | +| Fix problems installing or upgrading to a previous version? | no | +| Introduce features? | no | +| **Fix bugs?** | **yes** | +| **Fix security vulnerabilities?** | **yes** | + +## Security advisories + +* **[CIVI-SA-2023-04](https://civicrm.org/advisory/civi-sa-2023-04-file-type-restrictions): File Type Restrictions** +* **[CIVI-SA-2023-05](https://civicrm.org/advisory/civi-sa-2023-05-quick-add-xss): Quick Add XSS (WordPress)** +* **[CIVI-SA-2023-06](https://civicrm.org/advisory/civi-sa-2023-06-dompdf-203): Dompdf 2.0.3 RCE** + +## Bugs resolved + +* **_CiviContribute_: PDF invoice renders with incorrect formatting ([dev/core#4080](https://lab.civicrm.org/dev/core/-/issues/4080): [#25547](https://github.com/civicrm/civicrm-core/pull/25547))** +* **_CiviEvent_: Excessive validation of title field ([dev/core#4119](https://lab.civicrm.org/dev/core/-/issues/4119): [#25578](https://github.com/civicrm/civicrm-core/pull/25578))** +* **_CiviReports_: Error "no such field" when displaying to limited-access user ([dev/core#4068](https://lab.civicrm.org/dev/core/-/issues/4068): [#25525](https://github.com/civicrm/civicrm-core/pull/25525))** +* **_Extensions_: During installation, new classes may not initially load ([dev/core#4055](https://lab.civicrm.org/dev/core/-/issues/4055): [#25379](https://github.com/civicrm/civicrm-core/pull/25379))** +* **_Status Check_: Tweak severity of new timezone warning ([#25583](https://github.com/civicrm/civicrm-core/pull/25583/))** +* **_Testing_: Headless tests should initialize timezone ([#25534](https://github.com/civicrm/civicrm-core/pull/25534))** +* **_Tokens_: Tokens like `{contact.email_primary.email}` do not render consistently ([dev/core#4109](https://lab.civicrm.org/dev/core/-/issues/4109): [#25548](https://github.com/civicrm/civicrm-core/pull/25548/))** + +## Credits + +This release was developed by the following authors and reviewers: + +Wikimedia Foundation - Eileen McNaughton; timinaust; Tadpole Collective - Kevin Cristiano; +Megaphone Technology Consulting - Jon Goldberg; Maria; JMA Consulting - Seamus Lee; +Deloitte - Andrea Intilangelo; Dave D; CiviDesk - Yashodha Chaku; CiviCRM - Tim Otten; +CiviCoop - Klaas Eikelboom, Erik Hommel; Circle Interactive - Pradeep Nayak; Bob Silvern; +ben_fairless; Australian Greens - Andrew Cormick-Dockery + +## 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/drupal/sites/all/modules/civicrm/sql/civicrm_data.mysql b/drupal/sites/all/modules/civicrm/sql/civicrm_data.mysql index 2dfca6f7c6..aaf3e96633 100644 --- a/drupal/sites/all/modules/civicrm/sql/civicrm_data.mysql +++ b/drupal/sites/all/modules/civicrm/sql/civicrm_data.mysql @@ -23665,4 +23665,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.58.0'; +UPDATE civicrm_domain SET version = '5.58.1'; diff --git a/drupal/sites/all/modules/civicrm/sql/civicrm_generated.mysql b/drupal/sites/all/modules/civicrm/sql/civicrm_generated.mysql index 9804f8dbc1..83764dab85 100644 --- a/drupal/sites/all/modules/civicrm/sql/civicrm_generated.mysql +++ b/drupal/sites/all/modules/civicrm/sql/civicrm_generated.mysql @@ -3056,7 +3056,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.58.0',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); + (1,'Default Domain Name',NULL,'5.58.1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */; UNLOCK TABLES; diff --git a/drupal/sites/all/modules/civicrm/vendor/autoload.php b/drupal/sites/all/modules/civicrm/vendor/autoload.php index 06c26c107e..88d7f9c244 100644 --- a/drupal/sites/all/modules/civicrm/vendor/autoload.php +++ b/drupal/sites/all/modules/civicrm/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit0a6d5998695b3b88d8c91af1ab91d6ad::getLoader(); +return ComposerAutoloaderInit9f9955bf8d90b6eb142de17e7c9fca9f::getLoader(); diff --git a/drupal/sites/all/modules/civicrm/vendor/composer/autoload_real.php b/drupal/sites/all/modules/civicrm/vendor/composer/autoload_real.php index 7b36999685..af7d58b020 100644 --- a/drupal/sites/all/modules/civicrm/vendor/composer/autoload_real.php +++ b/drupal/sites/all/modules/civicrm/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit0a6d5998695b3b88d8c91af1ab91d6ad +class ComposerAutoloaderInit9f9955bf8d90b6eb142de17e7c9fca9f { private static $loader; @@ -24,9 +24,9 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit0a6d5998695b3b88d8c91af1ab91d6ad', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit9f9955bf8d90b6eb142de17e7c9fca9f', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); - spl_autoload_unregister(array('ComposerAutoloaderInit0a6d5998695b3b88d8c91af1ab91d6ad', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit9f9955bf8d90b6eb142de17e7c9fca9f', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); @@ -36,7 +36,7 @@ public static function getLoader() if ($useStaticLoader) { require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -57,12 +57,12 @@ public static function getLoader() $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire0a6d5998695b3b88d8c91af1ab91d6ad($fileIdentifier, $file); + composerRequire9f9955bf8d90b6eb142de17e7c9fca9f($fileIdentifier, $file); } return $loader; @@ -74,7 +74,7 @@ public static function getLoader() * @param string $file * @return void */ -function composerRequire0a6d5998695b3b88d8c91af1ab91d6ad($fileIdentifier, $file) +function composerRequire9f9955bf8d90b6eb142de17e7c9fca9f($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/drupal/sites/all/modules/civicrm/vendor/composer/autoload_static.php b/drupal/sites/all/modules/civicrm/vendor/composer/autoload_static.php index 252be81cf2..fa4028dd78 100644 --- a/drupal/sites/all/modules/civicrm/vendor/composer/autoload_static.php +++ b/drupal/sites/all/modules/civicrm/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad +class ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f { public static $files = array ( 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', @@ -738,11 +738,11 @@ class ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad::$prefixesPsr0; - $loader->fallbackDirsPsr0 = ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad::$fallbackDirsPsr0; - $loader->classMap = ComposerStaticInit0a6d5998695b3b88d8c91af1ab91d6ad::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f::$prefixesPsr0; + $loader->fallbackDirsPsr0 = ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f::$fallbackDirsPsr0; + $loader->classMap = ComposerStaticInit9f9955bf8d90b6eb142de17e7c9fca9f::$classMap; }, null, ClassLoader::class); } diff --git a/drupal/sites/all/modules/civicrm/vendor/composer/include_paths.php b/drupal/sites/all/modules/civicrm/vendor/composer/include_paths.php index 189ce0e9b6..06cf2843ee 100644 --- a/drupal/sites/all/modules/civicrm/vendor/composer/include_paths.php +++ b/drupal/sites/all/modules/civicrm/vendor/composer/include_paths.php @@ -12,9 +12,9 @@ $vendorDir . '/pear/console_getopt', $vendorDir . '/pear/pear-core-minimal/src', $vendorDir . '/pear/db', - $vendorDir . '/pear/log', $vendorDir . '/pear/mail', $vendorDir . '/pear/mail_mime', + $vendorDir . '/pear/log', $vendorDir . '/pear/net_socket', $vendorDir . '/pear/net_smtp', $vendorDir . '/pear/validate_finance_creditcard', diff --git a/drupal/sites/all/modules/civicrm/vendor/composer/installed.json b/drupal/sites/all/modules/civicrm/vendor/composer/installed.json index d391cf0e34..a193a2405d 100644 --- a/drupal/sites/all/modules/civicrm/vendor/composer/installed.json +++ b/drupal/sites/all/modules/civicrm/vendor/composer/installed.json @@ -644,17 +644,17 @@ }, { "name": "dompdf/dompdf", - "version": "v2.0.2", - "version_normalized": "2.0.2.0", + "version": "v2.0.3", + "version_normalized": "2.0.3.0", "source": { "type": "git", "url": "https://github.com/dompdf/dompdf.git", - "reference": "ad4c631bf8897fc1ca7b566468a969cfd71a558a" + "reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/dompdf/zipball/ad4c631bf8897fc1ca7b566468a969cfd71a558a", - "reference": "ad4c631bf8897fc1ca7b566468a969cfd71a558a", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/e8d2d5e37e8b0b30f0732a011295ab80680d7e85", + "reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85", "shasum": "" }, "require": { @@ -678,7 +678,7 @@ "ext-imagick": "Improves image processing performance", "ext-zlib": "Needed for pdf stream compression" }, - "time": "2023-01-31T13:30:40+00:00", + "time": "2023-02-07T12:51:48+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -703,7 +703,7 @@ "homepage": "https://github.com/dompdf/dompdf", "support": { "issues": "https://github.com/dompdf/dompdf/issues", - "source": "https://github.com/dompdf/dompdf/tree/v2.0.2" + "source": "https://github.com/dompdf/dompdf/tree/v2.0.3" }, "install-path": "../dompdf/dompdf" }, diff --git a/drupal/sites/all/modules/civicrm/vendor/composer/installed.php b/drupal/sites/all/modules/civicrm/vendor/composer/installed.php index fa86928f8c..906722d6a1 100644 --- a/drupal/sites/all/modules/civicrm/vendor/composer/installed.php +++ b/drupal/sites/all/modules/civicrm/vendor/composer/installed.php @@ -5,7 +5,7 @@ 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => 'cd24acea9d5cf85df3b0fe54fc5cadfcf60a8cef', + 'reference' => '755314ae9e46286a587e1138a15b92aaaa0278a1', 'name' => 'civicrm/civicrm-core', 'dev' => true, ), @@ -61,7 +61,7 @@ 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => 'cd24acea9d5cf85df3b0fe54fc5cadfcf60a8cef', + 'reference' => '755314ae9e46286a587e1138a15b92aaaa0278a1', 'dev_requirement' => false, ), 'civicrm/civicrm-cxn-rpc' => array( @@ -119,12 +119,12 @@ 'dev_requirement' => false, ), 'dompdf/dompdf' => array( - 'pretty_version' => 'v2.0.2', - 'version' => '2.0.2.0', + 'pretty_version' => 'v2.0.3', + 'version' => '2.0.3.0', 'type' => 'library', 'install_path' => __DIR__ . '/../dompdf/dompdf', 'aliases' => array(), - 'reference' => 'ad4c631bf8897fc1ca7b566468a969cfd71a558a', + 'reference' => 'e8d2d5e37e8b0b30f0732a011295ab80680d7e85', 'dev_requirement' => false, ), 'ezyang/htmlpurifier' => array( diff --git a/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/VERSION b/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/VERSION index e9307ca575..50ffc5aa7f 100644 --- a/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/VERSION +++ b/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/VERSION @@ -1 +1 @@ -2.0.2 +2.0.3 diff --git a/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/src/Image/Cache.php b/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/src/Image/Cache.php index 6141cb503a..8e36aa2b7c 100644 --- a/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/src/Image/Cache.php +++ b/drupal/sites/all/modules/civicrm/vendor/dompdf/dompdf/src/Image/Cache.php @@ -135,15 +135,19 @@ static function resolve_url($url, $protocol, $host, $base_path, Options $options function ($parser, $name, $attributes) use ($options, $parsed_url, $full_url) { if (strtolower($name) === "image") { $attributes = array_change_key_case($attributes, CASE_LOWER); - $url = $attributes["xlink:href"] ?? $attributes["href"]; - if (!empty($url)) { - $inner_full_url = Helpers::build_url($parsed_url["protocol"], $parsed_url["host"], $parsed_url["path"], $url); - if ($inner_full_url === $full_url) { - throw new ImageException("SVG self-reference is not allowed", E_WARNING); - } - [$resolved_url, $type, $message] = self::resolve_url($url, $parsed_url["protocol"], $parsed_url["host"], $parsed_url["path"], $options); - if (!empty($message)) { - throw new ImageException("This SVG document references a restricted resource. $message", E_WARNING); + $urls = []; + $urls[] = $attributes["xlink:href"] ?? ""; + $urls[] = $attributes["href"] ?? ""; + foreach ($urls as $url) { + if (!empty($url)) { + $inner_full_url = Helpers::build_url($parsed_url["protocol"], $parsed_url["host"], $parsed_url["path"], $url); + if ($inner_full_url === $full_url) { + throw new ImageException("SVG self-reference is not allowed", E_WARNING); + } + [$resolved_url, $type, $message] = self::resolve_url($url, $parsed_url["protocol"], $parsed_url["host"], $parsed_url["path"], $options); + if (!empty($message)) { + throw new ImageException("This SVG document references a restricted resource. $message", E_WARNING); + } } } } @@ -156,6 +160,7 @@ function ($parser, $name, $attributes) use ($options, $parsed_url, $full_url) { xml_parse($parser, $line, false); } fclose($fp); + xml_parse($parser, "", true); } xml_parser_free($parser); } diff --git a/drupal/sites/all/modules/civicrm/xml/version.xml b/drupal/sites/all/modules/civicrm/xml/version.xml index 06550a834c..679fb654b1 100644 --- a/drupal/sites/all/modules/civicrm/xml/version.xml +++ b/drupal/sites/all/modules/civicrm/xml/version.xml @@ -1,4 +1,4 @@ - 5.58.0 + 5.58.1