CRM_Core_DAO_AllCoreTables::getBriefName('CRM_Core_BAO_UFField') returns NULL
Overview
CRM_Core_DAO_AllCoreTables::getBriefName('CRM_Core_BAO_UFField') returns NULL instead of the correct brief name. This creates a crashing bug or data corruption when attempting to copy a profile if there are custom data fields for Contact records.
Reproduction steps
- call CRM_Core_DAO_AllCoreTables::getBriefName('CRM_Core_BAO_UFField').
- Examine the return value.
Current behaviour
The return value is NULL.
Expected behaviour
It should return a string that is the brief name (presumably UFField or something like that).
Environment information
- Browser: Safari 13
- CiviCRM: 5.22.0
- PHP: 7.2_
- CMS: Drupal 7.30
Comments
I found this issue when attempting to make a copy of a Profile, which crashed. Here is the backtrace:
#0 /mysite/sites/all/modules/civicrm/CRM/Core/Error.php(148): CRM_Core_Error::backtrace()
#1 /mysite/sites/all/modules/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(922): CRM_Core_Error::handle(Object(DB_Error))
#2 /mysite/sites/all/modules/civicrm/packages/DB.php(987): PEAR_Error->__construct("DB Error: constraint violation", -3, 16, (Array:2), "INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...")
#3 /mysite/sites/all/modules/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(575): DB_Error->__construct(-3, 16, (Array:2), "INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...")
#4 /mysite/sites/all/modules/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(223): PEAR->_raiseError(Object(DB_mysqli), NULL, -3, 16, (Array:2), "INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...", "DB_Error", TRUE)
#5 /mysite/sites/all/modules/civicrm/packages/DB/common.php(1920): PEAR->__call("raiseError", (Array:7))
#6 /mysite/sites/all/modules/civicrm/packages/DB/mysqli.php(933): DB_common->raiseError(-3, NULL, NULL, "INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...", "1452 ** Cannot add or update a child row: a foreign key constraint fails (`dr...")
#7 /mysite/sites/all/modules/civicrm/packages/DB/mysqli.php(403): DB_mysqli->mysqliRaiseError()
#8 /mysite/sites/all/modules/civicrm/packages/DB/common.php(1229): DB_mysqli->simpleQuery("INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...")
#9 /mysite/sites/all/modules/civicrm/packages/DB/DataObject.php(2416): DB_common->query("INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...")
#10 /mysite/sites/all/modules/civicrm/packages/DB/DataObject.php(1607): DB_DataObject->_query("INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...")
#11 /mysite/sites/all/modules/civicrm/CRM/Core/DAO.php(420): DB_DataObject->query("INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...")
#12 /mysite/sites/all/modules/civicrm/CRM/Core/DAO.php(1419): CRM_Core_DAO->query("INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...", TRUE)
#13 /mysite/sites/all/modules/civicrm/CRM/Core/BAO/CustomValueTable.php(255): CRM_Core_DAO::executeQuery("INSERT INTO civicrm_value_member_data_11 ( `membership_number_108`,`entity_i...", (Array:2))
#14 /mysite/sites/all/modules/civicrm/CRM/Core/BAO/CustomValueTable.php(372): CRM_Core_BAO_CustomValueTable::create((Array:1), NULL)
#15 /mysite/sites/all/modules/civicrm/CRM/Core/BAO/CustomValueTable.php(391): CRM_Core_BAO_CustomValueTable::store((Array:1), "civicrm_uf_field", 2064)
#16 /mysite/sites/all/modules/civicrm/CRM/Core/DAO.php(1742): CRM_Core_BAO_CustomValueTable::postProcess((Array:1), "civicrm_uf_field", 2064, NULL)
*****HERE IS WHERE THE PROBLEM HAPPENS
The problem arises in function copyCustomFields($entityID, $newEntityID). Both entities are UFField. The first lines of the function are:
$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);
The problem is that even though get_class($this) returns 'CRM_Core_BAO_UFField', the call to CRM_Core_DAO_AllCoreTables::getBriefName('CRM_Core_BAO_UFField') is returning NULL, instead of the appropriate entity type.
So the second parameter passed to CRM_Core_BAO_CustomValueTable::getEntityValues($entityID, $entity) is NULL, and so getEntityValues defaults to assuming the $entityID refers to a Contact (per documentation of getEntityValues), event though $entityID is the ID of a UFField. So getEntityValues returns a bunch of custom values for Contacts, and then tries to do things with them, resulting in a crash or the insertion of bad data somewhere in the db.
***** END OF PROBLEM DISCUSSION
#17 /mysite/sites/all/modules/civicrm/CRM/Core/DAO.php(1683): CRM_Core_DAO->copyCustomFields("1645", 2064)
#18 /mysite/sites/all/modules/civicrm/CRM/Core/BAO/UFGroup.php(2649): CRM_Core_DAO::copyGeneric("CRM_Core_BAO_UFField", (Array:1), (Array:1))
#19 /mysite/sites/all/modules/civicrm/CRM/UF/Page/Group.php(191): CRM_Core_BAO_UFGroup::copy("120")
#20 /mysite/sites/all/modules/civicrm/CRM/UF/Page/Group.php(171): CRM_UF_Page_Group->copy()
#21 /mysite/sites/all/modules/civicrm/CRM/Core/Invoke.php(268): CRM_UF_Page_Group->run((Array:4), NULL)
#22 /mysite/sites/all/modules/civicrm/CRM/Core/Invoke.php(68): CRM_Core_Invoke::runItem((Array:16))
#23 /mysite/sites/all/modules/civicrm/CRM/Core/Invoke.php(36): CRM_Core_Invoke::_invoke((Array:4))
#24 /mysite/sites/all/modules/civicrm/drupal/civicrm.module(456): CRM_Core_Invoke::invoke((Array:4))
#25 /mysite/includes/menu.inc(527): civicrm_invoke("admin", "uf", "group")
#26 /mysite/index.php(21): menu_execute_active_handler()
#27 {main}