Merge branch 'master' into feature/tree
This commit is contained in:
@@ -28,7 +28,7 @@ use \Espo\ORM\Entity;
|
||||
class Email extends \Espo\Core\Acl\Base
|
||||
{
|
||||
|
||||
public function checkRead(User $user, Entity $entity, $data)
|
||||
public function checkEntityRead(User $user, Entity $entity, $data)
|
||||
{
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
return true;
|
||||
|
||||
@@ -194,5 +194,30 @@ class Base implements Injectable
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, $data)
|
||||
{
|
||||
$result = $this->checkEntity($user, $entity, $data, 'delete');
|
||||
if (!$result) {
|
||||
if (is_array($data)) {
|
||||
if ($data['edit'] != 'no') {
|
||||
if ($entity->has('createdById') && $entity->get('createdById') == $user->id) {
|
||||
if (!$entity->has('assignedUserId')) {
|
||||
return true;
|
||||
} else {
|
||||
if (!$entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
if ($entity->get('assignedUserId') == $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,11 +166,30 @@ class Table
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getScopeList()
|
||||
{
|
||||
$scopeList = [];
|
||||
$scopes = $this->metadata->get('scopes');
|
||||
foreach ($scopes as $scope => $d) {
|
||||
if (!empty($d['acl'])) {
|
||||
$scopeList[] = $scope;
|
||||
}
|
||||
}
|
||||
return $scopeList;
|
||||
}
|
||||
|
||||
private function merge($tables)
|
||||
{
|
||||
$data = array();
|
||||
$scopeList = $this->getScopeList();
|
||||
|
||||
foreach ($tables as $table) {
|
||||
foreach ($table as $scope => $row) {
|
||||
foreach ($scopeList as $scope) {
|
||||
if (!isset($table->$scope)) {
|
||||
continue;
|
||||
}
|
||||
$row = $table->$scope;
|
||||
|
||||
if ($row == false) {
|
||||
if (!isset($data[$scope])) {
|
||||
$data[$scope] = false;
|
||||
@@ -184,7 +203,8 @@ class Table
|
||||
if ($data[$scope] == false) {
|
||||
$data[$scope] = array();
|
||||
}
|
||||
if (is_array($row)) {
|
||||
|
||||
if (is_array($row) || $row instanceof \stdClass) {
|
||||
foreach ($row as $action => $level) {
|
||||
if (!isset($data[$scope][$action])) {
|
||||
$data[$scope][$action] = $level;
|
||||
@@ -198,6 +218,15 @@ class Table
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($scopeList as $scope) {
|
||||
if (!array_key_exists($scope, $data)) {
|
||||
$aclType = $this->metadata->get('scopes.' . $scope . '.acl');
|
||||
if (!empty($aclType) && ($aclType === true || $aclType === 'record')) {
|
||||
$data[$scope] = $this->metadata->get('app.acl.recordDefault');
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,13 +149,13 @@ class AclManager
|
||||
$entityType = $entity->getEntityType();
|
||||
|
||||
$impl = $this->getImplementation($entityType);
|
||||
$methodName = 'check' . ucfirst($action);
|
||||
$methodName = 'checkEntity' . ucfirst($action);
|
||||
if (method_exists($impl, $methodName)) {
|
||||
$data = $this->getTable($user)->getScopeData($entityType);
|
||||
return $impl->$methodName($user, $entity, $data);
|
||||
}
|
||||
|
||||
return $this->checkEntity($user, $entity, $action, $isOwner, $inTeam, $entity);
|
||||
return $this->checkEntity($user, $entity, $action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,11 +284,18 @@ class Sender
|
||||
|
||||
$message->setBody($body);
|
||||
|
||||
if (!$message->getHeaders()->has('content-type')) {
|
||||
$contentTypeHeader = new \Zend\Mail\Header\ContentType();
|
||||
$message->getHeaders()->addHeader($contentTypeHeader);
|
||||
if ($messageType == 'text/plain') {
|
||||
if ($message->getHeaders()->has('content-type')) {
|
||||
$message->getHeaders()->removeHeader('content-type');
|
||||
}
|
||||
$message->getHeaders()->addHeaderLine('Content-Type', 'text/plain; charset=UTF-8');
|
||||
} else {
|
||||
if (!$message->getHeaders()->has('content-type')) {
|
||||
$contentTypeHeader = new \Zend\Mail\Header\ContentType();
|
||||
$message->getHeaders()->addHeader($contentTypeHeader);
|
||||
}
|
||||
$message->getHeaders()->get('content-type')->setType($messageType);
|
||||
}
|
||||
$message->getHeaders()->get('content-type')->setType($messageType);
|
||||
|
||||
$message->setEncoding('UTF-8');
|
||||
|
||||
|
||||
@@ -33,10 +33,14 @@ class Job
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private $cronScheduledJob;
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
|
||||
$this->cronScheduledJob = new ScheduledJob($this->config, $this->entityManager);
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
@@ -49,6 +53,11 @@ class Job
|
||||
return $this->entityManager;
|
||||
}
|
||||
|
||||
protected function getCronScheduledJob()
|
||||
{
|
||||
return $this->cronScheduledJob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Pending Jobs
|
||||
*
|
||||
@@ -145,13 +154,30 @@ class Job
|
||||
$currentTime = time();
|
||||
$periodTime = $currentTime - intval($jobConfigs['jobPeriod']);
|
||||
|
||||
$update = "UPDATE job SET `status` = '" . CronManager::FAILED ."' WHERE
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
|
||||
$select = "SELECT id, scheduled_job_id, execute_time FROM `job` WHERE
|
||||
(`status` = '" . CronManager::RUNNING ."')
|
||||
AND execute_time < '".date('Y-m-d H:i:s', $periodTime)."' ";
|
||||
$sth = $pdo->prepare($select);
|
||||
$sth->execute();
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
$jobData = array();
|
||||
while ($row = $sth->fetch(PDO::FETCH_ASSOC)){
|
||||
$jobData[$row['id']] = $row;
|
||||
}
|
||||
|
||||
$update = "UPDATE job SET `status` = '". CronManager::FAILED ."' WHERE id IN ('".implode("', '", array_keys($jobData))."')";
|
||||
$sth = $pdo->prepare($update);
|
||||
$sth->execute();
|
||||
|
||||
//add status 'Failed' to SchediledJobLog
|
||||
$cronScheduledJob = $this->getCronScheduledJob();
|
||||
foreach ($jobData as $jobId => $job) {
|
||||
if (!empty($job['scheduled_job_id'])) {
|
||||
$cronScheduledJob->addLogRecord($job['scheduled_job_id'], CronManager::FAILED, $job['execute_time']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -81,14 +81,16 @@ class ScheduledJob
|
||||
*
|
||||
* @return string ID of created ScheduledJobLogRecord
|
||||
*/
|
||||
public function addLogRecord($scheduledJobId, $status)
|
||||
public function addLogRecord($scheduledJobId, $status, $runTime = null)
|
||||
{
|
||||
$lastRun = date('Y-m-d H:i:s');
|
||||
if (!isset($runTime)) {
|
||||
$runTime = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$entityManager = $this->getEntityManager();
|
||||
|
||||
$scheduledJob = $entityManager->getEntity('ScheduledJob', $scheduledJobId);
|
||||
$scheduledJob->set('lastRun', $lastRun);
|
||||
$scheduledJob->set('lastRun', $runTime);
|
||||
$entityManager->saveEntity($scheduledJob);
|
||||
|
||||
$scheduledJobLog = $entityManager->getEntity('ScheduledJobLogRecord');
|
||||
@@ -96,7 +98,7 @@ class ScheduledJob
|
||||
'scheduledJobId' => $scheduledJobId,
|
||||
'name' => $scheduledJob->get('name'),
|
||||
'status' => $status,
|
||||
'executionTime' => $lastRun,
|
||||
'executionTime' => $runTime,
|
||||
));
|
||||
$scheduledJobLogId = $entityManager->saveEntity($scheduledJobLog);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class Converter
|
||||
{
|
||||
private $metadata;
|
||||
private $fileManager;
|
||||
private $metadataUtils;
|
||||
private $metadataHelper;
|
||||
|
||||
private $relationManager;
|
||||
|
||||
@@ -82,7 +82,6 @@ class Converter
|
||||
'len' => '24',
|
||||
);
|
||||
|
||||
|
||||
public function __construct(\Espo\Core\Utils\Metadata $metadata, \Espo\Core\Utils\File\Manager $fileManager)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
@@ -90,10 +89,9 @@ class Converter
|
||||
|
||||
$this->relationManager = new RelationManager($this->metadata);
|
||||
|
||||
$this->metadataUtils = new \Espo\Core\Utils\Metadata\Utils($this->metadata);
|
||||
$this->metadataHelper = new \Espo\Core\Utils\Metadata\Helper($this->metadata);
|
||||
}
|
||||
|
||||
|
||||
protected function getMetadata()
|
||||
{
|
||||
return $this->metadata;
|
||||
@@ -118,9 +116,9 @@ class Converter
|
||||
return $this->relationManager;
|
||||
}
|
||||
|
||||
protected function getMetadataUtils()
|
||||
protected function getMetadataHelper()
|
||||
{
|
||||
return $this->metadataUtils;
|
||||
return $this->metadataHelper;
|
||||
}
|
||||
|
||||
public function process()
|
||||
@@ -225,31 +223,16 @@ class Converter
|
||||
foreach($entityMeta['fields'] as $fieldName => $fieldParams) {
|
||||
|
||||
/** check if "fields" option exists in $fieldMeta */
|
||||
$fieldTypeMeta = $this->getMetadataUtils()->getFieldDefsByType($fieldParams);
|
||||
$fieldTypeMeta = $this->getMetadataHelper()->getFieldDefsByType($fieldParams);
|
||||
|
||||
if (isset($fieldTypeMeta['fields']) && is_array($fieldTypeMeta['fields'])) {
|
||||
|
||||
foreach($fieldTypeMeta['actualFields'] as $subFieldName) {
|
||||
|
||||
$subField = $this->convertActualFields($entityName, $fieldName, $fieldParams, $subFieldName, $fieldTypeMeta);
|
||||
|
||||
if (!isset($outputMeta[ $subField['naming'] ])) {
|
||||
$subFieldDefs = $this->convertField($entityName, $subField['name'], $subField['params']);
|
||||
if ($subFieldDefs !== false) {
|
||||
$outputMeta[ $subField['naming'] ] = $subFieldDefs; //push fieldDefs to the main array
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$fieldDefs = $this->convertField($entityName, $fieldName, $fieldParams, $fieldTypeMeta);
|
||||
if ($fieldDefs !== false) {
|
||||
$outputMeta[$fieldName] = $fieldDefs; //push fieldDefs to the main array
|
||||
}
|
||||
$fieldDefs = $this->convertField($entityName, $fieldName, $fieldParams, $fieldTypeMeta);
|
||||
if ($fieldDefs !== false) {
|
||||
$outputMeta[$fieldName] = $fieldDefs; //push fieldDefs to the main array
|
||||
}
|
||||
|
||||
/** check and set the linkDefs from 'fields' metadata */
|
||||
if (isset($fieldTypeMeta['linkDefs'])) {
|
||||
$linkDefs = $this->getMetadataUtils()->getLinkDefsInFieldMeta($entityName, $fieldParams, $fieldTypeMeta['linkDefs']);
|
||||
$linkDefs = $this->getMetadataHelper()->getLinkDefsInFieldMeta($entityName, $fieldParams, $fieldTypeMeta['linkDefs']);
|
||||
if (isset($linkDefs)) {
|
||||
if (!isset($entityMeta['links'])) {
|
||||
$entityMeta['links'] = array();
|
||||
@@ -310,17 +293,12 @@ class Converter
|
||||
if (isset($scopeDefs['stream']) && $scopeDefs['stream']) {
|
||||
if (!isset($entityMeta['fields']['isFollowed'])) {
|
||||
$ormMeta[$entityName]['fields']['isFollowed'] = array(
|
||||
'type' => 'bool',
|
||||
'type' => 'varchar',
|
||||
'notStorable' => true,
|
||||
);
|
||||
}
|
||||
} //END: add a field 'isFollowed' for stream => true
|
||||
|
||||
$ormMeta[$entityName]['fields']['isEditable'] = array(
|
||||
'type' => 'bool',
|
||||
'notStorable' => true
|
||||
);
|
||||
|
||||
return $ormMeta;
|
||||
}
|
||||
|
||||
@@ -334,15 +312,15 @@ class Converter
|
||||
|
||||
/** merge fieldDefs option from field definition */
|
||||
if (!isset($fieldTypeMeta)) {
|
||||
$fieldTypeMeta = $this->getMetadataUtils()->getFieldDefsByType($fieldParams);
|
||||
$fieldTypeMeta = $this->getMetadataHelper()->getFieldDefsByType($fieldParams);
|
||||
}
|
||||
|
||||
if (isset($fieldTypeMeta['fieldDefs'])) {
|
||||
$fieldParams = Util::merge($fieldParams, $fieldTypeMeta['fieldDefs']);
|
||||
}
|
||||
|
||||
/** check if need to skip this field in ORM metadata */
|
||||
if (isset($fieldParams['skip']) && $fieldParams['skip'] === true) {
|
||||
/** check if need to skipOrmDefs this field in ORM metadata */
|
||||
if (isset($fieldParams['skipOrmDefs']) && $fieldParams['skipOrmDefs'] === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -366,37 +344,6 @@ class Converter
|
||||
return $fieldDefs;
|
||||
}
|
||||
|
||||
protected function convertActualFields($entityName, $fieldName, $fieldParams, $subFieldName, $fieldTypeMeta)
|
||||
{
|
||||
$subField = array();
|
||||
|
||||
$subField['params'] = $this->getInitValues($fieldParams);
|
||||
|
||||
if (isset($fieldTypeMeta['fieldDefs'])) {
|
||||
$subField['params'] = Util::merge($subField['params'], $fieldTypeMeta['fieldDefs']);
|
||||
}
|
||||
|
||||
//if empty field name, then use the main field
|
||||
if (trim($subFieldName) == '') {
|
||||
|
||||
$subField['name'] = $fieldName;
|
||||
$subField['naming'] = $fieldName;
|
||||
|
||||
} else {
|
||||
|
||||
$namingType = isset($fieldTypeMeta['naming']) ? $fieldTypeMeta['naming'] : $this->defaultNaming;
|
||||
|
||||
$subField['name'] = $subFieldName;
|
||||
$subField['naming'] = Util::getNaming($fieldName, $subFieldName, $namingType);
|
||||
if (isset($fieldTypeMeta['fields'][$subFieldName])) {
|
||||
$subField['params'] = Util::merge($subField['params'], $fieldTypeMeta['fields'][$subFieldName]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $subField;
|
||||
}
|
||||
|
||||
protected function convertLinks($entityName, $entityMeta, $ormMeta)
|
||||
{
|
||||
if (!isset($entityMeta['links'])) {
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
namespace Espo\Core\Utils\Database\Orm\Relations;
|
||||
|
||||
use Espo\Core\Utils\Util;
|
||||
|
||||
class Base extends \Espo\Core\Utils\Database\Orm\Base
|
||||
{
|
||||
private $params;
|
||||
@@ -119,8 +121,11 @@ class Base extends \Espo\Core\Utils\Database\Orm\Base
|
||||
|
||||
$additionalParrams = $this->getAllowedAdditionalParams($name);
|
||||
|
||||
if (isset($additionalParrams) && !isset($linkParams[$name])) {
|
||||
if (isset($additionalParrams)) {
|
||||
$linkParams[$name] = $additionalParrams;
|
||||
if (isset($linkParams[$name]) && is_array($linkParams[$name])) {
|
||||
$linkParams[$name] = Util::merge($linkParams[$name], $additionalParrams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class EntityManager
|
||||
|
||||
private $fileManager;
|
||||
|
||||
private $metadataUtils;
|
||||
private $metadataHelper;
|
||||
|
||||
public function __construct(Metadata $metadata, Language $language, File\Manager $fileManager)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ class EntityManager
|
||||
$this->language = $language;
|
||||
$this->fileManager = $fileManager;
|
||||
|
||||
$this->metadataUtils = new \Espo\Core\Utils\Metadata\Utils($this->metadata);
|
||||
$this->metadataHelper = new \Espo\Core\Utils\Metadata\Helper($this->metadata);
|
||||
}
|
||||
|
||||
protected function getMetadata()
|
||||
@@ -61,9 +61,9 @@ class EntityManager
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getMetadataUtils()
|
||||
protected function getMetadataHelper()
|
||||
{
|
||||
return $this->metadataUtils;
|
||||
return $this->metadataHelper;
|
||||
}
|
||||
|
||||
public function create($name, $type, $params = array())
|
||||
@@ -352,6 +352,10 @@ class EntityManager
|
||||
)
|
||||
)
|
||||
);
|
||||
if ($entityForeign == $entity) {
|
||||
$dataLeft['links'][$link]['midKeys'] = ['leftId', 'rightId'];
|
||||
$dataRight['links'][$linkForeign]['midKeys'] = ['rightId', 'leftId'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class FieldManager
|
||||
|
||||
private $language;
|
||||
|
||||
private $metadataUtils;
|
||||
private $metadataHelper;
|
||||
|
||||
protected $isChanged = null;
|
||||
|
||||
@@ -44,7 +44,7 @@ class FieldManager
|
||||
$this->metadata = $metadata;
|
||||
$this->language = $language;
|
||||
|
||||
$this->metadataUtils = new \Espo\Core\Utils\Metadata\Utils($this->metadata);
|
||||
$this->metadataHelper = new \Espo\Core\Utils\Metadata\Helper($this->metadata);
|
||||
}
|
||||
|
||||
protected function getMetadata()
|
||||
@@ -57,9 +57,9 @@ class FieldManager
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
protected function getMetadataUtils()
|
||||
protected function getMetadataHelper()
|
||||
{
|
||||
return $this->metadataUtils;
|
||||
return $this->metadataHelper;
|
||||
}
|
||||
|
||||
public function read($name, $scope)
|
||||
@@ -187,11 +187,6 @@ class FieldManager
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($fieldDef['linkDefs'])) {
|
||||
$linkDefs = $fieldDef['linkDefs'];
|
||||
unset($fieldDef['linkDefs']);
|
||||
}
|
||||
|
||||
$currentOptionList = array_keys((array) $this->getFieldDef($name, $scope));
|
||||
foreach ($fieldDef as $defName => $defValue) {
|
||||
if ( (!isset($defValue) || $defValue === '') && !in_array($defName, $currentOptionList) ) {
|
||||
@@ -214,11 +209,16 @@ class FieldManager
|
||||
{
|
||||
$fieldDef = $this->prepareFieldDef($fieldName, $fieldDef, $scope);
|
||||
|
||||
$metaFieldDef = $this->getMetadataUtils()->getFieldDefsInFieldMeta($fieldDef);
|
||||
$metaFieldDef = $this->getMetadataHelper()->getFieldDefsInFieldMeta($fieldDef);
|
||||
if (isset($metaFieldDef)) {
|
||||
$fieldDef = Util::merge($metaFieldDef, $fieldDef);
|
||||
}
|
||||
|
||||
if (isset($fieldDef['linkDefs'])) {
|
||||
$linkDefs = $fieldDef['linkDefs'];
|
||||
unset($fieldDef['linkDefs']);
|
||||
}
|
||||
|
||||
$defs = array(
|
||||
'fields' => array(
|
||||
$fieldName => $fieldDef,
|
||||
@@ -226,7 +226,7 @@ class FieldManager
|
||||
);
|
||||
|
||||
/** Save links for a field. */
|
||||
$metaLinkDef = $this->getMetadataUtils()->getLinkDefsInFieldMeta($scope, $fieldDef);
|
||||
$metaLinkDef = $this->getMetadataHelper()->getLinkDefsInFieldMeta($scope, $fieldDef);
|
||||
if (isset($linkDefs) || isset($metaLinkDef)) {
|
||||
$linkDefs = Util::merge((array) $metaLinkDef, (array) $linkDefs);
|
||||
$defs['links'] = array(
|
||||
|
||||
@@ -35,6 +35,7 @@ class Metadata
|
||||
private $fileManager;
|
||||
private $converter;
|
||||
private $moduleConfig;
|
||||
private $metadataHelper;
|
||||
|
||||
/**
|
||||
* @var string - uses for loading default values
|
||||
@@ -76,12 +77,6 @@ class Metadata
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->fileManager = $fileManager;
|
||||
|
||||
$this->unifier = new \Espo\Core\Utils\File\Unifier($this->fileManager);
|
||||
|
||||
$this->converter = new \Espo\Core\Utils\Database\Converter($this, $this->fileManager);
|
||||
|
||||
$this->moduleConfig = new \Espo\Core\Utils\Module($this->config, $this->fileManager);
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
@@ -89,26 +84,47 @@ class Metadata
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
protected function getUnifier()
|
||||
{
|
||||
return $this->unifier;
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
{
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getUnifier()
|
||||
{
|
||||
if (!isset($this->unifier)) {
|
||||
$this->unifier = new \Espo\Core\Utils\File\Unifier($this->fileManager);
|
||||
}
|
||||
|
||||
return $this->unifier;
|
||||
}
|
||||
|
||||
protected function getConverter()
|
||||
{
|
||||
if (!isset($this->converter)) {
|
||||
$this->converter = new \Espo\Core\Utils\Database\Converter($this, $this->fileManager);
|
||||
}
|
||||
|
||||
return $this->converter;
|
||||
}
|
||||
|
||||
protected function getModuleConfig()
|
||||
{
|
||||
if (!isset($this->moduleConfig)) {
|
||||
$this->moduleConfig = new \Espo\Core\Utils\Module($this->config, $this->fileManager);
|
||||
}
|
||||
|
||||
return $this->moduleConfig;
|
||||
}
|
||||
|
||||
protected function getMetadataHelper()
|
||||
{
|
||||
if (!isset($this->metadataHelper)) {
|
||||
$this->metadataHelper = new Metadata\Helper($this);
|
||||
}
|
||||
|
||||
return $this->metadataHelper;
|
||||
}
|
||||
|
||||
public function isCached()
|
||||
{
|
||||
if (!$this->getConfig()->get('useCache')) {
|
||||
@@ -139,6 +155,7 @@ class Metadata
|
||||
} else {
|
||||
$this->meta = $this->getUnifier()->unify($this->name, $this->paths, true);
|
||||
$this->meta = $this->setLanguageFromConfig($this->meta);
|
||||
$this->meta = $this->addAdditionalFields($this->meta);
|
||||
|
||||
if ($this->getConfig()->get('useCache')) {
|
||||
$isSaved = $this->getFileManager()->putPhpContents($this->cacheFile, $this->meta);
|
||||
@@ -197,6 +214,7 @@ class Metadata
|
||||
}
|
||||
|
||||
/**
|
||||
* todo: move to a separate file
|
||||
* Set language list and default for Settings, Preferences metadata
|
||||
*
|
||||
* @param array $data Meta
|
||||
@@ -222,6 +240,37 @@ class Metadata
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* todo: move to a separate file
|
||||
* Add additional fields defined from metadata -> fields
|
||||
*
|
||||
* @param array $meta
|
||||
*/
|
||||
protected function addAdditionalFields(array $meta)
|
||||
{
|
||||
$metaCopy = $meta;
|
||||
$definitionList = $meta['fields'];
|
||||
|
||||
foreach ($metaCopy['entityDefs'] as $entityName => $entityParams) {
|
||||
foreach ($entityParams['fields'] as $fieldName => $fieldParams) {
|
||||
|
||||
$additionalFields = $this->getMetadataHelper()->getAdditionalFieldList($fieldName, $fieldParams, $definitionList);
|
||||
if (!empty($additionalFields)) {
|
||||
//merge or add to the end of meta array
|
||||
foreach ($additionalFields as $subFieldName => $subFieldParams) {
|
||||
if (isset($entityParams['fields'][$subFieldName])) {
|
||||
$meta['entityDefs'][$entityName]['fields'][$subFieldName] = Util::merge($subFieldParams, $entityParams['fields'][$subFieldName]);
|
||||
} else {
|
||||
$meta['entityDefs'][$entityName]['fields'][$subFieldName] = $subFieldParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Metadata data
|
||||
* Ex. $key1 = menu, $key2 = Account then will be created a file metadataFolder/menu/Account.json
|
||||
|
||||
+53
-3
@@ -22,10 +22,26 @@
|
||||
|
||||
namespace Espo\Core\Utils\Metadata;
|
||||
|
||||
class Utils
|
||||
use Espo\Core\Utils\Util;
|
||||
|
||||
class Helper
|
||||
{
|
||||
private $metadata;
|
||||
|
||||
protected $defaultNaming = 'postfix';
|
||||
|
||||
/**
|
||||
* List of copied params for metadata -> 'fields' from parent items
|
||||
*/
|
||||
protected $copiedDefParams = array(
|
||||
'readOnly',
|
||||
'notStorable',
|
||||
'layoutListDisabled',
|
||||
'layoutDetailDisabled',
|
||||
'layoutMassUpdateDisabled',
|
||||
'layoutFiltersDisabled',
|
||||
);
|
||||
|
||||
public function __construct(\Espo\Core\Utils\Metadata $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
@@ -102,7 +118,41 @@ class Utils
|
||||
return $linkFieldDefsByType;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Get additional field list based on field definition in metadata 'fields'
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param array $fieldParams
|
||||
* @param array|null $definitionList
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAdditionalFieldList($fieldName, array $fieldParams, array $definitionList = null)
|
||||
{
|
||||
if (empty($fieldParams['type'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fieldType = $fieldParams['type'];
|
||||
$fieldDefinition = isset($definitionList[$fieldType]) ? $definitionList[$fieldType] : $this->getMetadata()->get('fields.'.$fieldType);
|
||||
|
||||
?>
|
||||
if (!empty($fieldDefinition['fields']) && is_array($fieldDefinition['fields'])) {
|
||||
|
||||
$copiedParams = array_intersect_key($fieldParams, array_flip($this->copiedDefParams));
|
||||
|
||||
$additionalFields = array();
|
||||
|
||||
//add additional fields
|
||||
foreach ($fieldDefinition['fields'] as $subFieldName => $subFieldParams) {
|
||||
$namingType = isset($fieldDefinition['naming']) ? $fieldDefinition['naming'] : $this->defaultNaming;
|
||||
|
||||
$subFieldNaming = Util::getNaming($fieldName, $subFieldName, $namingType);
|
||||
$additionalFields[$subFieldNaming] = array_merge($copiedParams, $subFieldParams);
|
||||
}
|
||||
|
||||
return $additionalFields;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,21 +49,26 @@ class Cleanup extends \Espo\Core\Jobs\Base
|
||||
|
||||
protected function cleanupScheduledJobLog()
|
||||
{
|
||||
$lastTenRecords = "SELECT c.id FROM (
|
||||
SELECT i1.id
|
||||
FROM scheduled_job_log_record i1
|
||||
CROSS JOIN scheduled_job_log_record i2 ON ( i1.scheduled_job_id = i2.scheduled_job_id
|
||||
AND i1.id < i2.id )
|
||||
GROUP BY i1.id
|
||||
HAVING COUNT( * ) <10
|
||||
ORDER BY i1.created_at DESC
|
||||
) AS c";
|
||||
|
||||
$query = "DELETE FROM `scheduled_job_log_record` WHERE DATE(created_at) < '".$this->getDate()."' AND id NOT IN (".$lastTenRecords.") ";
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
$sth = $pdo->prepare($query);
|
||||
|
||||
$sql = "SELECT id FROM scheduled_job";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute();
|
||||
while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$id = $row['id'];
|
||||
|
||||
$lastRowsSql = "SELECT id FROM scheduled_job_log_record WHERE scheduled_job_id = '".$id."' ORDER BY created_at DESC LIMIT 0,10";
|
||||
$lastRowsSth = $pdo->prepare($lastRowsSql);
|
||||
$lastRowsSth->execute();
|
||||
$lastRowIds = $lastRowsSth->fetchAll(\PDO::FETCH_COLUMN, 0);
|
||||
|
||||
$delSql = "DELETE FROM `scheduled_job_log_record`
|
||||
WHERE scheduled_job_id = '".$id."'
|
||||
AND DATE(created_at) < '".$this->getDate()."'
|
||||
AND id NOT IN ('".implode("', '", $lastRowIds)."')
|
||||
";
|
||||
$pdo->query($delSql);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDate($format = 'Y-m-d')
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
"description": "Description",
|
||||
"isOverdue": "Is Overdue",
|
||||
"account": "Account",
|
||||
"dateCompleted": "Date Completed"
|
||||
"dateCompleted": "Date Completed",
|
||||
"attachments": "Attachments"
|
||||
},
|
||||
"links": {
|
||||
"attachments": "Attachments"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
{"name":"priority"}],
|
||||
[{"name":"dateStart"},{"name":"dateCompleted"}],
|
||||
[{"name":"dateEnd"},false],
|
||||
[{"name":"description", "fullWidth": true}]
|
||||
[{"name":"description", "fullWidth": true}],
|
||||
[{"name":"attachments"},false]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -147,7 +147,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"contacts": {
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"users": {
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"targetLists": {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"inboundEmail": {
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"account": {
|
||||
@@ -209,7 +209,7 @@
|
||||
},
|
||||
"emails": {
|
||||
"type": "hasChildren",
|
||||
"entity": "Task",
|
||||
"entity": "Email",
|
||||
"foreign": "parent",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
}
|
||||
},
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"opportunities": {
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"users": {
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"account": {
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
}
|
||||
},
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"campaigns": {
|
||||
|
||||
@@ -79,6 +79,10 @@
|
||||
},
|
||||
"teams": {
|
||||
"type": "linkMultiple"
|
||||
},
|
||||
"attachments": {
|
||||
"type": "linkMultiple",
|
||||
"view": "Fields.AttachmentMultiple"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
@@ -97,7 +101,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam",
|
||||
"relationName": "entityTeam",
|
||||
"layoutRelationshipsDisabled": true
|
||||
},
|
||||
"parent": {
|
||||
@@ -108,6 +112,13 @@
|
||||
"account": {
|
||||
"type": "belongsTo",
|
||||
"entity": "Account"
|
||||
},
|
||||
"attachments": {
|
||||
"type": "hasChildren",
|
||||
"entity": "Attachment",
|
||||
"foreign": "parent",
|
||||
"relationName": "attachments",
|
||||
"layoutRelationshipsDisabled": true
|
||||
}
|
||||
},
|
||||
"collection": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"body": "Тело",
|
||||
"subject": "Тема",
|
||||
"attachments": "Вложения",
|
||||
"insertField": "Project-Id-Version: Russian Translation\nPOT-Creation-Date: \nPO-Revision-Date: \nLast-Translator: \nLanguage-Team: EspoCRM <infobox@espocrm.com>\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nLanguage: ru_RU\nX-Generator: Poedit 1.6.5\n"
|
||||
"insertField": ""
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
|
||||
@@ -31,5 +31,10 @@
|
||||
"delete": "own"
|
||||
},
|
||||
"Role": false
|
||||
},
|
||||
"recordDefault": {
|
||||
"read": "all",
|
||||
"edit": "all",
|
||||
"delete": "no"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam"
|
||||
"relationName": "entityTeam"
|
||||
},
|
||||
"users": {
|
||||
"type": "hasMany",
|
||||
@@ -191,7 +191,7 @@
|
||||
"type": "hasChildren",
|
||||
"entity": "Attachment",
|
||||
"foreign": "parent",
|
||||
"relationName": "Attachments"
|
||||
"relationName": "attachments"
|
||||
},
|
||||
"parent": {
|
||||
"type": "belongsToParent",
|
||||
@@ -205,7 +205,7 @@
|
||||
"toEmailAddresses": {
|
||||
"type": "hasMany",
|
||||
"entity": "EmailAddress",
|
||||
"relationName": "EmailEmailAddress",
|
||||
"relationName": "emailEmailAddress",
|
||||
"conditions": {
|
||||
"addressType": "to"
|
||||
},
|
||||
@@ -219,7 +219,7 @@
|
||||
"ccEmailAddresses": {
|
||||
"type": "hasMany",
|
||||
"entity": "EmailAddress",
|
||||
"relationName": "EmailEmailAddress",
|
||||
"relationName": "emailEmailAddress",
|
||||
"conditions": {
|
||||
"addressType": "cc"
|
||||
},
|
||||
@@ -233,7 +233,7 @@
|
||||
"bccEmailAddresses": {
|
||||
"type": "hasMany",
|
||||
"entity": "EmailAddress",
|
||||
"relationName": "EmailEmailAddress",
|
||||
"relationName": "emailEmailAddress",
|
||||
"conditions": {
|
||||
"addressType": "bcc"
|
||||
},
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"teams": {
|
||||
"type": "hasMany",
|
||||
"entity": "Team",
|
||||
"relationName": "EntityTeam"
|
||||
"relationName": "entityTeam"
|
||||
},
|
||||
"assignedUser": {
|
||||
"type": "belongsTo",
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"attachments": {
|
||||
"type": "hasChildren",
|
||||
"entity": "Attachment",
|
||||
"relationName": "Attachments",
|
||||
"relationName": "attachments",
|
||||
"foreign": "parent"
|
||||
},
|
||||
"parent": {
|
||||
|
||||
@@ -27,5 +27,8 @@
|
||||
},
|
||||
"mergable":false,
|
||||
"notCreatable": false,
|
||||
"filter": true
|
||||
"filter": true,
|
||||
"fieldDefs":{
|
||||
"skipOrmDefs":true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
"filter": true,
|
||||
"notCreatable": true,
|
||||
"fieldDefs":{
|
||||
"skip": true
|
||||
"skipOrmDefs": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
"entity": "Attachment"
|
||||
},
|
||||
"fieldDefs":{
|
||||
"skip": true
|
||||
"skipOrmDefs": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,5 @@
|
||||
}
|
||||
],
|
||||
"filter": true,
|
||||
"notCreatable": true,
|
||||
"fieldDefs":{
|
||||
"skip": false
|
||||
}
|
||||
"notCreatable": true
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
"entity": "Attachment"
|
||||
},
|
||||
"fieldDefs":{
|
||||
"skip": true
|
||||
"skipOrmDefs": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,6 @@
|
||||
"notCreatable": true,
|
||||
"filter": true,
|
||||
"fieldDefs":{
|
||||
"default":""
|
||||
"notStorable":true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,13 @@ Espo.define('Crm:Views.Calendar.CalendarPage', 'View', function (Dep) {
|
||||
el: '#main',
|
||||
|
||||
setup: function () {
|
||||
var mode = this.options.mode || null;
|
||||
if (!mode) {
|
||||
var mode = this.getStorage().get('state', 'calendarMode') || null;
|
||||
}
|
||||
this.createView('calendar', 'Crm:Calendar.Calendar', {
|
||||
date: this.options.date,
|
||||
mode: this.options.mode,
|
||||
mode: mode,
|
||||
el: '#main > .calendar-container',
|
||||
}, function (view) {
|
||||
var first = true;
|
||||
@@ -39,7 +43,10 @@ Espo.define('Crm:Views.Calendar.CalendarPage', 'View', function (Dep) {
|
||||
this.getRouter().navigate('#Calendar/show/date=' + date + '&mode=' + mode);
|
||||
}
|
||||
first = false;
|
||||
}.bind(this));
|
||||
}, this);
|
||||
this.listenTo(view, 'change:mode', function (mode) {
|
||||
this.getStorage().set('state', 'calendarMode', mode);
|
||||
}, this);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ Espo.define('Crm:Views.Calendar.Calendar', ['View', 'lib!FullCalendar'], functio
|
||||
this.$el.find('button[data-mode="' + mode + '"]').addClass('active');
|
||||
this.$calendar.fullCalendar('changeView', mode);
|
||||
this.updateDate();
|
||||
this.trigger('change:mode', mode);
|
||||
},
|
||||
'click [data-action="refresh"]': function (e) {
|
||||
this.$calendar.fullCalendar('refetchEvents');
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<label>{{label}}</label>
|
||||
</div>
|
||||
{{#if ../editable}}
|
||||
<div class="right"><a href="javascript:" data-action="edit-field" class="edit-field"><i class="glyphicon glyphicon-pencil"></i></a></div>
|
||||
<div class="right"><a href="javascript:" data-action="editField" class="edit-field"><i class="glyphicon glyphicon-pencil"></i></a></div>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
@@ -75,25 +75,27 @@ _.extend(Espo.Acl.prototype, {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!value || value === 'no') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof isOwner === 'undefined') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isOwner && action == 'delete' && value === 'no') {
|
||||
return this.check(controller, 'edit', isOwner);
|
||||
}
|
||||
|
||||
if (!value || value === 'no') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isOwner) {
|
||||
if (value === 'own' || value === 'team') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//if (inTeam) {
|
||||
if (value === 'team') {
|
||||
return true;
|
||||
}
|
||||
//}
|
||||
if (value === 'team') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -17,31 +17,31 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
************************************************************************/
|
||||
|
||||
Espo.define('Views.Admin.Layouts.Rows', 'Views.Admin.Layouts.Base', function (Dep) {
|
||||
************************************************************************/
|
||||
|
||||
Espo.define('Views.Admin.Layouts.Rows', 'Views.Admin.Layouts.Base', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
template: 'admin.layouts.rows',
|
||||
|
||||
|
||||
|
||||
events: _.extend({
|
||||
'click #layout a[data-action="editField"]': function (e) {
|
||||
'click #layout a[data-action="editField"]': function (e) {
|
||||
var data = {};
|
||||
this.dataAttributes.forEach(function (attr) {
|
||||
data[attr] = $(e.target).closest('li').data(Espo.Utils.toDom(attr))
|
||||
});
|
||||
});
|
||||
this.openEditDialog(data);
|
||||
},
|
||||
}, Dep.prototype.events),
|
||||
|
||||
|
||||
dataAttributes: null,
|
||||
|
||||
|
||||
dataAttributesDefs: {},
|
||||
|
||||
|
||||
editable: false,
|
||||
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
scope: this.scope,
|
||||
@@ -54,14 +54,14 @@ Espo.define('Views.Admin.Layouts.Rows', 'Views.Admin.Layouts.Base', function (De
|
||||
dataAttributesDefs: this.dataAttributesDefs,
|
||||
editable: this.editable,
|
||||
};
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
$('#layout ul.enabled, #layout ul.disabled').sortable({
|
||||
connectWith: '#layout ul.connected'
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
fetch: function () {
|
||||
var layout = [];
|
||||
$("#layout ul.enabled > li").each(function (i, el) {
|
||||
@@ -71,19 +71,19 @@ Espo.define('Views.Admin.Layouts.Rows', 'Views.Admin.Layouts.Base', function (De
|
||||
if (value) {
|
||||
o[attr] = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
layout.push(o);
|
||||
}.bind(this));
|
||||
return layout;
|
||||
},
|
||||
|
||||
|
||||
validate: function (layout) {
|
||||
if (layout.length == 0) {
|
||||
this.notify('Layout cannot be empty', 'error');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ Espo.define('Views.Admin.LinkManager.Index', 'View', function (Dep) {
|
||||
this.getMetadata().load(function () {
|
||||
this.setupLinkData();
|
||||
this.render();
|
||||
}.bind(this));
|
||||
}.bind(this), true);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ Espo.define('Views.Admin.LinkManager.Modals.Edit', ['Views.Modal', 'Views.Admin.
|
||||
this.getMetadata().load(function () {
|
||||
this.trigger('after:save');
|
||||
this.close();
|
||||
}.bind(this));
|
||||
}.bind(this), true);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
|
||||
@@ -31,11 +31,13 @@ Espo.define('Views.Email.Modals.Detail', ['Views.Modals.Detail', 'Views.Email.De
|
||||
'label': 'Reply',
|
||||
'style': 'danger'
|
||||
});
|
||||
this.listenToOnce(this.model, 'sync', function () {
|
||||
setTimeout(function () {
|
||||
this.model.set('isRead', true);
|
||||
}.bind(this), 50);
|
||||
}, this);
|
||||
if (this.model) {
|
||||
this.listenToOnce(this.model, 'sync', function () {
|
||||
setTimeout(function () {
|
||||
this.model.set('isRead', true);
|
||||
}.bind(this), 50);
|
||||
}, this);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ Espo.define('Views.Fields.LinkMultiple', 'Views.Fields.Base', function (Dep) {
|
||||
this.ids.forEach(function (id) {
|
||||
names.push(this.getDetailLinkHtml(id));
|
||||
}, this);
|
||||
return names.join(', ');
|
||||
return '<div>' + names.join('</div><div>') + '</div>';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ Espo.define('Views.Modals.SelectRecords', 'Views.Modal', function (Dep) {
|
||||
type: 'listSmall',
|
||||
searchManager: searchManager,
|
||||
checkAllResultDisabled: !this.massRelateEnabled,
|
||||
disableButtons: true
|
||||
buttonsDisabled: true
|
||||
}, function (list) {
|
||||
list.once('select', function (model) {
|
||||
this.trigger('select', model);
|
||||
|
||||
@@ -199,6 +199,8 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
|
||||
|
||||
checkAllResultDisabled: false,
|
||||
|
||||
buttonsDisabled: false,
|
||||
|
||||
allResultIsChecked: false,
|
||||
|
||||
data: function () {
|
||||
@@ -218,7 +220,7 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
|
||||
checkboxes: this.checkboxes,
|
||||
massActionList: this.massActionList,
|
||||
rows: this.rows,
|
||||
topBar: paginationTop || this.checkboxes || (this.buttonList.length && !this.disableButtons),
|
||||
topBar: paginationTop || this.checkboxes || (this.buttonList.length && !this.buttonsDisabled),
|
||||
bottomBar: paginationBottom,
|
||||
checkAllResultDisabled: this.checkAllResultDisabled,
|
||||
buttonList: this.buttonList
|
||||
@@ -235,7 +237,10 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
|
||||
this.rowActionsView = _.isUndefined(this.options.rowActionsView) ? this.rowActionsView : this.options.rowActionsView;
|
||||
this.showMore = _.isUndefined(this.options.showMore) ? this.showMore : this.options.showMore;
|
||||
|
||||
this.disableButtons = this.options.disableButtons || false;
|
||||
|
||||
if ('buttonsDisabled' in this.options) {
|
||||
this.buttonsDisabled = this.options.buttonsDisabled;
|
||||
}
|
||||
|
||||
if ('checkAllResultDisabled' in this.options) {
|
||||
this.checkAllResultDisabled = this.options.checkAllResultDisabled;
|
||||
|
||||
@@ -113,7 +113,7 @@ Espo.define('Views.Record.Panels.Relationship', ['Views.Record.Panels.Bottom', '
|
||||
listLayout: listLayout,
|
||||
checkboxes: false,
|
||||
rowActionsView: this.defs.readOnly ? false : (this.defs.rowActionsView || this.rowActionsView),
|
||||
disableButtons: true,
|
||||
buttonsDisabled: true,
|
||||
el: this.options.el + ' .list-container',
|
||||
}, function (view) {
|
||||
view.render();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"labels": {
|
||||
"Main page title": "Welcome to EspoCRM",
|
||||
"Main page header": "Project-Id-Version: Russian Translation\nPOT-Creation-Date: \nPO-Revision-Date: \nLast-Translator: \nLanguage-Team: EspoCRM <infobox@espocrm.com>\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nLanguage: ru_RU\nX-Generator: Poedit 1.6.5\n",
|
||||
"Main page header": "",
|
||||
"Start page title": "License Agreement",
|
||||
"Step1 page title": "License Agreement",
|
||||
"License Agreement": "License Agreement",
|
||||
@@ -120,7 +120,7 @@
|
||||
"windows": "<br> <pre>1. Find the httpd.conf file (usually you will find it in a folder called conf, config or something along those lines)<br>\n2. Inside the httpd.conf file uncomment the line LoadModule rewrite_module modules/mod_rewrite.so (remove the pound '#' sign from in front of the line)<br>\n3. Also find the line ClearModuleList is uncommented then find and make sure that the line AddModule mod_rewrite.c is not commented out.\n</pre>"
|
||||
},
|
||||
"microsoft-iis": {
|
||||
"windows": "Project-Id-Version: Russian Translation\nPOT-Creation-Date: \nPO-Revision-Date: \nLast-Translator: \nLanguage-Team: EspoCRM <infobox@espocrm.com>\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nLanguage: ru_RU\nX-Generator: Poedit 1.6.5\n"
|
||||
"windows": ""
|
||||
}
|
||||
},
|
||||
"modRewriteHelp": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"labels": {
|
||||
"Main page title": "Ласкаво просимо EspoCRM",
|
||||
"Main page header": "Project-Id-Version: \nPOT-Creation-Date: \nPO-Revision-Date: 2015-04-09 15:16+0300\nLast-Translator: alihor <ihor.aleksejev@gmail.com>\nLanguage-Team: EspoCRM <infobox@espocrm.com>\nLanguage: uk\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\nX-Generator: Virtaal 0.7.1\n",
|
||||
"Main page header": "",
|
||||
"Start page title": "Ліцензійна Угода",
|
||||
"Step1 page title": "Ліцензійна Угода",
|
||||
"License Agreement": "Ліцензійна Угода",
|
||||
|
||||
Reference in New Issue
Block a user