foreign attributes unset and foregn names load
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user