From 50182f0e6358a2121d305f2045bba8ee4348aca1 Mon Sep 17 00:00:00 2001 From: eileen Date: Thu, 2 May 2019 00:19:51 +1200 Subject: [PATCH 1/2] [ref] Move copyCustomFields function from Event to Core_DAO for re-usablibilty --- CRM/Core/DAO.php | 55 +++++++++++++++++++++++++++++++++++++++++ CRM/Event/BAO/Event.php | 53 +-------------------------------------- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index 027dba4a89fd..a31428d79a56 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -1679,6 +1679,61 @@ public static function ©Generic($daoName, $criteria, $newData = NULL, $field return $newObject; } + /** + * Method that copies custom fields values from an old event 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 + * so it's not clear why this is needed - best guess is the custom fields are not handled - this is ALSO the + * situation with the dedupe. + * + * @param int $oldEventID + * @param int $newCopyID + */ + public function copyCustomFields($oldEventID, $newCopyID) { + // Obtain custom values for old event + $customParams = $htmlType = []; + $customValues = CRM_Core_BAO_CustomValueTable::getEntityValues($oldEventID, 'Event'); + + // 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, $oldEventID); + $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, 'civicrm_event', $newCopyID, 'Event'); + } + + // copy activity attachments ( if any ) + CRM_Core_BAO_File::copyEntityFile('civicrm_event', $oldEventID, 'civicrm_event', $newCopyID); + } + /** * Cascade update through related entities. * diff --git a/CRM/Event/BAO/Event.php b/CRM/Event/BAO/Event.php index 518bc9bd0bb3..35b747363258 100644 --- a/CRM/Event/BAO/Event.php +++ b/CRM/Event/BAO/Event.php @@ -986,7 +986,7 @@ public static function copy($id, $params = []) { ['entity_value' => $id, 'mapping_id' => $oldMapping->getId()], ['entity_value' => $copyEvent->id, 'mapping_id' => $copyMapping->getId()] ); - self::copyCustomFields($id, $copyEvent->id); + $copyEvent->copyCustomFields($id, $copyEvent->id); $copyEvent->save(); @@ -996,57 +996,6 @@ public static function copy($id, $params = []) { return $copyEvent; } - /** - * Method that copies custom fields values from an old event 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. - * - * @param int $oldEventID - * @param int $newCopyID - */ - public static function copyCustomFields($oldEventID, $newCopyID) { - // Obtain custom values for old event - $customParams = $htmlType = []; - $customValues = CRM_Core_BAO_CustomValueTable::getEntityValues($oldEventID, 'Event'); - - // 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, $oldEventID); - $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, 'civicrm_event', $newCopyID, 'Event'); - } - - // copy activity attachments ( if any ) - CRM_Core_BAO_File::copyEntityFile('civicrm_event', $oldEventID, 'civicrm_event', $newCopyID); - } - /** * This is sometimes called in a loop (during event search). * From e60bcca67867394a5efae2b00942af6a71590e91 Mon Sep 17 00:00:00 2001 From: eileen Date: Thu, 2 May 2019 01:28:30 +1200 Subject: [PATCH 2/2] Follow up by making more generic --- CRM/Core/DAO.php | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index a31428d79a56..aa814ab776a4 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -1680,21 +1680,24 @@ public static function ©Generic($daoName, $criteria, $newData = NULL, $field } /** - * Method that copies custom fields values from an old event to a new one. Fixes bug CRM-19302, + * 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 - * so it's not clear why this is needed - best guess is the custom fields are not handled - this is ALSO the - * situation with the dedupe. + * but it seems to be bypassed & perhaps less good than this (or this just duplicates it...) * - * @param int $oldEventID - * @param int $newCopyID + * @param int $entityID + * @param int $newEntityID */ - public function copyCustomFields($oldEventID, $newCopyID) { + 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($oldEventID, 'Event'); + $customValues = CRM_Core_BAO_CustomValueTable::getEntityValues($entityID, $entity); // If custom values present, we copy them if (!empty($customValues)) { @@ -1713,7 +1716,7 @@ public function copyCustomFields($oldEventID, $newCopyID) { if ($value !== NULL) { // Handle File type attributes if (in_array($field, $htmlType)) { - $fileValues = CRM_Core_BAO_File::path($value, $oldEventID); + $fileValues = CRM_Core_BAO_File::path($value, $entityID); $customParams["custom_{$field}_-1"] = [ 'name' => CRM_Utils_File::duplicate($fileValues[0]), 'type' => $fileValues[1], @@ -1727,11 +1730,11 @@ public function copyCustomFields($oldEventID, $newCopyID) { } // Save Custom Fields for new Event - CRM_Core_BAO_CustomValueTable::postProcess($customParams, 'civicrm_event', $newCopyID, 'Event'); + CRM_Core_BAO_CustomValueTable::postProcess($customParams, $tableName, $newEntityID, $entity); } // copy activity attachments ( if any ) - CRM_Core_BAO_File::copyEntityFile('civicrm_event', $oldEventID, 'civicrm_event', $newCopyID); + CRM_Core_BAO_File::copyEntityFile($tableName, $entityID, $tableName, $newEntityID); } /**