email template foreign fields and acl

This commit is contained in:
yuri
2016-08-25 10:43:06 +03:00
parent e72557bb59
commit d8cd0d31db
4 changed files with 143 additions and 5 deletions
+33 -3
View File
@@ -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;
}
}
+32
View File
@@ -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');