Details
-
Type: Bug
-
Status: Done/Fixed
-
Priority: Critical
-
Resolution: Fixed/Completed
-
Affects Version/s: 4.7.15
-
Fix Version/s: 4.7.25
-
Component/s: None
-
Labels:None
-
Versioning Impact:Patch (backwards-compatible bug fixes)
-
Documentation Required?:None
-
Funding Source:Contributed Code
-
Verified?:No
Description
Hi all,
A client with a lot of events just ran into this Civi error while adding her latest event:
"DB Error: already exists."
When I looked at the error log I found this:
{{Mar 08 16:33:29 [info] $Fatal Error Details = Array
(
[callback] => Array
(
[0] => CRM_Core_Error
[1] => handle
)
[code] => -5
[message] => DB Error: already exists
[mode] => 16
[debug_info] => INSERT INTO civicrm_price_set (name , title , is_active , extends , financial_type_id , is_quick_config , is_reserved , min_amount ) VALUES ('cle_event_template_Copy_id_73_Copy_id_82_Copy_id_85_Copy_id_99_Copy_id_106_Copy_id_107_Copy_id_111_Copy_id_112_Copy_id_113_Copy_id_125_Copy_id_126_Copy_id_130_Copy_id_131_Copy_id_136_Copy_id_137_Copy_id_138_Copy_id_139_Copy_id_141' , 'CLE Event Template [Copy id 73] [Copy id 82] [Copy id 85] [Copy id 99] [Copy id 106] [Copy id 107] [Copy id 111] [Copy id 112] [Copy id 113] [Copy id 125] [Copy id 126] [Copy id 130] [Copy id 131] [Copy id 136] [Copy id 137] [Copy id 138] [Copy id 139] [Copy id 141]' , 1 , '1' , 4 , 1 , 0 , 0 ) [nativecode=1062 ** Duplicate entry 'cle_event_template__Copy_id_73___Copy_id_82___Copy_id_85___Copy_' for key 'UI_name']
[type] => DB_Error
[user_info] => INSERT INTO civicrm_price_set (name , title , is_active , extends , financial_type_id , is_quick_config , is_reserved , min_amount ) VALUES ('cle_event_template_Copy_id_73_Copy_id_82_Copy_id_85_Copy_id_99_Copy_id_106_Copy_id_107_Copy_id_111_Copy_id_112_Copy_id_113_Copy_id_125_Copy_id_126_Copy_id_130_Copy_id_131_Copy_id_136_Copy_id_137_Copy_id_138_Copy_id_139_Copy_id_141' , 'CLE Event Template [Copy id 73] [Copy id 82] [Copy id 85] [Copy id 99] [Copy id 106] [Copy id 107] [Copy id 111] [Copy id 112] [Copy id 113] [Copy id 125] [Copy id 126] [Copy id 130] [Copy id 131] [Copy id 136] [Copy id 137] [Copy id 138] [Copy id 139] [Copy id 141]' , 1 , '1' , 4 , 1 , 0 , 0 ) [nativecode=1062 ** Duplicate entry 'cle_event_template__Copy_id_73___Copy_id_82___Copy_id_85___Copy_' for key 'UI_name']
[to_string] => [db_error: message="DB Error: already exists" code=-5 mode=callback callback=CRM_Core_Error::handle prefix="" info="INSERT INTO civicrm_price_set (name , title , is_active , extends , financial_type_id , is_quick_config , is_reserved , min_amount ) VALUES ('cle_event_template_Copy_id_73_Copy_id_82_Copy_id_85_Copy_id_99_Copy_id_106_Copy_id_107_Copy_id_111_Copy_id_112_Copy_id_113_Copy_id_125_Copy_id_126_Copy_id_130_Copy_id_131_Copy_id_136_Copy_id_137_Copy_id_138_Copy_id_139_Copy_id_141' , 'CLE Event Template [Copy id 73] [Copy id 82] [Copy id 85] [Copy id 99] [Copy id 106] [Copy id 107] [Copy id 111] [Copy id 112] [Copy id 113] [Copy id 125] [Copy id 126] [Copy id 130] [Copy id 131] [Copy id 136] [Copy id 137] [Copy id 138] [Copy id 139] [Copy id 141]' , 1 , '1' , 4 , 1 , 0 , 0 ) [nativecode=1062 ** Duplicate entry 'cle_event_template__Copy_id_73___Copy_id_82___Copy_id_85___Copy_' for key 'UI_name']"]
)}}
It looks like every time a priceset is copied from an event, the word "Copy_id" is getting added to the name and title fields of the civicrm_price_set table. However, the `title` field is only 255 characters long and must be unique. So at a certain point when the string of copy_id_##copy_id## gets too long and becomes truncated, the values are no-longer identical.
I found that I could do a preg_replace() and delete the old "Copy" text before Civi tries to add on a new suffix.
Here is my fix below, but maybe someone with more Civi knowledge than me can check if it is indeed the best solution or if there should be something else.
civicrm/CRM/Core/DAO.php @ Line 1507
if (isset($fieldsToSuffix[$dbName])) {
/* preg_replace to remove old copy suffix first */
$pattern = '/__Copy_id_\d+_$/';
$newObject->$dbName = preg_replace($pattern, "", $newObject->$dbName);
$pattern = '/\[Copy id \d+\]$/';
$newObject->$dbName = preg_replace($pattern, "", $newObject->$dbName);
/* end preg_replace to remove old copy suffix first */
$newObject->$dbName .= $fieldsToSuffix[$dbName];
}