Defining cg_extend_objects subtypes dynamically does not work as described
The cg_extend_objects
option group is used to define entity types that can receive custom fields. This can be optionally refined for sub types of entity types, in which case the option value description can contain a static method with optional arguments that is supposed to return all sub types for the respective entity type, as is done for CiviCase case types (note the description
):
{
"id": "608",
"option_group_id": "57",
"label": "Cases",
"value": "Case",
"name": "civicrm_case",
"filter": "0",
"weight": "7",
"description": "CRM_Case_PseudoConstant::caseType;",
"is_optgroup": "0",
"is_reserved": "0",
"is_active": "1"
}
The argument part (everything after the ;
), however, does not work as described in the code:
foreach ($extendObjs as $ovId => $ovValues) {
if ($ovValues['description']) {
// description is expected to be a callback func to subtypes
list($callback, $args) = explode(';', trim($ovValues['description']));
if (empty($args)) {
$args = [];
}
if (!is_array($args)) {
throw new CRM_Core_Exception('Arg is not of type array');
}
list($className) = explode('::', $callback);
require_once str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$objTypes[$ovValues['value']] = call_user_func_array($callback, $args);
}
}
$args
can never be an array when it's not empty, as explode()
always returns an array of strings. So this code will always fail when there's something after the ;
.
There should be a format defined for how arguments are to be passed (comma-separated, serialized, json, ...).
And yes, this is "esoteric" in the first place, but currently the only way to pass e.g. the entity type itself for generating a list of sub types, which makes sense for contrib stuff. As an explanation: My extension's entity types do not have their own PHP classes, but share a generic controller, so the entity type name needs to be passed here for each entity type having dedicated custom fields.