foreign attributes unset and foregn names load

This commit is contained in:
Yuri Kuznetsov
2024-04-09 13:07:45 +03:00
parent 7253082497
commit bb091a0301
3 changed files with 133 additions and 19 deletions
+38 -13
View File
@@ -79,15 +79,25 @@ class Entity extends BaseEntity
throw new LogicException("Called `loadParentNameField` on non-link-parent field `$field`.");
}
$parentId = $this->get($field . 'Id');
$idAttribute = $field . 'Id';
$nameAttribute = $field . 'Name';
$parentId = $this->get($idAttribute);
$parentType = $this->get($field . 'Type');
if (!$this->entityManager) {
throw new LogicException("No entity-manager.");
}
$toSetFetched = !$this->isNew() && !$this->hasFetched($idAttribute);
if (!$parentId || !$parentType) {
$this->set($field . 'Name', null);
/** @noinspection PhpRedundantOptionalArgumentInspection */
$this->set($nameAttribute, null);
if ($toSetFetched) {
$this->setFetched($nameAttribute, null);
}
return;
}
@@ -105,13 +115,13 @@ class Entity extends BaseEntity
->where(['id' => $parentId])
->findOne();
if ($foreignEntity) {
$this->set($field . 'Name', $foreignEntity->get('name'));
$entityName = $foreignEntity ? $foreignEntity->get('name') : null;
return;
$this->set($nameAttribute, $entityName);
if ($toSetFetched) {
$this->setFetched($nameAttribute, $entityName);
}
$this->set($field . 'Name', null);
}
/**
@@ -262,21 +272,34 @@ class Entity extends BaseEntity
}
$idsAttribute = $field . 'Ids';
$namesAttribute = $field . 'Names';
$typesAttribute = $field . 'Types';
$columnsAttribute = $field . 'Columns';
$toSetFetched = !$this->isNew() && !$this->hasFetched($idsAttribute);
$this->set($idsAttribute, $ids);
$this->set($namesAttribute, $names);
if (!$this->isNew() && !$this->hasFetched($idsAttribute)) {
if ($toSetFetched) {
$this->setFetched($idsAttribute, $ids);
$this->setFetched($namesAttribute, $names);
}
$this->set($field . 'Names', $names);
if ($hasType) {
$this->set($field . 'Types', $types);
$this->set($typesAttribute, $types);
if ($toSetFetched) {
$this->setFetched($typesAttribute, $types);
}
}
if (!empty($columns)) {
$this->set($field . 'Columns', $columnsData);
$this->set($columnsAttribute, $columnsData);
if ($toSetFetched) {
$this->setFetched($columnsAttribute, $columnsData);
}
}
}
@@ -317,13 +340,15 @@ class Entity extends BaseEntity
}
$idAttribute = $field . 'Id';
$nameAttribute = $field . 'Name';
if (!$this->isNew() && !$this->hasFetched($idAttribute)) {
$this->setFetched($idAttribute, $entityId);
$this->setFetched($nameAttribute, $entityName);
}
$this->set($idAttribute, $entityId);
$this->set($field . 'Name', $entityName);
$this->set($nameAttribute, $entityName);
}
/**
@@ -48,10 +48,13 @@ use Espo\ORM\Defs\FieldDefs;
use Espo\ORM\Defs\RelationDefs;
use Espo\ORM\Entity;
use Espo\ORM\EntityManager;
use Espo\ORM\Type\AttributeType;
use Espo\ORM\Type\RelationType;
use stdClass;
/**
* Check access for record linking. When linking directly through relationships or via link fields.
* Also loads foreign name attributes.
*/
class LinkCheck
{
@@ -135,6 +138,7 @@ class LinkCheck
/** @var string[] $oldIds */
$oldIds = $entity->getFetched($attribute) ?? [];
$setIds = $ids;
$ids = array_values(array_diff($ids, $oldIds));
$removedIds = array_values(array_diff($oldIds, $ids));
@@ -148,9 +152,25 @@ class LinkCheck
continue;
}
$namesAttribute = $name . 'Names';
$names = $this->prepareNames($entity, $namesAttribute, $setIds);
foreach ($ids as $id) {
$this->processLinkedRecordsCheckItem($entity, $relationDefs, $id);
$foreignEntity = $this->processLinkedRecordsCheckItem($entity, $relationDefs, $id);
if ($foreignEntity) {
$names->$id = $foreignEntity->get('name');
}
}
$namesAttributeDefs = $entityDefs->tryGetAttribute($namesAttribute);
if (!$namesAttributeDefs || !$namesAttributeDefs->getParam('isLinkMultipleNameMap')) {
continue;
}
$entity->set($namesAttribute, $names);
}
}
@@ -190,13 +210,13 @@ class LinkCheck
RelationDefs $defs,
string $id,
bool $isOne = false
): void {
): ?Entity {
$entityType = $entity->getEntityType();
$link = $defs->getName();
if ($this->getParam($entityType, $link, 'linkCheckDisabled')) {
return;
return null;
}
$foreignEntityType = null;
@@ -206,7 +226,7 @@ class LinkCheck
}
if (!$foreignEntityType && !$defs->hasForeignEntityType()) {
return;
return null;
}
$foreignEntityType ??= $defs->getForeignEntityType();
@@ -226,10 +246,12 @@ class LinkCheck
$toSkip = $this->linkForeignAccessCheck($isOne, $entityType, $link, $foreignEntity);
if ($toSkip) {
return;
return $foreignEntity;
}
$this->linkEntityAccessCheck($entity, $foreignEntity, $link);
return $foreignEntity;
}
/**
@@ -548,6 +570,7 @@ class LinkCheck
foreach ($entityDefs->getRelationList() as $relationDefs) {
$name = $relationDefs->getName();
$attribute = $name . 'Id';
$nameAttribute = $name . 'Name';
if (
!in_array($relationDefs->getType(), $typeList) ||
@@ -562,7 +585,26 @@ class LinkCheck
$id = $entity->get($attribute);
$this->processLinkedRecordsCheckItem($entity, $relationDefs, $id, true);
$foreignEntity = $this->processLinkedRecordsCheckItem($entity, $relationDefs, $id, true);
if (!$foreignEntity) {
continue;
}
$nameAttributeDefs = $entityDefs->tryGetAttribute($nameAttribute);
if (!$nameAttributeDefs) {
return;
}
if (
$nameAttributeDefs->getType() === AttributeType::FOREIGN ||
$nameAttributeDefs->isNotStorable()
) {
$foreignName = $relationDefs->getParam('foreignName') ?? 'name';
$entity->set($nameAttribute, $foreignEntity->get($foreignName));
}
}
}
@@ -633,4 +675,26 @@ class LinkCheck
return $defaultAttributes->$attribute ?? null;
}
/**
* @param string[] $setIds
*/
private function prepareNames(Entity $entity, string $namesAttribute, array $setIds): stdClass
{
$oldNames = $entity->getFetched($namesAttribute);
if (!$oldNames instanceof stdClass) {
$oldNames = (object) [];
}
$names = (object) [];
foreach ($setIds as $id) {
if (isset($oldNames->$id)) {
$names->$id = $oldNames->$id;
}
}
return $names;
}
}
+25
View File
@@ -69,6 +69,7 @@ use Espo\ORM\Entity;
use Espo\ORM\Repository\RDBRepository;
use Espo\ORM\Collection;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Type\AttributeType;
use Espo\Tools\Stream\Service as StreamService;
use Espo\Entities\User;
@@ -582,6 +583,30 @@ class Service implements Crud,
unset($data->$attribute);
}
}
$this->filterInputForeignAttributes($data);
}
private function filterInputForeignAttributes(stdClass $data): void
{
$entityDefs = $this->entityManager->getDefs()->tryGetEntity($this->entityType);
if (!$entityDefs) {
return;
}
foreach ($entityDefs->getAttributeList() as $attributeDefs) {
if (
$attributeDefs->getType() !== AttributeType::FOREIGN &&
!$attributeDefs->getParam('isLinkMultipleNameMap')
) {
continue;
}
$attribute = $attributeDefs->getName();
unset($data->$attribute);
}
}
private function filterInputSystemAttributes(stdClass $data): void