From 9304f06aef7ff5a6b5ccdb1a136ac0208c33b029 Mon Sep 17 00:00:00 2001
From: Kevin Cristiano <kcristiano@kcristiano.com>
Date: Thu, 5 Aug 2021 08:44:19 -0400
Subject: [PATCH] civicrm release

---
 civicrm.php                                   |  6 +-
 civicrm/CRM/Contact/BAO/GroupContactCache.php | 64 +++++++++++++++----
 civicrm/CRM/Contact/BAO/Query.php             | 10 +--
 .../CRM/Contribute/Form/Task/TaskTrait.php    |  4 +-
 civicrm/CRM/Event/Form/Participant.php        |  2 +-
 civicrm/CRM/Price/BAO/PriceSet.php            |  2 +-
 civicrm/civicrm-version.php                   |  2 +-
 civicrm/ext/afform/admin/info.xml             |  2 +-
 civicrm/ext/afform/core/info.xml              |  2 +-
 civicrm/ext/afform/html/info.xml              |  2 +-
 civicrm/ext/afform/mock/info.xml              |  2 +-
 civicrm/ext/authx/info.xml                    |  2 +-
 .../ext/contributioncancelactions/info.xml    |  2 +-
 civicrm/ext/eventcart/info.xml                |  2 +-
 civicrm/ext/ewaysingle/info.xml               |  2 +-
 civicrm/ext/financialacls/info.xml            |  2 +-
 civicrm/ext/flexmailer/info.xml               |  2 +-
 civicrm/ext/greenwich/info.xml                |  2 +-
 civicrm/ext/oauth-client/info.xml             |  2 +-
 civicrm/ext/payflowpro/info.xml               |  2 +-
 civicrm/ext/recaptcha/info.xml                |  2 +-
 civicrm/ext/recaptcha/recaptcha.php           |  2 +-
 civicrm/ext/recaptcha/xml/Menu/recaptcha.xml  |  2 +
 civicrm/ext/search_kit/info.xml               |  2 +-
 civicrm/ext/sequentialcreditnotes/info.xml    |  2 +-
 civicrm/js/crm.ajax.js                        | 10 ++-
 civicrm/release-notes.md                      |  9 +++
 civicrm/release-notes/5.39.1.md               | 45 +++++++++++++
 civicrm/sql/civicrm_data.mysql                |  2 +-
 civicrm/sql/civicrm_generated.mysql           |  2 +-
 civicrm/vendor/autoload.php                   |  2 +-
 civicrm/vendor/composer/autoload_real.php     | 14 ++--
 civicrm/vendor/composer/autoload_static.php   | 12 ++--
 civicrm/xml/version.xml                       |  2 +-
 34 files changed, 158 insertions(+), 66 deletions(-)
 create mode 100644 civicrm/release-notes/5.39.1.md

diff --git a/civicrm.php b/civicrm.php
index 2041354c74..9f687375c3 100644
--- a/civicrm.php
+++ b/civicrm.php
@@ -2,14 +2,12 @@
 /**
  * Plugin Name: CiviCRM
  * Description: CiviCRM - Growing and Sustaining Relationships
- * Version: 5.39.0
+ * Version: 5.39.1
  * Requires at least: 4.9
  * Requires PHP:      7.2
  * Author: CiviCRM LLC
  * Author URI: https://civicrm.org/
  * Plugin URI: https://docs.civicrm.org/sysadmin/en/latest/install/wordpress/
- * GitHub Plugin URI: tadpolecc/civicrm
- * GitHub Plugin URI: https://github.com/tadpolecc/civicrm.git
  * License: AGPL3
  * Text Domain: civicrm
  * Domain Path: /languages
@@ -56,7 +54,7 @@ if (!defined('ABSPATH')) {
 }
 
 // Set version here: when it changes, will force Javascript & CSS to reload.
-define('CIVICRM_PLUGIN_VERSION', '5.39.0');
+define('CIVICRM_PLUGIN_VERSION', '5.39.1');
 
 // Store reference to this file.
 if (!defined('CIVICRM_PLUGIN_FILE')) {
diff --git a/civicrm/CRM/Contact/BAO/GroupContactCache.php b/civicrm/CRM/Contact/BAO/GroupContactCache.php
index 61c40739f0..537ef19567 100644
--- a/civicrm/CRM/Contact/BAO/GroupContactCache.php
+++ b/civicrm/CRM/Contact/BAO/GroupContactCache.php
@@ -129,6 +129,8 @@ AND (
       $groupIDs = (array) $groupIDs;
     }
 
+    // Treat the default help text in Scheduled Jobs as equivalent to no limit.
+    $limit = (int) $limit;
     $processGroupIDs = self::getGroupsNeedingRefreshing($groupIDs, $limit);
 
     if (!empty($processGroupIDs)) {
@@ -372,14 +374,14 @@ WHERE  id IN ( $groupIDs )
       self::invalidateGroupContactCache($group->id);
     }
 
-    $locks = self::getLocksForRefreshableGroupsTo([$groupID]);
-    foreach ($locks as $groupID => $lock) {
+    $lockedGroups = self::getLocksForRefreshableGroupsTo([$groupID]);
+    foreach ($lockedGroups as $groupID) {
       $groupContactsTempTable = CRM_Utils_SQL_TempTable::build()
         ->setCategory('gccache')
         ->setMemory();
       self::buildGroupContactTempTable([$groupID], $groupContactsTempTable);
       self::updateCacheFromTempTable($groupContactsTempTable, [$groupID]);
-      $lock->release();
+      self::releaseGroupLocks([$groupID]);
     }
   }
 
@@ -399,9 +401,8 @@ WHERE  id IN ( $groupIDs )
     $locks = [];
     $groupIDs = self::getGroupsNeedingRefreshing($groupIDs);
     foreach ($groupIDs as $groupID) {
-      $lock = Civi::lockManager()->acquire("data.core.group.{$groupID}");
-      if ($lock->isAcquired()) {
-        $locks[$groupID] = $lock;
+      if (self::getGroupLock($groupID)) {
+        $locks[] = $groupID;
       }
     }
     return $locks;
@@ -673,9 +674,9 @@ ORDER BY   gc.contact_id, g.children
       $groupContactsTempTable = CRM_Utils_SQL_TempTable::build()
         ->setCategory('gccache')
         ->setMemory();
-      $locks = self::getLocksForRefreshableGroupsTo($smartGroups);
-      if (!empty($locks)) {
-        self::buildGroupContactTempTable(array_keys($locks), $groupContactsTempTable);
+      $lockedGroups = self::getLocksForRefreshableGroupsTo($smartGroups);
+      if (!empty($lockedGroups)) {
+        self::buildGroupContactTempTable($lockedGroups, $groupContactsTempTable);
         // Note in theory we could do this transfer from the temp
         // table to the group_contact_cache table out-of-process - possibly by
         // continuing on after the browser is released (which seems to be
@@ -689,11 +690,8 @@ ORDER BY   gc.contact_id, g.children
         // Also - if we switched to the 'triple union' approach described above
         // we could throw a try-catch around this line since best-effort would
         // be good enough & potentially improve user experience.
-        self::updateCacheFromTempTable($groupContactsTempTable, array_keys($locks));
-
-        foreach ($locks as $lock) {
-          $lock->release();
-        }
+        self::updateCacheFromTempTable($groupContactsTempTable, $lockedGroups);
+        self::releaseGroupLocks($lockedGroups);
       }
 
       $smartGroups = implode(',', $smartGroups);
@@ -872,4 +870,42 @@ AND  civicrm_group_contact.group_id = $groupID ";
     }
   }
 
+  /**
+   * Get a lock, if available, for the given group.
+   *
+   * @param int $groupID
+   *
+   * @return bool
+   * @throws \CRM_Core_Exception
+   */
+  protected static function getGroupLock(int $groupID): bool {
+    $cacheKey = "data.core.group.$groupID";
+    if (isset(Civi::$statics["data.core.group.$groupID"])) {
+      // Loop avoidance for a circular parent-child situation.
+      // This would occur where the parent is a criteria of the child
+      // but needs to resolve the child to resolve itself.
+      // This has a unit test - testGroupWithParentInCriteria
+      return FALSE;
+    }
+    $lock = Civi::lockManager()->acquire($cacheKey);
+    if ($lock->isAcquired()) {
+      Civi::$statics["data.core.group.$groupID"] = $lock;
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Release locks on the groups.
+   *
+   * @param array $groupIDs
+   */
+  protected static function releaseGroupLocks(array $groupIDs): void {
+    foreach ($groupIDs as $groupID) {
+      $lock = Civi::$statics["data.core.group.$groupID"];
+      $lock->release();
+      unset(Civi::$statics["data.core.group.$groupID"]);
+    }
+  }
+
 }
diff --git a/civicrm/CRM/Contact/BAO/Query.php b/civicrm/CRM/Contact/BAO/Query.php
index cdde954b26..24944a78a5 100644
--- a/civicrm/CRM/Contact/BAO/Query.php
+++ b/civicrm/CRM/Contact/BAO/Query.php
@@ -5791,7 +5791,7 @@ INNER JOIN civicrm_relationship displayRelType ON ( displayRelType.contact_id_a
 INNER JOIN $tableName transform_temp ON ( transform_temp.contact_id = displayRelType.contact_id_a OR transform_temp.contact_id = displayRelType.contact_id_b )
 ";
         $qcache['where'] = "
-AND displayRelType.relationship_type_id = {$this->_displayRelationshipType}
+WHERE displayRelType.relationship_type_id = {$this->_displayRelationshipType}
 AND   displayRelType.is_active = 1
 ";
       }
@@ -5812,7 +5812,7 @@ INNER JOIN $tableName transform_temp ON ( transform_temp.contact_id = displayRel
 ";
         }
         $qcache['where'] = "
-AND displayRelType.relationship_type_id = $relType
+WHERE displayRelType.relationship_type_id = $relType
 AND   displayRelType.is_active = 1
 ";
       }
@@ -5836,14 +5836,10 @@ AND   displayRelType.is_active = 1
       else {
         $from .= $qcache['from'];
       }
-      if (!strlen($where)) {
-        $where = " WHERE 1 ";
-      }
-      $where .= $qcache['where'];
+      $where = $qcache['where'];
       if (!empty($this->_tables['civicrm_case'])) {
         // Change the join on CiviCRM case so that it joins on the right contac from the relationship.
         $from = str_replace("ON civicrm_case_contact.contact_id = contact_a.id", "ON civicrm_case_contact.contact_id = transform_temp.contact_id", $from);
-        $where = str_replace("AND civicrm_case_contact.contact_id = contact_a.id", "AND civicrm_case_contact.contact_id = transform_temp.contact_id", $where);
         $where .= " AND displayRelType.case_id = civicrm_case_contact.case_id ";
       }
       if (!empty($this->_permissionFromClause) && !stripos($from, 'aclContactCache')) {
diff --git a/civicrm/CRM/Contribute/Form/Task/TaskTrait.php b/civicrm/CRM/Contribute/Form/Task/TaskTrait.php
index 2534bb0a55..04e64a349b 100644
--- a/civicrm/CRM/Contribute/Form/Task/TaskTrait.php
+++ b/civicrm/CRM/Contribute/Form/Task/TaskTrait.php
@@ -114,7 +114,9 @@ trait CRM_Contribute_Form_Task_TaskTrait {
    * @throws \CRM_Core_Exception
    */
   protected function calculateIDS() {
-    if ($this->controller->get('id')) {
+    // contact search forms use the id property to store the selected uf_group_id
+    // rather than entity (contribution) IDs, so don't use the property in that case
+    if (!$this->controller instanceof CRM_Contact_Controller_Search && $this->controller->get('id')) {
       return explode(',', $this->controller->get('id'));
     }
     $ids = $this->getSelectedIDs($this->getSearchFormValues());
diff --git a/civicrm/CRM/Event/Form/Participant.php b/civicrm/CRM/Event/Form/Participant.php
index 951c2e0536..f928a9dfe4 100644
--- a/civicrm/CRM/Event/Form/Participant.php
+++ b/civicrm/CRM/Event/Form/Participant.php
@@ -1662,7 +1662,7 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment
 
       //retrieve custom information
       $form->_values = [];
-      CRM_Event_Form_Registration::initEventFee($form, $event['id']);
+      CRM_Event_Form_Registration::initEventFee($form, $event['id'], FALSE);
       CRM_Event_Form_Registration_Register::buildAmount($form, TRUE, $form->_discountId);
       $lineItem = [];
       $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
diff --git a/civicrm/CRM/Price/BAO/PriceSet.php b/civicrm/CRM/Price/BAO/PriceSet.php
index 53687d2834..9d30fcbee1 100644
--- a/civicrm/CRM/Price/BAO/PriceSet.php
+++ b/civicrm/CRM/Price/BAO/PriceSet.php
@@ -456,11 +456,11 @@ WHERE     cpf.price_set_id = %1";
     $where = "
 WHERE price_set_id = %1
 AND is_active = 1
-AND ( active_on IS NULL OR active_on <= {$currentTime} )
 ";
     $dateSelect = '';
     if ($doNotIncludeExpiredFields) {
       $dateSelect = "
+AND ( active_on IS NULL OR active_on <= {$currentTime} )
 AND ( expire_on IS NULL OR expire_on >= {$currentTime} )
 ";
     }
diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php
index fbbcc6829e..53b70d8074 100644
--- a/civicrm/civicrm-version.php
+++ b/civicrm/civicrm-version.php
@@ -1,7 +1,7 @@
 <?php
 /** @deprecated */
 function civicrmVersion( ) {
-  return array( 'version'  => '5.39.0',
+  return array( 'version'  => '5.39.1',
                 'cms'      => 'Wordpress',
                 'revision' => '' );
 }
diff --git a/civicrm/ext/afform/admin/info.xml b/civicrm/ext/afform/admin/info.xml
index f86c6a08b7..389826b6dc 100644
--- a/civicrm/ext/afform/admin/info.xml
+++ b/civicrm/ext/afform/admin/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.23</ver>
diff --git a/civicrm/ext/afform/core/info.xml b/civicrm/ext/afform/core/info.xml
index 6e283533b8..ccea548afe 100644
--- a/civicrm/ext/afform/core/info.xml
+++ b/civicrm/ext/afform/core/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.23</ver>
diff --git a/civicrm/ext/afform/html/info.xml b/civicrm/ext/afform/html/info.xml
index e4d975ddf9..b00bf92881 100644
--- a/civicrm/ext/afform/html/info.xml
+++ b/civicrm/ext/afform/html/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.23</ver>
diff --git a/civicrm/ext/afform/mock/info.xml b/civicrm/ext/afform/mock/info.xml
index ffeb562900..c28d7fc9d5 100644
--- a/civicrm/ext/afform/mock/info.xml
+++ b/civicrm/ext/afform/mock/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/authx/info.xml b/civicrm/ext/authx/info.xml
index 9337aed9a4..f763e1fa98 100644
--- a/civicrm/ext/authx/info.xml
+++ b/civicrm/ext/authx/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-02-11</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.0</ver>
diff --git a/civicrm/ext/contributioncancelactions/info.xml b/civicrm/ext/contributioncancelactions/info.xml
index 44b6e9fddd..f8cf312a02 100644
--- a/civicrm/ext/contributioncancelactions/info.xml
+++ b/civicrm/ext/contributioncancelactions/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-10-12</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.32</ver>
diff --git a/civicrm/ext/eventcart/info.xml b/civicrm/ext/eventcart/info.xml
index e459f2d70d..716c1a3de9 100644
--- a/civicrm/ext/eventcart/info.xml
+++ b/civicrm/ext/eventcart/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-08-03</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/ewaysingle/info.xml b/civicrm/ext/ewaysingle/info.xml
index e5facac41a..36b7dc598f 100644
--- a/civicrm/ext/ewaysingle/info.xml
+++ b/civicrm/ext/ewaysingle/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-10-07</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/financialacls/info.xml b/civicrm/ext/financialacls/info.xml
index 27423c8c5e..0b283eee32 100644
--- a/civicrm/ext/financialacls/info.xml
+++ b/civicrm/ext/financialacls/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-08-27</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.30</ver>
diff --git a/civicrm/ext/flexmailer/info.xml b/civicrm/ext/flexmailer/info.xml
index f26a4a5ac8..a27b8289ba 100644
--- a/civicrm/ext/flexmailer/info.xml
+++ b/civicrm/ext/flexmailer/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-08-05</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>stable</develStage>
   <comments>
     FlexMailer is an email delivery engine which replaces the internal guts
diff --git a/civicrm/ext/greenwich/info.xml b/civicrm/ext/greenwich/info.xml
index 6da868e0ab..09fbfbb7a6 100644
--- a/civicrm/ext/greenwich/info.xml
+++ b/civicrm/ext/greenwich/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-07-21</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/oauth-client/info.xml b/civicrm/ext/oauth-client/info.xml
index 8fd908977d..fb8aef6997 100644
--- a/civicrm/ext/oauth-client/info.xml
+++ b/civicrm/ext/oauth-client/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-10-23</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.38</ver>
diff --git a/civicrm/ext/payflowpro/info.xml b/civicrm/ext/payflowpro/info.xml
index 7b23f67ace..f3d4167b01 100644
--- a/civicrm/ext/payflowpro/info.xml
+++ b/civicrm/ext/payflowpro/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-04-13</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.0</ver>
diff --git a/civicrm/ext/recaptcha/info.xml b/civicrm/ext/recaptcha/info.xml
index 8d62bfd02c..d3507d96ed 100644
--- a/civicrm/ext/recaptcha/info.xml
+++ b/civicrm/ext/recaptcha/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-04-03</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/recaptcha/recaptcha.php b/civicrm/ext/recaptcha/recaptcha.php
index 4cf2ea5523..9cad89a71c 100644
--- a/civicrm/ext/recaptcha/recaptcha.php
+++ b/civicrm/ext/recaptcha/recaptcha.php
@@ -127,7 +127,7 @@ function recaptcha_civicrm_entityTypes(&$entityTypes) {
  * Implements hook_civicrm_navigationMenu().
  */
 function recaptcha_civicrm_navigationMenu(&$menu) {
-  _recaptcha_civix_insert_navigation_menu($menu, 'Administer/Customize Data and Screens', [
+  _recaptcha_civix_insert_navigation_menu($menu, 'Administer/System Settings', [
     'label' => E::ts('reCAPTCHA Settings'),
     'name' => 'recaptcha_settings',
     'url' => 'civicrm/admin/setting/recaptcha',
diff --git a/civicrm/ext/recaptcha/xml/Menu/recaptcha.xml b/civicrm/ext/recaptcha/xml/Menu/recaptcha.xml
index 46472f77a8..558cefcf2c 100644
--- a/civicrm/ext/recaptcha/xml/Menu/recaptcha.xml
+++ b/civicrm/ext/recaptcha/xml/Menu/recaptcha.xml
@@ -3,7 +3,9 @@
   <item>
     <path>civicrm/admin/setting/recaptcha</path>
     <title>reCAPTCHA Settings</title>
+    <desc>Configure anti-abuse/bot-prevention service</desc>
     <page_callback>CRM_Admin_Form_Generic</page_callback>
     <access_arguments>administer CiviCRM</access_arguments>
+    <adminGroup>System Settings</adminGroup>
   </item>
 </menu>
diff --git a/civicrm/ext/search_kit/info.xml b/civicrm/ext/search_kit/info.xml
index 0d98947df4..d90ef6eb0c 100644
--- a/civicrm/ext/search_kit/info.xml
+++ b/civicrm/ext/search_kit/info.xml
@@ -14,7 +14,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-01-06</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <develStage>beta</develStage>
   <compatibility>
     <ver>5.38</ver>
diff --git a/civicrm/ext/sequentialcreditnotes/info.xml b/civicrm/ext/sequentialcreditnotes/info.xml
index 718dbd74b3..e2c9daeeb5 100644
--- a/civicrm/ext/sequentialcreditnotes/info.xml
+++ b/civicrm/ext/sequentialcreditnotes/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-28</releaseDate>
-  <version>5.39.0</version>
+  <version>5.39.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/js/crm.ajax.js b/civicrm/js/crm.ajax.js
index 563e57a6df..609e1074a1 100644
--- a/civicrm/js/crm.ajax.js
+++ b/civicrm/js/crm.ajax.js
@@ -22,8 +22,12 @@
       mode = CRM.config && CRM.config.isFrontend ? 'front' : 'back';
     }
     query = query || '';
-    var url,
-      frag = path.split('?');
+    var url, frag, hash = '';
+    if (path.indexOf('#') > -1) {
+      hash = '#' + path.split('#')[1];
+      path = path.split('#')[0];
+    }
+    frag = path.split('?');
     // Encode url path only if slashes in placeholder were also encoded
     if (tplURL[mode].indexOf('civicrm/placeholder-url-path') >= 0) {
       url = tplURL[mode].replace('civicrm/placeholder-url-path', frag[0]);
@@ -39,7 +43,7 @@
     if (frag[1]) {
       url += (url.indexOf('?') < 0 ? '?' : '&') + frag[1];
     }
-    return url;
+    return url + hash;
   };
 
   $.fn.crmURL = function () {
diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md
index 682f61cc3b..b1da3ea7be 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.39.1
+
+Released August 5, 2021
+
+- **[Synopsis](release-notes/5.39.1.md#synopsis)**
+- **[Bugs resolved](release-notes/5.39.1.md#bugs)**
+- **[Credits](release-notes/5.39.1.md#credits)**
+- **[Feedback](release-notes/5.39.1.md#feedback)**
+
 ## CiviCRM 5.39.0
 
 Released July 7, 2021
diff --git a/civicrm/release-notes/5.39.1.md b/civicrm/release-notes/5.39.1.md
new file mode 100644
index 0000000000..eaa6fd1d0c
--- /dev/null
+++ b/civicrm/release-notes/5.39.1.md
@@ -0,0 +1,45 @@
+# CiviCRM 5.39.1
+
+Released August 5, 2021
+
+- **[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?                     | no       |
+| Fix problems installing or upgrading to a previous version?     | no       |
+| Introduce features?                                             | no       |
+| **Fix bugs?**                                                   | **yes**  |
+
+## <a name="bugs"></a>Bugs resolved
+
+* **_ACLs_: Circular group resolution ([dev/core#2725](https://lab.civicrm.org/dev/core/-/issues/2725): [#21012](https://github.com/civicrm/civicrm-core/pull/21012))**
+* **_Advanced Search_: Related contacts are not displayed ([dev/core#2707](https://lab.civicrm.org/dev/core/-/issues/2707): [#21016](https://github.com/civicrm/civicrm-core/pull/21016))**
+* **_CiviContribute_: Search-tasks sometimes receive wrong contribution IDs ([dev/core#2739](https://lab.civicrm.org/dev/core/-/issues/2739): [#21014](https://github.com/civicrm/civicrm-core/pull/21014))**
+* **_CiviEvent_: Always expose price fields on backend ([dev/event#62](https://lab.civicrm.org/dev/event/-/issues/62): [#21028](https://github.com/civicrm/civicrm-core/pull/21028))**
+* **_ReCAPTCHA_: Restore administrative hyperlink ([dev/core#2728](https://lab.civicrm.org/dev/core/-/issues/2728): [#21017](https://github.com/civicrm/civicrm-core/pull/21017))**
+* **_Smart Groups_: Scheduled job fails with error "must be of the type int" ([dev/core#2687](https://lab.civicrm.org/dev/core/-/issues/2687): [#20835](https://github.com/civicrm/civicrm-core/pull/20835))**
+* **_WordPress_: Fix generation of URL fragments ([#21020](https://github.com/civicrm/civicrm-core/pull/21020/))**
+
+## <a name="credits"></a>Credits
+
+This release was developed by the following authors and reviewers:
+
+Wikimedia Foundation - Eileen McNaughton; Tadpole Collective - Kevin Cristiano; Progressive Technology Project - Jamie
+McClelland; pcurrier; Megaphone Technology Consulting - Jon Goldberg; MJW Consulting - Matthew Wire; Lighthouse
+Consulting and Design - Brian Shaughnessy; John Gehrig; JMA Consulting - Seamus Lee; Greenpeace Central and Eastern
+Europe - Patrick Figel; Gahrt; Fuzion - Peter Davis; Francesc Bassas i Bullich; Dave Tarrant; Dave D; CiviCoop - Jaap
+Jansma; CiviCRM - Coleman Watts, Tim Otten; Centrale Organisatie van Voetbal Scheidsrechters (COVS) - Ed van Leeuwen
+
+## <a name="feedback"></a>Feedback
+
+These release notes are edited by Tim Otten and Andrew Hunt.  If you'd like to
+provide feedback on them, please login to https://chat.civicrm.org/civicrm and
+contact `@agh1`.
diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql
index ed14e98a65..20d17b9829 100644
--- a/civicrm/sql/civicrm_data.mysql
+++ b/civicrm/sql/civicrm_data.mysql
@@ -23940,4 +23940,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.39.0';
+UPDATE civicrm_domain SET version = '5.39.1';
diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql
index 921eee62bf..705a6621a9 100644
--- a/civicrm/sql/civicrm_generated.mysql
+++ b/civicrm/sql/civicrm_generated.mysql
@@ -2864,7 +2864,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.39.0',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
+ (1,'Default Domain Name',NULL,'5.39.1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
 /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
 UNLOCK TABLES;
 
diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php
index ab9058ca6a..d6d9c5d7f0 100644
--- a/civicrm/vendor/autoload.php
+++ b/civicrm/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInitf5d7800057351310fcea45738163c661::getLoader();
+return ComposerAutoloaderInit6a70bf22583ef5cfdc10b13376855fe9::getLoader();
diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php
index fe18c134f1..5e49c3a130 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 ComposerAutoloaderInitf5d7800057351310fcea45738163c661
+class ComposerAutoloaderInit6a70bf22583ef5cfdc10b13376855fe9
 {
     private static $loader;
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitf5d7800057351310fcea45738163c661
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInitf5d7800057351310fcea45738163c661', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit6a70bf22583ef5cfdc10b13376855fe9', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInitf5d7800057351310fcea45738163c661', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit6a70bf22583ef5cfdc10b13376855fe9', 'loadClassLoader'));
 
         $includePaths = require __DIR__ . '/include_paths.php';
         $includePaths[] = get_include_path();
@@ -31,7 +31,7 @@ class ComposerAutoloaderInitf5d7800057351310fcea45738163c661
         if ($useStaticLoader) {
             require_once __DIR__ . '/autoload_static.php';
 
-            call_user_func(\Composer\Autoload\ComposerStaticInitf5d7800057351310fcea45738163c661::getInitializer($loader));
+            call_user_func(\Composer\Autoload\ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9::getInitializer($loader));
         } else {
             $map = require __DIR__ . '/autoload_namespaces.php';
             foreach ($map as $namespace => $path) {
@@ -52,19 +52,19 @@ class ComposerAutoloaderInitf5d7800057351310fcea45738163c661
         $loader->register(true);
 
         if ($useStaticLoader) {
-            $includeFiles = Composer\Autoload\ComposerStaticInitf5d7800057351310fcea45738163c661::$files;
+            $includeFiles = Composer\Autoload\ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequiref5d7800057351310fcea45738163c661($fileIdentifier, $file);
+            composerRequire6a70bf22583ef5cfdc10b13376855fe9($fileIdentifier, $file);
         }
 
         return $loader;
     }
 }
 
-function composerRequiref5d7800057351310fcea45738163c661($fileIdentifier, $file)
+function composerRequire6a70bf22583ef5cfdc10b13376855fe9($fileIdentifier, $file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
         require $file;
diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php
index fd24629fc6..8a5fd5adff 100644
--- a/civicrm/vendor/composer/autoload_static.php
+++ b/civicrm/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInitf5d7800057351310fcea45738163c661
+class ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9
 {
     public static $files = array (
         '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
@@ -572,11 +572,11 @@ class ComposerStaticInitf5d7800057351310fcea45738163c661
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInitf5d7800057351310fcea45738163c661::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInitf5d7800057351310fcea45738163c661::$prefixDirsPsr4;
-            $loader->prefixesPsr0 = ComposerStaticInitf5d7800057351310fcea45738163c661::$prefixesPsr0;
-            $loader->fallbackDirsPsr0 = ComposerStaticInitf5d7800057351310fcea45738163c661::$fallbackDirsPsr0;
-            $loader->classMap = ComposerStaticInitf5d7800057351310fcea45738163c661::$classMap;
+            $loader->prefixLengthsPsr4 = ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9::$prefixDirsPsr4;
+            $loader->prefixesPsr0 = ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9::$prefixesPsr0;
+            $loader->fallbackDirsPsr0 = ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9::$fallbackDirsPsr0;
+            $loader->classMap = ComposerStaticInit6a70bf22583ef5cfdc10b13376855fe9::$classMap;
 
         }, null, ClassLoader::class);
     }
diff --git a/civicrm/xml/version.xml b/civicrm/xml/version.xml
index 9acc111112..456e25853d 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.39.0</version_no>
+  <version_no>5.39.1</version_no>
 </version>
-- 
GitLab