Core - Cleanup BAO::del() functions with unnecessary FK checks
[civicrm-core.git] / CRM / Core / DAO.php
index a7af426b2db5fa018a04a8550356d5adabe3bde2..4e76a60f4d80796c89811ea9b73e468141944e4f 100644 (file)
@@ -32,6 +32,13 @@ require_once 'CRM/Core/I18n.php';
  */
 class CRM_Core_DAO extends DB_DataObject {
 
+  /**
+   * Primary key field(s).
+   *
+   * @var string[]
+   */
+  public static $_primaryKey = ['id'];
+
   /**
    * How many times has this instance been cloned.
    *
@@ -107,8 +114,6 @@ class CRM_Core_DAO extends DB_DataObject {
    */
   public static $_factory = NULL;
 
-  public static $_checkedSqlFunctionsExist = FALSE;
-
   /**
    * https://issues.civicrm.org/jira/browse/CRM-17748
    * internal variable for DAO to hold per-query settings
@@ -137,6 +142,15 @@ class CRM_Core_DAO extends DB_DataObject {
     return CRM_Core_DAO_AllCoreTables::getBriefName($className);
   }
 
+  /**
+   * Returns user-friendly description of this entity.
+   *
+   * @return string|null
+   */
+  public static function getEntityDescription() {
+    return NULL;
+  }
+
   public function __clone() {
     if (!empty($this->_DB_resultid)) {
       $this->resultCopies++;
@@ -943,6 +957,7 @@ class CRM_Core_DAO extends DB_DataObject {
     if (empty($record['id'])) {
       throw new CRM_Core_Exception("Cannot delete {$entityName} with no id.");
     }
+    CRM_Utils_Type::validate($record['id'], 'Positive');
 
     CRM_Utils_Hook::pre('delete', $entityName, $record['id'], $record);
     $instance = new $className();
@@ -2451,23 +2466,6 @@ SELECT contact_id
     Civi::service('sql_triggers')->rebuild($tableName, $force);
   }
 
-  /**
-   * Because sql functions are sometimes lost, esp during db migration, we check here to avoid numerous support requests
-   * @see http://issues.civicrm.org/jira/browse/CRM-13822
-   * TODO: Alternative solutions might be
-   *  * Stop using functions and find another way to strip numeric characters from phones
-   *  * Give better error messages (currently a missing fn fatals with "unknown error")
-   */
-  public static function checkSqlFunctionsExist() {
-    if (!self::$_checkedSqlFunctionsExist) {
-      self::$_checkedSqlFunctionsExist = TRUE;
-      $dao = CRM_Core_DAO::executeQuery("SHOW function status WHERE db = database() AND name = 'civicrm_strip_non_numeric'");
-      if (!$dao->fetch()) {
-        self::triggerRebuild();
-      }
-    }
-  }
-
   /**
    * Wrapper function to drop triggers.
    *
@@ -2582,7 +2580,7 @@ SELECT contact_id
    * @param string $tableName
    *   Table referred to.
    *
-   * @return array
+   * @return CRM_Core_Reference_Interface[]
    *   structure of table and column, listing every table with a
    *   foreign key reference to $tableName, and the column where the key appears.
    */
@@ -2619,7 +2617,12 @@ SELECT contact_id
     $contactReferences = [];
     $coreReferences = CRM_Core_DAO::getReferencesToTable('civicrm_contact');
     foreach ($coreReferences as $coreReference) {
-      if (!is_a($coreReference, 'CRM_Core_Reference_Dynamic')) {
+      if (
+        // Exclude option values
+        !is_a($coreReference, 'CRM_Core_Reference_Dynamic') &&
+        // Exclude references to other columns
+        $coreReference->getTargetKey() === 'id'
+      ) {
         $contactReferences[$coreReference->getReferenceTable()][] = $coreReference->getReferenceKey();
       }
     }
@@ -2879,20 +2882,9 @@ SELECT contact_id
    */
   public static function createSQLFilter($fieldName, $filter, $type = NULL, $alias = NULL, $returnSanitisedArray = FALSE) {
     foreach ($filter as $operator => $criteria) {
-      if (!CRM_Core_BAO_SchemaHandler::databaseSupportsUTF8MB4()) {
-        foreach ((array) $criteria as $criterion) {
-          if (!empty($criterion) && !is_numeric($criterion)
-            // The first 2 criteria are redundant but are added as they
-            // seem like they would
-            // be quicker than this 3rd check.
-            && max(array_map('ord', str_split($criterion))) >= 240) {
-            // String contains unsupported emojis.
-            // We return a clause that resolves to false as an emoji string by definition cannot be saved.
-            // note that if we return just 0 for false if gets lost in empty checks.
-            // https://stackoverflow.com/questions/16496554/can-php-detect-4-byte-encoded-utf8-chars
-            return '0 = 1';
-          }
-        }
+      $emojiFilter = CRM_Utils_SQL::handleEmojiInQuery($criteria);
+      if ($emojiFilter === '0 = 1') {
+        return $emojiFilter;
       }
 
       if (in_array($operator, self::acceptedSQLOperators(), TRUE)) {
@@ -3075,7 +3067,7 @@ SELECT contact_id
         $clauses[$fieldName] = CRM_Utils_SQL::mergeSubquery('Contact');
       }
       // Clause for an entity_table/entity_id combo
-      if ($fieldName == 'entity_id' && isset($fields['entity_table'])) {
+      if ($fieldName === 'entity_id' && isset($fields['entity_table'])) {
         $relatedClauses = [];
         $relatedEntities = $this->buildOptions('entity_table', 'get');
         foreach ((array) $relatedEntities as $table => $ent) {
@@ -3124,7 +3116,7 @@ SELECT contact_id
 
   /**
    * ensure database name is 'safe', i.e. only contains word characters (includes underscores)
-   * and dashes, and contains at least one [a-z] case insenstive.
+   * and dashes, and contains at least one [a-z] case insensitive.
    *
    * @param $database
    *