Merge pull request #18936 from eileenmcnaughton/ppp
authorMatthew Wire <mjw@mjwconsult.co.uk>
Sun, 8 Nov 2020 14:45:48 +0000 (14:45 +0000)
committerGitHub <noreply@github.com>
Sun, 8 Nov 2020 14:45:48 +0000 (14:45 +0000)
[Ref] Use variables directly

30 files changed:
CRM/Contact/DAO/Group.php
CRM/Core/BAO/CustomField.php
CRM/Core/BAO/SchemaHandler.php
CRM/Core/I18n/SchemaStructure.php
CRM/Logging/Differ.php
CRM/Logging/ReportDetail.php
CRM/Upgrade/Incremental/php/FiveThirtyOne.php
CRM/Upgrade/Incremental/php/FiveThirtyThree.php [new file with mode: 0644]
CRM/Upgrade/Incremental/sql/5.31.beta2.mysql.tpl [new file with mode: 0644]
CRM/Upgrade/Incremental/sql/5.32.beta1.mysql.tpl [new file with mode: 0644]
CRM/Upgrade/Incremental/sql/5.33.alpha1.mysql.tpl [new file with mode: 0644]
Civi/Install/Requirements.php
composer.lock
ext/oauth-client/ang/oauthJwtDebug.aff.html
release-notes.md
release-notes/5.32.0.md [new file with mode: 0644]
setup/plugins/blocks/advanced.tpl.php
setup/plugins/checkRequirements/CoreRequirementsAdapter.civi-setup.php
setup/plugins/init/Backdrop.civi-setup.php
setup/plugins/init/Drupal.civi-setup.php
setup/plugins/init/Drupal8.civi-setup.php
setup/plugins/init/WordPress.civi-setup.php
setup/src/Setup/DbUtil.php
sql/civicrm_generated.mysql
sql/test_data_second_domain.mysql
templates/CRM/Block/FullTextSearch.tpl
templates/CRM/Report/Form/Layout/Overlay.tpl
templates/CRM/Report/Form/Layout/Table.tpl
xml/schema/Contact/Group.xml
xml/version.xml

index ff7e1c8beb51bf0c0a6614e18faa9720bd27be44..b126c0e9fdd09e20655366d0f9562b98b7bf69a5 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Contact/Group.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:49027c63bf6fd142e79220b39f84056d)
+ * (GenCodeChecksum:e40e779ac8e9bec5ea4d6c55f6f3b863)
  */
 
 /**
@@ -273,7 +273,6 @@ class CRM_Contact_DAO_Group extends CRM_Core_DAO {
           'type' => CRM_Utils_Type::T_STRING,
           'title' => ts('Group Title'),
           'description' => ts('Name of Group.'),
-          'required' => TRUE,
           'maxlength' => 255,
           'size' => CRM_Utils_Type::HUGE,
           'where' => 'civicrm_group.title',
index 66a5cf26a275db508f45062b4b2288da43220355..4a0ae0fba333a56b001bbafabf77631b65f20092 100644 (file)
@@ -114,7 +114,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
    * @throws \CiviCRM_API3_Exception
    */
   public static function bulkSave($bulkParams, $defaults = []) {
-    $addedColumns = $sql = $tables = $customFields = [];
+    $addedColumns = $sql = $customFields = [];
     foreach ($bulkParams as $index => $fieldParams) {
       $params = array_merge($defaults, $fieldParams);
       $customField = self::createCustomFieldRecord($params);
@@ -122,17 +122,9 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
       if (!isset($params['custom_group_id'])) {
         $params['custom_group_id'] = civicrm_api3('CustomField', 'getvalue', ['id' => $customField->id, 'return' => 'custom_group_id']);
       }
-      if (!isset($params['table_name'])) {
-        if (!isset($tables[$params['custom_group_id']])) {
-          $tables[$params['custom_group_id']] = civicrm_api3('CustomGroup', 'getvalue', [
-            'id' => $params['custom_group_id'],
-            'return' => 'table_name',
-          ]);
-        }
-        $params['table_name'] = $tables[$params['custom_group_id']];
-      }
-      $sql[$params['table_name']][] = $fieldSQL;
-      $addedColumns[$params['table_name']][] = $customField->name;
+      $tableName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $customField->custom_group_id, 'table_name');
+      $sql[$tableName][] = $fieldSQL;
+      $addedColumns[$tableName][] = $customField->name;
       $customFields[$index] = $customField;
     }
 
@@ -145,7 +137,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         $logging->fixSchemaDifferencesFor($tableName, ['ADD' => $addedColumns[$tableName]]);
       }
 
-      Civi::service('sql_triggers')->rebuild($params['table_name'], TRUE);
+      Civi::service('sql_triggers')->rebuild($tableName, TRUE);
     }
     CRM_Utils_System::flushCache();
     foreach ($customFields as $index => $customField) {
index 154bd55992ad4c7eaf65aa05407baf76f1090eff..cb56200c4b740e846df19fd8325b9e13347e7d91 100644 (file)
@@ -271,43 +271,6 @@ ALTER TABLE {$tableName}
     return $sql;
   }
 
-  /**
-   * @deprecated
-   *
-   * @param array $params
-   * @param bool $indexExist
-   * @param bool $triggerRebuild
-   *
-   * @return bool
-   */
-  public static function alterFieldSQL($params, $indexExist = FALSE, $triggerRebuild = TRUE) {
-    CRM_Core_Error::deprecatedFunctionWarning('function no longer in use / supported');
-    // lets suppress the required flag, since that can cause sql issue
-    $params['required'] = FALSE;
-
-    $sql = self::buildFieldChangeSql($params, $indexExist);
-
-    // CRM-7007: do not i18n-rewrite this query
-    CRM_Core_DAO::executeQuery($sql, [], TRUE, NULL, FALSE, FALSE);
-
-    $config = CRM_Core_Config::singleton();
-    if ($config->logging) {
-      // CRM-16717 not sure why this was originally limited to add.
-      // For example custom tables can have field length changes - which need to flow through to logging.
-      // Are there any modifies we DON'T was to call this function for (& shouldn't it be clever enough to cope?)
-      if ($params['operation'] == 'add' || $params['operation'] == 'modify') {
-        $logging = new CRM_Logging_Schema();
-        $logging->fixSchemaDifferencesFor($params['table_name'], [trim(strtoupper($params['operation'])) => [$params['name']]]);
-      }
-    }
-
-    if ($triggerRebuild) {
-      Civi::service('sql_triggers')->rebuild($params['table_name'], TRUE);
-    }
-
-    return TRUE;
-  }
-
   /**
    * Delete a CiviCRM-table.
    *
index 641d565d23d64bbf27f9d2f33413b3acbd881ad4..03fda988b5ff60b694dc55d571dbc63f302bd177 100644 (file)
@@ -92,7 +92,7 @@ class CRM_Core_I18n_SchemaStructure {
           'description' => "text COMMENT 'Optional description.'",
         ],
         'civicrm_group' => [
-          'title' => "varchar(255) NOT NULL COMMENT 'Name of Group.'",
+          'title' => "varchar(255) COMMENT 'Name of Group.'",
           'frontend_title' => "varchar(255) DEFAULT NULL COMMENT 'Alternative public title for this Group.'",
           'frontend_description' => "text DEFAULT NULL COMMENT 'Alternative public description of the group.'",
         ],
@@ -414,7 +414,6 @@ class CRM_Core_I18n_SchemaStructure {
         'civicrm_group' => [
           'title' => [
             'type' => "Text",
-            'required' => "true",
           ],
           'frontend_title' => [
             'type' => "Text",
index 863322bb2aae8f04b3499783396023da5b6fe5a0..b6040c7bbac6aa531bcb12ae1efd75adec8c0492 100644 (file)
@@ -403,11 +403,20 @@ ORDER BY log_date
    *
    * @param array $tables
    *   Array of tables to inspect.
+   * @param int $limit
+   *   Limit result to x
+   * @param int $offset
+   *   Offset result to y
    *
    * @return array
    */
-  public function getAllChangesForConnection($tables) {
-    $params = [1 => [$this->log_conn_id, 'String']];
+  public function getAllChangesForConnection($tables, $limit = 0, $offset = 0) {
+    $params = [
+      1 => [$this->log_conn_id, 'String'],
+      2 => [$limit, 'Integer'],
+      3 => [$offset, 'Integer'],
+    ];
+
     foreach ($tables as $table) {
       if (empty($sql)) {
         $sql = " SELECT '{$table}' as table_name, id FROM {$this->db}.log_{$table} WHERE log_conn_id = %1";
@@ -416,17 +425,48 @@ ORDER BY log_date
         $sql .= " UNION SELECT '{$table}' as table_name, id FROM {$this->db}.log_{$table} WHERE log_conn_id = %1";
       }
     }
+    if ($limit) {
+      $sql .= " LIMIT %2";
+    }
+    if ($offset) {
+      $sql .= " OFFSET %3";
+    }
     $diffs = [];
     $dao = CRM_Core_DAO::executeQuery($sql, $params);
     while ($dao->fetch()) {
       if (empty($this->log_date)) {
-        $this->log_date = CRM_Core_DAO::singleValueQuery("SELECT log_date FROM {$this->db}.log_{$table} WHERE log_conn_id = %1 LIMIT 1", $params);
+        // look for available table in above query instead of looking for last table. this will avoid multiple loops
+        $this->log_date = CRM_Core_DAO::singleValueQuery("SELECT log_date FROM {$this->db}.log_{$dao->table_name} WHERE log_conn_id = %1 LIMIT 1", $params);
       }
       $diffs = array_merge($diffs, $this->diffsInTableForId($dao->table_name, $dao->id));
     }
     return $diffs;
   }
 
+  /**
+   * Get count of all changes made in the connection.
+   *
+   * @param array $tables
+   *   Array of tables to inspect.
+   *
+   * @return array
+   */
+  public function getCountOfAllContactChangesForConnection($tables) {
+    $count = 0;
+    $params = [1 => [$this->log_conn_id, 'String']];
+    foreach ($tables as $table) {
+      if (empty($sql)) {
+        $sql = " SELECT '{$table}' as table_name, id FROM {$this->db}.log_{$table} WHERE log_conn_id = %1";
+      }
+      else {
+        $sql .= " UNION SELECT '{$table}' as table_name, id FROM {$this->db}.log_{$table} WHERE log_conn_id = %1";
+      }
+    }
+    $countSQL = " SELECT count(*) as countOfContacts FROM ({$sql}) count";
+    $count = CRM_Core_DAO::singleValueQuery($countSQL, $params);
+    return $count;
+  }
+
   /**
    * Check that the log record relates to a unique log id.
    *
index fdbd92216a895882e7e64861f067e6119585fb40..ad16340ec68b273fee25f9e5fb0b502c19077ddc 100644 (file)
@@ -15,6 +15,8 @@
  * @copyright CiviCRM LLC https://civicrm.org/licensing
  */
 class CRM_Logging_ReportDetail extends CRM_Report_Form {
+
+  const ROW_COUNT_LIMIT = 50;
   protected $cid;
 
   /**
@@ -172,6 +174,7 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
 
     // populate $rows with only the differences between $changed and $original (skipping certain columns and NULL ↔ empty changes unless raw requested)
     $skipped = ['id'];
+    $nRows = $rows = [];
     foreach ($this->diffs as $diff) {
       $table = $diff['table'];
       if (empty($metadata[$table])) {
@@ -228,10 +231,31 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
           $to = '';
         }
       }
-
-      $rows[] = ['field' => $field . " (id: {$diff['id']})", 'from' => $from, 'to' => $to];
+      // Rework the results to provide grouping based on the ID
+      // We don't need that field displayed so we will output empty
+      if ($field == 'Modified Date') {
+        $nRows[$diff['id']][] = ['field' => '', 'from' => $from, 'to' => $to];
+      }
+      else {
+        $nRows[$diff['id']][] = ['field' => $field . " (id: {$diff['id']})", 'from' => $from, 'to' => $to];
+      }
     }
+    // Transform the output so that we can compact the changes into the proper amount of rows IF trData is holding more than 1 array
+    foreach ($nRows as $trData) {
+      if (count($trData) > 1) {
+        $keys = array_intersect(...array_map('array_keys', $trData));
+        $mergedRes = array_combine($keys, array_map(function ($key) use ($trData) {
+          // If more than 1 entry is found, we are assigning them as subarrays, then the tpls will be responsible for concatenating the results
+          return array_column($trData, $key);
+        }, $keys));
+        $rows[] = $mergedRes;
+      }
+      else {
+        // We always need the first row of that array
+        $rows[] = $trData[0];
+      }
 
+    }
     return $rows;
   }
 
@@ -266,6 +290,9 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
    * Calculate all the contact related diffs for the change.
    */
   protected function calculateContactDiffs() {
+    $this->_rowsFound = $this->getCountOfAllContactChangesForConnection();
+    // Apply some limits before asking for all contact changes
+    $this->getLimit();
     $this->diffs = $this->getAllContactChangesForConnection();
   }
 
@@ -280,10 +307,28 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
     }
     $this->setDiffer();
     try {
-      return $this->differ->getAllChangesForConnection($this->tables);
+      return $this->differ->getAllChangesForConnection($this->tables, $this->dblimit, $this->dboffset);
+    }
+    catch (CRM_Core_Exception $e) {
+      CRM_Core_Error::statusBounce($e->getMessage());
+    }
+  }
+
+  /**
+   * Get an count of contacts with changes.
+   *
+   * @return mixed
+   */
+  public function getCountOfAllContactChangesForConnection() {
+    if (empty($this->log_conn_id)) {
+      return [];
+    }
+    $this->setDiffer();
+    try {
+      return $this->differ->getCountOfAllContactChangesForConnection($this->tables);
     }
     catch (CRM_Core_Exception $e) {
-      CRM_Core_Error::statusBounce(ts($e->getMessage()));
+      CRM_Core_Error::statusBounce($e->getMessage());
     }
   }
 
@@ -347,6 +392,61 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
     $this->altered_name = CRM_Utils_Request::retrieve('alteredName', 'String');
     $this->altered_by = CRM_Utils_Request::retrieve('alteredBy', 'String');
     $this->altered_by_id = CRM_Utils_Request::retrieve('alteredById', 'Integer');
+    $this->layout = CRM_Utils_Request::retrieve('layout', 'String');
+  }
+
+  /**
+   * Override to set limit
+   * @param int $rowCount
+   */
+  public function limit($rowCount = self::ROW_COUNT_LIMIT) {
+    parent::limit($rowCount);
+  }
+
+  /**
+   * Override to set pager with limit
+   * @param int $rowCount
+   */
+  public function setPager($rowCount = self::ROW_COUNT_LIMIT) {
+    // We should not be rendering the pager in overlay mode
+    if (!isset($this->layout)) {
+      $this->_dashBoardRowCount = $rowCount;
+      $this->_limit = TRUE;
+      parent::setPager($rowCount);
+    }
+  }
+
+  /**
+   * This is a function similar to limit, in fact we copied it as-is and removed
+   * some `set` statements
+   *
+   */
+  public function getLimit($rowCount = self::ROW_COUNT_LIMIT) {
+    if ($this->addPaging) {
+
+      $pageId = CRM_Utils_Request::retrieve('crmPID', 'Integer');
+
+      // @todo all http vars should be extracted in the preProcess
+      // - not randomly in the class
+      if (!$pageId && !empty($_POST)) {
+        if (isset($_POST['PagerBottomButton']) && isset($_POST['crmPID_B'])) {
+          $pageId = max((int) $_POST['crmPID_B'], 1);
+        }
+        elseif (isset($_POST['PagerTopButton']) && isset($_POST['crmPID'])) {
+          $pageId = max((int) $_POST['crmPID'], 1);
+        }
+        unset($_POST['crmPID_B'], $_POST['crmPID']);
+      }
+
+      $pageId = $pageId ? $pageId : 1;
+      $offset = ($pageId - 1) * $rowCount;
+
+      $offset = CRM_Utils_Type::escape($offset, 'Int');
+      $rowCount = CRM_Utils_Type::escape($rowCount, 'Int');
+      $this->_limit = " LIMIT $offset, $rowCount";
+      $this->dblimit = $rowCount;
+      $this->dboffset = $offset;
+    }
   }
 
 }
index 105161699a2f06f75f171e0c5ac3c88414318c89..42b905011c0dc34ab97c21dfdce1ae4d22da57d4 100644 (file)
@@ -71,6 +71,11 @@ class CRM_Upgrade_Incremental_php_FiveThirtyOne extends CRM_Upgrade_Incremental_
       'civicrm_mail_settings', 'is_contact_creation_disabled_if_no_match', "TINYINT DEFAULT 0 NOT NULL COMMENT 'If this option is enabled, CiviCRM will not create new contacts when filing emails'");
   }
 
+  public function upgrade_5_31_beta2($rev) {
+    $this->addTask('Restore null-ity of "civicrm_group.title" field', 'groupTitleRestore');
+    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+  }
+
   public static function enableEwaySingleExtension(CRM_Queue_TaskContext $ctx) {
     $eWAYPaymentProcessorType = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_payment_processor_type WHERE class_name = 'Payment_eWAY'");
     if ($eWAYPaymentProcessorType) {
@@ -164,4 +169,28 @@ class CRM_Upgrade_Incremental_php_FiveThirtyOne extends CRM_Upgrade_Incremental_
     return TRUE;
   }
 
+  /**
+   * The prior task grouptitlefieldExpand went a bit too far in making the `title` NOT NULL.
+   *
+   * @link https://lab.civicrm.org/dev/translation/-/issues/58
+   * @param \CRM_Queue_TaskContext $ctx
+   * @return bool
+   */
+  public static function groupTitleRestore(CRM_Queue_TaskContext $ctx) {
+    $locales = CRM_Core_I18n::getMultilingual();
+    $queries = [];
+    if ($locales) {
+      foreach ($locales as $locale) {
+        $queries[] = "ALTER TABLE civicrm_group CHANGE `title_{$locale}` `title_{$locale}` varchar(255) DEFAULT NULL COMMENT 'Name of Group.'";
+      }
+    }
+    else {
+      $queries[] = "ALTER TABLE civicrm_group CHANGE `title` `title` varchar(255) DEFAULT NULL COMMENT 'Name of Group.'";
+    }
+    foreach ($queries as $query) {
+      CRM_Core_DAO::executeQuery($query, [], TRUE, NULL, FALSE, FALSE);
+    }
+    return TRUE;
+  }
+
 }
diff --git a/CRM/Upgrade/Incremental/php/FiveThirtyThree.php b/CRM/Upgrade/Incremental/php/FiveThirtyThree.php
new file mode 100644 (file)
index 0000000..f7bc1ab
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved.                        |
+ |                                                                    |
+ | This work is published under the GNU AGPLv3 license with some      |
+ | permitted exceptions and without any warranty. For full license    |
+ | and copyright information, see https://civicrm.org/licensing       |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * Upgrade logic for FiveThirtyThree */
+class CRM_Upgrade_Incremental_php_FiveThirtyThree extends CRM_Upgrade_Incremental_Base {
+
+  /**
+   * Compute any messages which should be displayed beforeupgrade.
+   *
+   * Note: This function is called iteratively for each upcoming
+   * revision to the database.
+   *
+   * @param string $preUpgradeMessage
+   * @param string $rev
+   *   a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
+   * @param null $currentVer
+   */
+  public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
+    // Example: Generate a pre-upgrade message.
+    // if ($rev == '5.12.34') {
+    //   $preUpgradeMessage .= '<p>' . ts('A new permission, "%1", has been added. This permission is now used to control access to the Manage Tags screen.', array(1 => ts('manage tags'))) . '</p>';
+    // }
+  }
+
+  /**
+   * Compute any messages which should be displayed after upgrade.
+   *
+   * @param string $postUpgradeMessage
+   *   alterable.
+   * @param string $rev
+   *   an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
+   */
+  public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
+    // Example: Generate a post-upgrade message.
+    // if ($rev == '5.12.34') {
+    //   $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'.");
+    // }
+  }
+
+  /*
+   * Important! All upgrade functions MUST add a 'runSql' task.
+   * Uncomment and use the following template for a new upgrade version
+   * (change the x in the function name):
+   */
+
+  //  /**
+  //   * Upgrade function.
+  //   *
+  //   * @param string $rev
+  //   */
+  //  public function upgrade_5_0_x($rev) {
+  //    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+  //    $this->addTask('Do the foo change', 'taskFoo', ...);
+  //    // Additional tasks here...
+  //    // Note: do not use ts() in the addTask description because it adds unnecessary strings to transifex.
+  //    // The above is an exception because 'Upgrade DB to %1: SQL' is generic & reusable.
+  //  }
+
+  // public static function taskFoo(CRM_Queue_TaskContext $ctx, ...) {
+  //   return TRUE;
+  // }
+
+}
diff --git a/CRM/Upgrade/Incremental/sql/5.31.beta2.mysql.tpl b/CRM/Upgrade/Incremental/sql/5.31.beta2.mysql.tpl
new file mode 100644 (file)
index 0000000..33384db
--- /dev/null
@@ -0,0 +1 @@
+{* file to handle db changes in 5.31.beta2 during upgrade *}
diff --git a/CRM/Upgrade/Incremental/sql/5.32.beta1.mysql.tpl b/CRM/Upgrade/Incremental/sql/5.32.beta1.mysql.tpl
new file mode 100644 (file)
index 0000000..e2257e2
--- /dev/null
@@ -0,0 +1 @@
+{* file to handle db changes in 5.32.beta1 during upgrade *}
diff --git a/CRM/Upgrade/Incremental/sql/5.33.alpha1.mysql.tpl b/CRM/Upgrade/Incremental/sql/5.33.alpha1.mysql.tpl
new file mode 100644 (file)
index 0000000..483b660
--- /dev/null
@@ -0,0 +1 @@
+{* file to handle db changes in 5.33.alpha1 during upgrade *}
index 7d30855076b79c0380a1d6746f7deece5ce0e2b0..813b2f6f19391bc9296f0c79276bccba02877f24 100644 (file)
@@ -133,7 +133,7 @@ class Requirements {
       $host = $db_config['server'];
     }
     if (empty($db_config['ssl_params'])) {
-      $conn = @mysqli_connect($host, $db_config['username'], $db_config['password'], $db_config['database'], !empty($db_config['port']) ? $db_config['port'] : NULL);
+      $conn = @mysqli_connect($host, $db_config['username'], $db_config['password'], $db_config['database'], !empty($db_config['port']) ? $db_config['port'] : NULL, $db_config['socket'] ?? NULL);
     }
     else {
       $conn = NULL;
@@ -146,7 +146,7 @@ class Requirements {
         $db_config['ssl_params']['capath'] ?? NULL,
         $db_config['ssl_params']['cipher'] ?? NULL
       );
-      if (@mysqli_real_connect($init, $host, $db_config['username'], $db_config['password'], $db_config['database'], (!empty($db_config['port']) ? $db_config['port'] : NULL), NULL, MYSQLI_CLIENT_SSL)) {
+      if (@mysqli_real_connect($init, $host, $db_config['username'], $db_config['password'], $db_config['database'], (!empty($db_config['port']) ? $db_config['port'] : NULL), $db_config['socket'] ?? NULL, MYSQLI_CLIENT_SSL)) {
         $conn = $init;
       }
     }
index 6175675441323343db702a50cbda9c2b1730e25b..8a7b77d823597dfe3b658ceacbf0b97396d17885 100644 (file)
                 }
             ],
             "description": "Composer plugin for downloading additional files within any composer package.",
-            "time": "2020-11-02T05:26:23+00:00"
+            "time": "2020-11-02T04:00:42+00:00"
         },
         {
             "name": "cweagans/composer-patches",
-            "version": "1.6.5",
+            "version": "1.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/cweagans/composer-patches.git",
-                "reference": "2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3"
+                "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3",
-                "reference": "2ec4f00ff5fb64de584c8c4aea53bf9053ecb0b3",
+                "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/ae02121445ad75f4eaff800cc532b5e6233e2ddf",
+                "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf",
                 "shasum": ""
             },
             "require": {
-                "composer-plugin-api": "^1.0",
+                "composer-plugin-api": "^1.0 || ^2.0",
                 "php": ">=5.3.0"
             },
             "require-dev": {
-                "composer/composer": "~1.0",
+                "composer/composer": "~1.0 || ~2.0",
                 "phpunit/phpunit": "~4.6"
             },
             "type": "composer-plugin",
                 }
             ],
             "description": "Provides a way to patch Composer packages.",
-            "time": "2018-05-11T18:00:16+00:00"
+            "time": "2020-09-30T17:56:20+00:00"
         },
         {
             "name": "dflydev/apache-mime-types",
             ],
             "description": "Symfony Config Component",
             "homepage": "https://symfony.com",
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-04-12T14:33:46+00:00"
         },
         {
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com",
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-04-13T09:33:40+00:00"
         },
         {
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-03-15T09:38:08+00:00"
         },
         {
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-04-12T16:54:01+00:00"
         },
         {
                 "polyfill",
                 "portable"
             ],
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-05-12T16:14:59+00:00"
         },
         {
                 "portable",
                 "shim"
             ],
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-05-12T16:47:27+00:00"
         },
         {
                 "portable",
                 "shim"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-12T16:47:27+00:00"
         },
         {
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-04-12T14:33:46+00:00"
         },
         {
index bafa5dd7257d8973397fb925adc3965f20464e3e..5096a2489182e57d22233bb68265a4470599df22 100644 (file)
@@ -5,29 +5,27 @@
 
   <p>Some (but not all) OAuth2 tokens are based on <a href="https://en.wikipedia.org/wiki/JSON_Web_Token">JWT</a>. If a token is based on JWT, then we can examine its content to learn more about what the token signifies. This may help with debugging token-access issues.</p>
 
-  <h3>Token ID</h3>
+  <div af-api4-ctrl="tokens" af-api4="['OAuthSysToken', 'get', {'where': [['id', '=', routeParams.id]]}]"></div>
 
-  <input ng-model="routeParams.id" type="text"/>
-
-  <div class="btn-group">
-    <a class="btn btn-default"
-       af-api4-action="['OAuthSysToken', 'get', {where: [['id', '=', data.tokenId]]}]"
-       af-api4-start-msg="ts('Fetching...')"
-       af-api4-success-msg="ts('Fetched')"
-       af-api4-success="data.token = response"
-    >{{ts('Inspect')}}</a>
+  <div ng-if="tokens.result.length == 0">
+    No tokens found.
   </div>
 
+  <div ng-repeat="token in tokens.result">
+
+    <h3>Token Record</h3>
 
-  <div ng-if="!!data.token">
+    <pre>{{token|json}}</pre>
 
     <h3>Access Token: Raw</h3>
 
-    <pre>{{data.token[0].access_token}}</pre>
+    <pre>{{token.access_token}}</pre>
 
     <h3>Access Token: JWT Payload</h3>
 
-    <pre>{{data.token[0].access_token|unvalidatedJwtDecode|json}}</pre>
+    (This will only display meaningful data if the token is based on JWT.)
+
+    <pre>{{token.access_token|unvalidatedJwtDecode|json}}</pre>
 
   </div>
 
index 627d65ab053ebf558221f5ba2d21788977835a21..1d4f602400aea8ae0a8e15e0a1b1394dfe01c943 100644 (file)
@@ -15,6 +15,17 @@ Other resources for identifying changes are:
     * https://github.com/civicrm/civicrm-joomla
     * https://github.com/civicrm/civicrm-wordpress
 
+## CiviCRM 5.32.0
+
+Released December 2, 2020
+
+- **[Synopsis](release-notes/5.32.0.md#synopsis)**
+- **[Features](release-notes/5.32.0.md#features)**
+- **[Bugs resolved](release-notes/5.32.0.md#bugs)**
+- **[Miscellany](release-notes/5.32.0.md#misc)**
+- **[Credits](release-notes/5.32.0.md#credits)**
+- **[Feedback](release-notes/5.32.0.md#feedback)**
+
 ## CiviCRM 5.31.0
 
 Released November 4, 2020
diff --git a/release-notes/5.32.0.md b/release-notes/5.32.0.md
new file mode 100644 (file)
index 0000000..2acf716
--- /dev/null
@@ -0,0 +1,369 @@
+# CiviCRM 5.32.0
+
+Released December 2, 2020
+
+- **[Synopsis](#synopsis)**
+- **[Features](#features)**
+- **[Bugs resolved](#bugs)**
+- **[Miscellany](#misc)**
+- **[Credits](#credits)**
+- **[Feedback](#feedback)**
+
+## <a name="synopsis"></a>Synopsis
+
+| *Does this version...?*                                         |         |
+|:--------------------------------------------------------------- |:-------:|
+| Fix security vulnerabilities?                                   |         |
+| Change the database schema?                                     |         |
+| Alter the API?                                                  |         |
+| Require attention to configuration options?                     |         |
+| Fix problems installing or upgrading to a previous version?     |         |
+| Introduce features?                                             |         |
+| Fix bugs?                                                       |         |
+
+## <a name="features"></a>Features
+
+### Core CiviCRM
+
+- **crm- Missing Summary ([18913](https://github.com/civicrm/civicrm-core/pull/18913))**
+
+- **CRM-5048 Missing Summary ([18859](https://github.com/civicrm/civicrm-core/pull/18859))**
+
+- **CRM-9362 Missing Summary ([18411](https://github.com/civicrm/civicrm-core/pull/18411))**
+
+- **CRM- Missing Summary ([115](https://github.com/civicrm/civicrm-backdrop/pull/115))**
+
+## <a name="bugs"></a>Bugs resolved
+
+### Core CiviCRM
+
+- **get log date from tables available in query with data instead of last table ([18868](https://github.com/civicrm/civicrm-core/pull/18868))**
+
+- **Adds performance improvement when browsing the report logs ([18851](https://github.com/civicrm/civicrm-core/pull/18851))**
+
+- **Schema handler fixes ([18932](https://github.com/civicrm/civicrm-core/pull/18932))**
+
+- **5.31.0 - Set version. Update notes. ([18933](https://github.com/civicrm/civicrm-core/pull/18933))**
+
+- **5.31 ([18931](https://github.com/civicrm/civicrm-core/pull/18931))**
+
+- **closes financial/#156: Set contribution status to refunded even if cancelled_payment_id is set ([18930](https://github.com/civicrm/civicrm-core/pull/18930))**
+
+- **dev/core#2166 - E_NOTICE when deleting mail account ([18927](https://github.com/civicrm/civicrm-core/pull/18927))**
+
+- **dev/mail#2141 - MailSettings - Add button+API for testing a connection ([18911](https://github.com/civicrm/civicrm-core/pull/18911))**
+
+- **5.31 to master ([18923](https://github.com/civicrm/civicrm-core/pull/18923))**
+
+- **Add UI metadata for payment_processor_id on financialTrxn ([18917](https://github.com/civicrm/civicrm-core/pull/18917))**
+
+- **dev/core#2139 fix defaulting for multi-select custom fields ([18907](https://github.com/civicrm/civicrm-core/pull/18907))**
+
+- **Search ext: Fix validation and saving on search admin screen ([18919](https://github.com/civicrm/civicrm-core/pull/18919))**
+
+- **dev/core#2141 - Add "oauth-client" extension (hidden) ([18914](https://github.com/civicrm/civicrm-core/pull/18914))**
+
+- **dev/core#2148 - Incorrect use of ts, quotes, escape in log call ([18864](https://github.com/civicrm/civicrm-core/pull/18864))**
+
+- **Use standard names for entity paths and add a few more paths ([18915](https://github.com/civicrm/civicrm-core/pull/18915))**
+
+- **CRM_Core_Error::formatFooException - Don't bomb on 'Error' ([18910](https://github.com/civicrm/civicrm-core/pull/18910))**
+
+- **Search ext: Add links to search admin and improve links in displays ([18909](https://github.com/civicrm/civicrm-core/pull/18909))**
+
+- **dev/core#2141 - composer.json - Require league/oauth2-{client,google}  ([18908](https://github.com/civicrm/civicrm-core/pull/18908))**
+
+- **5.31 ([18904](https://github.com/civicrm/civicrm-core/pull/18904))**
+
+- **dev/core#2043 Remove instance of pass-by-ref ([18802](https://github.com/civicrm/civicrm-core/pull/18802))**
+
+- **Move call to update related pledges on contribution cancel to extension ([18894](https://github.com/civicrm/civicrm-core/pull/18894))**
+
+- **Remove IPN reference to _relatedObjects, deprecate property ([18895](https://github.com/civicrm/civicrm-core/pull/18895))**
+
+- **[Ref] Simplify params ([18896](https://github.com/civicrm/civicrm-core/pull/18896))**
+
+- **[REF] Simplify use of shared code. ([18900](https://github.com/civicrm/civicrm-core/pull/18900))**
+
+- **Remove deprecated code ([18903](https://github.com/civicrm/civicrm-core/pull/18903))**
+
+- **Add postProcess hook to MessageTemplates ([18807](https://github.com/civicrm/civicrm-core/pull/18807))**
+
+- **[REF] Remove silly if ([18897](https://github.com/civicrm/civicrm-core/pull/18897))**
+
+- **dev/core#2141 - Add hook_civicrm_alterMailStore ([18902](https://github.com/civicrm/civicrm-core/pull/18902))**
+
+- **[Ref] Move sending the email back out of the recur function ([18852](https://github.com/civicrm/civicrm-core/pull/18852))**
+
+- **5.31 to master ([18893](https://github.com/civicrm/civicrm-core/pull/18893))**
+
+- **dev/core#927 Move handling of participant.cancel from BaseIPN to  contributioncancelactions ([18881](https://github.com/civicrm/civicrm-core/pull/18881))**
+
+- **[Ref] Use direct version of participant id ([18882](https://github.com/civicrm/civicrm-core/pull/18882))**
+
+- **Hack away at false negative test fails ([18892](https://github.com/civicrm/civicrm-core/pull/18892))**
+
+- **5.31 ([18891](https://github.com/civicrm/civicrm-core/pull/18891))**
+
+- **Add entity paths to schema & APIv4 ([18887](https://github.com/civicrm/civicrm-core/pull/18887))**
+
+- **Lotsa new features for the Search Kit extension ([18876](https://github.com/civicrm/civicrm-core/pull/18876))**
+
+- **Deprecate hook_civicrm_crudLink ([18888](https://github.com/civicrm/civicrm-core/pull/18888))**
+
+- **dev/core#2141 - "Add Mail Account" - Allow hookable listing of setup links ([18885](https://github.com/civicrm/civicrm-core/pull/18885))**
+
+- **(NFC) Fix typo in Money valueFormat depretation warning ([18886](https://github.com/civicrm/civicrm-core/pull/18886))**
+
+- **/dev/core#2152: Merge contacts keep case roles ([18884](https://github.com/civicrm/civicrm-core/pull/18884))**
+
+- **Remove always-true & otherwise silly if ([18883](https://github.com/civicrm/civicrm-core/pull/18883))**
+
+- **Fix extension generated DAO files to pass civilint ([18879](https://github.com/civicrm/civicrm-core/pull/18879))**
+
+- **Merge branch 5.31 into master ([18875](https://github.com/civicrm/civicrm-core/pull/18875))**
+
+- **Participant Calculate/Fees: fix ts usage, simplify wording ([18874](https://github.com/civicrm/civicrm-core/pull/18874))**
+
+- **dev/core#1879 Fix inconsistent ability to view event information ([18712](https://github.com/civicrm/civicrm-core/pull/18712))**
+
+- **Show only Active SMS provider List on Mass SMS form ([18867](https://github.com/civicrm/civicrm-core/pull/18867))**
+
+- **dev/core#2150 Re-enact the recapture validation by validating the res… ([18872](https://github.com/civicrm/civicrm-core/pull/18872))**
+
+- **APIv4 - Add `$result->single()` helper ([18871](https://github.com/civicrm/civicrm-core/pull/18871))**
+
+- **ClassLoader - Fix autoloading of `API_Exception` ([18870](https://github.com/civicrm/civicrm-core/pull/18870))**
+
+- **Refactor entityParams in Order.Create API so it is easier to understand/modify ([18306](https://github.com/civicrm/civicrm-core/pull/18306))**
+
+- **(core/dev#2104) Add gender column for target contact to activity report ([18840](https://github.com/civicrm/civicrm-core/pull/18840))**
+
+- **dev/core#927 Move cancelling of related memberships to extension from BaseIPN ([18853](https://github.com/civicrm/civicrm-core/pull/18853))**
+
+- **Move filtering of unpermitted options for reports/ search select to financialacl extension ([18849](https://github.com/civicrm/civicrm-core/pull/18849))**
+
+- **dev/core#2146 - Long unicode contact names get truncated badly causing a crash ([18862](https://github.com/civicrm/civicrm-core/pull/18862))**
+
+- **APIv4 - Fix type coersion of non-string input ([18860](https://github.com/civicrm/civicrm-core/pull/18860))**
+
+- **Remove meaningless legacy code ([18856](https://github.com/civicrm/civicrm-core/pull/18856))**
+
+- **5.31 ([18861](https://github.com/civicrm/civicrm-core/pull/18861))**
+
+- **Fix campaign_id handling for batch entry ([18792](https://github.com/civicrm/civicrm-core/pull/18792))**
+
+- **Set id after save for the mailing component in the postProcess ([18808](https://github.com/civicrm/civicrm-core/pull/18808))**
+
+- **Move CRM_Member_BAO_MembershipType::getPermissionedMembershipTypes to financial acl extension ([18848](https://github.com/civicrm/civicrm-core/pull/18848))**
+
+- **backdrop#116 Override sessionStart function and use backdrop function… ([18745](https://github.com/civicrm/civicrm-core/pull/18745))**
+
+- **Get phone_type by name. dev/core#2138 ([18842](https://github.com/civicrm/civicrm-core/pull/18842))**
+
+- **dev/user-interface#34 Replace <th> with <td> on ContributionPage configuration Amount tab ([18850](https://github.com/civicrm/civicrm-core/pull/18850))**
+
+- **dev/financial#152 [REF] Clean up interaction with contribution recur object ([18835](https://github.com/civicrm/civicrm-core/pull/18835))**
+
+- **dev/core#927 preliminary cleanup ([18813](https://github.com/civicrm/civicrm-core/pull/18813))**
+
+- **dev/core#2029 exclude ornery test ([18846](https://github.com/civicrm/civicrm-core/pull/18846))**
+
+- **[REF] Determine values where they are needed rather than passing them  around (in tested function) ([18837](https://github.com/civicrm/civicrm-core/pull/18837))**
+
+- **5.31 to master ([18847](https://github.com/civicrm/civicrm-core/pull/18847))**
+
+- **dev/core#2140 Fix site path for Drupal 8 and 9 ([18843](https://github.com/civicrm/civicrm-core/pull/18843))**
+
+- **5.31 ([18839](https://github.com/civicrm/civicrm-core/pull/18839))**
+
+- **5.31 ([18836](https://github.com/civicrm/civicrm-core/pull/18836))**
+
+- **[REF] Minor extraction ([18829](https://github.com/civicrm/civicrm-core/pull/18829))**
+
+- **Remove a few lines of deprecated code ([18826](https://github.com/civicrm/civicrm-core/pull/18826))**
+
+- **(core/dev#2104) Add birth date column for target contact to activity … ([18827](https://github.com/civicrm/civicrm-core/pull/18827))**
+
+- **[REF] Include contributioncancelactions extension in dismaker and reg… ([18825](https://github.com/civicrm/civicrm-core/pull/18825))**
+
+- **dev/core#927 Remove code to update recur on cancel & fail where there is no recur ([18814](https://github.com/civicrm/civicrm-core/pull/18814))**
+
+- **[REF] Extract handling for loading contribution recur object. ([18746](https://github.com/civicrm/civicrm-core/pull/18746))**
+
+- **5.31 ([18818](https://github.com/civicrm/civicrm-core/pull/18818))**
+
+- **(NFC) dev/core#2029 - Make assertions in PrevNextTest more skimmable ([18822](https://github.com/civicrm/civicrm-core/pull/18822))**
+
+- **dev/core#2115 Move some more financialacl code to a hook within the extension ([18740](https://github.com/civicrm/civicrm-core/pull/18740))**
+
+- **dev/financial#152 move code only relevant to repeattransaction into that function ([18815](https://github.com/civicrm/civicrm-core/pull/18815))**
+
+- **dev/core#927 Enable contribution cancel actions extension ([18812](https://github.com/civicrm/civicrm-core/pull/18812))**
+
+- **Rationalise date formatting ([18805](https://github.com/civicrm/civicrm-core/pull/18805))**
+
+- **SavedSearch: add UI_name index to upgrade script ([18811](https://github.com/civicrm/civicrm-core/pull/18811))**
+
+- **dev/core#927 add first test on cancel  ([18786](https://github.com/civicrm/civicrm-core/pull/18786))**
+
+- **Update CRM_Utils_Constant::value to support env variables ([18806](https://github.com/civicrm/civicrm-core/pull/18806))**
+
+- **Declare support for cancelRecurring in manual processor ([18804](https://github.com/civicrm/civicrm-core/pull/18804))**
+
+- **Remove always-true IF ([18803](https://github.com/civicrm/civicrm-core/pull/18803))**
+
+- **dev/core#927 Add shell extension to move contribution cancel actions into ([18784](https://github.com/civicrm/civicrm-core/pull/18784))**
+
+- **SavedSearch - Add name and label columns ([18809](https://github.com/civicrm/civicrm-core/pull/18809))**
+
+- **Display public title and description on profiles and unsubscribe/subs… ([18645](https://github.com/civicrm/civicrm-core/pull/18645))**
+
+- **Remove always true if ([18801](https://github.com/civicrm/civicrm-core/pull/18801))**
+
+- **Add test for recurring links and clean up method of retrieving recurring ([18790](https://github.com/civicrm/civicrm-core/pull/18790))**
+
+- **Replace BAO calls with api calls in test class ([18798](https://github.com/civicrm/civicrm-core/pull/18798))**
+
+- **Switch to calling api ([18797](https://github.com/civicrm/civicrm-core/pull/18797))**
+
+- **Switch to calling the api ([18796](https://github.com/civicrm/civicrm-core/pull/18796))**
+
+- **unit test for #18306 - order create api test for contribution ([18785](https://github.com/civicrm/civicrm-core/pull/18785))**
+
+- **Fix sendconfirmation api to override receipt params ([18789](https://github.com/civicrm/civicrm-core/pull/18789))**
+
+- **[Test] - Fix some tests to call API not BAO ([18795](https://github.com/civicrm/civicrm-core/pull/18795))**
+
+- **Remove instances of variable variables ([18791](https://github.com/civicrm/civicrm-core/pull/18791))**
+
+- **[Ref] Minor code extraction ([18739](https://github.com/civicrm/civicrm-core/pull/18739))**
+
+- **5.31 ([18788](https://github.com/civicrm/civicrm-core/pull/18788))**
+
+- **dev/core#2034 Fix paypal standard cancel url ([18540](https://github.com/civicrm/civicrm-core/pull/18540))**
+
+- **dev/core#2066 Use shared function to set the next url ([18773](https://github.com/civicrm/civicrm-core/pull/18773))**
+
+- **dev/core#2066 Further cleanup on search actions ([18783](https://github.com/civicrm/civicrm-core/pull/18783))**
+
+- **Contribution confirmation page should not display the name of payment processor type ([17568](https://github.com/civicrm/civicrm-core/pull/17568))**
+
+- **Fix pluralize function for words like 'display' ([18778](https://github.com/civicrm/civicrm-core/pull/18778))**
+
+- **5.31 ([18777](https://github.com/civicrm/civicrm-core/pull/18777))**
+
+- **[REF] Search ext: Reorganize code into modules ([18775](https://github.com/civicrm/civicrm-core/pull/18775))**
+
+- **class.api.php: In remote api calls, allow referer and useragent to be set. ([18400](https://github.com/civicrm/civicrm-core/pull/18400))**
+
+- **5.31 to master ([18774](https://github.com/civicrm/civicrm-core/pull/18774))**
+
+- **Test for event#43 ([18761](https://github.com/civicrm/civicrm-core/pull/18761))**
+
+- **5.31 ([18770](https://github.com/civicrm/civicrm-core/pull/18770))**
+
+- **dev/core#2066 Extract getSelectedIDs ([18768](https://github.com/civicrm/civicrm-core/pull/18768))**
+
+- **dev/core#2066 Use shared function to set the next url ([18767](https://github.com/civicrm/civicrm-core/pull/18767))**
+
+- **Allow custom fields of type Autocomplete-Select to be multivalued ([18449](https://github.com/civicrm/civicrm-core/pull/18449))**
+
+- **5.31 ([18764](https://github.com/civicrm/civicrm-core/pull/18764))**
+
+- **dev/drupal#137 - Alternate PR - On drupal status report need different check when civi is already installed ([18581](https://github.com/civicrm/civicrm-core/pull/18581))**
+
+- **Typo in call to fixSchemaDifferencesForAll ([18762](https://github.com/civicrm/civicrm-core/pull/18762))**
+
+- **5.31 ([18757](https://github.com/civicrm/civicrm-core/pull/18757))**
+
+- **Angular Loader: Allow modules to specify permissions to add client-side ([18754](https://github.com/civicrm/civicrm-core/pull/18754))**
+
+- **5.31 to master ([18756](https://github.com/civicrm/civicrm-core/pull/18756))**
+
+- **Extract setNextUrl ([18750](https://github.com/civicrm/civicrm-core/pull/18750))**
+
+- **crmMailing - Only load Angular settings if they're needed ([18749](https://github.com/civicrm/civicrm-core/pull/18749))**
+
+- **AngularLoader: Support 'settingsFactory' callbacks in angular modules. ([18731](https://github.com/civicrm/civicrm-core/pull/18731))**
+
+- **[REF] Replace long if block with early return ([18747](https://github.com/civicrm/civicrm-core/pull/18747))**
+
+- **dev/financial#152 simplify passed parameters ([18744](https://github.com/civicrm/civicrm-core/pull/18744))**
+
+- **More accurate language around social media sharing ([18743](https://github.com/civicrm/civicrm-core/pull/18743))**
+
+- **Fix main contact uf url on merge screen ([18742](https://github.com/civicrm/civicrm-core/pull/18742))**
+
+- **dev/core#2115 remove reference to financialACLs in bounce ([18738](https://github.com/civicrm/civicrm-core/pull/18738))**
+
+- **dev/financial#152 simplify interaction with membership, deprecate function ([18735](https://github.com/civicrm/civicrm-core/pull/18735))**
+
+- **dev/financial#152 simplify passed parameters ([18736](https://github.com/civicrm/civicrm-core/pull/18736))**
+
+- **dev/core#2079 Eliminate unused query on CRM_Core_BAO_CustomQuery::_construct ([18668](https://github.com/civicrm/civicrm-core/pull/18668))**
+
+- **[REF]  Separate export form classes out & simplify task handling ([18589](https://github.com/civicrm/civicrm-core/pull/18589))**
+
+- **dev/core#2047 Fix merge code so that deleted contacts are not left without a primary address ([18555](https://github.com/civicrm/civicrm-core/pull/18555))**
+
+- **dev/financial#152 remove unused parameter ([18737](https://github.com/civicrm/civicrm-core/pull/18737))**
+
+- **[REF] Minor simplification - don't use a variable for table name ([18651](https://github.com/civicrm/civicrm-core/pull/18651))**
+
+- **dev/financial#152 Pass contribution directly to completeOrder ([18728](https://github.com/civicrm/civicrm-core/pull/18728))**
+
+- **dev/financial#152 [REF] Extract getMembershipID ([18733](https://github.com/civicrm/civicrm-core/pull/18733))**
+
+- **dev/financial#152 Remove unreachable code ([18734](https://github.com/civicrm/civicrm-core/pull/18734))**
+
+- **[Test] Ensure all APIv4 entities have basic info ([18727](https://github.com/civicrm/civicrm-core/pull/18727))**
+
+- **dev/financial#152 Remove unused parameters from BaseIPN->failed signature ([18732](https://github.com/civicrm/civicrm-core/pull/18732))**
+
+- **dev/financial#152 Remove unused parameters from BaseIPN->cancelled signature ([18730](https://github.com/civicrm/civicrm-core/pull/18730))**
+
+- **dev/financial#152 Clean up & test contributionPageID handling ([18729](https://github.com/civicrm/civicrm-core/pull/18729))**
+
+- **dev/core#2110 - Warning "Non-static method CRM_Contact_Page_AJAX::pdfFormat() should not be called statically" when changing the page format on print/merge document ([18726](https://github.com/civicrm/civicrm-core/pull/18726))**
+
+- **dev/financial#152 [REF] Parse ids before sending to single function (minor simplification) ([18631](https://github.com/civicrm/civicrm-core/pull/18631))**
+
+- **dev/financial#152 [REF] Parse ids before sending to recur function (minor simplification) ([18629](https://github.com/civicrm/civicrm-core/pull/18629))**
+
+- **dev/cloud-native#16 Migrate Contribution Page widget extern url to us… ([17969](https://github.com/civicrm/civicrm-core/pull/17969))**
+
+- **5.31 ([18725](https://github.com/civicrm/civicrm-core/pull/18725))**
+
+- **dev/core#1428 Add test for Activity::update() ([18720](https://github.com/civicrm/civicrm-core/pull/18720))**
+
+- **dev/financial#11 Expand unit test to ensure that the correct currency… ([18715](https://github.com/civicrm/civicrm-core/pull/18715))**
+
+- **Financial#111: Contribution tokens always display amount with default… ([18714](https://github.com/civicrm/civicrm-core/pull/18714))**
+
+- **[REF] Upgrade DomPDF to v0.8.6 ([18688](https://github.com/civicrm/civicrm-core/pull/18688))**
+
+- **Protect against undefined index query in heartbeat callback ([220](https://github.com/civicrm/civicrm-wordpress/pull/220))**
+
+- **(dev/joomla#14) Joomla 4.0 compatibility fixes ([52](https://github.com/civicrm/civicrm-joomla/pull/52))**
+
+- **dev/core#2150 Update checking of response function to work with v2 api ([311](https://github.com/civicrm/civicrm-packages/pull/311))**
+
+## <a name="misc"></a>Miscellany
+
+## <a name="credits"></a>Credits
+
+This release was developed by the following code authors:
+
+AGH Strategies - Alice Frumin, Andrew Hunt; Agileware - Francis Whittle, Justin Freeman, Pengyi Zhang; Andrew Thompson; Christian Wach; Circle Interactive - Pradeep Nayak; CiviCoop - Jaap Jansma; CiviCRM - Coleman Watts, Tim Otten; CiviDesk - Sunil Pawar, Yashodha Chaku; CiviFirst - John Kirk; CompuCorp - Debarshi Bhaumik; Coop SymbioTIC - Mathieu Lutfy; Dave D; Diego Muñio; Freeform Solutions - Herb van den Dool; Fuzion - Jitendra Purohit; iXiam - Luciano Spiegel, Vangelis Pantazis; JMA Consulting - Monish Deb, Seamus Lee; John Kingsnorth; masetto; Megaphone Technology Consulting - Jon Goldberg; mglaman; MJW Consulting - Matthew Wire; Nicol Wistreich; Progressive Technology Project - Jamie McClelland; Richard van Oosterhout; Squiffle Consulting - Aidan Saunders; Wikimedia Foundation - Eileen McNaughton
+
+Most authors also reviewed code for this release; in addition, the following
+reviewers contributed their comments:
+
+AGH Strategies - Alice Frumin; Agileware - Justin Freeman; Andrew Thompson; Artful Robot - Rich Lott; Australian Greens - John Twyman; Circle Interactive - Pradeep Nayak; civibot[bot]; civicrm-builder; CiviCRM - Coleman Watts, Tim Otten; CiviDesk - Sunil Pawar, Yashodha Chaku; Coop SymbioTIC - Mathieu Lutfy; Dave D; Diego Muñio; Freeform Solutions - Herb van den Dool; Fuzion - Jitendra Purohit, Luke Stewart; Greenpeace Central and Eastern Europe - Patrick Figel; iXiam - Vangelis Pantazis; JMA Consulting - Joe Murray, Monish Deb, Seamus Lee; jvos; Lighthouse Consulting and Design - Brian Shaughnessy; masetto; maxtsero; Megaphone Technology Consulting - Jon Goldberg; mglaman; MJCO - Mikey O'Toole; MJW Consulting - Matthew Wire; Nicol Wistreich; Semper IT - Karin Gerritsen; Tadpole Collective - Kevin Cristiano; Wikimedia Foundation - Eileen McNaughton
+
+## <a name="feedback"></a>Feedback
+
+These release notes are edited by Alice Frumin and Andrew Hunt.  If you'd like
+to provide feedback on them, please log in to https://chat.civicrm.org/civicrm
+and contact `@agh1`.
index abfc0392604922e9ef9663e0eed42870d09358e0..52665827de2d3e4af241825552df2a4a2009705b 100644 (file)
@@ -39,6 +39,7 @@ endif; ?>
           <p><?php echo ts('By default, CiviCRM uses the same database as your website. You may install on a separate database if you need more fine-grained control over permissions, replication, hardware capacity, etc.'); ?></p>
           <p><?php echo ts('<strong>Example</strong>: <code>%1</code>', array(1 => 'mysql://admin:secret@localhost/civicrm')); ?></p>
           <p><?php echo ts('<strong>Example</strong>: <code>%1</code>', array(1 => 'mysql://admin:secret@127.0.0.1:3306/otherdb')); ?></p>
+          <p><?php echo ts('<strong>Example</strong>: <code>%1</code>', array(1 => 'mysql://admin:secret@unix(/var/lib/mysql/mysql.sock)/otherdb')); ?></p>
         </div>
       </td>
     </tr>
index 4e4e051f31a759dafe229fea743fba5dedf557de..a4fc784f90634cffed522431ebb16e8def9f64c7 100644 (file)
@@ -22,10 +22,11 @@ if (!defined('CIVI_SETUP')) {
     _corereqadapter_addMessages($e, 'system', $systemMsgs);
 
     \Civi\Setup::log()->info(sprintf('[%s] Run Requirements::checkDatabase()', basename(__FILE__)));
-    list ($host, $port) = \Civi\Setup\DbUtil::decodeHostPort($model->db['server']);
+    list ($host, $port, $socket) = \Civi\Setup\DbUtil::decodeHostPort($model->db['server']);
     $dbMsgs = $r->checkDatabase(array(
       'host' => $host,
       'port' => $port,
+      'socket' => $socket,
       'username' => $model->db['username'],
       'password' => $model->db['password'],
       'database' => $model->db['database'],
index 2320b88dace623244d904118b1d3147093f953bc..4805d998f46b6c8e3e411a3989207a4217b668cb 100644 (file)
@@ -40,6 +40,7 @@ if (!defined('CIVI_SETUP')) {
     // Compute DSN.
     global $databases;
     $ssl_params = \Civi\Setup\DrupalUtil::guessSslParams($databases['default']['default']);
+    // @todo Does Backdrop support unixsocket in config? Set 'server' => 'unix(/path/to/socket.sock)'
     $model->db = $model->cmsDb = array(
       'server' => \Civi\Setup\DbUtil::encodeHostPort($databases['default']['default']['host'], $databases['default']['default']['port'] ?: NULL),
       'username' => $databases['default']['default']['username'],
index d57ff432c21cfa4f80be5129073b00d7e4a9dceb..c65d12f220ff445e04d0dce18b27240fdf843a73 100644 (file)
@@ -38,6 +38,7 @@ if (!defined('CIVI_SETUP')) {
     // Compute DSN.
     global $databases;
     $ssl_params = \Civi\Setup\DrupalUtil::guessSslParams($databases['default']['default']);
+    // @todo Does Drupal support unixsocket in config? Set 'server' => 'unix(/path/to/socket.sock)'
     $model->db = $model->cmsDb = array(
       'server' => \Civi\Setup\DbUtil::encodeHostPort($databases['default']['default']['host'], $databases['default']['default']['port'] ?: NULL),
       'username' => $databases['default']['default']['username'],
index 3522907e0fd0edc520ed72fc6ed283b92f249d6b..98586c695e0f89d5ca0eab75fbe6cc42201f30a9 100644 (file)
@@ -41,6 +41,7 @@ if (!defined('CIVI_SETUP')) {
     // Compute DSN.
     $connectionOptions = \Drupal::database()->getConnectionOptions();
     $ssl_params = \Civi\Setup\DrupalUtil::guessSslParams($connectionOptions);
+    // @todo Does Drupal support unixsocket in config? Set 'server' => 'unix(/path/to/socket.sock)'
     $model->db = $model->cmsDb = array(
       'server' => \Civi\Setup\DbUtil::encodeHostPort($connectionOptions['host'], $connectionOptions['port'] ?: NULL),
       'username' => $connectionOptions['username'],
index 21294a6e2a0d83eaf6177d7bf6589166a0f120e7..f273231d0c8e32f0eb60106b27d432a34c8e90c9 100644 (file)
@@ -50,8 +50,9 @@ if (!defined('CIVI_SETUP')) {
     $model->templateCompilePath = implode(DIRECTORY_SEPARATOR, [$uploadDir['basedir'], 'civicrm', 'templates_c']);
 
     // Compute DSN.
+    list(/*$host*/, /*$port*/, $socket) = Civi\Setup\DbUtil::decodeHostPort(DB_HOST);
     $model->db = $model->cmsDb = array(
-      'server' => DB_HOST,
+      'server' => $socket ? sprintf('unix(%s)', $socket) : DB_HOST,
       'username' => DB_USER,
       'password' => DB_PASSWORD,
       'database' => DB_NAME,
index 87849057c6d896932e818dc87d7a01a38f104f90..6c23c251658c7ade05f8ae4cbbc96a8cf2ea2cf6 100644 (file)
@@ -11,11 +11,27 @@ class DbUtil {
    */
   public static function parseDsn($dsn) {
     $parsed = parse_url($dsn);
+    // parse_url parses 'mysql://admin:secret@unix(/var/lib/mysql/mysql.sock)/otherdb' like:
+    // [
+    //   'host'   => 'unix(',
+    //   'path'   => '/var/lib/mysql/mysql.sock)/otherdb',
+    //   ...
+    // ]
+    if ($parsed['host'] == 'unix(') {
+      preg_match('/(unix\(.*\))(\/(.+)?)?$/', $dsn, $matches);
+      $server = $matches[1];
+      $database = $matches[3] ?? NULL;
+    }
+    else {
+      $server = self::encodeHostPort($parsed['host'], $parsed['port'] ?? NULL);
+      $database = $parsed['path'] ? ltrim($parsed['path'], '/') : NULL;
+    }
+
     return array(
-      'server' => self::encodeHostPort($parsed['host'], $parsed['port'] ?? NULL),
+      'server' => $server,
       'username' => $parsed['user'] ?: NULL,
       'password' => $parsed['pass'] ?: NULL,
-      'database' => $parsed['path'] ? ltrim($parsed['path'], '/') : NULL,
+      'database' => $database,
       'ssl_params' => self::parseSSL($parsed['query'] ?? NULL),
     );
   }
@@ -41,9 +57,9 @@ class DbUtil {
    * @return \mysqli
    */
   public static function softConnect($db) {
-    list($host, $port) = self::decodeHostPort($db['server']);
+    list($host, $port, $socket) = self::decodeHostPort($db['server']);
     if (empty($db['ssl_params'])) {
-      $conn = @mysqli_connect($host, $db['username'], $db['password'], $db['database'], $port);
+      $conn = @mysqli_connect($host, $db['username'], $db['password'], $db['database'], $port, $socket);
     }
     else {
       $conn = NULL;
@@ -56,8 +72,7 @@ class DbUtil {
         $db['ssl_params']['capath'] ?? NULL,
         $db['ssl_params']['cipher'] ?? NULL
       );
-      // @todo socket parameter, but if you're using sockets do you need SSL?
-      if (@mysqli_real_connect($init, $host, $db['username'], $db['password'], $db['database'], $port, NULL, MYSQLI_CLIENT_SSL)) {
+      if (@mysqli_real_connect($init, $host, $db['username'], $db['password'], $db['database'], $port, $socket, MYSQLI_CLIENT_SSL)) {
         $conn = $init;
       }
     }
@@ -84,21 +99,34 @@ class DbUtil {
    *   Ex: '127.0.0.1:123'
    *   Ex: '[1234:abcd]'
    *   Ex: '[1234:abcd]:123'
+   *   Ex: 'localhost:/path/to/socket.sock
+   *   Ex: 'unix(/path/to/socket.sock)
    * @return array
-   *   Combination: [0 => string $host, 1 => numeric|NULL $port].
-   *   Ex: ['localhost', NULL].
-   *   Ex: ['127.0.0.1', 3306]
+   *   Combination: [0 => string $host, 1 => numeric|NULL $port, 2 => string|NULL].
+   *   Ex: ['localhost', NULL, NULL].
+   *   Ex: ['127.0.0.1', 3306, NULL]
    */
   public static function decodeHostPort($host) {
-    $hostParts = explode(':', $host);
-    if (count($hostParts) > 1 && strrpos($host, ']') !== strlen($host) - 1) {
-      $port = array_pop($hostParts);
-      $host = implode(':', $hostParts);
+    $port = NULL;
+    $socket = NULL;
+    if (preg_match('/^unix\(([^)]+)\)$/', $host, $matches) === 1) {
+      $host = 'localhost';
+      $socket = $matches[1];
     }
     else {
-      $port = NULL;
+      $hostParts = explode(':', $host);
+      if (count($hostParts) > 1 && strrpos($host, ']') !== strlen($host) - 1) {
+        $portOrSocket = array_pop($hostParts);
+        if (substr($portOrSocket, /*start*/ 0, /*length*/ 1) == '/') {
+          $socket = $portOrSocket;
+        }
+        else {
+          $port = $portOrSocket;
+        }
+        $host = implode(':', $hostParts);
+      }
     }
-    return array($host, $port);
+    return array($host, $port, $socket);
   }
 
   /**
index b82352974f6ff23f6fa15022a760d25d6ac341e4..ade11c28c4c785f2b87ffb174dabffe2dc06a87c 100644 (file)
@@ -399,7 +399,7 @@ UNLOCK TABLES;
 
 LOCK TABLES `civicrm_domain` WRITE;
 /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */;
-INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,'5.32.alpha1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
+INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,'5.33.alpha1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
 /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
 UNLOCK TABLES;
 
index 83dc830de32254d50a977976f3095c85b4005cb4..c8e46441a40b0cf28a15e8aed8aa045807a20ed5 100644 (file)
@@ -963,4 +963,4 @@ INSERT INTO civicrm_navigation
 VALUES
     ( @domainID, CONCAT('civicrm/report/instance/', @instanceID,'&reset=1'), 'Mailing Detail Report', 'Mailing Detail Report', 'administer CiviMail', 'OR', @reportlastID, '1', NULL, @instanceID+2 );
 UPDATE civicrm_report_instance SET navigation_id = LAST_INSERT_ID() WHERE id = @instanceID;
-UPDATE civicrm_domain SET version = '5.32.alpha1';
+UPDATE civicrm_domain SET version = '5.33.alpha1';
index b076bc2f3a1f2d1c6d63a980f9e7c9474194b988..9a7299a39b98a8735d06c18cb571bca178374470 100644 (file)
@@ -24,7 +24,7 @@
 <div class="block-crm crm-container">
     <form method="post" id="id_fulltext_search">
     <div style="margin-bottom: 8px;">
-    <input type="text" name="text" id='text' value="" class="crm-form-text" style="width: 10em;" />&nbsp;<button type="submit" name="submit" id="fulltext_submit" class="crm-button crm-form-submit" onclick='submitForm();'>{ts}Go{/ts}</button>
+    <input type="text" name="text" id='text' value="" class="crm-form-text" />
     <input type="hidden" name="qfKey" value="{crmKey name='CRM_Contact_Controller_Search' addSequence=1}" />
   </div>
   <select class="form-select" id="fulltext_table" name="fulltext_table">
@@ -46,5 +46,6 @@
         <option value="Membership">{ts}Memberships{/ts}</option>
 {/if}
     </select> {help id="id-fullText" file="CRM/Contact/Form/Search/Custom/FullText.hlp"}
+    <div class="crm-submit-buttons"><button type="submit" name="submit" id="fulltext_submit" class="crm-button crm-form-submit" onclick='submitForm();'>{ts}Search{/ts}</button></div>
     </form>
 </div>
index cb582857e391c21577cd691e419cd3f7f9c004fd..a75e03b04fd934de33175be0043e52253911633b 100644 (file)
                             <a title="{$row.$fieldHover|escape}" href="{$row.$fieldLink}" {$row.$fieldClass}>
                         {/if}
 
-                        {if $row.$field eq 'Subtotal'}
+                        {if is_array($row.$field)}
+                            {foreach from=$row.$field item=fieldrow key=fieldid}
+                                <div class="crm-report-{$field}-row-{$fieldid}">{$fieldrow}</div>
+                            {/foreach}
+                        {elseif $row.$field eq 'Subtotal'}
                             {$row.$field}
                         {elseif $header.type & 4 OR $header.type & 256}
                             {if $header.group_by eq 'MONTH' or $header.group_by eq 'QUARTER'}
index 4e0c9c2401d0edfd4bd72143a86f6e8a114354f9..3e28f420ac2ca511b3deb030f7680bce42320b9d 100644 (file)
                             <a title="{$row.$fieldHover|escape}" href="{$row.$fieldLink}"  {if $row.$fieldClass} class="{$row.$fieldClass}"{/if}>
                         {/if}
 
-                        {if $row.$field eq 'Subtotal'}
+                        {if is_array($row.$field)}
+                            {foreach from=$row.$field item=fieldrow key=fieldid}
+                                <div class="crm-report-{$field}-row-{$fieldid}">{$fieldrow}</div>
+                            {/foreach}
+                        {elseif $row.$field eq 'Subtotal'}
                             {$row.$field}
                         {elseif $header.type & 4 OR $header.type & 256}
                             {if $header.group_by eq 'MONTH' or $header.group_by eq 'QUARTER'}
index 4121891f93e62a3a99879332461e93fbf77c1073..41948bbb39bd88ee3bcf1f749ffd505672c41b38 100644 (file)
@@ -37,7 +37,6 @@
     <title>Group Title</title>
     <length>255</length>
     <localizable>true</localizable>
-    <required>true</required>
     <comment>Name of Group.</comment>
     <add>1.1</add>
     <html>
index bece5ae308ee56eb0a04042f6556f81954b0f843..c60cbeb03d2dd17a756036708abab1bab3288aef 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="iso-8859-1" ?>
 <version>
-  <version_no>5.32.alpha1</version_no>
+  <version_no>5.33.alpha1</version_no>
 </version>