Merge pull request #17981 from eileenmcnaughton/merge_form
[civicrm-core.git] / CRM / Core / DAO.php
index a58eaacccaa1c511d4acb780e9beeb5497b7d56b..a1cd6f7498915e29b1919cb62dd88662533a633a 100644 (file)
@@ -163,6 +163,11 @@ class CRM_Core_DAO extends DB_DataObject {
     $options = &PEAR::getStaticProperty('DB_DataObject', 'options');
     $options['database'] = $dsn;
     $options['quote_identifiers'] = TRUE;
+    if (self::isSSLDSN($dsn)) {
+      // There are two different options arrays.
+      $other_options = &PEAR::getStaticProperty('DB', 'options');
+      $other_options['ssl'] = TRUE;
+    }
     if (defined('CIVICRM_DAO_DEBUG')) {
       self::DebugLevel(CIVICRM_DAO_DEBUG);
     }
@@ -530,6 +535,43 @@ class CRM_Core_DAO extends DB_DataObject {
     return $result;
   }
 
+  /**
+   * Returns all usable fields, indexed by name.
+   *
+   * This function differs from fields() in that it indexes by name rather than unique_name.
+   *
+   * It excludes fields not added yet by pending upgrades.
+   * This avoids problems with trying to SELECT a field that exists in code but has not yet been added to the db.
+   *
+   * @param bool $checkPermissions
+   *   Filter by field permissions.
+   * @return array
+   */
+  public static function getSupportedFields($checkPermissions = FALSE) {
+    $fields = array_column((array) static::fields(), NULL, 'name');
+
+    // Exclude fields yet not added by pending upgrades
+    $dbVer = \CRM_Core_BAO_Domain::version();
+    if ($fields && version_compare($dbVer, \CRM_Utils_System::version()) < 0) {
+      $fields = array_filter($fields, function($field) use ($dbVer) {
+        $add = $field['add'] ?? '1.0.0';
+        if (substr_count($add, '.') < 2) {
+          $add .= '.alpha1';
+        }
+        return version_compare($dbVer, $add, '>=');
+      });
+    }
+
+    // Exclude fields the user does not have permission for
+    if ($checkPermissions) {
+      $fields = array_filter($fields, function($field) {
+        return empty($field['permission']) || CRM_Core_Permission::check($field['permission']);
+      });
+    }
+
+    return $fields;
+  }
+
   /**
    * Get/set an associative array of table columns
    *
@@ -3069,4 +3111,21 @@ SELECT contact_id
     }
   }
 
+  /**
+   * Does the DSN indicate the connection should use ssl.
+   *
+   * @param string $dsn
+   *
+   * @return bool
+   */
+  public static function isSSLDSN(string $dsn):bool {
+    // Note that ssl= below is not an official PEAR::DB option. It doesn't know
+    // what to do with it. We made it up because it's not required
+    // to have client-side certificates to use ssl, so here you can specify
+    // you want that by putting ssl=1 in the DSN string.
+    //
+    // Cast to bool in case of error which we interpret as no ssl.
+    return (bool) preg_match('/[\?&](key|cert|ca|capath|cipher|ssl)=/', $dsn);
+  }
+
 }