*/
class Entity extends Generic\AbstractEntity {
+ /**
+ * @var array[]
+ */
+ public static $entityFields = [
+ [
+ 'name' => 'name',
+ 'description' => 'Entity name',
+ ],
+ [
+ 'name' => 'title',
+ 'description' => 'Localized title (singular)',
+ ],
+ [
+ 'name' => 'title_plural',
+ 'description' => 'Localized title (plural)',
+ ],
+ [
+ 'name' => 'type',
+ 'data_type' => 'Array',
+ 'description' => 'Base class for this entity',
+ 'pseudoconstant' => ['callback' => ['Civi\Api4\Utils\CoreUtil', 'getEntityTypes']],
+ ],
+ [
+ 'name' => 'description',
+ 'description' => 'Description from docblock',
+ ],
+ [
+ 'name' => 'comment',
+ 'description' => 'Comments from docblock',
+ ],
+ [
+ 'name' => 'icon',
+ 'description' => 'crm-i icon class associated with this entity',
+ ],
+ [
+ 'name' => 'dao',
+ 'description' => 'Class name for dao-based entities',
+ ],
+ [
+ 'name' => 'table_name',
+ 'description' => 'Name of sql table, if applicable',
+ ],
+ [
+ 'name' => 'primary_key',
+ 'data_type' => 'Array',
+ 'description' => 'Name of unique identifier field(s) (e.g. [id])',
+ ],
+ [
+ 'name' => 'label_field',
+ 'description' => 'Field to show when displaying a record',
+ ],
+ [
+ 'name' => 'order_by',
+ 'description' => 'Default column to sort results',
+ ],
+ [
+ 'name' => 'searchable',
+ 'description' => 'How should this entity be presented in search UIs',
+ 'pseudoconstant' => ['callback' => ['Civi\Api4\Utils\CoreUtil', 'getSearchableOptions']],
+ ],
+ [
+ 'name' => 'paths',
+ 'data_type' => 'Array',
+ 'description' => 'System paths for accessing this entity',
+ ],
+ [
+ 'name' => 'see',
+ 'data_type' => 'Array',
+ 'description' => 'Any @see annotations from docblock',
+ ],
+ [
+ 'name' => 'since',
+ 'data_type' => 'String',
+ 'description' => 'Version this API entity was added',
+ ],
+ [
+ 'name' => 'class',
+ 'data_type' => 'String',
+ 'description' => 'PHP class name',
+ ],
+ [
+ 'name' => 'class_args',
+ 'data_type' => 'Array',
+ 'description' => 'Arguments needed by php action factory functions (used when multiple entities share a class, e.g. CustomValue).',
+ ],
+ [
+ 'name' => 'bridge',
+ 'data_type' => 'Array',
+ 'description' => 'Connecting fields for EntityBridge types',
+ ],
+ [
+ 'name' => 'ui_join_filters',
+ 'data_type' => 'Array',
+ 'description' => 'When joining entities in the UI, which fields should be presented by default in the ON clause',
+ ],
+ [
+ 'name' => 'group_weights_by',
+ 'data_type' => 'Array',
+ 'description' => 'For sortable entities, what field groupings are used to order by weight',
+ ],
+ ];
+
/**
* @param bool $checkPermissions
* @return Action\Entity\Get
*/
public static function getFields($checkPermissions = TRUE) {
return (new Generic\BasicGetFieldsAction('Entity', __FUNCTION__, function(Generic\BasicGetFieldsAction $getFields) {
- return [
- [
- 'name' => 'name',
- 'description' => 'Entity name',
- ],
- [
- 'name' => 'title',
- 'description' => 'Localized title (singular)',
- ],
- [
- 'name' => 'title_plural',
- 'description' => 'Localized title (plural)',
- ],
- [
- 'name' => 'type',
- 'data_type' => 'Array',
- 'description' => 'Base class for this entity',
- 'options' => $getFields->getLoadOptions() ? self::getEntityTypes() : TRUE,
- ],
- [
- 'name' => 'description',
- 'description' => 'Description from docblock',
- ],
- [
- 'name' => 'comment',
- 'description' => 'Comments from docblock',
- ],
- [
- 'name' => 'icon',
- 'description' => 'crm-i icon class associated with this entity',
- ],
- [
- 'name' => 'dao',
- 'description' => 'Class name for dao-based entities',
- ],
- [
- 'name' => 'table_name',
- 'description' => 'Name of sql table, if applicable',
- ],
- [
- 'name' => 'primary_key',
- 'data_type' => 'Array',
- 'description' => 'Name of unique identifier field(s) (e.g. [id])',
- ],
- [
- 'name' => 'label_field',
- 'description' => 'Field to show when displaying a record',
- ],
- [
- 'name' => 'order_by',
- 'description' => 'Default column to sort results',
- ],
- [
- 'name' => 'searchable',
- 'description' => 'How should this entity be presented in search UIs',
- 'options' => [
- 'primary' => ts('Primary'),
- 'secondary' => ts('Secondary'),
- 'bridge' => ts('Bridge'),
- 'none' => ts('None'),
- ],
- ],
- [
- 'name' => 'paths',
- 'data_type' => 'Array',
- 'description' => 'System paths for accessing this entity',
- ],
- [
- 'name' => 'see',
- 'data_type' => 'Array',
- 'description' => 'Any @see annotations from docblock',
- ],
- [
- 'name' => 'since',
- 'data_type' => 'String',
- 'description' => 'Version this API entity was added',
- ],
- [
- 'name' => 'class',
- 'data_type' => 'String',
- 'description' => 'PHP class name',
- ],
- [
- 'name' => 'class_args',
- 'data_type' => 'Array',
- 'description' => 'Arguments needed by php action factory functions (used when multiple entities share a class, e.g. CustomValue).',
- ],
- [
- 'name' => 'bridge',
- 'data_type' => 'Array',
- 'description' => 'Connecting fields for EntityBridge types',
- ],
- [
- 'name' => 'ui_join_filters',
- 'data_type' => 'Array',
- 'description' => 'When joining entities in the UI, which fields should be presented by default in the ON clause',
- ],
- [
- 'name' => 'group_weights_by',
- 'data_type' => 'Array',
- 'description' => 'For sortable entities, what field groupings are used to order by weight',
- ],
- ];
+ return Entity::$entityFields;
}))->setCheckPermissions($checkPermissions);
}
];
}
- /**
- * Collect the 'type' values from every entity.
- *
- * @return array
- */
- private static function getEntityTypes() {
- $provider = \Civi::service('action_object_provider');
- $entityTypes = [];
- foreach ($provider->getEntities() as $entity) {
- foreach ($entity['type'] ?? [] as $type) {
- $entityTypes[$type] = $type;
- }
- }
- return $entityTypes;
- }
-
}
namespace Civi\Api4\Generic;
use Civi\API\Exception\NotImplementedException;
+use Civi\Api4\Utils\CoreUtil;
/**
* Lists information about fields for the $ENTITY entity.
$this->setFieldSuffixes($field);
}
if (isset($defaults['options'])) {
- $field['options'] = $this->formatOptionList($field['options']);
+ $this->formatOptionList($field);
}
$field = array_diff_key($field, $internalProps);
}
}
/**
- * Transforms option list into the format specified in $this->loadOptions
+ * Sets `options` and `suffixes` based on pseudoconstant if given.
*
- * @param $options
- * @return array|bool
+ * Transforms option list into the format specified in $this->loadOptions.
+ *
+ * @param array $field
*/
- private function formatOptionList($options) {
- if (!$this->loadOptions || !is_array($options)) {
- return (bool) $options;
+ private function formatOptionList(&$field) {
+ if (empty($field['options'])) {
+ $field['options'] = !empty($field['pseudoconstant']);
+ }
+ if (!empty($field['pseudoconstant']['optionGroupName'])) {
+ $field['suffixes'] = CoreUtil::getOptionValueFields($field['pseudoconstant']['optionGroupName']);
+ }
+ if (!$this->loadOptions || !$field['options']) {
+ $field['options'] = (bool) $field['options'];
+ return;
+ }
+ if (!empty($field['pseudoconstant'])) {
+ if (!empty($field['pseudoconstant']['optionGroupName'])) {
+ $field['options'] = self::pseudoconstantOptions($field['pseudoconstant']['optionGroupName']);
+ }
+ elseif (!empty($field['pseudoconstant']['callback'])) {
+ $field['options'] = call_user_func(\Civi\Core\Resolver::singleton()->get($field['pseudoconstant']['callback']));
+ }
+ else {
+ throw new \CRM_Core_Exception('Unsupported pseudoconstant type for field "' . $field['name'] . '"');
+ }
}
- if (!$options) {
- return $options;
+ if (!$field['options'] || !is_array($field['options'])) {
+ return;
}
+
$formatted = [];
- $first = reset($options);
+ $first = reset($field['options']);
// Flat array requested
if ($this->loadOptions === TRUE) {
// Convert non-associative to flat array
if (is_array($first) && isset($first['id'])) {
- foreach ($options as $option) {
+ foreach ($field['options'] as $option) {
$formatted[$option['id']] = $option['label'] ?? $option['name'] ?? $option['id'];
}
- return $formatted;
+ $field['options'] = $formatted;
}
- return $options;
}
// Non-associative array of multiple properties requested
- foreach ($options as $id => $option) {
- // Transform a flat list
- if (!is_array($option)) {
- $option = [
- 'id' => $id,
- 'name' => $id,
- 'label' => $option,
- ];
+ else {
+ foreach ($field['options'] as $id => $option) {
+ // Transform a flat list
+ if (!is_array($option)) {
+ $option = [
+ 'id' => $id,
+ 'name' => $id,
+ 'label' => $option,
+ ];
+ }
+ $formatted[] = array_intersect_key($option, array_flip($this->loadOptions));
}
- $formatted[] = array_intersect_key($option, array_flip($this->loadOptions));
+ $field['options'] = $formatted;
}
- return $formatted;
}
/**
'data_type' => 'Array',
'default_value' => FALSE,
],
+ [
+ 'name' => 'pseudoconstant',
+ '@internal' => TRUE,
+ ],
[
'name' => 'suffixes',
'data_type' => 'Array',