* @see \Civi\Api4\Activity
* @package Civi\Api4
*/
-class ActivityContact extends Generic\BridgeEntity {
+class ActivityContact extends Generic\DAOEntity {
+ use Generic\Traits\EntityBridge;
}
* @package Civi\Api4
*/
class Country extends Generic\DAOEntity {
+ use Generic\Traits\OptionList;
}
* @see \Civi\Api4\Dashboard
* @package Civi\Api4
*/
-class DashboardContact extends Generic\BridgeEntity {
+class DashboardContact extends Generic\DAOEntity {
+ use Generic\Traits\EntityBridge;
}
],
[
'name' => 'type',
+ 'data_type' => 'Array',
'description' => 'Base class for this entity',
- 'options' => ['DAOEntity' => 'DAOEntity', 'BasicEntity' => 'BasicEntity', 'BridgeEntity' => 'BridgeEntity', 'AbstractEntity' => 'AbstractEntity'],
+ 'options' => [
+ 'AbstractEntity' => 'AbstractEntity',
+ 'DAOEntity' => 'DAOEntity',
+ 'BasicEntity' => 'BasicEntity',
+ 'EntityBridge' => 'EntityBridge',
+ 'OptionList' => 'OptionList',
+ ],
],
[
'name' => 'description',
*
* @package Civi\Api4
*/
-class EntityTag extends Generic\BridgeEntity {
+class EntityTag extends Generic\DAOEntity {
+ use Generic\Traits\EntityBridge;
}
'name' => static::getEntityName(),
'title' => static::getEntityTitle(),
'title_plural' => static::getEntityTitle(TRUE),
- 'type' => self::stripNamespace(get_parent_class(static::class)),
+ 'type' => [self::stripNamespace(get_parent_class(static::class))],
'paths' => static::getEntityPaths(),
];
+ foreach (ReflectionUtils::getTraits(static::class) as $trait) {
+ $info['type'][] = self::stripNamespace($trait);
+ }
$reflection = new \ReflectionClass(static::class);
$info += ReflectionUtils::getCodeDocs($reflection, NULL, ['entity' => $info['name']]);
unset($info['package'], $info['method']);
*
* - `Entity`: the name of the api entity to join onto.
* - `Required`: `TRUE` for an `INNER JOIN`, `FALSE` for a `LEFT JOIN`.
- * - `Bridge` (optional): Name of a BridgeEntity to incorporate into the join.
+ * - `Bridge` (optional): Name of a Bridge to incorporate into the join.
* - `[field, op, value]...`: zero or more conditions for the ON clause, using the same nested format as WHERE and HAVING
* but with the difference that "value" is interpreted as an expression (e.g. can be the name of a field).
* Enclose literal values with quotes.
*
* @var array
- * @see \Civi\Api4\Generic\BridgeEntity
+ * @see \Civi\Api4\Generic\Traits\EntityBridge
*/
protected $join = [];
+--------------------------------------------------------------------+
*/
-namespace Civi\Api4\Generic;
+namespace Civi\Api4\Generic\Traits;
/**
* A bridge is a small table that provides an intermediary link between two other tables.
*
- * The API can automatically incorporate a bridgeEntity into a join expression.
+ * The API can automatically incorporate a Bridge into a join expression.
*/
-class BridgeEntity extends DAOEntity {
+trait EntityBridge {
}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Generic\Traits;
+
+/**
+ * An optionList is a small entity whose primary purpose is to supply a semi-static list of options to fields in other entities.
+ *
+ * The options appear in the field metadata for other entities that reference this one via pseudoconstant.
+ */
+trait OptionList {
+
+}
*
* @package Civi\Api4
*/
-class GroupContact extends Generic\BridgeEntity {
+class GroupContact extends Generic\DAOEntity {
+ use Generic\Traits\EntityBridge;
/**
* @param bool $checkPermissions
* @package Civi\Api4
*/
class LocationType extends Generic\DAOEntity {
+ use Generic\Traits\OptionList;
}
* @package Civi\Api4
*/
class MembershipType extends Generic\DAOEntity {
+ use Generic\Traits\OptionList;
}
* @package Civi\Api4
*/
class OptionValue extends Generic\DAOEntity {
+ use Generic\Traits\OptionList;
}
* @package Civi\Api4
*/
class PaymentProcessorType extends Generic\DAOEntity {
+ use Generic\Traits\OptionList;
}
}
/**
- * Join onto a BridgeEntity table
+ * Join onto a Bridge table
*
* @param array $joinTree
* @param string $joinEntity
*/
protected function getBridgeJoin(&$joinTree, $joinEntity, $alias) {
$bridgeEntity = array_shift($joinTree);
- if (!is_a('\Civi\Api4\\' . $bridgeEntity, '\Civi\Api4\Generic\BridgeEntity', TRUE)) {
+ /* @var \Civi\Api4\Generic\DAOEntity $bridgeEntityClass */
+ $bridgeEntityClass = '\Civi\Api4\\' . $bridgeEntity;
+ if (!in_array('EntityBridge', $bridgeEntityClass::getInfo()['type'], TRUE)) {
throw new \API_Exception("Illegal bridge entity specified: " . $bridgeEntity);
}
$bridgeAlias = $alias . '_via_' . strtolower($bridgeEntity);
$bridgeTable = CoreUtil::getTableName($bridgeEntity);
$joinTable = CoreUtil::getTableName($joinEntity);
- $bridgeEntityGet = \Civi\API\Request::create($bridgeEntity, 'get', ['version' => 4, 'checkPermissions' => $this->getCheckPermissions()]);
+ $bridgeEntityGet = $bridgeEntityClass::get($this->getCheckPermissions());
$fkToJoinField = $fkToBaseField = NULL;
// Find the bridge field that links to the joinEntity (either an explicit FK or an entity_id/entity_table combo)
foreach ($bridgeEntityGet->entityFields() as $name => $field) {
* @package Civi\Api4
*/
class RelationshipCache extends Generic\AbstractEntity {
+ use Generic\Traits\EntityBridge;
/**
* @param bool $checkPermissions
* @package Civi\Api4
*/
class RelationshipType extends Generic\DAOEntity {
+ use Generic\Traits\OptionList;
}
* @package Civi\Api4
*/
class StateProvince extends Generic\DAOEntity {
+ use Generic\Traits\OptionList;
}
* @package Civi\Api4
*/
class UFJoin extends Generic\DAOEntity {
+ use Generic\Traits\EntityBridge;
}
*
* @package Civi\Api4
*/
-class UFMatch extends Generic\BridgeEntity {
+class UFMatch extends Generic\DAOEntity {
+ use Generic\Traits\EntityBridge;
}
$scope.controls = {};
$scope.langs = ['php', 'js', 'ang', 'cli'];
$scope.joinTypes = [{k: false, v: 'FALSE (LEFT JOIN)'}, {k: true, v: 'TRUE (INNER JOIN)'}];
- $scope.bridgeEntities = _.filter(schema, {type: 'BridgeEntity'});
+ $scope.bridgeEntities = _.filter(schema, function(entity) {return _.includes(entity.type, 'EntityBridge');});
$scope.code = {
php: [
{name: 'oop', label: ts('OOP Style'), code: ''},
setHelp($scope.entity, {
description: entityInfo.description,
comment: entityInfo.comment,
+ type: entityInfo.type,
see: entityInfo.see
});
}
public static function getSchema() {
$schema = [];
$entities = \Civi\Api4\Entity::get()
- ->addSelect('name', 'title', 'title_plural', 'description', 'icon', 'paths')
+ ->addSelect('name', 'title', 'type', 'title_plural', 'description', 'icon', 'paths')
->addWhere('name', '!=', 'Entity')
->addOrderBy('title_plural')
->setChain([
$scope.controls = {tab: 'compose'};
$scope.joinTypes = [{k: false, v: ts('Optional')}, {k: true, v: ts('Required')}];
$scope.groupOptions = CRM.crmSearchActions.groupOptions;
- $scope.entities = formatForSelect2(CRM.vars.search.schema, 'name', 'title_plural', ['description', 'icon']);
+ // Try to create a sensible list of entities one might want to search for,
+ // excluding those whos primary purpose is to provide joins or option lists to other entities
+ var primaryEntities = _.filter(CRM.vars.search.schema, function(entity) {
+ return !_.includes(entity.type, 'EntityBridge') && !_.includes(entity.type, 'OptionList');
+ });
+ $scope.entities = formatForSelect2(primaryEntities, 'name', 'title_plural', ['description', 'icon']);
this.perm = {
editGroups: CRM.checkPerm('edit groups')
};