RelationQueryHelper

This commit is contained in:
Yuri Kuznetsov
2024-09-15 14:23:12 +03:00
parent e211147225
commit af7d88dd6b
3 changed files with 91 additions and 28 deletions
@@ -30,9 +30,9 @@
namespace Espo\Core\Select\AccessControl\Filters;
use Espo\Core\Select\AccessControl\Filter;
use Espo\Core\Select\Helpers\RelationQueryHelper;
use Espo\Core\Select\Helpers\FieldHelper;
use Espo\Entities\User;
use Espo\ORM\Defs;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyOwn implements Filter
@@ -41,31 +41,15 @@ class OnlyOwn implements Filter
private User $user,
private FieldHelper $fieldHelper,
private string $entityType,
private Defs $defs
private RelationQueryHelper $relationQueryHelper,
) {}
public function apply(QueryBuilder $queryBuilder): void
{
if ($this->fieldHelper->hasAssignedUsersField()) {
$relationDefs = $this->defs
->getEntity($this->entityType)
->getRelation('assignedUsers');
$middleEntityType = ucfirst($relationDefs->getRelationshipName());
$key1 = $relationDefs->getMidKey();
$key2 = $relationDefs->getForeignMidKey();
$subQuery = QueryBuilder::create()
->select('id')
->from($this->entityType)
->leftJoin($middleEntityType, 'assignedUsersMiddle', [
"assignedUsersMiddle.$key1:" => 'id',
'assignedUsersMiddle.deleted' => false,
])
->where(["assignedUsersMiddle.$key2" => $this->user->getId()])
->build();
$queryBuilder->where(['id=s' => $subQuery]);
$queryBuilder->where(
$this->relationQueryHelper->prepareAssignedUsersWhere($this->entityType, $this->user->getId())
);
return;
}
@@ -0,0 +1,80 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM Open Source CRM application.
* Copyright (C) 2014-2024 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Core\Select\Helpers;
use Espo\ORM\Defs;
use Espo\ORM\Query\Part\Condition;
use Espo\ORM\Query\Part\Expression;
use Espo\ORM\Query\Part\WhereItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
/**
* @since 8.5.0
*/
class RelationQueryHelper
{
public function __construct(
private Defs $defs,
) {}
/**
* @param string|string[] $id
*/
public function prepareMiddleWhere(string $entityType, string $link, string|array $id): WhereItem
{
$relationDefs = $this->defs
->getEntity($entityType)
->getRelation($link);
$middleEntityType = ucfirst($relationDefs->getRelationshipName());
$key1 = $relationDefs->getMidKey();
$key2 = $relationDefs->getForeignMidKey();
$subQuery = QueryBuilder::create()
->select('id')
->from($entityType)
->leftJoin($middleEntityType, 'm', [
"m.$key1:" => 'id',
'm.deleted' => false,
])
->where(["m.$key2" => $id])
->build();
return Condition::in(
Expression::column('id'),
$subQuery
);
}
public function prepareAssignedUsersWhere(string $entityType, string $userId): WhereItem
{
return $this->prepareMiddleWhere($entityType, 'assignedUsers', $userId);
}
}
@@ -37,6 +37,7 @@ use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\NotFound;
use Espo\Core\Field\DateTime as DateTimeField;
use Espo\Core\Select\Helpers\RelationQueryHelper;
use Espo\Core\Select\SelectBuilderFactory;
use Espo\Core\Utils\Config;
use Espo\Core\Utils\Metadata;
@@ -76,7 +77,8 @@ class Service
private Metadata $metadata,
private SelectBuilderFactory $selectBuilderFactory,
private User $user,
private ServiceFactory $serviceFactory
private ServiceFactory $serviceFactory,
private RelationQueryHelper $relationQueryHelper,
) {}
/**
@@ -524,12 +526,9 @@ class Service
$this->metadata->get(['entityDefs', 'Task', 'fields', 'assignedUsers', 'type']) === 'linkMultiple' &&
!$this->metadata->get(['entityDefs', 'Task', 'fields', 'assignedUsers', 'disabled'])
) {
$queryBuilder
->distinct()
->leftJoin('assignedUsers', 'assignedUsers')
->where([
'assignedUsers.id' => $userId,
]);
$queryBuilder->where(
$this->relationQueryHelper->prepareAssignedUsersWhere(Task::ENTITY_TYPE, $userId)
);
} else {
$queryBuilder->where([
'assignedUserId' => $userId,