*/
protected $apiVersion = 4;
+ /**
+ * @var array
+ * Maps select fields to [<table_alias>, <column_alias>]
+ */
+ protected $fkSelectAliases = [];
+
/**
* @var \Civi\Api4\Service\Schema\Joinable\Joinable[]
* The joinable tables that have been joined so far
}
$baoName = CoreUtil::getBAOFromApiName($this->entity);
$this->entityFieldNames = array_column($baoName::fields(), 'name');
- foreach ($apiGet->entityFields() as $path => $field) {
- $field['sql_name'] = '`' . self::MAIN_TABLE_ALIAS . '`.`' . $field['column_name'] . '`';
- $this->addSpecField($path, $field);
+ $this->apiFieldSpec = $apiGet->entityFields();
+ foreach ($this->apiFieldSpec as $key => $field) {
+ $this->apiFieldSpec[$key]['sql_name'] = '`' . self::MAIN_TABLE_ALIAS . '`.`' . $field['column_name'] . '`';
}
$this->constructQueryObject($baoName);
}
protected function buildSelectClause() {
- // An empty select is the same as *
if (empty($this->select)) {
$this->select = $this->entityFieldNames;
}
}
foreach ($this->select as $fieldName) {
$field = $this->getField($fieldName);
+ if (!$this->isOneToOneField($fieldName)) {
+ continue;
+ }
+ elseif ($field) {
+ $this->query->select($field['sql_name'] . " AS `$fieldName`");
+ }
// Remove unknown fields without raising an error
- if (!$field) {
+ else {
$this->select = array_diff($this->select, [$fieldName]);
if (is_array($this->debugOutput)) {
$this->debugOutput['undefined_fields'][] = $fieldName;
}
}
- elseif ($field['is_many']) {
- continue;
- }
- elseif ($field) {
- $this->query->select($field['sql_name'] . " AS `$fieldName`");
- }
}
}
$this->joinFK($fieldName);
}
$field = $this->apiFieldSpec[$fieldName] ?? NULL;
- if ($field) {
+ // Check if field exists and we have permission to view it
+ if ($field && (!$this->checkPermissions || empty($field['permission']) || \CRM_Core_Permission::check($field['permission']))) {
return $field;
}
elseif ($strict) {
* Joins a path and adds all fields in the joined eneity to apiFieldSpec
*
* @param $key
+ * @return bool
* @throws \API_Exception
* @throws \Exception
*/
protected function joinFK($key) {
if (isset($this->apiFieldSpec[$key])) {
- return;
+ return TRUE;
}
$pathArray = explode('.', $key);
$pathString = implode('.', $pathArray);
if (!$joiner->canJoin($this, $pathString)) {
- return;
+ return FALSE;
}
$joinPath = $joiner->join($this, $pathString);
-
- $isMany = FALSE;
- foreach ($joinPath as $joinable) {
- if ($joinable->getJoinType() === Joinable::JOIN_TYPE_ONE_TO_MANY) {
- $isMany = TRUE;
- }
- }
-
/** @var \Civi\Api4\Service\Schema\Joinable\Joinable $lastLink */
$lastLink = array_pop($joinPath);
// Custom field names are already prefixed
- $isCustom = $lastLink instanceof CustomGroupJoinable;
- if ($isCustom) {
+ if ($lastLink instanceof CustomGroupJoinable) {
array_pop($pathArray);
}
$prefix = $pathArray ? implode('.', $pathArray) . '.' : '';
foreach ($lastLink->getEntityFields() as $fieldObject) {
$fieldArray = ['entity' => $joinEntity] + $fieldObject->toArray();
$fieldArray['sql_name'] = '`' . $lastLink->getAlias() . '`.`' . $fieldArray['column_name'] . '`';
- $fieldArray['is_custom'] = $isCustom;
- $fieldArray['is_join'] = TRUE;
- $fieldArray['is_many'] = $isMany;
- $this->addSpecField($prefix . $fieldArray['name'], $fieldArray);
+ $this->apiFieldSpec[$prefix . $fieldArray['name']] = $fieldArray;
}
+
+ return TRUE;
}
/**
return $path;
}
- /**
- * @param $path
- * @param $field
- */
- private function addSpecField($path, $field) {
- // Only add field to spec if we have permission
- if ($this->checkPermissions && !empty($field['permission']) && !\CRM_Core_Permission::check($field['permission'])) {
- $this->apiFieldSpec[$path] = FALSE;
- return;
- }
- $defaults = [];
- $defaults['is_custom'] = $defaults['is_join'] = $defaults['is_many'] = FALSE;
- $field += $defaults;
- $this->apiFieldSpec[$path] = $field;
- }
-
}