stream acl

This commit is contained in:
yuri
2018-09-03 13:39:32 +03:00
parent b046da1d79
commit 0021e16962
8 changed files with 649 additions and 138 deletions
+1 -1
View File
@@ -34,6 +34,7 @@ use \Espo\ORM\Entity;
class Email extends \Espo\Core\Acl\Base
{
protected $ownerUserIdAttribute = 'usersIds';
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
{
@@ -118,4 +119,3 @@ class Email extends \Espo\Core\Acl\Base
return false;
}
}
+1
View File
@@ -34,6 +34,7 @@ use \Espo\ORM\Entity;
class Email extends \Espo\Core\AclPortal\Base
{
protected $ownerUserIdAttribute = 'usersIds';
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
{
+21 -1
View File
@@ -46,6 +46,8 @@ class Base implements Injectable
protected $injections = array();
protected $ownerUserIdAttribute = null;
public function inject($name, $object)
{
$this->injections[$name] = $object;
@@ -281,5 +283,23 @@ class Base implements Injectable
return false;
}
}
public function getOwnerUserIdAttribute(Entity $entity)
{
if ($this->ownerUserIdAttribute) {
return $this->ownerUserIdAttribute;
}
if ($entity->hasLinkMultipleField('assignedUsers')) {
return 'assignedUsersIds';
}
if ($entity->hasAttribute('assignedUserId')) {
return 'assignedUserId';
}
if ($entity->hasAttribute('createdById')) {
return 'createdById';
}
}
}
+8
View File
@@ -247,6 +247,14 @@ class Container
);
}
protected function loadInternalAclManager()
{
$className = $this->getServiceClassName('acl', '\\Espo\\Core\\AclManager');
return new $className(
$this->get('container')
);
}
protected function loadAcl()
{
$className = $this->getServiceClassName('acl', '\\Espo\\Core\\Acl');
+1 -1
View File
@@ -178,7 +178,7 @@ class Stream extends \Espo\Core\Hooks\Base
return $userIdList;
}
public function afterSave(Entity $entity, array $options = array())
public function afterSave(Entity $entity, array $options = [])
{
$entityType = $entity->getEntityType();
@@ -0,0 +1,124 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2018 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://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 General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Hooks\Common;
use Espo\ORM\Entity;
class StreamNotesAcl extends \Espo\Core\Hooks\Base
{
protected $streamService = null;
public static $order = 10;
protected function init()
{
parent::init();
$this->addDependency('serviceFactory');
$this->addDependency('aclManager');
}
protected function getServiceFactory()
{
return $this->getInjection('serviceFactory');
}
protected function getAclManager()
{
return $this->getInjection('aclManager');
}
public function afterSave(Entity $entity, array $options = [])
{
if (!empty($options['noStream'])) return;
if (!empty($options['silent'])) return;
if ($entity->isNew()) return;
$entityType = $entity->getEntityType();
if (in_array($entityType, ['Note', 'User', 'Team', 'Role', 'Portal', 'PortalRole'])) return;
if (!$this->getMetadata()->get(['scopes', $entityType, 'acl'])) return;
if (!$this->getMetadata()->get(['scopes', $entityType, 'object'])) return;
$ownerUserIdAttribute = $this->getAclManager()->getImplementation($entityType)->getOwnerUserIdAttribute($entity);
$usersAttributeIsChanged = false;
$teamsAttributeIsChanged = false;
if ($ownerUserIdAttribute) {
if ($entity->isAttributeChanged($ownerUserIdAttribute)) {
$usersAttributeIsChanged = true;
if ($entity->getAttributeParam($ownerUserIdAttribute, 'isLinkMultipleIdList')) {
$userIdList = $entity->get($ownerUserIdAttribute);
} else {
$userId = $entity->get($ownerUserIdAttribute);
if ($userId) {
$userIdList = [$userId];
} else {
$userIdList = [];
}
}
}
}
if ($entity->hasLinkMultipleField('teams') && $entity->isAttributeChanged('teamsIds')) {
$teamsAttributeIsChanged = true;
$teamIdList = $entity->get('teamsIds');
}
if ($usersAttributeIsChanged || $teamsAttributeIsChanged) {
$noteList = $this->getEntityManager()->getRepository('Note')->where([
'OR' => [
[
'relatedId' => $entity->id,
'relatedType' => $entityType
],
[
'parentId' => $entity->id,
'parentType' => $entityType,
'superParentId!=' => null,
'relatedId' => null
]
]
])->find();
foreach ($noteList as $note) {
if ($teamsAttributeIsChanged) {
$note->set('teamsIds', $teamIdList);
}
if ($usersAttributeIsChanged) {
$note->set('usersIds', $userIdList);
}
$this->getEntityManager()->saveEntity($note);
}
}
}
}
+101 -28
View File
@@ -40,6 +40,7 @@ class Notifications extends \Espo\Core\Hooks\Base
protected function init()
{
$this->addDependency('serviceFactory');
$this->addDependency('container');
}
protected function getServiceFactory()
@@ -47,6 +48,16 @@ class Notifications extends \Espo\Core\Hooks\Base
return $this->getInjection('serviceFactory');
}
protected function getInternalAclManager()
{
return $this->getInjection('container')->get('internalAclManager');
}
protected function getPortalAclManager()
{
return $this->getInjection('container')->get('portalAclManager');
}
protected function getMentionedUserIdList($entity)
{
$mentionedUserList = array();
@@ -60,7 +71,7 @@ class Notifications extends \Espo\Core\Hooks\Base
return $mentionedUserList;
}
protected function getSubscriberIdList($parentType, $parentId, $isInternal = false)
protected function getSubscriberList($parentType, $parentId, $isInternal = false)
{
$pdo = $this->getEntityManager()->getPDO();
@@ -80,15 +91,14 @@ class Notifications extends \Espo\Core\Hooks\Base
user.is_portal_user = 0
";
}
$sth = $pdo->prepare($sql);
$sth->execute();
$userIdList = [];
while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) {
if ($this->getUser()->id != $row['userId']) {
$userIdList[] = $row['userId'];
}
}
return $userIdList;
$userList = $this->getEntityManager()->getRepository('User')->where([
'isActive' => true
])->select(['id', 'isPortalUser', 'isAdmin'])->find([
'customWhere' => "AND user.id IN (".$sql.")"
]);
return $userList;
}
public function afterSave(Entity $entity)
@@ -99,13 +109,77 @@ class Notifications extends \Espo\Core\Hooks\Base
$superParentType = $entity->get('superParentType');
$superParentId = $entity->get('superParentId');
$userIdList = [];
$notifyUserIdList = [];
if ($parentType && $parentId) {
$userIdList = array_merge($userIdList, $this->getSubscriberIdList($parentType, $parentId, $entity->get('isInternal')));
if ($superParentType && $superParentId) {
$userIdList = array_merge($userIdList, $this->getSubscriberIdList($superParentType, $superParentId, $entity->get('isInternal')));
$userList = $this->getSubscriberList($parentType, $parentId, $entity->get('isInternal'));
$userIdMetList = [];
foreach ($userList as $user) {
$userIdMetList[] = $user->id;
}
if ($superParentType && $superParentId) {
$additionalUserList = $this->getSubscriberList($superParentType, $superParentId, $entity->get('isInternal'));
foreach ($additionalUserList as $user) {
if ($user->isPortal()) continue;
if (in_array($user->id, $userIdMetList)) continue;
$userIdMetList[] = $user->id;
$userList[] = $user;
}
}
if ($entity->get('relatedType')) {
$targetType = $entity->get('relatedType');
} else {
$targetType = $parentType;
}
$teamIdList = $entity->getLinkMultipleIdList('teams');
$userIdList = $entity->getLinkMultipleIdList('users');
foreach ($userList as $user) {
if ($user->isAdmin()) {
$notifyUserIdList[] = $user->id;
continue;
}
if ($user->isPortal()) {
if ($entity->get('relatedType')) {
continue;
} else {
$notifyUserIdList[] = $user->id;
}
continue;
}
$level = $this->getInternalAclManager()->getLevel($user, $targetType, 'read');
if ($level === 'all') {
$notifyUserIdList[] = $user->id;
continue;
} else if ($level === 'team') {
if (in_array($user->id, $userIdList)) {
$notifyUserIdList[] = $user->id;
continue;
}
if (!empty($teamIdList)) {
$userTeamIdList = $user->getLinkMultipleIdList('teams');
foreach ($teamIdList as $teamId) {
if (in_array($teamId, $userTeamIdList)) {
$notifyUserIdList[] = $user->id;
break;
}
}
}
continue;
} else if ($level === 'own') {
if (in_array($user->id, $userIdList)) {
$notifyUserIdList[] = $user->id;
continue;
}
}
}
} else {
$targetType = $entity->get('targetType');
if ($targetType === 'users') {
@@ -113,8 +187,8 @@ class Notifications extends \Espo\Core\Hooks\Base
if (is_array($targetUserIdList)) {
foreach ($targetUserIdList as $userId) {
if ($userId === $this->getUser()->id) continue;
if (in_array($userId, $userIdList)) continue;
$userIdList[] = $userId;
if (in_array($userId, $notifyUserIdList)) continue;
$notifyUserIdList[] = $userId;
}
}
} else if ($targetType === 'teams') {
@@ -130,8 +204,8 @@ class Notifications extends \Espo\Core\Hooks\Base
));
foreach ($targetUserList as $user) {
if ($user->id === $this->getUser()->id) continue;
if (in_array($user->id, $userIdList)) continue;
$userIdList[] = $user->id;
if (in_array($user->id, $notifyUserIdList)) continue;
$notifyUserIdList[] = $user->id;
}
}
}
@@ -148,8 +222,8 @@ class Notifications extends \Espo\Core\Hooks\Base
));
foreach ($targetUserList as $user) {
if ($user->id === $this->getUser()->id) continue;
if (in_array($user->id, $userIdList)) continue;
$userIdList[] = $user->id;
if (in_array($user->id, $notifyUserIdList)) continue;
$notifyUserIdList[] = $user->id;
}
}
}
@@ -162,22 +236,22 @@ class Notifications extends \Espo\Core\Hooks\Base
));
foreach ($targetUserList as $user) {
if ($user->id === $this->getUser()->id) continue;
$userIdList[] = $user->id;
$notifyUserIdList[] = $user->id;
}
}
}
$userIdList = array_unique($userIdList);
$notifyUserIdList = array_unique($notifyUserIdList);
foreach ($userIdList as $i => $userId) {
foreach ($notifyUserIdList as $i => $userId) {
if ($entity->isUserIdNotified($userId)) {
unset($userIdList[$i]);
unset($notifyUserIdList[$i]);
}
}
$userIdList = array_values($userIdList);
$notifyUserIdList = array_values($notifyUserIdList);
if (!empty($userIdList)) {
$this->getNotificationService()->notifyAboutNote($userIdList, $entity);
if (!empty($notifyUserIdList)) {
$this->getNotificationService()->notifyAboutNote($notifyUserIdList, $entity);
}
}
}
@@ -190,4 +264,3 @@ class Notifications extends \Espo\Core\Hooks\Base
return $this->notificationService;
}
}
+392 -107
View File
@@ -314,6 +314,8 @@ class Stream extends \Espo\Core\Services\Base
}
}
$teamIdList = $user->getTeamIdList();
$pdo = $this->getEntityManager()->getPDO();
$select = [
@@ -321,9 +323,12 @@ class Stream extends \Espo\Core\Services\Base
'targetType', 'createdAt', 'createdById', 'createdByName', 'isGlobal', 'isInternal', 'createdByGender'
];
$onlyTeamEntityTypeList = $this->getOnlyTeamEntityTypeList($user);
$onlyOwnEntityTypeList = $this->getOnlyOwnEntityTypeList($user);
$selectParamsList = [];
$selectParamsSubscription = array(
$selectParamsSubscription = [
'select' => $select,
'leftJoins' => ['createdBy'],
'customJoin' => "
@@ -334,22 +339,78 @@ class Stream extends \Espo\Core\Services\Base
note.parent_id = subscription.entity_id
)
) AND
subscription.user_id = ".$pdo->quote($user->id) . "
subscription.user_id = ". $pdo->quote($user->id) ."
",
'whereClause' => array(),
'whereClause' => [],
'orderBy' => 'number',
'order' => 'DESC'
);
];
if ($user->get('isPortalUser')) {
$selectParamsSubscription['whereClause'][] = array(
if ($user->isPortal()) {
$selectParamsSubscription['whereClause'][] = [
'isInternal' => false
);
];
$notAllEntityTypeList = $this->getNotAllEntityTypeList($user);
$selectParamsSubscription['whereClause'][] = [
'OR' => [
[
'relatedId' => null
],
[
'relatedId!=' => null,
'relatedType!=' => $notAllEntityTypeList
]
]
];
$selectParamsList[] = $selectParamsSubscription;
} else {
$selectParamsSubscriptionRest = $selectParamsSubscription;
$selectParamsSubscriptionRest['whereClause'][] = [
'OR' => [
[
'relatedId!=' => null,
'relatedType!=' => array_merge($onlyTeamEntityTypeList, $onlyOwnEntityTypeList)
],
[
'relatedId=' => null
]
]
];
$selectParamsList[] = $selectParamsSubscriptionRest;
if (count($onlyTeamEntityTypeList)) {
$selectParamsSubscriptionTeam = $selectParamsSubscription;
$selectParamsSubscriptionTeam['distinct'] = true;
$selectParamsSubscriptionTeam['leftJoins'][] = 'teams';
$selectParamsSubscriptionTeam['whereClause'][] = [
[
'relatedId!=' => null,
'relatedType=' => $onlyTeamEntityTypeList
],
'teamsMiddle.teamId' => $teamIdList
];
$selectParamsList[] = $selectParamsSubscriptionTeam;
}
if (count($onlyOwnEntityTypeList)) {
$selectParamsSubscriptionOwn = $selectParamsSubscription;
$selectParamsSubscriptionOwn['distinct'] = true;
$selectParamsSubscriptionOwn['leftJoins'][] = 'users';
$selectParamsSubscriptionOwn['whereClause'][] = [
[
'relatedId!=' => null,
'relatedType=' => $onlyOwnEntityTypeList
],
'usersMiddle.userId' => $user->id
];
$selectParamsList[] = $selectParamsSubscriptionOwn;
}
}
$selectParamsList[] = $selectParamsSubscription;
$selectParamsSubscriptionSuper = array(
$selectParamsSubscriptionSuper = [
'select' => $select,
'leftJoins' => ['createdBy'],
'customJoin' => "
@@ -368,58 +429,109 @@ class Stream extends \Espo\Core\Services\Base
note.parent_type <> note.super_parent_type
)
',
'whereClause' => array(),
'whereClause' => [],
'orderBy' => 'number',
'order' => 'DESC'
);
];
if ($user->get('isPortalUser')) {
$selectParamsSubscriptionSuper['whereClause'][] = array(
'isInternal' => false
);
if ($user->isPortal()) {
} else {
$selectParamsSubscriptionRest = $selectParamsSubscriptionSuper;
$selectParamsSubscriptionRest['whereClause'][] = [
'OR' => [
[
'relatedId!=' => null,
'relatedType!=' => array_merge($onlyTeamEntityTypeList, $onlyOwnEntityTypeList)
],
[
'relatedId=' => null,
'parentType!=' => array_merge($onlyTeamEntityTypeList, $onlyOwnEntityTypeList)
]
]
];
$selectParamsList[] = $selectParamsSubscriptionRest;
if (count($onlyTeamEntityTypeList)) {
$selectParamsSubscriptionTeam = $selectParamsSubscriptionSuper;
$selectParamsSubscriptionTeam['distinct'] = true;
$selectParamsSubscriptionTeam['leftJoins'][] = 'teams';
$selectParamsSubscriptionTeam['whereClause'][] = [
'OR' => [
[
'relatedId!=' => null,
'relatedType=' => $onlyTeamEntityTypeList
],
[
'relatedId=' => null,
'parentType=' => $onlyTeamEntityTypeList
]
],
'teamsMiddle.teamId' => $teamIdList
];
$selectParamsList[] = $selectParamsSubscriptionTeam;
}
if (count($onlyOwnEntityTypeList)) {
$selectParamsSubscriptionOwn = $selectParamsSubscriptionSuper;
$selectParamsSubscriptionOwn['distinct'] = true;
$selectParamsSubscriptionOwn['leftJoins'][] = 'users';
$selectParamsSubscriptionOwn['whereClause'][] = [
'OR' => [
[
'relatedId!=' => null,
'relatedType=' => $onlyOwnEntityTypeList
],
[
'relatedId=' => null,
'parentType=' => $onlyOwnEntityTypeList
]
],
'usersMiddle.userId' => $user->id
];
$selectParamsList[] = $selectParamsSubscriptionOwn;
}
}
$selectParamsList[] = $selectParamsSubscriptionSuper;
$selectParamsList[] = array(
$selectParamsList[] = [
'select' => $select,
'leftJoins' => ['createdBy'],
'whereClause' => array(
'whereClause' => [
'createdById' => $user->id,
'parentId' => null,
'type' => 'Post',
'isGlobal' => false
),
],
'orderBy' => 'number',
'order' => 'DESC'
);
];
$selectParamsList[] = array(
$selectParamsList[] = [
'select' => $select,
'leftJoins' => ['users', 'createdBy'],
'whereClause' => array(
'whereClause' => [
'createdById!=' => $user->id,
'usersMiddle.userId' => $user->id,
'parentId' => null,
'type' => 'Post',
'isGlobal' => false
),
],
'orderBy' => 'number',
'order' => 'DESC'
);
];
if (!$user->get('isPortalUser') || $user->get('isAdmin')) {
$selectParamsList[] = array(
$selectParamsList[] = [
'select' => $select,
'leftJoins' => ['createdBy'],
'whereClause' => array(
'whereClause' => [
'parentId' => null,
'type' => 'Post',
'isGlobal' => true
),
],
'orderBy' => 'number',
'order' => 'DESC'
);
];
}
if ($user->get('isPortalUser')) {
@@ -429,42 +541,37 @@ class Stream extends \Espo\Core\Services\Base
$portalIdQuotedList[] = $pdo->quote($portalId);
}
if (!empty($portalIdQuotedList)) {
$selectParamsList[] = array(
$selectParamsList[] = [
'select' => $select,
'leftJoins' => ['portals', 'createdBy'],
'whereClause' => array(
'whereClause' => [
'parentId' => null,
'portalsMiddle.portalId' => $portalIdList,
'type' => 'Post',
'isGlobal' => false
),
],
'orderBy' => 'number',
'order' => 'DESC'
);
];
}
}
$teamIdList = $user->getTeamIdList();
$teamIdQuotedList = [];
foreach ($teamIdList as $teamId) {
$teamIdQuotedList[] = $pdo->quote($teamId);
}
if (!empty($teamIdList)) {
$selectParamsList[] = array(
$selectParamsList[] = [
'select' => $select,
'leftJoins' => ['teams', 'createdBy'],
'whereClause' => array(
'whereClause' => [
'parentId' => null,
'teamsMiddle.teamId' => $teamIdList,
'type' => 'Post',
'isGlobal' => false
),
],
'orderBy' => 'number',
'order' => 'DESC'
);
];
}
$whereClause = array();
$whereClause = [];
if (!empty($params['after'])) {
$whereClause[]['createdAt>'] = $params['after'];
}
@@ -480,32 +587,32 @@ class Stream extends \Espo\Core\Services\Base
}
}
$ignoreScopeList = $this->getIgnoreScopeList();
$ignoreScopeList = $this->getIgnoreScopeList($user);
if (!empty($ignoreScopeList)) {
$whereClause[] = array(
'OR' => array(
$whereClause[] = [
'OR' => [
'relatedType' => null,
'relatedType!=' => $ignoreScopeList
)
);
$whereClause[] = array(
'OR' => array(
]
];
$whereClause[] = [
'OR' => [
'parentType' => null,
'parentType!=' => $ignoreScopeList
)
);
]
];
if (in_array('Email', $ignoreScopeList)) {
$whereClause[] = array(
$whereClause[] = [
'type!=' => ['EmailReceived', 'EmailSent']
);
];
}
}
$sqlPartList = [];
foreach ($selectParamsList as $i => $selectParams) {
if (empty($selectParams['whereClause'])) {
$selectParams['whereClause'] = array();
$selectParams['whereClause'] = [];
}
$selectParams['whereClause'][] = $whereClause;
$sqlPartList[] = "(\n" . $this->getEntityManager()->getQuery()->createSelectQuery('Note', $selectParams) . "\n)";
@@ -560,7 +667,7 @@ class Stream extends \Espo\Core\Services\Base
);
}
public function find($scope, $id, $params = array())
public function find($scope, $id, $params = [])
{
if ($scope === 'User') {
if (empty($id)) {
@@ -570,6 +677,9 @@ class Stream extends \Espo\Core\Services\Base
}
$entity = $this->getEntityManager()->getEntity($scope, $id);
$onlyTeamEntityTypeList = $this->getOnlyTeamEntityTypeList($this->getUser());
$onlyOwnEntityTypeList = $this->getOnlyOwnEntityTypeList($this->getUser());
if (empty($entity)) {
throw new NotFound();
}
@@ -578,18 +688,101 @@ class Stream extends \Espo\Core\Services\Base
throw new Forbidden();
}
$where = array(
'OR' => array(
array(
$selectParams = [
'offset' => $params['offset'],
'limit' => $params['maxSize'],
'orderBy' => 'number',
'order' => 'DESC'
];
$where = [
'OR' => [
[
'parentType' => $scope,
'parentId' => $id
),
array(
],
[
'superParentType' => $scope,
'superParentId' => $id
)
)
);
]
]
];
if ($this->getUser()->isPortal()) {
$where = [
'OR' => [
[
'parentType' => $scope,
'parentId' => $id
]
]
];
$notAllEntityTypeList = $this->getNotAllEntityTypeList($this->getUser());
$where[] = [
'OR' => [
[
'relatedId' => null
],
[
'relatedId!=' => null,
'relatedType!=' => $notAllEntityTypeList
]
]
];
} else {
if (count($onlyTeamEntityTypeList) || count($onlyOwnEntityTypeList)) {
$selectParams['leftJoins'] = ['teams', 'users'];
$selectParams['distinct'] = true;
$where[] = [
'OR' => [
'OR' => [
[
'relatedId!=' => null,
'relatedType!=' => array_merge($onlyTeamEntityTypeList, $onlyOwnEntityTypeList)
],
[
'relatedId=' => null,
'superParentId' => $id,
'superParentType' => $scope,
'parentId!=' => null,
'parentType!=' => array_merge($onlyTeamEntityTypeList, $onlyOwnEntityTypeList)
],
[
'relatedId=' => null,
'parentType=' => $scope,
'parentId=' => $id
]
],
[
'OR' => [
[
'relatedId!=' => null,
'relatedType=' => $onlyTeamEntityTypeList
],
[
'relatedId=' => null,
'parentType=' => $onlyTeamEntityTypeList
]
],
'teamsMiddle.teamId' => $this->getUser()->getTeamIdList()
],
[
'OR' => [
[
'relatedId!=' => null,
'relatedType=' => $onlyOwnEntityTypeList
],
[
'relatedId=' => null,
'parentType=' => $onlyOwnEntityTypeList
]
],
'usersMiddle.userId' => $this->getUser()->id
]
]
];
}
}
if (!empty($params['after'])) {
$where['createdAt>'] = $params['after'];
@@ -606,41 +799,36 @@ class Stream extends \Espo\Core\Services\Base
}
}
$ignoreScopeList = $this->getIgnoreScopeList();
$ignoreScopeList = $this->getIgnoreScopeList($this->getUser());
if (!empty($ignoreScopeList)) {
$where[] = array(
'OR' => array(
$where[] = [
'OR' => [
'relatedType' => null,
'relatedType!=' => $ignoreScopeList
)
);
$where[] = array(
'OR' => array(
]
];
$where[] = [
'OR' => [
'parentType' => null,
'parentType!=' => $ignoreScopeList
)
);
]
];
if (in_array('Email', $ignoreScopeList)) {
$where[] = array(
$where[] = [
'type!=' => ['EmailReceived', 'EmailSent']
);
];
}
}
if ($this->getUser()->get('isPortalUser')) {
$where[] = array(
$where[] = [
'isInternal' => false
);
];
}
$collection = $this->getEntityManager()->getRepository('Note')->find(array(
'whereClause' => $where,
'offset' => $params['offset'],
'limit' => $params['maxSize'],
'orderBy' => 'number',
'order' => 'DESC'
));
$selectParams['whereClause'] = $where;
$collection = $this->getEntityManager()->getRepository('Note')->find($selectParams);
foreach ($collection as $e) {
if ($e->get('type') == 'Post' || $e->get('type') == 'EmailReceived') {
@@ -658,13 +846,15 @@ class Stream extends \Espo\Core\Services\Base
if ($e->get('relatedId') && $e->get('relatedType')) {
$e->loadParentNameField('related');
}
}
unset($where['createdAt>']);
$count = $this->getEntityManager()->getRepository('Note')->count(array(
'whereClause' => $where,
));
unset($selectParams['offset']);
unset($selectParams['limit']);
$selectParams['where'] = $where;
$count = $this->getEntityManager()->getRepository('Note')->count($selectParams);
return array(
'total' => $count,
@@ -680,6 +870,27 @@ class Stream extends \Espo\Core\Services\Base
}
}
protected function processNoteTeamsUsers(Entity $note, Entity $entity)
{
if ($entity->hasLinkMultipleField('teams') && $entity->has('teamsIds')) {
$teamIdList = $entity->get('teamsIds');
if (!empty($teamIdList)) {
$note->set('teamsIds', $teamIdList);
}
}
$ownerUserIdAttribute = $this->getAclManager()->getImplementation($entity->getEntityType())->getOwnerUserIdAttribute($entity);
if ($ownerUserIdAttribute && $entity->get($ownerUserIdAttribute)) {
if ($entity->getAttributeParam($ownerUserIdAttribute, 'isLinkMultipleIdList')) {
$userIdList = $entity->get($ownerUserIdAttribute);
} else {
$userId = $entity->get($ownerUserIdAttribute);
$userIdList = [$userId];
}
$note->set('usersIds', $userIdList);
}
}
public function noteEmailReceived(Entity $entity, Entity $email, $isInitial = false)
{
$entityType = $entity->getEntityType();
@@ -702,6 +913,8 @@ class Stream extends \Espo\Core\Services\Base
$note->set('relatedId', $email->id);
$note->set('relatedType', 'Email');
$this->processNoteTeamsUsers($note, $email);
if ($email->get('accountId')) {
$note->set('superParentId', $email->get('accountId'));
$note->set('superParentType', 'Account');
@@ -751,6 +964,8 @@ class Stream extends \Espo\Core\Services\Base
$note->set('relatedId', $email->id);
$note->set('relatedType', 'Email');
$this->processNoteTeamsUsers($note, $email);
if ($email->get('accountId')) {
$note->set('superParentId', $email->get('accountId'));
$note->set('superParentType', 'Account');
@@ -805,9 +1020,11 @@ class Stream extends \Espo\Core\Services\Base
if ($entity->has('accountId') && $entity->get('accountId')) {
$note->set('superParentId', $entity->get('accountId'));
$note->set('superParentType', 'Account');
$this->processNoteTeamsUsers($note, $entity);
}
$data = array();
$data = [];
if ($entity->get('assignedUserId')) {
if (!$entity->has('assignedUserName')) {
@@ -854,10 +1071,12 @@ class Stream extends \Espo\Core\Services\Base
$note->set('type', 'CreateRelated');
$note->set('parentId', $parentId);
$note->set('parentType', $parentType);
$note->set(array(
$note->set([
'relatedType' => $entityType,
'relatedId' => $entity->id,
));
'relatedId' => $entity->id
]);
$this->processNoteTeamsUsers($note, $entity);
if ($entity->has('accountId') && $entity->get('accountId')) {
$note->set('superParentId', $entity->get('accountId'));
@@ -878,20 +1097,22 @@ class Stream extends \Espo\Core\Services\Base
if ($entity->has('accountId') && $entity->get('accountId')) {
$note->set('superParentId', $entity->get('accountId'));
$note->set('superParentType', 'Account');
$this->processNoteTeamsUsers($note, $entity);
}
if ($entity->get('assignedUserId')) {
if (!$entity->has('assignedUserName')) {
$this->loadAssignedUserName($entity);
}
$note->set('data', array(
$note->set('data', [
'assignedUserId' => $entity->get('assignedUserId'),
'assignedUserName' => $entity->get('assignedUserName'),
));
]);
} else {
$note->set('data', array(
$note->set('data', [
'assignedUserId' => null
));
]);
}
$this->getEntityManager()->saveEntity($note);
@@ -908,6 +1129,8 @@ class Stream extends \Espo\Core\Services\Base
if ($entity->has('accountId') && $entity->get('accountId')) {
$note->set('superParentId', $entity->get('accountId'));
$note->set('superParentType', 'Account');
$this->processNoteTeamsUsers($note, $entity);
}
$style = 'default';
@@ -1009,13 +1232,13 @@ class Stream extends \Espo\Core\Services\Base
$note->set('parentId', $entity->id);
$note->set('parentType', $entity->getEntityType());
$note->set('data', array(
$note->set('data', [
'fields' => $updatedFieldList,
'attributes' => array(
'attributes' => [
'was' => $was,
'became' => $became
)
));
]
]);
$this->getEntityManager()->saveEntity($note);
}
@@ -1095,14 +1318,76 @@ class Stream extends \Espo\Core\Services\Base
}
protected function getIgnoreScopeList()
protected function getOnlyTeamEntityTypeList(\Espo\Entities\User $user)
{
if ($user->isPortal()) return [];
$list = [];
$scopes = $this->getMetadata()->get('scopes', []);
foreach ($scopes as $scope => $item) {
if ($scope === 'User') continue;
if (empty($item['entity'])) continue;
if (empty($item['object'])) continue;
if (
$this->getAclManager()->getLevel($user, $scope, 'read') === 'team'
) {
$list[] = $scope;
}
}
return $list;
}
protected function getOnlyOwnEntityTypeList(\Espo\Entities\User $user)
{
if ($user->isPortal()) return [];
$list = [];
$scopes = $this->getMetadata()->get('scopes', []);
foreach ($scopes as $scope => $item) {
if ($scope === 'User') continue;
if (empty($item['entity'])) continue;
if (empty($item['object'])) continue;
if (
$this->getAclManager()->getLevel($user, $scope, 'read') === 'own'
) {
$list[] = $scope;
}
}
return $list;
}
protected function getNotAllEntityTypeList(\Espo\Entities\User $user)
{
if (!$user->isPortal()) return [];
$list = [];
$scopes = $this->getMetadata()->get('scopes', []);
foreach ($scopes as $scope => $item) {
if ($scope === 'User') continue;
if (empty($item['entity'])) continue;
if (empty($item['object'])) continue;
if (
$this->getAclManager()->getLevel($user, $scope, 'read') !== 'all'
) {
$list[] = $scope;
}
}
return $list;
}
protected function getIgnoreScopeList(\Espo\Entities\User $user)
{
$ignoreScopeList = [];
$scopes = $this->getMetadata()->get('scopes', array());
foreach ($scopes as $scope => $d) {
if (empty($d['entity']) || !$d['entity']) continue;
if (empty($d['object']) || !$d['object']) continue;
if (!$this->getAcl()->checkScope($scope, 'read') || !$this->getAcl()->checkScope($scope, 'stream')) {
$scopes = $this->getMetadata()->get('scopes', []);
foreach ($scopes as $scope => $item) {
if (empty($item['entity'])) continue;
if (empty($item['object'])) continue;
if (
!$this->getAclManager()->checkScope($user, $scope, 'read')
||
!$this->getAclManager()->checkScope($user, $scope, 'stream')
) {
$ignoreScopeList[] = $scope;
}
}