diff --git a/application/Espo/Core/Acl.php b/application/Espo/Core/Acl.php
index e2781a893c..66b73e92bd 100644
--- a/application/Espo/Core/Acl.php
+++ b/application/Espo/Core/Acl.php
@@ -124,6 +124,11 @@ class Acl
return $this->getAclManager()->getScopeForbiddenFieldList($this->getUser(), $scope, $action, $thresholdLevel);
}
+ public function getScopeForbiddenLinkList($scope, $action = 'read', $thresholdLevel = 'no')
+ {
+ return $this->getAclManager()->getScopeForbiddenLinkList($this->getUser(), $scope, $action, $thresholdLevel);
+ }
+
public function checkUserPermission($target, $permissionType = 'userPermission')
{
return $this->getAclManager()->checkUserPermission($this->getUser(), $target, $permissionType);
diff --git a/application/Espo/Core/AclManager.php b/application/Espo/Core/AclManager.php
index 296cbb1574..679b6f3b5d 100644
--- a/application/Espo/Core/AclManager.php
+++ b/application/Espo/Core/AclManager.php
@@ -309,6 +309,22 @@ class AclManager
return $list;
}
+
+ public function getScopeForbiddenLinkList(User $user, $scope, $action = 'read', $thresholdLevel = 'no')
+ {
+ $list = [];
+
+ if ($thresholdLevel === 'no') {
+ $list = array_merge(
+ $list,
+ $this->getScopeRestrictedLinkList($scope, $this->getGlobalRestrictionTypeList($user, $action))
+ );
+ $list = array_values($list);
+ }
+
+ return $list;
+ }
+
public function checkUserPermission(User $user, $target, $permissionType = 'userPermission')
{
$permission = $this->get($user, $permissionType);
diff --git a/application/Espo/Core/Formula/Functions/EntityGroup/SumRelatedType.php b/application/Espo/Core/Formula/Functions/EntityGroup/SumRelatedType.php
index 8b1bd599e4..80c5ffd1d9 100644
--- a/application/Espo/Core/Formula/Functions/EntityGroup/SumRelatedType.php
+++ b/application/Espo/Core/Formula/Functions/EntityGroup/SumRelatedType.php
@@ -101,6 +101,10 @@ class SumRelatedType extends \Espo\Core\Formula\Functions\Base
$selectParams['groupBy'] = [$foreignLink . '.id'];
+ $selectParams['whereClause'][] = [
+ $foreignLink . '.id' => $entity->id
+ ];
+
$entityManager->getRepository($foreignEntityType)->handleSelectParams($selectParams);
$sql = $entityManager->getQuery()->createSelectQuery($foreignEntityType, $selectParams);
diff --git a/application/Espo/Core/SelectManagers/Base.php b/application/Espo/Core/SelectManagers/Base.php
index c41479a81e..668e8fbf90 100644
--- a/application/Espo/Core/SelectManagers/Base.php
+++ b/application/Espo/Core/SelectManagers/Base.php
@@ -782,13 +782,42 @@ class Base
if (isset($w['attribute'])) {
$attribute = $w['attribute'];
}
+
+ $type = null;
+ if (isset($w['type'])) {
+ $type = $w['type'];
+ }
+
+ $entityType = $this->getEntityType();
+
if ($attribute) {
- if (isset($w['type']) && in_array($w['type'], ['isLinked', 'isNotLinked', 'linkedWith', 'notLinkedWith', 'isUserFromTeams'])) {
- if (in_array($attribute, $this->getAcl()->getScopeForbiddenFieldList($this->getEntityType()))) {
+ if (strpos($attribute, '.')) {
+ list($link, $attribute) = explode('.', $attribute);
+ if (!$this->getSeed()->hasRelation($link)) {
+ throw new Forbidden("SelectManager::checkWhere: Unknow relation '{$link}' in where.");
+ }
+ $entityType = $this->getSeed($this->getEntityType())->getRelationParam($link, 'entity');
+ if (!$entityType) {
+ throw new Forbidden("SelectManager::checkWhere: Bad relation.");
+ }
+ if (!$this->getAcl()->checkScope($entityType)) {
+ throw new Forbidden();
+ }
+ }
+
+ if ($type && in_array($type, ['isLinked', 'isNotLinked', 'linkedWith', 'notLinkedWith', 'isUserFromTeams'])) {
+ if (in_array($attribute, $this->getAcl()->getScopeForbiddenFieldList($entityType))) {
+ throw new Forbidden();
+ }
+ if (
+ $this->getSeed()->hasRelation($attribute)
+ &&
+ in_array($attribute, $this->getAcl()->getScopeForbiddenLinkList($entityType))
+ ) {
throw new Forbidden();
}
} else {
- if (in_array($attribute, $this->getAcl()->getScopeForbiddenAttributeList($this->getEntityType()))) {
+ if (in_array($attribute, $this->getAcl()->getScopeForbiddenAttributeList($entityType))) {
throw new Forbidden();
}
}
@@ -2075,13 +2104,13 @@ class Base
}
}
- $attibute = null;
- if (!empty($item['attribute'])) $attibute = $item['attribute'];
- if (!$attibute) return;
+ $attribute = null;
+ if (!empty($item['attribute'])) $attribute = $item['attribute'];
+ if (!$attribute) return;
- $attributeType = $this->getSeed()->getAttributeType($attibute);
+ $attributeType = $this->getSeed()->getAttributeType($attribute);
if ($attributeType === 'foreign') {
- $relation = $this->getSeed()->getAttributeParam($attibute, 'relation');
+ $relation = $this->getSeed()->getAttributeParam($attribute, 'relation');
if ($relation) {
$this->addLeftJoin($relation, $result);
}
diff --git a/application/Espo/Repositories/EmailAddress.php b/application/Espo/Repositories/EmailAddress.php
index c9b2a71f96..fc8239dada 100644
--- a/application/Espo/Repositories/EmailAddress.php
+++ b/application/Espo/Repositories/EmailAddress.php
@@ -306,7 +306,7 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB
if ($emailAddressValue) {
$key = strtolower($emailAddressValue);
if ($key && isset($hash->$key)) {
- $hash->$key['optOut'] = $entity->get('emailAddressIsOptedOut');
+ $hash->{$key}['optOut'] = $entity->get('emailAddressIsOptedOut');
}
}
}
@@ -337,19 +337,19 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB
$new = true;
$changed = false;
- if ($hash->$key['primary']) {
+ if ($hash->{$key}['primary']) {
$primary = $key;
}
if (property_exists($hashPrevious, $key)) {
$new = false;
$changed =
- $hash->$key['optOut'] != $hashPrevious->$key['optOut'] ||
- $hash->$key['invalid'] != $hashPrevious->$key['invalid'] ||
- $hash->$key['emailAddress'] !== $hashPrevious->$key['emailAddress'];
+ $hash->{$key}['optOut'] != $hashPrevious->$key['optOut'] ||
+ $hash->{$key}['invalid'] != $hashPrevious->$key['invalid'] ||
+ $hash->{$key}['emailAddress'] !== $hashPrevious->$key['emailAddress'];
- if ($hash->$key['primary']) {
- if ($hash->$key['primary'] == $hashPrevious->$key['primary']) {
+ if ($hash->{$key}['primary']) {
+ if ($hash->{$key}['primary'] == $hashPrevious->$key['primary']) {
$primary = false;
}
}
@@ -390,9 +390,9 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB
$skipSave = $this->checkChangeIsForbidden($emailAddress, $entity);
if (!$skipSave) {
$emailAddress->set([
- 'optOut' => $hash->$address['optOut'],
- 'invalid' => $hash->$address['invalid'],
- 'name' => $hash->$address['emailAddress']
+ 'optOut' => $hash->{$address}['optOut'],
+ 'invalid' => $hash->{$address}['invalid'],
+ 'name' => $hash->{$address}['emailAddress']
]);
$this->save($emailAddress);
} else {
@@ -410,23 +410,23 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB
$emailAddress = $this->get();
$emailAddress->set([
- 'name' => $hash->$address['emailAddress'],
- 'optOut' => $hash->$address['optOut'],
- 'invalid' => $hash->$address['invalid'],
+ 'name' => $hash->{$address}['emailAddress'],
+ 'optOut' => $hash->{$address}['optOut'],
+ 'invalid' => $hash->{$address}['invalid'],
]);
$this->save($emailAddress);
} else {
$skipSave = $this->checkChangeIsForbidden($emailAddress, $entity);
if (!$skipSave) {
if (
- $emailAddress->get('optOut') != $hash->$address['optOut'] ||
- $emailAddress->get('invalid') != $hash->$address['invalid'] ||
- $emailAddress->get('emailAddress') != $hash->$address['emailAddress']
+ $emailAddress->get('optOut') != $hash->{$address}['optOut'] ||
+ $emailAddress->get('invalid') != $hash->{$address}['invalid'] ||
+ $emailAddress->get('emailAddress') != $hash->{$address}['emailAddress']
) {
$emailAddress->set([
- 'optOut' => $hash->$address['optOut'],
- 'invalid' => $hash->$address['invalid'],
- 'name' => $hash->$address['emailAddress']
+ 'optOut' => $hash->{$address}['optOut'],
+ 'invalid' => $hash->{$address}['invalid'],
+ 'name' => $hash->{$address}['emailAddress']
]);
$this->save($emailAddress);
}
diff --git a/application/Espo/Repositories/PhoneNumber.php b/application/Espo/Repositories/PhoneNumber.php
index 4f94159bcb..5419155b7d 100644
--- a/application/Espo/Repositories/PhoneNumber.php
+++ b/application/Espo/Repositories/PhoneNumber.php
@@ -252,15 +252,15 @@ class PhoneNumber extends \Espo\Core\ORM\Repositories\RDB
$new = true;
$changed = false;
- if ($hash->$key['primary']) {
+ if ($hash->{$key}['primary']) {
$primary = $key;
}
if (property_exists($hashPrevious, $key)) {
$new = false;
- $changed = $hash->$key['type'] != $hashPrevious->$key['type'];
- if ($hash->$key['primary']) {
- if ($hash->$key['primary'] == $hashPrevious->$key['primary']) {
+ $changed = $hash->{$key}['type'] != $hashPrevious->$key['type'];
+ if ($hash->{$key}['primary']) {
+ if ($hash->{$key}['primary'] == $hashPrevious->$key['primary']) {
$primary = false;
}
}
@@ -301,7 +301,7 @@ class PhoneNumber extends \Espo\Core\ORM\Repositories\RDB
$skipSave = $this->checkChangeIsForbidden($phoneNumber, $entity);
if (!$skipSave) {
$phoneNumber->set([
- 'type' => $hash->$number['type'],
+ 'type' => $hash->{$number}['type'],
]);
$this->save($phoneNumber);
} else {
@@ -319,15 +319,15 @@ class PhoneNumber extends \Espo\Core\ORM\Repositories\RDB
$phoneNumber->set([
'name' => $number,
- 'type' => $hash->$number['type'],
+ 'type' => $hash->{$number}['type'],
]);
$this->save($phoneNumber);
} else {
$skipSave = $this->checkChangeIsForbidden($phoneNumber, $entity);
if (!$skipSave) {
- if ($phoneNumber->get('type') != $hash->$number['type']) {
+ if ($phoneNumber->get('type') != $hash->{$number}['type']) {
$phoneNumber->set([
- 'type' => $hash->$number['type'],
+ 'type' => $hash->{$number}['type'],
]);
$this->save($phoneNumber);
}
diff --git a/client/res/templates/fields/email/edit.tpl b/client/res/templates/fields/email/edit.tpl
index bcbbeda92f..742d888191 100644
--- a/client/res/templates/fields/email/edit.tpl
+++ b/client/res/templates/fields/email/edit.tpl
@@ -13,7 +13,7 @@
-