From 9302c3de014e79f622e59d3c69af00bb302a7473 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Sat, 14 Sep 2024 09:53:35 +0300 Subject: [PATCH] portal access filter ref, no distinct --- .../Filters/PortalOnlyAccount.php | 77 +++++++++++++------ .../Filters/PortalOnlyContact.php | 45 +++++++---- .../Espo/Core/Select/Helpers/FieldHelper.php | 9 +++ 3 files changed, 96 insertions(+), 35 deletions(-) diff --git a/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyAccount.php b/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyAccount.php index ab7663bcfe..57c15b067f 100644 --- a/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyAccount.php +++ b/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyAccount.php @@ -34,6 +34,10 @@ use Espo\Core\Select\Helpers\FieldHelper; use Espo\Entities\User; use Espo\Modules\Crm\Entities\Account; use Espo\Modules\Crm\Entities\Contact; +use Espo\ORM\Query\Part\Condition as Cond; +use Espo\ORM\Query\Part\Expression as Expr; +use Espo\ORM\Query\Part\Where\OrGroup; +use Espo\ORM\Query\Part\WhereClause; use Espo\ORM\Query\SelectBuilder as QueryBuilder; class PortalOnlyAccount implements Filter @@ -45,63 +49,92 @@ class PortalOnlyAccount implements Filter public function apply(QueryBuilder $queryBuilder): void { - $orGroup = []; + $orBuilder = OrGroup::createBuilder(); $accountIdList = $this->user->getLinkMultipleIdList('accounts'); $contactId = $this->user->get('contactId'); if (count($accountIdList)) { if ($this->fieldHelper->hasAccountField()) { - $orGroup['accountId'] = $accountIdList; + $orBuilder->add( + Cond::in( + Expr::column('accountId'), + $accountIdList + ) + ); } if ($this->fieldHelper->hasAccountsRelation()) { - $queryBuilder - ->leftJoin('accounts', 'accountsAccess') - ->distinct(); + $defs = $this->fieldHelper->getRelationDefs('accounts'); - $orGroup['accountsAccess.id'] = $accountIdList; + $orBuilder->add( + Cond::in( + Expr::column('id'), + QueryBuilder::create() + ->from(ucfirst($defs->getRelationshipName()), 'm') + ->select($defs->getMidKey()) + ->where([$defs->getForeignMidKey() => $accountIdList]) + ->build() + ) + ); } if ($this->fieldHelper->hasParentField()) { - $orGroup[] = [ - 'parentType' => Account::ENTITY_TYPE, - 'parentId' => $accountIdList, - ]; + $orBuilder->add( + WhereClause::fromRaw([ + 'parentType' => Account::ENTITY_TYPE, + 'parentId' => $accountIdList, + ]) + ); if ($contactId) { - $orGroup[] = [ - 'parentType' => Contact::ENTITY_TYPE, - 'parentId' => $contactId, - ]; + $orBuilder->add( + WhereClause::fromRaw([ + 'parentType' => Contact::ENTITY_TYPE, + 'parentId' => $contactId, + ]) + ); } } } if ($contactId) { if ($this->fieldHelper->hasContactField()) { - $orGroup['contactId'] = $contactId; + $orBuilder->add( + WhereClause::fromRaw(['contactId' => $contactId]) + ); } if ($this->fieldHelper->hasContactsRelation()) { - $queryBuilder - ->leftJoin('contacts', 'contactsAccess') - ->distinct(); + $defs = $this->fieldHelper->getRelationDefs('contacts'); - $orGroup['contactsAccess.id'] = $contactId; + $orBuilder->add( + Cond::in( + Expr::column('id'), + QueryBuilder::create() + ->from(ucfirst($defs->getRelationshipName()), 'm') + ->select($defs->getMidKey()) + ->where([$defs->getForeignMidKey() => $contactId]) + ->build() + ) + ); } } if ($this->fieldHelper->hasCreatedByField()) { - $orGroup['createdById'] = $this->user->getId(); + $orBuilder->add( + WhereClause::fromRaw(['createdById' => $this->user->getId()]) + ); } - if (empty($orGroup)) { + $orGroup = $orBuilder->build(); + + if ($orGroup->getItemCount() === 0) { $queryBuilder->where(['id' => null]); return; } - $queryBuilder->where(['OR' => $orGroup]); + $queryBuilder->where($orGroup); } } diff --git a/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyContact.php b/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyContact.php index 9c910c2d65..fc5b4096b0 100644 --- a/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyContact.php +++ b/application/Espo/Core/Select/AccessControl/Filters/PortalOnlyContact.php @@ -33,6 +33,10 @@ use Espo\Core\Select\AccessControl\Filter; use Espo\Core\Select\Helpers\FieldHelper; use Espo\Entities\User; use Espo\Modules\Crm\Entities\Contact; +use Espo\ORM\Query\Part\Condition as Cond; +use Espo\ORM\Query\Part\Expression as Expr; +use Espo\ORM\Query\Part\Where\OrGroup; +use Espo\ORM\Query\Part\WhereClause; use Espo\ORM\Query\SelectBuilder as QueryBuilder; class PortalOnlyContact implements Filter @@ -44,41 +48,56 @@ class PortalOnlyContact implements Filter public function apply(QueryBuilder $queryBuilder): void { - $orGroup = []; + $orBuilder = OrGroup::createBuilder(); $contactId = $this->user->get('contactId'); if ($contactId) { if ($this->fieldHelper->hasContactField()) { - $orGroup['contactId'] = $contactId; + $orBuilder->add( + WhereClause::fromRaw(['contactId' => $contactId]) + ); } if ($this->fieldHelper->hasContactsRelation()) { - $queryBuilder - ->leftJoin('contacts', 'contactsAccess') - ->distinct(); + $defs = $this->fieldHelper->getRelationDefs('contacts'); - $orGroup['contactsAccess.id'] = $contactId; + $orBuilder->add( + Cond::in( + Expr::column('id'), + QueryBuilder::create() + ->from(ucfirst($defs->getRelationshipName()), 'm') + ->select($defs->getMidKey()) + ->where([$defs->getForeignMidKey() => $contactId]) + ->build() + ) + ); } if ($this->fieldHelper->hasParentField()) { - $orGroup[] = [ - 'parentType' => Contact::ENTITY_TYPE, - 'parentId' => $contactId, - ]; + $orBuilder->add( + WhereClause::fromRaw([ + 'parentType' => Contact::ENTITY_TYPE, + 'parentId' => $contactId, + ]) + ); } } if ($this->fieldHelper->hasCreatedByField()) { - $orGroup['createdById'] = $this->user->getId(); + $orBuilder->add( + WhereClause::fromRaw(['createdById' => $this->user->getId()]) + ); } - if (empty($orGroup)) { + $orGroup = $orBuilder->build(); + + if ($orGroup->getItemCount() === 0) { $queryBuilder->where(['id' => null]); return; } - $queryBuilder->where(['OR' => $orGroup]); + $queryBuilder->where($orGroup); } } diff --git a/application/Espo/Core/Select/Helpers/FieldHelper.php b/application/Espo/Core/Select/Helpers/FieldHelper.php index 81ef15e89f..ad47680c36 100644 --- a/application/Espo/Core/Select/Helpers/FieldHelper.php +++ b/application/Espo/Core/Select/Helpers/FieldHelper.php @@ -29,6 +29,7 @@ namespace Espo\Core\Select\Helpers; +use Espo\ORM\Defs\RelationDefs; use Espo\ORM\EntityManager; use Espo\ORM\Entity; use Espo\ORM\BaseEntity; @@ -125,6 +126,14 @@ class FieldHelper $this->getRelationParam($this->getSeed(), 'accounts', 'entity') === 'Account'; } + public function getRelationDefs(string $name): RelationDefs + { + return $this->entityManager + ->getDefs() + ->getEntity($this->entityType) + ->getRelation($name); + } + /** * @return mixed */