Merge pull request #14656 from eileenmcnaughton/ad_hoc_mailing
[civicrm-core.git] / CRM / Core / DAO.php
index 027dba4a89fd3b0b262541ac9b4ca2980ddc6f5b..f4593a4bd57e7b6560cd0cc1e6176cbefd6280ce 100644 (file)
@@ -936,7 +936,7 @@ class CRM_Core_DAO extends DB_DataObject {
 
     if (!array_key_exists($tableName, $show)) {
       $query = "SHOW CREATE TABLE $tableName";
-      $dao = CRM_Core_DAO::executeQuery($query);
+      $dao = CRM_Core_DAO::executeQuery($query, [], TRUE, NULL, FALSE, FALSE);
 
       if (!$dao->fetch()) {
         CRM_Core_Error::fatal();
@@ -963,7 +963,7 @@ class CRM_Core_DAO extends DB_DataObject {
     foreach ($tables as $tableName) {
       if (!array_key_exists($tableName, $show)) {
         $query = "SHOW CREATE TABLE $tableName";
-        $dao = CRM_Core_DAO::executeQuery($query);
+        $dao = CRM_Core_DAO::executeQuery($query, [], TRUE, NULL, FALSE, FALSE);
 
         if (!$dao->fetch()) {
           CRM_Core_Error::fatal();
@@ -1600,11 +1600,12 @@ FROM   civicrm_domain
    *   Fields that you want to block from.
    *   getting copied
    *
-   * @return CRM_Core_DAO
-   *   the newly created copy of the object
+   * @return CRM_Core_DAO|bool
+   *   the newly created copy of the object. False if none created.
    */
-  public static function &copyGeneric($daoName, $criteria, $newData = NULL, $fieldsFix = NULL, $blockCopyOfDependencies = NULL) {
+  public static function copyGeneric($daoName, $criteria, $newData = NULL, $fieldsFix = NULL, $blockCopyOfDependencies = NULL) {
     $object = new $daoName();
+    $newObject = FALSE;
     if (!$newData) {
       $object->id = $criteria['id'];
     }
@@ -1670,15 +1671,71 @@ FROM   civicrm_domain
         }
       }
       $newObject->save();
-      if (!empty($newData['custom'])) {
-        CRM_Core_BAO_CustomValueTable::store($newData['custom'], $newObject::getTableName(), $newObject->id);
-      }
+      $newObject->copyCustomFields($object->id, $newObject->id);
       CRM_Utils_Hook::post('create', CRM_Core_DAO_AllCoreTables::getBriefName($daoName), $newObject->id, $newObject);
     }
 
     return $newObject;
   }
 
+  /**
+   * Method that copies custom fields values from an old entity to a new one.
+   *
+   * Fixes bug CRM-19302,
+   * where if a custom field of File type was present, left both events using the same file,
+   * breaking download URL's for the old event.
+   *
+   * @todo the goal here is to clean this up so that it works for any entity. Copy Generic already DOES some custom field stuff
+   * but it seems to be bypassed & perhaps less good than this (or this just duplicates it...)
+   *
+   * @param int $entityID
+   * @param int $newEntityID
+   */
+  public function copyCustomFields($entityID, $newEntityID) {
+    $entity = CRM_Core_DAO_AllCoreTables::getBriefName(get_class($this));
+    $tableName = CRM_Core_DAO_AllCoreTables::getTableForClass(get_class($this));
+    // Obtain custom values for old event
+    $customParams = $htmlType = [];
+    $customValues = CRM_Core_BAO_CustomValueTable::getEntityValues($entityID, $entity);
+
+    // If custom values present, we copy them
+    if (!empty($customValues)) {
+      // Get Field ID's and identify File type attributes, to handle file copying.
+      $fieldIds = implode(', ', array_keys($customValues));
+      $sql = "SELECT id FROM civicrm_custom_field WHERE html_type = 'File' AND id IN ( {$fieldIds} )";
+      $result = CRM_Core_DAO::executeQuery($sql);
+
+      // Build array of File type fields
+      while ($result->fetch()) {
+        $htmlType[] = $result->id;
+      }
+
+      // Build params array of custom values
+      foreach ($customValues as $field => $value) {
+        if ($value !== NULL) {
+          // Handle File type attributes
+          if (in_array($field, $htmlType)) {
+            $fileValues = CRM_Core_BAO_File::path($value, $entityID);
+            $customParams["custom_{$field}_-1"] = [
+              'name' => CRM_Utils_File::duplicate($fileValues[0]),
+              'type' => $fileValues[1],
+            ];
+          }
+          // Handle other types
+          else {
+            $customParams["custom_{$field}_-1"] = $value;
+          }
+        }
+      }
+
+      // Save Custom Fields for new Event
+      CRM_Core_BAO_CustomValueTable::postProcess($customParams, $tableName, $newEntityID, $entity);
+    }
+
+    // copy activity attachments ( if any )
+    CRM_Core_BAO_File::copyEntityFile($tableName, $entityID, $tableName, $newEntityID);
+  }
+
   /**
    * Cascade update through related entities.
    *
@@ -2779,9 +2836,10 @@ SELECT contact_id
   /**
    * Transform an array to a serialized string for database storage.
    *
-   * @param array|NULL $value
-   * @param $serializationType
-   * @return string|NULL
+   * @param array|null $value
+   * @param int $serializationType
+   * @return string|null
+   *
    * @throws \Exception
    */
   public static function serializeField($value, $serializationType) {