mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 06:56:05 +00:00
ref
This commit is contained in:
@@ -31,6 +31,7 @@ namespace Espo\Core\Controllers;
|
||||
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\Core\Exceptions\NotFoundSilent;
|
||||
@@ -77,6 +78,7 @@ class Record extends RecordBase
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
* @throws Error
|
||||
*/
|
||||
public function postActionCreateLink(Request $request): bool
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ use stdClass;
|
||||
/**
|
||||
* Contains an ORM collection and total number of records.
|
||||
*
|
||||
* @template TEntity of \Espo\ORM\Entity
|
||||
* @template-covariant TEntity of \Espo\ORM\Entity
|
||||
*/
|
||||
class Collection
|
||||
{
|
||||
|
||||
@@ -251,7 +251,7 @@ class Service implements Crud,
|
||||
$entity = $this->getEntity($id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFoundSilent("Record {$id} does not exist.");
|
||||
throw new NotFoundSilent("Record $id does not exist.");
|
||||
}
|
||||
|
||||
$this->recordHookManager->processBeforeRead($entity, $params);
|
||||
@@ -712,7 +712,7 @@ class Service implements Crud,
|
||||
$this->getRepository()->getById($id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFound("Record {$id} not found.");
|
||||
throw new NotFound("Record $id not found.");
|
||||
}
|
||||
|
||||
if (!$this->getEntityBeforeUpdate) {
|
||||
@@ -773,7 +773,7 @@ class Service implements Crud,
|
||||
$entity = $this->getRepository()->getById($id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFound("Record {$id} not found.");
|
||||
throw new NotFound("Record $id not found.");
|
||||
}
|
||||
|
||||
if (!$this->acl->check($entity, AclTable::ACTION_DELETE)) {
|
||||
@@ -946,10 +946,8 @@ class Service implements Crud,
|
||||
|
||||
$this->processForbiddenLinkReadCheck($link);
|
||||
|
||||
$methodName = 'findLinked' . ucfirst($link);
|
||||
|
||||
if (method_exists($this, $methodName)) {
|
||||
return $this->$methodName($id, $searchParams);
|
||||
if ($methodResult = $this->processFindLinkedMethod($id, $link, $searchParams)) {
|
||||
return $methodResult;
|
||||
}
|
||||
|
||||
$foreignEntityType = $this->entityManager
|
||||
@@ -1028,6 +1026,27 @@ class Service implements Crud,
|
||||
return RecordCollection::create($collection, $total);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $link
|
||||
* @return ?RecordCollection<Entity>
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
*/
|
||||
private function processFindLinkedMethod(string $id, string $link, SearchParams $searchParams): ?RecordCollection
|
||||
{
|
||||
if ($link === 'followers') {
|
||||
return $this->findLinkedFollowers($id, $searchParams);
|
||||
}
|
||||
|
||||
$methodName = 'findLinked' . ucfirst($link);
|
||||
|
||||
if (method_exists($this, $methodName)) {
|
||||
return $this->$methodName($id, $searchParams);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Link records.
|
||||
*
|
||||
@@ -1059,18 +1078,14 @@ class Service implements Crud,
|
||||
|
||||
$this->getLinkCheck()->processLink($entity, $link);
|
||||
|
||||
$methodName = 'link' . ucfirst($link);
|
||||
|
||||
if ($link !== 'entity' && $link !== 'entityMass' && method_exists($this, $methodName)) {
|
||||
$this->$methodName($id, $foreignId);
|
||||
|
||||
if ($this->processLinkMethod($id, $link, $foreignId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$foreignEntityType = $entity->getRelationParam($link, 'entity');
|
||||
|
||||
if (!$foreignEntityType) {
|
||||
throw new LogicException("Entity '{$this->entityType}' has not relation '{$link}'.");
|
||||
throw new LogicException("Entity '$this->entityType' has not relation '$link'.");
|
||||
}
|
||||
|
||||
$foreignEntity = $this->entityManager->getEntityById($foreignEntityType, $foreignId);
|
||||
@@ -1119,18 +1134,14 @@ class Service implements Crud,
|
||||
|
||||
$this->getLinkCheck()->processLink($entity, $link);
|
||||
|
||||
$methodName = 'unlink' . ucfirst($link);
|
||||
|
||||
if ($link !== 'entity' && method_exists($this, $methodName)) {
|
||||
$this->$methodName($id, $foreignId);
|
||||
|
||||
if ($this->processUnlinkMethod($id, $link, $foreignId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$foreignEntityType = $entity->getRelationParam($link, 'entity');
|
||||
|
||||
if (!$foreignEntityType) {
|
||||
throw new LogicException("Entity '{$this->entityType}' has not relation '{$link}'.");
|
||||
throw new LogicException("Entity '$this->entityType' has not relation '$link'.");
|
||||
}
|
||||
|
||||
$foreignEntity = $this->entityManager->getEntityById($foreignEntityType, $foreignId);
|
||||
@@ -1148,12 +1159,65 @@ class Service implements Crud,
|
||||
->unrelate($foreignEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
*/
|
||||
private function processLinkMethod(string $id, string $link, string $foreignId): bool
|
||||
{
|
||||
if ($link === 'followers') {
|
||||
$this->linkFollowers($id, $foreignId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$methodName = 'link' . ucfirst($link);
|
||||
|
||||
if (
|
||||
$link !== 'entity' &&
|
||||
$link !== 'entityMass' &&
|
||||
method_exists($this, $methodName)
|
||||
) {
|
||||
$this->$methodName($id, $foreignId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
*/
|
||||
private function processUnlinkMethod(string $id, string $link, string $foreignId): bool
|
||||
{
|
||||
if ($link === 'followers') {
|
||||
$this->unlinkFollowers($id, $foreignId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$methodName = 'unlink' . ucfirst($link);
|
||||
|
||||
if (
|
||||
$link !== 'entity' &&
|
||||
method_exists($this, $methodName)
|
||||
) {
|
||||
$this->$methodName($id, $foreignId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
* @throws ForbiddenSilent
|
||||
*/
|
||||
public function linkFollowers(string $id, string $foreignId): void
|
||||
protected function linkFollowers(string $id, string $foreignId): void
|
||||
{
|
||||
if (!$this->acl->check($this->entityType, AclTable::ACTION_EDIT)) {
|
||||
throw new Forbidden();
|
||||
@@ -1169,8 +1233,8 @@ class Service implements Crud,
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
/** @var User|null $user */
|
||||
$user = $this->entityManager->getEntity(User::ENTITY_TYPE, $foreignId);
|
||||
/** @var ?User $user */
|
||||
$user = $this->entityManager->getEntityById(User::ENTITY_TYPE, $foreignId);
|
||||
|
||||
if (!$user) {
|
||||
throw new NotFound();
|
||||
@@ -1223,7 +1287,7 @@ class Service implements Crud,
|
||||
* @throws NotFound
|
||||
* @throws ForbiddenSilent
|
||||
*/
|
||||
public function unlinkFollowers(string $id, string $foreignId): void
|
||||
protected function unlinkFollowers(string $id, string $foreignId): void
|
||||
{
|
||||
if (!$this->acl->check($this->entityType, AclTable::ACTION_EDIT)) {
|
||||
throw new Forbidden();
|
||||
@@ -1277,6 +1341,7 @@ class Service implements Crud,
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
* @throws Error
|
||||
*/
|
||||
public function massLink(string $id, string $link, SearchParams $searchParams): bool
|
||||
{
|
||||
@@ -1313,7 +1378,7 @@ class Service implements Crud,
|
||||
$foreignEntityType = $entity->getRelationParam($link, 'entity');
|
||||
|
||||
if (empty($foreignEntityType)) {
|
||||
throw new LogicException("Link '{$link}' has no 'entity'.");
|
||||
throw new LogicException("Link '$link' has no 'entity'.");
|
||||
}
|
||||
|
||||
$accessActionRequired = AclTable::ACTION_EDIT;
|
||||
@@ -1372,7 +1437,7 @@ class Service implements Crud,
|
||||
protected function processForbiddenLinkReadCheck(string $link): void
|
||||
{
|
||||
$forbiddenLinkList = $this->acl
|
||||
->getScopeForbiddenLinkList($this->entityType, AclTable::ACTION_READ);
|
||||
->getScopeForbiddenLinkList($this->entityType);
|
||||
|
||||
if (in_array($link, $forbiddenLinkList)) {
|
||||
throw new Forbidden();
|
||||
@@ -1554,8 +1619,7 @@ class Service implements Crud,
|
||||
}
|
||||
}
|
||||
|
||||
$forbiddenAttributeList = $this->acl
|
||||
->getScopeForbiddenAttributeList($entity->getEntityType(), AclTable::ACTION_READ);
|
||||
$forbiddenAttributeList = $this->acl->getScopeForbiddenAttributeList($entity->getEntityType());
|
||||
|
||||
foreach ($forbiddenAttributeList as $attribute) {
|
||||
$entity->clear($attribute);
|
||||
@@ -1667,12 +1731,16 @@ class Service implements Crud,
|
||||
->find();
|
||||
|
||||
foreach ($linkedList as $linked) {
|
||||
$repository->relate($entity, $link, $linked);
|
||||
$repository
|
||||
->getRelation($entity, $link)
|
||||
->relate($linked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @todo Remove in v7.6.
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
*/
|
||||
|
||||
@@ -35,7 +35,7 @@ use stdClass;
|
||||
/**
|
||||
* A collection of entities.
|
||||
*
|
||||
* @template TEntity of Entity
|
||||
* @template-covariant TEntity of Entity
|
||||
* @extends Traversable<int, TEntity>
|
||||
*/
|
||||
interface Collection extends Traversable
|
||||
|
||||
Reference in New Issue
Block a user