Merge branch 'master' of https://github.com/espocrm/espocrm
This commit is contained in:
@@ -31,10 +31,12 @@ namespace Espo\Core\Acl;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Metadata,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\DataCache,
|
||||
Utils\FieldUtil,
|
||||
};
|
||||
|
||||
use StdClass;
|
||||
|
||||
/**
|
||||
* Lists of restricted fields can be obtained from here. Restricted fields are specified in metadata > entityAcl.
|
||||
*/
|
||||
@@ -56,32 +58,32 @@ class GlobalRestricton
|
||||
'nonAdminReadOnly' // read-only for non-admin users
|
||||
];
|
||||
|
||||
protected $cacheFilePath = 'data/cache/application/entityAcl.php';
|
||||
|
||||
private $metadata;
|
||||
|
||||
private $fileManager;
|
||||
|
||||
private $fieldUtil;
|
||||
|
||||
private $data;
|
||||
|
||||
protected $cacheKey = 'entityAcl';
|
||||
|
||||
private $metadata;
|
||||
private $dataCache;
|
||||
private $fieldUtil;
|
||||
|
||||
public function __construct(
|
||||
Metadata $metadata, FileManager $fileManager, FieldUtil $fieldUtil, bool $useCache = true
|
||||
Metadata $metadata, DataCache $dataCache, FieldUtil $fieldUtil, bool $useCache = true
|
||||
) {
|
||||
$this->metadata = $metadata;
|
||||
$this->fileManager = $fileManager;
|
||||
$this->dataCache = $dataCache;
|
||||
$this->fieldUtil = $fieldUtil;
|
||||
|
||||
$isFromCache = false;
|
||||
|
||||
if ($useCache) {
|
||||
if (file_exists($this->cacheFilePath)) {
|
||||
$this->data = include($this->cacheFilePath);
|
||||
if ($this->dataCache->has($this->cacheKey)) {
|
||||
$this->data = $this->dataCache->get($this->cacheKey);
|
||||
|
||||
$isFromCache = true;
|
||||
|
||||
if (!($this->data instanceof \StdClass)) {
|
||||
if (! $this->data instanceof StdClass) {
|
||||
$GLOBALS['log']->error("ACL GlobalRestricton: Bad data fetched from cache.");
|
||||
|
||||
$this->data = null;
|
||||
}
|
||||
}
|
||||
@@ -100,25 +102,25 @@ class GlobalRestricton
|
||||
|
||||
protected function storeCacheFile()
|
||||
{
|
||||
$this->getFileManager()->putPhpContents($this->cacheFilePath, $this->data, true);
|
||||
$this->dataCache->store($this->cacheKey, $this->data, true);
|
||||
}
|
||||
|
||||
protected function buildData()
|
||||
{
|
||||
$scopeList = array_keys($this->getMetadata()->get(['entityDefs'], []));
|
||||
$scopeList = array_keys($this->metadata->get(['entityDefs'], []));
|
||||
|
||||
$data = (object) [];
|
||||
|
||||
foreach ($scopeList as $scope) {
|
||||
$fieldList = array_keys($this->getMetadata()->get(['entityDefs', $scope, 'fields'], []));
|
||||
$linkList = array_keys($this->getMetadata()->get(['entityDefs', $scope, 'links'], []));
|
||||
$fieldList = array_keys($this->metadata->get(['entityDefs', $scope, 'fields'], []));
|
||||
$linkList = array_keys($this->metadata->get(['entityDefs', $scope, 'links'], []));
|
||||
|
||||
$isNotEmpty = false;
|
||||
|
||||
$scopeData = (object) [
|
||||
'fields' => (object) [],
|
||||
'attributes' => (object) [],
|
||||
'links' => (object) []
|
||||
'links' => (object) [],
|
||||
];
|
||||
|
||||
foreach ($this->fieldTypeList as $type) {
|
||||
@@ -126,10 +128,13 @@ class GlobalRestricton
|
||||
$resultAttributeList = [];
|
||||
|
||||
foreach ($fieldList as $field) {
|
||||
if ($this->getMetadata()->get(['entityAcl', $scope, 'fields', $field, $type])) {
|
||||
if ($this->metadata->get(['entityAcl', $scope, 'fields', $field, $type])) {
|
||||
$isNotEmpty = true;
|
||||
|
||||
$resultFieldList[] = $field;
|
||||
$fieldAttributeList = $this->getFieldUtil()->getAttributeList($scope, $field);
|
||||
|
||||
$fieldAttributeList = $this->fieldUtil->getAttributeList($scope, $field);
|
||||
|
||||
foreach ($fieldAttributeList as $attribute) {
|
||||
$resultAttributeList[] = $attribute;
|
||||
}
|
||||
@@ -141,9 +146,11 @@ class GlobalRestricton
|
||||
}
|
||||
foreach ($this->linkTypeList as $type) {
|
||||
$resultLinkList = [];
|
||||
|
||||
foreach ($linkList as $link) {
|
||||
if ($this->getMetadata()->get(['entityAcl', $scope, 'links', $link, $type])) {
|
||||
if ($this->metadata->get(['entityAcl', $scope, 'links', $link, $type])) {
|
||||
$isNotEmpty = true;
|
||||
|
||||
$resultLinkList[] = $link;
|
||||
}
|
||||
}
|
||||
@@ -158,44 +165,52 @@ class GlobalRestricton
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
protected function getMetadata()
|
||||
public function getScopeRestrictedFieldList(string $scope, string $type) : array
|
||||
{
|
||||
return $this->metadata;
|
||||
}
|
||||
if (!property_exists($this->data, $scope)) {
|
||||
return [];
|
||||
}
|
||||
if (!property_exists($this->data->$scope, 'fields')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
{
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getFieldUtil()
|
||||
{
|
||||
return $this->fieldUtil;
|
||||
}
|
||||
|
||||
public function getScopeRestrictedFieldList($scope, $type)
|
||||
{
|
||||
if (!property_exists($this->data, $scope)) return [];
|
||||
if (!property_exists($this->data->$scope, 'fields')) return [];
|
||||
if (!property_exists($this->data->$scope->fields, $type)) return [];
|
||||
if (!property_exists($this->data->$scope->fields, $type)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->data->$scope->fields->$type;
|
||||
}
|
||||
|
||||
public function getScopeRestrictedAttributeList($scope, $type)
|
||||
public function getScopeRestrictedAttributeList(string $scope, string $type) : array
|
||||
{
|
||||
if (!property_exists($this->data, $scope)) return [];
|
||||
if (!property_exists($this->data->$scope, 'attributes')) return [];
|
||||
if (!property_exists($this->data->$scope->attributes, $type)) return [];
|
||||
if (!property_exists($this->data, $scope)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!property_exists($this->data->$scope, 'attributes')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!property_exists($this->data->$scope->attributes, $type)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->data->$scope->attributes->$type;
|
||||
}
|
||||
|
||||
public function getScopeRestrictedLinkList($scope, $type)
|
||||
public function getScopeRestrictedLinkList(string $scope, string $type) : array
|
||||
{
|
||||
if (!property_exists($this->data, $scope)) return [];
|
||||
if (!property_exists($this->data->$scope, 'links')) return [];
|
||||
if (!property_exists($this->data->$scope->links, $type)) return [];
|
||||
if (!property_exists($this->data, $scope)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!property_exists($this->data->$scope, 'links')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!property_exists($this->data->$scope->links, $type)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->data->$scope->links->$type;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ use Espo\Core\{
|
||||
Utils\Config,
|
||||
Utils\Metadata,
|
||||
Utils\FieldUtil,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
use StdClass;
|
||||
@@ -57,7 +57,7 @@ class Table
|
||||
|
||||
private $data = null;
|
||||
|
||||
protected $cacheFilePath;
|
||||
protected $cacheKey;
|
||||
|
||||
protected $actionList = ['read', 'stream', 'edit', 'delete', 'create'];
|
||||
|
||||
@@ -84,17 +84,17 @@ class Table
|
||||
protected $entityManager;
|
||||
protected $user;
|
||||
protected $config;
|
||||
protected $fileManager;
|
||||
protected $metadata;
|
||||
protected $fieldUtil;
|
||||
protected $dataCache;
|
||||
|
||||
public function __construct(
|
||||
EntityManager $entityManager,
|
||||
User $user,
|
||||
Config $config = null,
|
||||
FileManager $fileManager = null,
|
||||
Metadata $metadata = null,
|
||||
FieldUtil $fieldUtil = null
|
||||
FieldUtil $fieldUtil = null,
|
||||
DataCache $dataCache
|
||||
) {
|
||||
$this->entityManager = $entityManager;
|
||||
|
||||
@@ -111,39 +111,34 @@ class Table
|
||||
}
|
||||
|
||||
$this->user = $user;
|
||||
|
||||
$this->metadata = $metadata;
|
||||
|
||||
if ($fieldUtil) {
|
||||
$this->fieldUtil = $fieldUtil;
|
||||
}
|
||||
$this->fieldUtil = $fieldUtil;
|
||||
$this->dataCache = $dataCache;
|
||||
|
||||
if (!$this->user->isFetched()) {
|
||||
throw new Error('User must be fetched before ACL check.');
|
||||
}
|
||||
|
||||
if ($fileManager) {
|
||||
$this->fileManager = $fileManager;
|
||||
}
|
||||
$this->valuePermissionList = $this->metadata->get(['app', $this->type, 'valuePermissionList'], []);
|
||||
$this->valuePermissionHighestLevels = $this->metadata->get(['app', $this->type, 'valuePermissionHighestLevels'], array());
|
||||
$this->valuePermissionHighestLevels = $this->metadata->get(['app', $this->type, 'valuePermissionHighestLevels'], []);
|
||||
|
||||
$this->initCacheFilePath();
|
||||
$this->initCacheKey();
|
||||
|
||||
if ($config && $config->get('useCache') && file_exists($this->cacheFilePath)) {
|
||||
$cached = include $this->cacheFilePath;
|
||||
$this->data = $cached;
|
||||
} else {
|
||||
if ($config && $config->get('useCache') && $this->dataCache->has($this->cacheKey)) {
|
||||
$this->data = $this->dataCache->get($this->cacheKey);
|
||||
}
|
||||
else {
|
||||
$this->load();
|
||||
if ($config && $fileManager && $config->get('useCache')) {
|
||||
|
||||
if ($config && $config->get('useCache')) {
|
||||
$this->buildCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function initCacheFilePath()
|
||||
protected function initCacheKey()
|
||||
{
|
||||
$this->cacheFilePath = 'data/cache/application/acl/' . $this->getUser()->id . '.php';
|
||||
$this->cacheKey = 'acl/' . $this->getUser()->id;
|
||||
}
|
||||
|
||||
protected function getUser()
|
||||
@@ -170,12 +165,16 @@ class Table
|
||||
{
|
||||
if (isset($this->data->table->$scope)) {
|
||||
$data = $this->data->table->$scope;
|
||||
|
||||
if (is_string($data)) {
|
||||
$data = $this->getScopeData($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -188,6 +187,7 @@ class Table
|
||||
if (isset($this->data->$permission)) {
|
||||
return $this->data->$permission;
|
||||
}
|
||||
|
||||
return 'no';
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@ class Table
|
||||
return $this->data->table->$scope->$action;
|
||||
}
|
||||
}
|
||||
|
||||
return 'no';
|
||||
}
|
||||
|
||||
@@ -205,15 +206,17 @@ class Table
|
||||
{
|
||||
if (in_array($action, $this->booleanActionList)) {
|
||||
return 'yes';
|
||||
} else {
|
||||
$level = $this->metadata->get(['scopes', $scope, $this->type . 'HighestLevel']);
|
||||
return $level ?? 'all';
|
||||
}
|
||||
|
||||
$level = $this->metadata->get(['scopes', $scope, $this->type . 'HighestLevel']);
|
||||
|
||||
return $level ?? 'all';
|
||||
}
|
||||
|
||||
private function load()
|
||||
{
|
||||
$valuePermissionLists = (object)[];
|
||||
$valuePermissionLists = (object) [];
|
||||
|
||||
foreach ($this->valuePermissionList as $permission) {
|
||||
$valuePermissionLists->$permission = [];
|
||||
}
|
||||
@@ -227,6 +230,7 @@ class Table
|
||||
foreach ($roleList as $role) {
|
||||
$aclTableList[] = $role->get('data');
|
||||
$fieldTableList[] = $role->get('fieldData');
|
||||
|
||||
foreach ($this->valuePermissionList as $permission) {
|
||||
$valuePermissionLists->{$permission}[] = $role->get($permission);
|
||||
}
|
||||
@@ -239,16 +243,20 @@ class Table
|
||||
$this->applyDisabled($aclTable, $fieldTable);
|
||||
$this->applyMandatory($aclTable, $fieldTable);
|
||||
$this->applyAdditional($aclTable, $fieldTable, $valuePermissionLists);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$aclTable = (object) [];
|
||||
|
||||
foreach ($this->getScopeList() as $scope) {
|
||||
if ($this->metadata->get("scopes.{$scope}.{$this->type}") === 'boolean') {
|
||||
$aclTable->$scope = true;
|
||||
} else {
|
||||
if ($this->metadata->get("scopes.{$scope}.entity")) {
|
||||
$aclTable->$scope = (object) [];
|
||||
|
||||
foreach ($this->actionList as $action) {
|
||||
$aclTable->$scope->$action = 'all';
|
||||
|
||||
if (in_array($action, $this->booleanActionList)) {
|
||||
$aclTable->$scope->$action = 'yes';
|
||||
}
|
||||
@@ -274,14 +282,17 @@ class Table
|
||||
|
||||
if (!$this->getUser()->isAdmin()) {
|
||||
$permissionsDefaultsGroupName = 'permissionsDefaults';
|
||||
|
||||
if ($this->isStrictMode) {
|
||||
$permissionsDefaultsGroupName = 'permissionsStrictDefaults';
|
||||
}
|
||||
|
||||
foreach ($this->valuePermissionList as $permission) {
|
||||
$this->data->$permission = $this->mergeValueList(
|
||||
$valuePermissionLists->$permission,
|
||||
$this->metadata->get(['app', $this->type, $permissionsDefaultsGroupName, $permission, 'yes'])
|
||||
);
|
||||
|
||||
if ($this->metadata->get('app.'.$this->type.'.mandatory.' . $permission)) {
|
||||
$this->data->$permission = $this->metadata->get('app.'.$this->type.'.mandatory.' . $permission);
|
||||
}
|
||||
@@ -291,8 +302,10 @@ class Table
|
||||
foreach ($this->valuePermissionList as $permission) {
|
||||
if (isset($this->valuePermissionHighestLevels[$permission])) {
|
||||
$this->data->$permission = $this->valuePermissionHighestLevels[$permission];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->data->$permission = 'all';
|
||||
}
|
||||
}
|
||||
@@ -341,6 +354,7 @@ class Table
|
||||
public function getScopeForbiddenAttributeList(string $scope, string $action = 'read', string $thresholdLevel = 'no') : array
|
||||
{
|
||||
$key = $scope . '_'. $action . '_' . $thresholdLevel;
|
||||
|
||||
if (isset($this->forbiddenAttributesCache[$key])) {
|
||||
return $this->forbiddenAttributesCache[$key];
|
||||
}
|
||||
@@ -352,10 +366,12 @@ class Table
|
||||
!isset($fieldTableQuickAccess->$scope->attributes->$action)
|
||||
) {
|
||||
$this->forbiddenAttributesCache[$key] = [];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$levelList = [];
|
||||
|
||||
foreach ($this->fieldLevelList as $level) {
|
||||
if (array_search($level, $this->fieldLevelList) >= array_search($thresholdLevel, $this->fieldLevelList)) {
|
||||
$levelList[] = $level;
|
||||
@@ -365,9 +381,15 @@ class Table
|
||||
$attributeList = [];
|
||||
|
||||
foreach ($levelList as $level) {
|
||||
if (!isset($fieldTableQuickAccess->$scope->attributes->$action->$level)) continue;
|
||||
if (!isset($fieldTableQuickAccess->$scope->attributes->$action->$level)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($fieldTableQuickAccess->$scope->attributes->$action->$level as $attribute) {
|
||||
if (in_array($attribute, $attributeList)) continue;
|
||||
if (in_array($attribute, $attributeList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributeList[] = $attribute;
|
||||
}
|
||||
}
|
||||
@@ -391,10 +413,12 @@ class Table
|
||||
!isset($fieldTableQuickAccess->$scope->fields->$action)
|
||||
) {
|
||||
$this->forbiddenFieldsCache[$key] = [];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$levelList = [];
|
||||
|
||||
foreach ($this->fieldLevelList as $level) {
|
||||
if (array_search($level, $this->fieldLevelList) >= array_search($thresholdLevel, $this->fieldLevelList)) {
|
||||
$levelList[] = $level;
|
||||
@@ -404,9 +428,15 @@ class Table
|
||||
$fieldList = [];
|
||||
|
||||
foreach ($levelList as $level) {
|
||||
if (!isset($fieldTableQuickAccess->$scope->fields->$action->$level)) continue;
|
||||
if (!isset($fieldTableQuickAccess->$scope->fields->$action->$level)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($fieldTableQuickAccess->$scope->fields->$action->$level as $field) {
|
||||
if (in_array($field, $fieldList)) continue;
|
||||
if (in_array($field, $fieldList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldList[] = $field;
|
||||
}
|
||||
}
|
||||
@@ -431,6 +461,7 @@ class Table
|
||||
foreach ($this->fieldActionList as $action) {
|
||||
$fieldTableQuickAccess->$scope->attributes->$action = (object) [];
|
||||
$fieldTableQuickAccess->$scope->fields->$action = (object) [];
|
||||
|
||||
foreach ($this->fieldLevelList as $level) {
|
||||
$fieldTableQuickAccess->$scope->attributes->$action->$level = [];
|
||||
$fieldTableQuickAccess->$scope->fields->$action->$level = [];
|
||||
@@ -441,10 +472,14 @@ class Table
|
||||
$attributeList = $this->getFieldUtil()->getAttributeList($scope, $field);
|
||||
|
||||
foreach ($this->fieldActionList as $action) {
|
||||
if (!isset($fieldData->$action)) continue;
|
||||
if (!isset($fieldData->$action)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($this->fieldLevelList as $level) {
|
||||
if ($fieldData->$action === $level) {
|
||||
$fieldTableQuickAccess->$scope->fields->$action->{$level}[] = $field;
|
||||
|
||||
foreach ($attributeList as $attribute) {
|
||||
$fieldTableQuickAccess->$scope->attributes->$action->{$level}[] = $attribute;
|
||||
}
|
||||
@@ -464,6 +499,7 @@ class Table
|
||||
}
|
||||
|
||||
$defaultsGroupName = 'default';
|
||||
|
||||
if ($this->isStrictMode) {
|
||||
$defaultsGroupName = 'strictDefault';
|
||||
}
|
||||
@@ -471,19 +507,29 @@ class Table
|
||||
$data = $this->metadata->get(['app', $this->type, $defaultsGroupName, 'scopeLevel'], []);
|
||||
|
||||
foreach ($data as $scope => $item) {
|
||||
if (isset($table->$scope)) continue;
|
||||
if (isset($table->$scope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $item;
|
||||
|
||||
if (is_array($item)) {
|
||||
$value = (object) $item;
|
||||
}
|
||||
|
||||
$table->$scope = $value;
|
||||
}
|
||||
|
||||
$defaultFieldData = $this->metadata->get(['app', $this->type, $defaultsGroupName, 'fieldLevel'], []);
|
||||
|
||||
foreach ($this->getScopeList() as $scope) {
|
||||
if (isset($table->$scope) && $table->$scope === false) continue;
|
||||
if (!$this->getMetadata()->get('scopes.' . $scope . '.entity')) continue;
|
||||
if (isset($table->$scope) && $table->$scope === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->getMetadata()->get('scopes.' . $scope . '.entity')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldList = array_keys($this->getMetadata()->get("entityDefs.{$scope}.fields", []));
|
||||
|
||||
@@ -491,14 +537,23 @@ class Table
|
||||
'app.'.$this->type.'.'.$defaultsGroupName.'.scopeFieldLevel.' . $scope, []);
|
||||
|
||||
foreach (array_merge($defaultFieldData, $defaultScopeFieldData) as $field => $f) {
|
||||
if (!in_array($field, $fieldList)) continue;
|
||||
if (!in_array($field, $fieldList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($fieldTable->$scope)) {
|
||||
$fieldTable->$scope = (object) [];
|
||||
}
|
||||
if (isset($fieldTable->$scope->$field)) continue;
|
||||
|
||||
if (isset($fieldTable->$scope->$field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldTable->$scope->$field = (object) [];
|
||||
|
||||
foreach ($this->fieldActionList as $action) {
|
||||
$level = 'no';
|
||||
|
||||
if ($f === true) {
|
||||
$level = 'yes';
|
||||
} else {
|
||||
@@ -514,25 +569,32 @@ class Table
|
||||
foreach ($this->getScopeWithAclList() as $scope) {
|
||||
if (!isset($table->$scope)) {
|
||||
$aclType = $this->metadata->get('scopes.' . $scope . '.' . $this->type);
|
||||
|
||||
if ($aclType === true) {
|
||||
$aclType = $this->defaultAclType;
|
||||
}
|
||||
|
||||
if (!empty($aclType)) {
|
||||
$paramDefaultsName = 'scopeLevelTypesDefaults';
|
||||
|
||||
if ($this->isStrictMode) {
|
||||
$paramDefaultsName = 'scopeLevelTypesStrictDefaults';
|
||||
}
|
||||
|
||||
$defaultValue = $this->metadata->get(
|
||||
['app', $this->type, $paramDefaultsName, $aclType],
|
||||
$this->metadata->get(['app', $this->type, $paramDefaultsName, 'record'])
|
||||
);
|
||||
|
||||
if (is_array($defaultValue)) {
|
||||
$defaultValue = (object) $defaultValue;
|
||||
}
|
||||
|
||||
$table->$scope = $defaultValue;
|
||||
|
||||
if (is_object($table->$scope)) {
|
||||
$actionList = $this->getMetadata()->get(['scopes', $scope, $this->type . 'ActionList']);
|
||||
|
||||
if ($actionList) {
|
||||
foreach (get_object_vars($table->$scope) as $action => $level) {
|
||||
if (!in_array($action, $actionList)) {
|
||||
@@ -556,30 +618,43 @@ class Table
|
||||
|
||||
foreach ($data as $scope => $item) {
|
||||
$value = $item;
|
||||
|
||||
if (is_array($item)) {
|
||||
$value = (object) $item;
|
||||
}
|
||||
|
||||
$table->$scope = $value;
|
||||
}
|
||||
|
||||
$mandatoryFieldData = $this->metadata->get('app.'.$this->type.'.mandatory.fieldLevel', array());
|
||||
|
||||
foreach ($this->getScopeList() as $scope) {
|
||||
if (isset($table->$scope) && $table->$scope === false) continue;
|
||||
if (!$this->getMetadata()->get('scopes.' . $scope . '.entity')) continue;
|
||||
if (isset($table->$scope) && $table->$scope === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->getMetadata()->get('scopes.' . $scope . '.entity')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldList = array_keys($this->getMetadata()->get("entityDefs.{$scope}.fields", []));
|
||||
|
||||
$mandatoryScopeFieldData = $this->metadata->get('app.'.$this->type.'.mandatory.scopeFieldLevel.' . $scope, array());
|
||||
|
||||
foreach (array_merge($mandatoryFieldData, $mandatoryScopeFieldData) as $field => $f) {
|
||||
if (!in_array($field, $fieldList)) continue;
|
||||
if (!in_array($field, $fieldList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($fieldTable->$scope)) {
|
||||
$fieldTable->$scope = (object) [];
|
||||
}
|
||||
|
||||
$fieldTable->$scope->$field = (object) [];
|
||||
|
||||
foreach ($this->fieldActionList as $action) {
|
||||
$level = 'no';
|
||||
|
||||
if ($f === true) {
|
||||
$level = 'yes';
|
||||
} else {
|
||||
@@ -614,6 +689,7 @@ class Table
|
||||
$table->$scope = false;
|
||||
unset($fieldTable->$scope);
|
||||
}
|
||||
|
||||
foreach ($this->valuePermissionList as $permission) {
|
||||
$valuePermissionLists->{$permission}[] = 'no';
|
||||
}
|
||||
@@ -623,29 +699,38 @@ class Table
|
||||
private function mergeValueList(array $list, $defaultValue)
|
||||
{
|
||||
$result = null;
|
||||
|
||||
foreach ($list as $level) {
|
||||
if ($level != 'not-set') {
|
||||
if (is_null($result)) {
|
||||
$result = $level;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array_search($result, $this->levelList) > array_search($level, $this->levelList)) {
|
||||
$result = $level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($result)) {
|
||||
$result = $defaultValue;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getScopeWithAclList()
|
||||
{
|
||||
$scopeList = [];
|
||||
|
||||
$scopes = $this->metadata->get('scopes');
|
||||
|
||||
foreach ($scopes as $scope => $d) {
|
||||
if (empty($d['acl'])) continue;
|
||||
if (empty($d['acl'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$scopeList[] = $scope;
|
||||
}
|
||||
return $scopeList;
|
||||
@@ -654,10 +739,13 @@ class Table
|
||||
protected function getScopeList()
|
||||
{
|
||||
$scopeList = [];
|
||||
|
||||
$scopes = $this->metadata->get('scopes');
|
||||
|
||||
foreach ($scopes as $scope => $d) {
|
||||
$scopeList[] = $scope;
|
||||
}
|
||||
|
||||
return $scopeList;
|
||||
}
|
||||
|
||||
@@ -668,7 +756,9 @@ class Table
|
||||
|
||||
foreach ($tableList as $table) {
|
||||
foreach ($scopeList as $scope) {
|
||||
if (!isset($table->$scope)) continue;
|
||||
if (!isset($table->$scope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$row = $table->$scope;
|
||||
|
||||
@@ -676,9 +766,11 @@ class Table
|
||||
if (!isset($data->$scope)) {
|
||||
$data->$scope = false;
|
||||
}
|
||||
} else if ($row === true) {
|
||||
}
|
||||
else if ($row === true) {
|
||||
$data->$scope = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!isset($data->$scope)) {
|
||||
$data->$scope = (object) [];
|
||||
}
|
||||
@@ -686,7 +778,9 @@ class Table
|
||||
$data->$scope = (object) [];
|
||||
}
|
||||
|
||||
if (!is_object($row)) continue;
|
||||
if (!is_object($row)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$actionList = $this->getMetadata()->get(['scopes', $scope, $this->type . 'ActionList'], $this->actionList);
|
||||
|
||||
@@ -726,33 +820,45 @@ class Table
|
||||
private function mergeFieldTableList(array $tableList)
|
||||
{
|
||||
$data = (object) [];
|
||||
|
||||
$scopeList = $this->getScopeWithAclList();
|
||||
|
||||
foreach ($tableList as $table) {
|
||||
foreach ($scopeList as $scope) {
|
||||
if (!isset($table->$scope)) continue;
|
||||
if (!isset($table->$scope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($data->$scope)) {
|
||||
$data->$scope = (object) [];
|
||||
}
|
||||
|
||||
if (!is_object($table->$scope)) continue;
|
||||
if (!is_object($table->$scope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldList = array_keys($this->getMetadata()->get("entityDefs.{$scope}.fields", []));
|
||||
|
||||
foreach (get_object_vars($table->$scope) as $field => $row) {
|
||||
if (!is_object($row)) continue;
|
||||
if (!is_object($row)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!in_array($field, $fieldList)) continue;
|
||||
if (!in_array($field, $fieldList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($data->$scope->$field)) {
|
||||
$data->$scope->$field = (object) [];
|
||||
}
|
||||
|
||||
foreach ($this->fieldActionList as $i => $action) {
|
||||
if (!isset($row->$action)) continue;
|
||||
if (!isset($row->$action)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$level = $row->$action;
|
||||
|
||||
if (!isset($data->$scope->$field->$action)) {
|
||||
$data->$scope->$field->$action = $level;
|
||||
} else {
|
||||
@@ -775,6 +881,6 @@ class Table
|
||||
|
||||
private function buildCache()
|
||||
{
|
||||
$this->fileManager->putPhpContents($this->cacheFilePath, $this->data, true);
|
||||
$this->dataCache->store($this->cacheKey, $this->data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ use Espo\Core\{
|
||||
Utils\Metadata,
|
||||
Utils\FieldUtil,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
use Traversable;
|
||||
@@ -64,9 +65,9 @@ class Table extends \Espo\Core\Acl\Table
|
||||
User $user,
|
||||
Portal $portal,
|
||||
Config $config = null,
|
||||
FileManager $fileManager = null,
|
||||
Metadata $metadata = null,
|
||||
FieldUtil $fieldUtil = null
|
||||
FieldUtil $fieldUtil = null,
|
||||
DataCache $dataCache
|
||||
) {
|
||||
if (empty($portal)) {
|
||||
throw new Error("No portal was passed to AclPortal\\Table constructor.");
|
||||
@@ -74,7 +75,7 @@ class Table extends \Espo\Core\Acl\Table
|
||||
|
||||
$this->portal = $portal;
|
||||
|
||||
parent::__construct($entityManager, $user, $config, $fileManager, $metadata, $fieldUtil);
|
||||
parent::__construct($entityManager, $user, $config, $metadata, $fieldUtil, $dataCache);
|
||||
}
|
||||
|
||||
protected function getPortal()
|
||||
@@ -82,9 +83,9 @@ class Table extends \Espo\Core\Acl\Table
|
||||
return $this->portal;
|
||||
}
|
||||
|
||||
protected function initCacheFilePath()
|
||||
protected function initCacheKey()
|
||||
{
|
||||
$this->cacheFilePath = 'data/cache/application/acl-portal/'.$this->getPortal()->id.'/' . $this->getUser()->id . '.php';
|
||||
$this->cacheKey = 'aclPortal/' . $this->getPortal()->id.'/' . $this->getUser()->id;
|
||||
}
|
||||
|
||||
protected function getRoleList()
|
||||
|
||||
@@ -37,6 +37,7 @@ use Espo\Core\{
|
||||
Utils\Metadata,
|
||||
Utils\Config,
|
||||
Utils\Util,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -55,7 +56,7 @@ class HookManager
|
||||
|
||||
private $hooks;
|
||||
|
||||
protected $cacheFile = 'data/cache/application/hooks.php';
|
||||
protected $cacheKey = 'hooks';
|
||||
|
||||
protected $ignoredMethodList = [
|
||||
'__construct',
|
||||
@@ -73,12 +74,14 @@ class HookManager
|
||||
InjectableFactory $injectableFactory,
|
||||
FileManager $fileManager,
|
||||
Metadata $metadata,
|
||||
Config $config
|
||||
Config $config,
|
||||
DataCache $dataCache
|
||||
) {
|
||||
$this->injectableFactory = $injectableFactory;
|
||||
$this->fileManager = $fileManager;
|
||||
$this->metadata = $metadata;
|
||||
$this->config = $config;
|
||||
$this->dataCache = $dataCache;
|
||||
}
|
||||
|
||||
public function process(string $scope, string $hookName, $injection = null, array $options = [], array $hookData = [])
|
||||
@@ -97,9 +100,14 @@ class HookManager
|
||||
foreach ($hookList as $className) {
|
||||
if (empty($this->hooks[$className])) {
|
||||
$this->hooks[$className] = $this->createHookByClassName($className);
|
||||
if (empty($this->hooks[$className])) continue;
|
||||
|
||||
if (empty($this->hooks[$className])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$hook = $this->hooks[$className];
|
||||
|
||||
$hook->$hookName($injection, $options, $hookData);
|
||||
}
|
||||
}
|
||||
@@ -123,8 +131,9 @@ class HookManager
|
||||
|
||||
protected function loadHooks()
|
||||
{
|
||||
if ($this->config->get('useCache') && file_exists($this->cacheFile)) {
|
||||
$this->data = $this->fileManager->getPhpContents($this->cacheFile);
|
||||
if ($this->config->get('useCache') && $this->dataCache->has($this->cacheKey)) {
|
||||
$this->data = $this->dataCache->get($this->cacheKey);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,6 +143,7 @@ class HookManager
|
||||
|
||||
foreach ($metadata->getModuleList() as $moduleName) {
|
||||
$modulePath = str_replace('{*}', $moduleName, $this->paths['modulePath']);
|
||||
|
||||
$data = $this->getHookData($modulePath, $data);
|
||||
}
|
||||
|
||||
@@ -142,13 +152,13 @@ class HookManager
|
||||
$this->data = $this->sortHooks($data);
|
||||
|
||||
if ($this->config->get('useCache')) {
|
||||
$this->fileManager->putPhpContents($this->cacheFile, $this->data);
|
||||
$this->dataCache->store($this->cacheKey, $this->data);
|
||||
}
|
||||
}
|
||||
|
||||
protected function createHookByClassName(string $className) : object
|
||||
{
|
||||
if (!@class_exists($className)) {
|
||||
if (!class_exists($className)) {
|
||||
$GLOBALS['log']->error("Hook class '{$className}' does not exist.");
|
||||
}
|
||||
|
||||
@@ -158,7 +168,7 @@ class HookManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and merge hook data by checking the files exist in $hookDirs
|
||||
* Get and merge hook data by checking the files exist in $hookDirs.
|
||||
*
|
||||
* @param $hookDirs - can be ['Espo/Hooks', 'Espo/Custom/Hooks', 'Espo/Modules/Crm/Hooks']
|
||||
*/
|
||||
@@ -172,6 +182,7 @@ class HookManager
|
||||
if (!file_exists($hookDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fileList = $this->fileManager->getFileList($hookDir, 1, '\.php$', true);
|
||||
|
||||
foreach ($fileList as $scopeName => $hookFiles) {
|
||||
@@ -179,6 +190,7 @@ class HookManager
|
||||
$normalizedScopeName = Util::normilizeScopeName($scopeName);
|
||||
|
||||
$scopeHooks = [];
|
||||
|
||||
foreach ($hookFiles as $hookFile) {
|
||||
$hookFilePath = Util::concatPath($hookScopeDirPath, $hookFile);
|
||||
$className = Util::getClassName($hookFilePath);
|
||||
@@ -187,12 +199,16 @@ class HookManager
|
||||
$hookMethods = array_diff($classMethods, $this->ignoredMethodList);
|
||||
|
||||
$hookMethods = array_filter($hookMethods, function ($item) {
|
||||
if (strpos($item, 'set') === 0) return false;
|
||||
if (strpos($item, 'set') === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
foreach ($hookMethods as $hookType) {
|
||||
$entityHookData = $hookData[$normalizedScopeName][$hookType] ?? [];
|
||||
|
||||
if (!$this->hookExists($className, $entityHookData)) {
|
||||
$hookData[$normalizedScopeName][$hookType][] = [
|
||||
'className' => $className,
|
||||
@@ -241,6 +257,7 @@ class HookManager
|
||||
}
|
||||
|
||||
$normalizedList = [];
|
||||
|
||||
foreach ($hookList as $hookData) {
|
||||
$normalizedList[] = $hookData['className'];
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ use Espo\Core\{
|
||||
Utils\Config,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\Language as LanguageService,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
class BaseLanguage implements Loader
|
||||
@@ -41,12 +42,14 @@ class BaseLanguage implements Loader
|
||||
protected $fileManager;
|
||||
protected $config;
|
||||
protected $metadata;
|
||||
protected $dataCache;
|
||||
|
||||
public function __construct(FileManager $fileManager, Config $config, Metadata $metadata)
|
||||
public function __construct(FileManager $fileManager, Config $config, Metadata $metadata, DataCache $dataCache)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
$this->config = $config;
|
||||
$this->metadata = $metadata;
|
||||
$this->dataCache = $dataCache;
|
||||
}
|
||||
|
||||
public function load() : LanguageService
|
||||
@@ -55,6 +58,7 @@ class BaseLanguage implements Loader
|
||||
'en_US',
|
||||
$this->fileManager,
|
||||
$this->metadata,
|
||||
$this->dataCache,
|
||||
$this->config->get('useCache')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ class DefaultLanguage extends BaseLanguage
|
||||
LanguageService::detectLanguage($this->config),
|
||||
$this->fileManager,
|
||||
$this->metadata,
|
||||
$this->dataCache,
|
||||
$this->config->get('useCache')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ use Espo\Core\{
|
||||
Utils\Config,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\Language as LanguageService,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
use Espo\Entities\Preferences;
|
||||
@@ -43,13 +44,16 @@ class Language implements Loader
|
||||
protected $fileManager;
|
||||
protected $config;
|
||||
protected $metadata;
|
||||
protected $dataCache;
|
||||
protected $preferences;
|
||||
|
||||
public function __construct(FileManager $fileManager, Config $config, Metadata $metadata, Preferences $preferences)
|
||||
{
|
||||
public function __construct(
|
||||
FileManager $fileManager, Config $config, Metadata $metadata, DataCache $dataCache, Preferences $preferences
|
||||
) {
|
||||
$this->fileManager = $fileManager;
|
||||
$this->config = $config;
|
||||
$this->metadata = $metadata;
|
||||
$this->dataCache = $dataCache;
|
||||
$this->preferences = $preferences;
|
||||
}
|
||||
|
||||
@@ -59,6 +63,7 @@ class Language implements Loader
|
||||
LanguageService::detectLanguage($this->config, $this->preferences),
|
||||
$this->fileManager,
|
||||
$this->metadata,
|
||||
$this->dataCache,
|
||||
$this->config->get('useCache')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ use Espo\Core\{
|
||||
Utils\File\Manager as FileManager,
|
||||
Portal\Utils\Language as LanguageService,
|
||||
Loaders\Loader as Loader,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
use Espo\Entities\{
|
||||
@@ -47,15 +48,17 @@ class Language implements Loader
|
||||
protected $fileManager;
|
||||
protected $config;
|
||||
protected $metadata;
|
||||
protected $dataCache;
|
||||
protected $preferences;
|
||||
protected $portal;
|
||||
|
||||
public function __construct(
|
||||
FileManager $fileManager, Config $config, Metadata $metadata, Preferences $preferences, Portal $portal
|
||||
FileManager $fileManager, Config $config, Metadata $metadata, DataCache $dataCache, Preferences $preferences, Portal $portal
|
||||
) {
|
||||
$this->fileManager = $fileManager;
|
||||
$this->config = $config;
|
||||
$this->metadata = $metadata;
|
||||
$this->dataCache = $dataCache;
|
||||
$this->preferences = $preferences;
|
||||
$this->portal = $portal;
|
||||
}
|
||||
@@ -66,6 +69,7 @@ class Language implements Loader
|
||||
LanguageService::detectLanguage($this->config, $this->preferences),
|
||||
$this->fileManager,
|
||||
$this->metadata,
|
||||
$this->dataCache,
|
||||
$this->config->get('useCache')
|
||||
);
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ class DataCache
|
||||
{
|
||||
if (
|
||||
$key === '' ||
|
||||
preg_match('/[^a-zA-Z0-9\/]/i', $key) ||
|
||||
preg_match('/[^a-zA-Z0-9_\/\-]/i', $key) ||
|
||||
$key[0] === '/' ||
|
||||
substr($key, -1) === '/'
|
||||
) {
|
||||
|
||||
@@ -920,19 +920,17 @@ class Manager
|
||||
|
||||
if (!$withObjects) {
|
||||
return "<?php\n" .
|
||||
"return " . var_export($content, true) . ";\n".
|
||||
"?>";
|
||||
"return " . var_export($content, true) . ";\n";
|
||||
}
|
||||
|
||||
return "<?php\n" .
|
||||
"return " . $this->varExport($content) . ";\n".
|
||||
"?>";
|
||||
"return " . $this->varExport($content) . ";\n";
|
||||
}
|
||||
|
||||
public function varExport($variable, $level = 0)
|
||||
protected function varExport($variable, int $level = 0)
|
||||
{
|
||||
$tab = '';
|
||||
$tabElement = ' ';
|
||||
$tabElement = ' ';
|
||||
|
||||
for ($i = 0; $i <= $level; $i++) {
|
||||
$tab .= $tabElement;
|
||||
@@ -941,22 +939,24 @@ class Manager
|
||||
$prevTab = substr($tab, 0, strlen($tab) - strlen($tabElement));
|
||||
|
||||
if ($variable instanceof StdClass) {
|
||||
$result = "(object) " . $this->varExport(get_object_vars($variable), $level);
|
||||
return "(object) " . $this->varExport(get_object_vars($variable), $level);
|
||||
}
|
||||
else if (is_array($variable)) {
|
||||
|
||||
if (is_array($variable)) {
|
||||
$array = [];
|
||||
|
||||
foreach ($variable as $key => $value) {
|
||||
$array[] = var_export($key, true) . " => " . $this->varExport($value, $level + 1);
|
||||
}
|
||||
|
||||
$result = "[\n" . $tab . implode(",\n" . $tab, $array) . "\n" . $prevTab . "]";
|
||||
}
|
||||
else {
|
||||
$result = var_export($variable, true);
|
||||
if (count($array) === 0) {
|
||||
return "[]";
|
||||
}
|
||||
|
||||
return "[\n" . $tab . implode(",\n" . $tab, $array) . "\n" . $prevTab . "]";
|
||||
}
|
||||
|
||||
return $result;
|
||||
return var_export($variable, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,7 @@ use Espo\Core\{
|
||||
Utils\Metadata,
|
||||
Utils\File\Unifier as FileUnifier,
|
||||
Utils\Config,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
use Espo\{
|
||||
@@ -58,8 +59,6 @@ class Language
|
||||
|
||||
private $currentLanguage = null;
|
||||
|
||||
protected $cacheFile = 'data/cache/application/languages/{language}.php';
|
||||
|
||||
protected $defaultLanguage = 'en_US';
|
||||
|
||||
protected $useCache = false;
|
||||
@@ -73,7 +72,12 @@ class Language
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
?string $language = null, FileManager $fileManager, Metadata $metadata, bool $useCache = false, bool $noCustom = false
|
||||
?string $language = null,
|
||||
FileManager $fileManager,
|
||||
Metadata $metadata,
|
||||
DataCache $dataCache,
|
||||
bool $useCache = false,
|
||||
bool $noCustom = false
|
||||
) {
|
||||
if ($language) {
|
||||
$this->currentLanguage = $language;
|
||||
@@ -83,6 +87,7 @@ class Language
|
||||
|
||||
$this->fileManager = $fileManager;
|
||||
$this->metadata = $metadata;
|
||||
$this->dataCache = $dataCache;
|
||||
|
||||
$this->useCache = $useCache;
|
||||
$this->noCustom = $noCustom;
|
||||
@@ -135,13 +140,11 @@ class Language
|
||||
$this->currentLanguage = $language;
|
||||
}
|
||||
|
||||
protected function getCacheFile(string $language = null) : string
|
||||
protected function getCacheKey(string $language = null) : string
|
||||
{
|
||||
$language = $language ?? $this->getLanguage();
|
||||
|
||||
$langCacheFile = str_replace('{language}', $language, $this->cacheFile);
|
||||
|
||||
return $langCacheFile;
|
||||
return 'languages/' . $language;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,12 +326,14 @@ class Language
|
||||
foreach ($name as $rowLabel) {
|
||||
$this->delete($scope, $category, $rowLabel);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->deletedData[$scope][$category][] = $name;
|
||||
|
||||
$currentLanguage = $this->getLanguage();
|
||||
|
||||
if (!isset($this->data[$currentLanguage])) {
|
||||
$this->init();
|
||||
}
|
||||
@@ -367,9 +372,9 @@ class Language
|
||||
{
|
||||
if ($reload || !isset($this->data[$language])) {
|
||||
|
||||
$cacheFile = $this->getCacheFile($language);
|
||||
$cacheKey = $this->getCacheKey($language);
|
||||
|
||||
if (!$this->useCache || !file_exists($cacheFile) || $reload) {
|
||||
if (!$this->useCache || !$this->dataCache->has($cacheKey) || $reload) {
|
||||
|
||||
$paths = $this->paths;
|
||||
|
||||
@@ -394,15 +399,12 @@ class Language
|
||||
$this->data[$language] = $data;
|
||||
|
||||
if ($this->useCache) {
|
||||
$putResult = $this->getFileManager()->putPhpContents($cacheFile, $data);
|
||||
if (!$putResult) {
|
||||
$GLOBALS['log']->error("Language: Could not store cache file for {$language}");
|
||||
}
|
||||
$this->dataCache->store($cacheKey, $data);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->useCache) {
|
||||
$this->data[$language] = $this->getFileManager()->getPhpContents($cacheFile);
|
||||
$this->data[$language] = $this->dataCache->get($cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,34 +35,35 @@ use Espo\Core\{
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\Config,
|
||||
Utils\Database\Converter,
|
||||
Utils\DataCache,
|
||||
Exceptions\Error,
|
||||
};
|
||||
|
||||
class OrmMetadata
|
||||
{
|
||||
protected $data = [];
|
||||
protected $data = null;
|
||||
|
||||
protected $cacheFile = 'data/cache/application/ormMetadata.php';
|
||||
|
||||
protected $metadata;
|
||||
|
||||
protected $fileManager;
|
||||
|
||||
protected $config;
|
||||
protected $cacheKey = 'ormMetadata';
|
||||
|
||||
protected $useCache;
|
||||
|
||||
public function __construct(Metadata $metadata, FileManager $fileManager, Config $config)
|
||||
protected $metadata;
|
||||
protected $fileManager;
|
||||
protected $dataCache;
|
||||
protected $config;
|
||||
|
||||
public function __construct(Metadata $metadata, FileManager $fileManager, DataCache $dataCache, Config $config)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
$this->fileManager = $fileManager;
|
||||
$this->dataCache = $dataCache;
|
||||
|
||||
$this->config = $config;
|
||||
|
||||
$this->useCache = $this->config->get('useCache', false);
|
||||
}
|
||||
|
||||
protected function getConverter()
|
||||
protected function getConverter() : Converter
|
||||
{
|
||||
if (!isset($this->converter)) {
|
||||
$this->converter = new Converter($this->metadata, $this->fileManager, $this->config);
|
||||
@@ -71,40 +72,22 @@ class OrmMetadata
|
||||
return $this->converter;
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
public function getData(bool $reload = false) : array
|
||||
{
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
public function clearData()
|
||||
{
|
||||
$this->ormData = null;
|
||||
}
|
||||
|
||||
public function getData($reload = false)
|
||||
{
|
||||
if (!empty($this->ormData) && !$reload) {
|
||||
return $data;
|
||||
if (isset($this->data) && !$reload) {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
if (!file_exists($this->cacheFile) || !$this->useCache || $reload) {
|
||||
$this->data = $this->getConverter()->process();
|
||||
if ($this->useCache && $this->dataCache->has($this->cacheKey) && !$reload) {
|
||||
$this->data = $this->dataCache->get($this->cacheKey);
|
||||
|
||||
if ($this->useCache) {
|
||||
$result = $this->getFileManager()->putPhpContents($this->cacheFile, $this->data);
|
||||
if ($result == false) {
|
||||
throw new Error('OrmMetadata::getData() - Cannot save ormMetadata to cache file');
|
||||
}
|
||||
}
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
if (empty($this->data)) {
|
||||
$this->data = $this->getFileManager()->getPhpContents($this->cacheFile);
|
||||
$this->data = $this->getConverter()->process();
|
||||
|
||||
if ($this->useCache) {
|
||||
$this->dataCache->store($this->cacheKey, $this->data);
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
|
||||
@@ -29,13 +29,19 @@
|
||||
|
||||
namespace Espo\Core\Utils;
|
||||
|
||||
use Espo\Core\Exceptions\Error;
|
||||
use Espo\Core\{
|
||||
Exceptions\Error,
|
||||
Utils\Config,
|
||||
Utils\Metadata,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
class Route
|
||||
{
|
||||
protected $data = null;
|
||||
|
||||
protected $cacheFile = 'data/cache/application/routes.php';
|
||||
protected $cacheKey = 'routes';
|
||||
|
||||
protected $paths = [
|
||||
'corePath' => 'application/Espo/Resources/routes.json',
|
||||
@@ -43,15 +49,17 @@ class Route
|
||||
'customPath' => 'custom/Espo/Custom/Resources/routes.json',
|
||||
];
|
||||
|
||||
private $fileManager;
|
||||
private $config;
|
||||
private $metadata;
|
||||
private $fileManager;
|
||||
private $dataCache;
|
||||
|
||||
public function __construct(Config $config, Metadata $metadata, File\Manager $fileManager)
|
||||
public function __construct(Config $config, Metadata $metadata, FileManager $fileManager, DataCache $dataCache)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->metadata = $metadata;
|
||||
$this->fileManager = $fileManager;
|
||||
$this->dataCache = $dataCache;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,8 +78,8 @@ class Route
|
||||
{
|
||||
$useCache = $this->config->get('useCache');
|
||||
|
||||
if (file_exists($this->cacheFile) && $useCache) {
|
||||
$this->data = $this->fileManager->getPhpContents($this->cacheFile);
|
||||
if ($this->dataCache->has($this->cacheKey) && $useCache) {
|
||||
$this->data = $this->dataCache->get($this->cacheKey);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -79,17 +87,10 @@ class Route
|
||||
$this->data = $this->unify();
|
||||
|
||||
if ($useCache) {
|
||||
$result = $this->fileManager->putPhpContents($this->cacheFile, $this->data);
|
||||
|
||||
if ($result == false) {
|
||||
throw new Error('Route - Cannot save unified routes');
|
||||
}
|
||||
$this->dataCache->store($this->cacheKey, $this->data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unify routes.
|
||||
*/
|
||||
protected function unify() : array
|
||||
{
|
||||
$data = $this->addDataFromFile([], $this->paths['customPath']);
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Espo\Core\Webhook;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Config,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\DataCache,
|
||||
Utils\FieldUtil,
|
||||
ORM\EntityManager,
|
||||
ORM\Entity,
|
||||
@@ -42,25 +42,25 @@ use Espo\Core\{
|
||||
*/
|
||||
class Manager
|
||||
{
|
||||
private $cacheFile = 'data/cache/application/webhooks.php';
|
||||
private $cacheKey = 'webhooks';
|
||||
|
||||
protected $skipAttributeList = ['isFollowed', 'modifiedAt', 'modifiedBy'];
|
||||
|
||||
private $data = null;
|
||||
|
||||
protected $config;
|
||||
protected $fileManager;
|
||||
protected $dataCache;
|
||||
protected $entityManager;
|
||||
protected $fieldUtil;
|
||||
|
||||
public function __construct(
|
||||
Config $config,
|
||||
FileManager $fileManager,
|
||||
DataCache $dataCache,
|
||||
EntityManager $entityManager,
|
||||
FieldUtil $fieldUtil
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->fileManager = $fileManager;
|
||||
$this->dataCache = $dataCache;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->fieldUtil = $fieldUtil;
|
||||
|
||||
@@ -70,10 +70,8 @@ class Manager
|
||||
private function loadData()
|
||||
{
|
||||
if ($this->config->get('useCache')) {
|
||||
if ($this->fileManager->isFile($this->cacheFile)) {
|
||||
if (file_exists($this->cacheFile)) {
|
||||
$this->data = $this->fileManager->getPhpContents($this->cacheFile);
|
||||
}
|
||||
if ($this->dataCache->has($this->cacheKey)) {
|
||||
$this->data = $this->dataCache->get($this->cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +86,7 @@ class Manager
|
||||
|
||||
private function storeDataToCache()
|
||||
{
|
||||
$this->fileManager->putPhpContents($this->cacheFile, $this->data);
|
||||
$this->dataCache->store($this->cacheKey, $this->data);
|
||||
}
|
||||
|
||||
private function buildData()
|
||||
@@ -128,13 +126,18 @@ class Manager
|
||||
*/
|
||||
public function removeEvent(string $event)
|
||||
{
|
||||
$notExists = !$this->entityManager->getRepository('Webhook')->select(['id'])->where([
|
||||
'event' => $event,
|
||||
'isActive' => true,
|
||||
])->findOne();
|
||||
$notExists = !$this->entityManager
|
||||
->getRepository('Webhook')
|
||||
->select(['id'])
|
||||
->where([
|
||||
'event' => $event,
|
||||
'isActive' => true,
|
||||
])
|
||||
->findOne();
|
||||
|
||||
if ($notExists) {
|
||||
unset($this->data[$event]);
|
||||
|
||||
if ($this->config->get('useCache')) {
|
||||
$this->storeDataToCache();
|
||||
}
|
||||
@@ -158,7 +161,9 @@ class Manager
|
||||
{
|
||||
$event = $entity->getEntityType() . '.create';
|
||||
|
||||
if (!$this->eventExists($event)) return;
|
||||
if (!$this->eventExists($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->entityManager->createEntity('WebhookEventQueueItem', [
|
||||
'event' => $event,
|
||||
@@ -177,7 +182,9 @@ class Manager
|
||||
{
|
||||
$event = $entity->getEntityType() . '.delete';
|
||||
|
||||
if (!$this->eventExists($event)) return;
|
||||
if (!$this->eventExists($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->entityManager->createEntity('WebhookEventQueueItem', [
|
||||
'event' => $event,
|
||||
@@ -199,14 +206,20 @@ class Manager
|
||||
$event = $entity->getEntityType() . '.update';
|
||||
|
||||
$data = (object) [];
|
||||
|
||||
foreach ($entity->getAttributeList() as $attribute) {
|
||||
if (in_array($attribute, $this->skipAttributeList)) continue;
|
||||
if (in_array($attribute, $this->skipAttributeList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($entity->isAttributeChanged($attribute)) {
|
||||
$data->$attribute = $entity->get($attribute);
|
||||
}
|
||||
}
|
||||
|
||||
if (!count(get_object_vars($data))) return;
|
||||
if (!count(get_object_vars($data))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data->id = $entity->id;
|
||||
|
||||
@@ -222,14 +235,22 @@ class Manager
|
||||
|
||||
foreach ($this->fieldUtil->getEntityTypeFieldList($entity->getEntityType()) as $field) {
|
||||
$itemEvent = $entity->getEntityType() . '.fieldUpdate.' . $field;
|
||||
if (!$this->eventExists($itemEvent)) continue;
|
||||
|
||||
if (!$this->eventExists($itemEvent)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributeList = $this->fieldUtil->getActualAttributeList($entity->getEntityType(), $field);
|
||||
$isChanged = false;
|
||||
|
||||
foreach ($attributeList as $attribute) {
|
||||
if (in_array($attribute, $this->skipAttributeList)) continue;
|
||||
if (in_array($attribute, $this->skipAttributeList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (property_exists($data, $attribute)) {
|
||||
$isChanged = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -238,8 +259,12 @@ class Manager
|
||||
$itemData = (object) [];
|
||||
$itemData->id = $entity->id;
|
||||
$attributeList = $this->fieldUtil->getAttributeList($entity->getEntityType(), $field);
|
||||
|
||||
foreach ($attributeList as $attribute) {
|
||||
if (in_array($attribute, $this->skipAttributeList)) continue;
|
||||
if (in_array($attribute, $this->skipAttributeList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$itemData->$attribute = $entity->get($attribute);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class ArrayTypeTest extends \tests\integration\Core\BaseTestCase
|
||||
|
||||
$fieldManager->create('Account', 'testArray', $fieldDefs);
|
||||
|
||||
$this->getContainer()->get('dataManager')->rebuild('Account');
|
||||
$this->getContainer()->get('dataManager')->rebuild(['Account']);
|
||||
|
||||
$app = $this->createApplication();
|
||||
|
||||
@@ -109,7 +109,7 @@ class ArrayTypeTest extends \tests\integration\Core\BaseTestCase
|
||||
|
||||
$fieldManager->update('Account', 'testArray', $fieldDefs);
|
||||
|
||||
$this->getContainer()->get('dataManager')->rebuild('Account');
|
||||
$this->getContainer()->get('dataManager')->rebuild(['Account']);
|
||||
|
||||
$app = $this->createApplication();
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class EnumTypeTest extends \tests\integration\Core\BaseTestCase
|
||||
$fieldDefs = get_object_vars(json_decode($this->jsonFieldDefs));
|
||||
|
||||
$fieldManager->create('Account', 'testEnum', $fieldDefs);
|
||||
$this->getContainer()->get('dataManager')->rebuild('Account');
|
||||
$this->getContainer()->get('dataManager')->rebuild(['Account']);
|
||||
|
||||
$app = $this->createApplication();
|
||||
|
||||
@@ -110,7 +110,7 @@ class EnumTypeTest extends \tests\integration\Core\BaseTestCase
|
||||
$fieldDefs['readOnly'] = true;
|
||||
|
||||
$fieldManager->update('Account', 'testEnum', $fieldDefs);
|
||||
$this->getContainer()->get('dataManager')->rebuild('Account');
|
||||
$this->getContainer()->get('dataManager')->rebuild(['Account']);
|
||||
|
||||
$app = $this->createApplication();
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ class VarcharTypeTest extends \tests\integration\Core\BaseTestCase
|
||||
$fieldDefs = get_object_vars(json_decode($this->jsonFieldDefs));
|
||||
|
||||
$fieldManager->create('Account', 'testVarchar', $fieldDefs);
|
||||
$this->getContainer()->get('dataManager')->rebuild('Account');
|
||||
$this->getContainer()->get('dataManager')->rebuild(['Account']);
|
||||
|
||||
$app = $this->createApplication();
|
||||
|
||||
@@ -106,7 +106,7 @@ class VarcharTypeTest extends \tests\integration\Core\BaseTestCase
|
||||
$fieldDefs['default'] = 'default-value';
|
||||
|
||||
$fieldManager->update('Account', 'testVarchar', $fieldDefs);
|
||||
$this->getContainer()->get('dataManager')->rebuild('Account');
|
||||
$this->getContainer()->get('dataManager')->rebuild(['Account']);
|
||||
|
||||
$app = $this->createApplication();
|
||||
|
||||
|
||||
@@ -31,6 +31,15 @@ namespace tests\unit\Espo\Core;
|
||||
|
||||
use tests\unit\ReflectionHelper;
|
||||
|
||||
use Espo\Core\{
|
||||
HookManager,
|
||||
InjectableFactory,
|
||||
Utils\Metadata,
|
||||
Utils\Config,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $object;
|
||||
@@ -42,23 +51,26 @@ class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
protected function setUp() : void
|
||||
{
|
||||
|
||||
$this->objects['metadata'] =
|
||||
$this->getMockBuilder('Espo\\Core\\Utils\\Metadata')->disableOriginalConstructor()->getMock();
|
||||
$this->metadata =
|
||||
$this->getMockBuilder(Metadata::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->objects['config'] =
|
||||
$this->getMockBuilder('Espo\\Core\\Utils\\Config')->disableOriginalConstructor()->getMock();
|
||||
$this->config =
|
||||
$this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->objects['injectableFactory'] =
|
||||
$this->getMockBuilder('Espo\\Core\\InjectableFactory')->disableOriginalConstructor()->getMock();
|
||||
$this->injectableFactory =
|
||||
$this->getMockBuilder(InjectableFactory::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->objects['fileManager'] = new \Espo\Core\Utils\File\Manager();
|
||||
$this->dataCache =
|
||||
$this->getMockBuilder(DataCache::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->fileManager = new FileManager();
|
||||
|
||||
$this->object = new \Espo\Core\HookManager(
|
||||
$this->objects['injectableFactory'],
|
||||
$this->objects['fileManager'],
|
||||
$this->objects['metadata'],
|
||||
$this->objects['config']
|
||||
$this->object = new HookManager(
|
||||
$this->injectableFactory,
|
||||
$this->fileManager,
|
||||
$this->metadata,
|
||||
$this->config,
|
||||
$this->dataCache
|
||||
);
|
||||
|
||||
$this->reflection = new ReflectionHelper($this->object);
|
||||
@@ -73,9 +85,9 @@ class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
public function testIsHookExists()
|
||||
{
|
||||
$data = array (
|
||||
'\\Espo\\Hooks\\Note\\Stream' => 8,
|
||||
'\\Espo\\Hooks\\Note\\Mentions' => 9,
|
||||
'\\Espo\\Hooks\\Note\\Notifications' => 14,
|
||||
'Espo\\Hooks\\Note\\Stream' => 8,
|
||||
'Espo\\Hooks\\Note\\Mentions' => 9,
|
||||
'Espo\\Hooks\\Note\\Notifications' => 14,
|
||||
);
|
||||
|
||||
$data = array (
|
||||
@@ -93,11 +105,21 @@ class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertTrue( $this->reflection->invokeMethod('hookExists', array('Espo\\Hooks\\Note\\Mentions', $data)) );
|
||||
$this->assertTrue( $this->reflection->invokeMethod('hookExists', array('Espo\\Modules\\Crm\\Hooks\\Note\\Mentions', $data)) );
|
||||
$this->assertTrue( $this->reflection->invokeMethod('hookExists', array('Espo\\Modules\\Test\\Hooks\\Note\\Mentions', $data)) );
|
||||
$this->assertTrue( $this->reflection->invokeMethod('hookExists', array('Espo\\Modules\\Test\\Hooks\\Common\\Stream', $data)) );
|
||||
$this->assertFalse( $this->reflection->invokeMethod('hookExists', array('Espo\\Hooks\\Note\\TestHook', $data)) );
|
||||
$this->assertTrue(
|
||||
$this->reflection->invokeMethod('hookExists', array('Espo\\Hooks\\Note\\Mentions', $data))
|
||||
);
|
||||
$this->assertTrue(
|
||||
$this->reflection->invokeMethod('hookExists', array('Espo\\Modules\\Crm\\Hooks\\Note\\Mentions', $data))
|
||||
);
|
||||
$this->assertTrue(
|
||||
$this->reflection->invokeMethod('hookExists', array('Espo\\Modules\\Test\\Hooks\\Note\\Mentions', $data))
|
||||
);
|
||||
$this->assertTrue(
|
||||
$this->reflection->invokeMethod('hookExists', array('Espo\\Modules\\Test\\Hooks\\Common\\Stream', $data))
|
||||
);
|
||||
$this->assertFalse(
|
||||
$this->reflection->invokeMethod('hookExists', array('Espo\\Hooks\\Note\\TestHook', $data))
|
||||
);
|
||||
}
|
||||
|
||||
public function testSortHooks()
|
||||
@@ -219,12 +241,12 @@ class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
'customPath' => $this->filesPath . '/testCase1/custom/Espo/Custom/Hooks',
|
||||
));
|
||||
|
||||
$this->objects['config']
|
||||
$this->config
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
@@ -258,12 +280,12 @@ class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
'customPath' => $this->filesPath . '/testCase2/custom/Espo/Custom/Hooks',
|
||||
));
|
||||
|
||||
$this->objects['config']
|
||||
$this->config
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
@@ -298,12 +320,12 @@ class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
'customPath' => $this->filesPath . '/testCase2/custom/Espo/Custom/Hooks',
|
||||
));
|
||||
|
||||
$this->objects['config']
|
||||
$this->config
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
@@ -338,12 +360,12 @@ class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
'customPath' => $this->filesPath . '/testCase3/custom/Espo/Custom/Hooks',
|
||||
));
|
||||
|
||||
$this->objects['config']
|
||||
$this->config
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->at(0))
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace tests\unit\Espo\Core\Utils;
|
||||
|
||||
use tests\unit\ReflectionHelper;
|
||||
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Utils\Language;
|
||||
use Espo\Core\Utils\DataCache;
|
||||
use Espo\Core\Utils\File\Manager as FileManager;
|
||||
|
||||
class LanguageTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $object;
|
||||
@@ -39,8 +44,6 @@ class LanguageTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
protected $reflection;
|
||||
|
||||
protected $cacheFile = 'tests/unit/testData/cache/application/languages/{language}.php';
|
||||
|
||||
protected $paths = [
|
||||
'corePath' => 'tests/unit/testData/Utils/I18n/Espo/Resources/i18n/{language}',
|
||||
'modulePath' => 'tests/unit/testData/Utils/I18n/Espo/Modules/{*}/Resources/i18n/{language}',
|
||||
@@ -49,22 +52,24 @@ class LanguageTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->objects['fileManager'] = new \Espo\Core\Utils\File\Manager();
|
||||
$this->fileManager = new FileManager();
|
||||
|
||||
$this->dataCache = $this->getMockBuilder(DataCache::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->objects['metadata'] = $this->getMockBuilder('\Espo\Core\Utils\Metadata')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['metadata']->expects($this->any())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(
|
||||
[
|
||||
'Crm',
|
||||
]
|
||||
));
|
||||
$this->metadata = $this->getMockBuilder(Metadata::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->object = new \Espo\Core\Utils\Language(null, $this->objects['fileManager'], $this->objects['metadata'], false);
|
||||
$this->metadata->expects($this->any())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(
|
||||
[
|
||||
'Crm',
|
||||
]
|
||||
));
|
||||
|
||||
$this->object = new Language(null, $this->fileManager, $this->metadata, $this->dataCache, false);
|
||||
|
||||
$this->reflection = new ReflectionHelper($this->object);
|
||||
$this->reflection->setProperty('cacheFile', $this->cacheFile);
|
||||
|
||||
$this->reflection->setProperty('paths', $this->paths);
|
||||
$this->reflection->setProperty('currentLanguage', 'en_US');
|
||||
}
|
||||
@@ -74,7 +79,6 @@ class LanguageTest extends \PHPUnit\Framework\TestCase
|
||||
$this->object = NULL;
|
||||
}
|
||||
|
||||
|
||||
public function testLanguage()
|
||||
{
|
||||
$this->assertEquals('en_US', $this->object->getLanguage());
|
||||
@@ -86,21 +90,6 @@ class LanguageTest extends \PHPUnit\Framework\TestCase
|
||||
$this->object->setLanguage($originalLang);
|
||||
}
|
||||
|
||||
public function testGetLangCacheFile()
|
||||
{
|
||||
$cacheFile = $this->cacheFile;
|
||||
|
||||
$result = str_replace('{language}', 'en_US', $cacheFile);
|
||||
$this->assertEquals($result, $this->reflection->invokeMethod('getCacheFile'));
|
||||
|
||||
$originalLang = $this->object->getLanguage();
|
||||
$this->object->setLanguage('lang_TEST');
|
||||
$result = str_replace('{language}', 'lang_TEST', $cacheFile);
|
||||
$this->assertEquals($result, $this->reflection->invokeMethod('getCacheFile'));
|
||||
|
||||
$this->object->setLanguage($originalLang);
|
||||
}
|
||||
|
||||
public function testGetData()
|
||||
{
|
||||
$result = [
|
||||
|
||||
@@ -31,6 +31,14 @@ namespace tests\unit\Espo\Core\Utils;
|
||||
|
||||
use tests\unit\ReflectionHelper;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Route,
|
||||
Utils\Config,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\Metadata,
|
||||
Utils\DataCache,
|
||||
};
|
||||
|
||||
class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $object;
|
||||
@@ -41,24 +49,17 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->objects['container'] = $this->getMockBuilder('\\Espo\\Core\\Container')->disableOriginalConstructor()->getMock();
|
||||
$this->config = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
|
||||
$this->fileManager = new FileManager();
|
||||
|
||||
$this->objects['config'] = $this->getMockBuilder('\\Espo\\Core\\Utils\\Config')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['fileManager'] = new \Espo\Core\Utils\File\Manager();
|
||||
$this->objects['metadata'] = $this->getMockBuilder('\\Espo\\Core\\Utils\\Metadata')->disableOriginalConstructor()->getMock();
|
||||
$this->metadata = $this->getMockBuilder(Metadata::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$map = array(
|
||||
array('config', $this->objects['config']),
|
||||
array('metadata', $this->objects['metadata']),
|
||||
array('fileManager', $this->objects['fileManager']),
|
||||
$this->dataCache = $this->getMockBuilder(DataCache::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->object = new Route(
|
||||
$this->config, $this->metadata, $this->fileManager, $this->dataCache
|
||||
);
|
||||
|
||||
$this->objects['container']
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnValueMap($map));
|
||||
|
||||
$this->object = new \Espo\Core\Utils\Route($this->objects['config'], $this->objects['metadata'], $this->objects['fileManager']);
|
||||
$this->reflection = new ReflectionHelper($this->object);
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
'customPath' => $this->filesPath . '/testCase1/custom/Espo/Custom/Resources/routes.json',
|
||||
));
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
@@ -165,7 +166,7 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
'customPath' => $this->filesPath . '/testCase2/custom/Espo/Custom/Resources/routes.json',
|
||||
));
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
@@ -252,7 +253,7 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
'customPath' => $this->filesPath . '/testCase3/custom/Espo/Custom/Resources/routes.json',
|
||||
));
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
@@ -342,7 +343,7 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
$this->reflection->setProperty('paths', $paths);
|
||||
|
||||
$this->objects['metadata']
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(array(
|
||||
|
||||
Reference in New Issue
Block a user