email template foreign fields and acl
This commit is contained in:
@@ -165,10 +165,15 @@ class EmailTemplate extends Record
|
||||
return $this->parseTemplate($emailTemplate, $params, $copyAttachments);
|
||||
}
|
||||
|
||||
protected function parseText($type, Entity $entity, $text)
|
||||
protected function parseText($type, Entity $entity, $text, $skipLinks = false, $prefixLink = null)
|
||||
{
|
||||
$fieldList = array_keys($entity->getFields());
|
||||
$fieldList = array_keys($entity->getAttributes());
|
||||
|
||||
$forbidenAttributeList = $this->getAcl()->getScopeForbiddenAttributeList($entity->getEntityType(), 'read');
|
||||
|
||||
foreach ($fieldList as $field) {
|
||||
if (in_array($field, $forbidenAttributeList)) continue;
|
||||
|
||||
$value = $entity->get($field);
|
||||
if (is_object($value)) {
|
||||
continue;
|
||||
@@ -195,9 +200,34 @@ class EmailTemplate extends Record
|
||||
}
|
||||
}
|
||||
if (is_string($value) || $value === null || is_scalar($value) || is_callable([$value, '__toString'])) {
|
||||
$text = str_replace('{' . $type . '.' . $field . '}', $value, $text);
|
||||
$variableName = $field;
|
||||
if (!is_null($prefixLink)) {
|
||||
$variableName = $prefixLink . '.' . $field;
|
||||
}
|
||||
$text = str_replace('{' . $type . '.' . $variableName . '}', $value, $text);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$skipLinks) {
|
||||
$relationDefs = $entity->getRelations();
|
||||
foreach ($entity->getRelationList() as $relation) {
|
||||
if (
|
||||
!empty($relationDefs[$relation]['type'])
|
||||
&&
|
||||
($entity->getRelationType($relation) === 'belongsTo' || $entity->getRelationType($relation) === 'belongsToParent')
|
||||
) {
|
||||
$relatedEntity = $entity->get($relation);
|
||||
if (!$relatedEntity) continue;
|
||||
if ($this->getAcl()) {
|
||||
if (!$this->getAcl()->check($relatedEntity, 'read')) continue;
|
||||
}
|
||||
|
||||
$text = $this->parseText($type, $relatedEntity, $text, true, $relation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ Espo.define('acl-manager', ['acl'], function (Acl) {
|
||||
this.implementationHash = {};
|
||||
this.forbiddenFieldsCache = {};
|
||||
this.implementationClassMap = {};
|
||||
this.forbiddenAttributesCache = {};
|
||||
},
|
||||
|
||||
getImplementation: function (scope) {
|
||||
@@ -220,6 +221,37 @@ Espo.define('acl-manager', ['acl'], function (Acl) {
|
||||
this.forbiddenFieldsCache[key] = fieldList;
|
||||
|
||||
return fieldList;
|
||||
},
|
||||
|
||||
getScopeForbiddenAttributeList: function (scope, action, thresholdLevel) {
|
||||
action = action || 'read';
|
||||
thresholdLevel = thresholdLevel || 'no';
|
||||
|
||||
var key = scope + '_' + action + '_' + thresholdLevel;
|
||||
if (key in this.forbiddenAttributesCache) {
|
||||
return this.forbiddenAttributesCache[key];
|
||||
}
|
||||
|
||||
var levelList = this.fieldLevelList.slice(this.fieldLevelList.indexOf(thresholdLevel));
|
||||
|
||||
var fieldTableQuickAccess = this.data.fieldTableQuickAccess || {};
|
||||
var scopeData = fieldTableQuickAccess[scope] || {};
|
||||
|
||||
var attributesData = scopeData.attributes || {};
|
||||
var actionData = attributesData[action] || {};
|
||||
|
||||
var attributeList = [];
|
||||
levelList.forEach(function (level) {
|
||||
var list = actionData[level] || [];
|
||||
list.forEach(function (attribute) {
|
||||
if (~attributeList.indexOf(attribute)) return;
|
||||
attributeList.push(attribute);
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
this.forbiddenAttributesCache[key] = attributeList;
|
||||
|
||||
return attributeList;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -56,19 +56,74 @@ Espo.define('views/email-template/fields/insert-field', 'views/fields/base', fun
|
||||
return (defs[scope].entity && (defs[scope].tab || defs[scope].object));
|
||||
});
|
||||
|
||||
this.translatedOptions = {};
|
||||
|
||||
var entityFields = {};
|
||||
entityList.forEach(function (scope) {
|
||||
this.translatedOptions[scope] = {};
|
||||
|
||||
var list = this.getFieldManager().getEntityAttributes(scope) || [];
|
||||
|
||||
var forbiddenList = this.getAcl().getScopeForbiddenAttributeList(scope);
|
||||
list = list.filter(function (item) {
|
||||
if (~forbiddenList.indexOf(item)) return;
|
||||
return true;
|
||||
}, this);
|
||||
|
||||
list.push('id');
|
||||
if (this.getMetadata().get('entityDefs.' + scope + '.fields.name.type') == 'personName') {
|
||||
list.unshift('name');
|
||||
this.translatedOptions[scope]['name'] = this.translate('name', 'fields', scope);
|
||||
};
|
||||
entityFields[scope] = list.sort(function (v1, v2) {
|
||||
return this.translate(v1, 'fields', scope).localeCompare(this.translate(v2, 'fields', scope));
|
||||
}.bind(this));
|
||||
|
||||
entityFields[scope].forEach(function (item) {
|
||||
this.translatedOptions[scope][item] = this.translate(item, 'fields', scope);
|
||||
}, this);
|
||||
|
||||
var links = this.getMetadata().get('entityDefs.' + scope + '.links') || {};
|
||||
|
||||
var linkList = Object.keys(links).sort(function (v1, v2) {
|
||||
return this.translate(v1, 'links', scope).localeCompare(this.translate(v2, 'links', scope));
|
||||
}.bind(this));
|
||||
|
||||
linkList.forEach(function (link) {
|
||||
var type = links[link].type
|
||||
if (type != 'belongsTo') return;
|
||||
var foreignScope = links[link].entity;
|
||||
if (!foreignScope) return;
|
||||
|
||||
var attributeList = this.getFieldManager().getEntityAttributes(foreignScope) || [];
|
||||
|
||||
var forbiddenList = this.getAcl().getScopeForbiddenAttributeList(scope);
|
||||
attributeList = attributeList.filter(function (item) {
|
||||
if (~forbiddenList.indexOf(item)) return;
|
||||
return true;
|
||||
}, this);
|
||||
|
||||
attributeList.push('id');
|
||||
if (this.getMetadata().get('entityDefs.' + foreignScope + '.fields.name.type') == 'personName') {
|
||||
attributeList.unshift('name');
|
||||
};
|
||||
|
||||
attributeList.sort(function (v1, v2) {
|
||||
return this.translate(v1, 'fields', foreignScope).localeCompare(this.translate(v2, 'fields', foreignScope));
|
||||
}.bind(this));
|
||||
|
||||
attributeList.forEach(function (item) {
|
||||
entityFields[scope].push(link + '.' + item);
|
||||
|
||||
this.translatedOptions[scope][link + '.' + item] =
|
||||
this.translate(link, 'links', scope) + '.' + this.translate(item, 'fields', foreignScope);
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
}, this);
|
||||
|
||||
entityFields['Person'] = ['name', 'firstName', 'lastName', 'salutationName', 'emailAddress', 'assignedUserName'];
|
||||
this.translatedOptions['Person'] = {};
|
||||
|
||||
this.entityList = entityList;
|
||||
this.entityFields = entityFields;
|
||||
@@ -109,13 +164,21 @@ Espo.define('views/email-template/fields/insert-field', 'views/fields/base', fun
|
||||
var entityType = this.$entityType.val();
|
||||
var fieldList = this.entityFields[entityType];
|
||||
|
||||
this.$field.empty();
|
||||
this.$field.html('');
|
||||
|
||||
fieldList.forEach(function (field) {
|
||||
this.$field.append('<option value="' + field + '">' + this.translate(field, 'fields', entityType) + '</option>');
|
||||
this.$field.append('<option value="' + field + '">' + this.translateItem(entityType, field) + '</option>');
|
||||
}, this);
|
||||
},
|
||||
|
||||
translateItem: function (entityType, item) {
|
||||
if (this.translatedOptions[entityType][item]) {
|
||||
return this.translatedOptions[entityType][item];
|
||||
} else {
|
||||
return this.translate(item, 'fields');
|
||||
}
|
||||
},
|
||||
|
||||
insert: function (entityType, field) {
|
||||
this.trigger('insert-field', {
|
||||
entityType: entityType,
|
||||
|
||||
@@ -69,6 +69,13 @@ Espo.define('views/template/fields/variables', 'views/fields/base', function (De
|
||||
var entityType = this.model.get('entityType');
|
||||
|
||||
var attributeList = this.getFieldManager().getEntityAttributes(entityType) || [];
|
||||
|
||||
var forbiddenList = this.getAcl().getScopeForbiddenAttributeList(entityType);
|
||||
attributeList = attributeList.filter(function (item) {
|
||||
if (~forbiddenList.indexOf(item)) return;
|
||||
return true;
|
||||
}, this);
|
||||
|
||||
attributeList.push('id');
|
||||
if (this.getMetadata().get('entityDefs.' + entityType + '.fields.name.type') == 'personName') {
|
||||
attributeList.unshift('name');
|
||||
@@ -100,6 +107,12 @@ Espo.define('views/template/fields/variables', 'views/fields/base', function (De
|
||||
|
||||
var attributeList = this.getFieldManager().getEntityAttributes(scope) || [];
|
||||
|
||||
var forbiddenList = this.getAcl().getScopeForbiddenAttributeList(scope);
|
||||
attributeList = attributeList.filter(function (item) {
|
||||
if (~forbiddenList.indexOf(item)) return;
|
||||
return true;
|
||||
}, this);
|
||||
|
||||
attributeList.push('id');
|
||||
if (this.getMetadata().get('entityDefs.' + scope + '.fields.name.type') == 'personName') {
|
||||
attributeList.unshift('name');
|
||||
|
||||
Reference in New Issue
Block a user