entity manager dev
This commit is contained in:
@@ -66,6 +66,11 @@ class EntityManager extends \Espo\Core\Controllers\Base
|
||||
$result = $this->getContainer()->get('entityManagerUtil')->create($name, $type, $params);
|
||||
|
||||
if ($result) {
|
||||
$tabList = $this->getConfig()->get('tabList', []);
|
||||
$tabList[] = $name;
|
||||
$this->getConfig()->set('tabList', $tabList);
|
||||
$this->getConfig()->save();
|
||||
|
||||
$this->getContainer()->get('dataManager')->rebuild();
|
||||
} else {
|
||||
throw new Error();
|
||||
@@ -92,6 +97,14 @@ class EntityManager extends \Espo\Core\Controllers\Base
|
||||
$result = $this->getContainer()->get('entityManagerUtil')->delete($name);
|
||||
|
||||
if ($result) {
|
||||
$tabList = $this->getConfig()->get('tabList', []);
|
||||
if (($key = array_search($name, $tabList)) !== false) {
|
||||
unset($tabList[$key]);
|
||||
$tabList = array_values($tabList);
|
||||
}
|
||||
$this->getConfig()->set('tabList', $tabList);
|
||||
$this->getConfig()->save();
|
||||
|
||||
$this->getContainer()->get('dataManager')->clearCache();
|
||||
} else {
|
||||
throw new Error();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": {
|
||||
"type": "personName"
|
||||
},
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
namespace Espo\Core\Templates\Repositories;
|
||||
|
||||
|
||||
class Base extends \Espo\Core\ORM\Repositories\RDB
|
||||
class Person extends \Espo\Core\ORM\Repositories\RDB
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +37,6 @@ class EntityManager
|
||||
|
||||
private $metadataUtils;
|
||||
|
||||
protected $isChanged = null;
|
||||
|
||||
public function __construct(Metadata $metadata, Language $language, File\Manager $fileManager)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
@@ -68,16 +66,7 @@ class EntityManager
|
||||
return $this->metadataUtils;
|
||||
}
|
||||
|
||||
public function read($name, $scope)
|
||||
{
|
||||
$fieldDef = $this->getFieldDef($name, $scope);
|
||||
|
||||
$fieldDef['label'] = $this->getLanguage()->translate($name, 'fields', $scope);
|
||||
|
||||
return $fieldDef;
|
||||
}
|
||||
|
||||
public function create($name, $type)
|
||||
public function create($name, $type, $params = array())
|
||||
{
|
||||
if ($this->getMetadata()->get('scopes.' . $name)) {
|
||||
throw new Conflict('Entity ['.$name.'] already exists.');
|
||||
@@ -120,6 +109,20 @@ class EntityManager
|
||||
$filePath = "custom/Espo/Custom/Repositories/{$name}.php";
|
||||
$this->getFileManager()->putContents($filePath, $contents);
|
||||
|
||||
$stream = false;
|
||||
if (!empty($params['stream'])) {
|
||||
$stream = $params['stream'];
|
||||
}
|
||||
$labelSingular = $name;
|
||||
if (!empty($params['labelSingular'])) {
|
||||
$labelSingular = $params['labelSingular'];
|
||||
}
|
||||
$labelPlural = $name;
|
||||
if (!empty($params['labelPlural'])) {
|
||||
$labelPlural = $params['labelPlural'];
|
||||
}
|
||||
$labelCreate = $this->getLanguage()->translate('Create') . ' ' . $labelSingular;
|
||||
|
||||
$scopeData = array(
|
||||
'entity' => true,
|
||||
'layouts' => true,
|
||||
@@ -129,7 +132,8 @@ class EntityManager
|
||||
'isCustom' => true,
|
||||
'customizable' => true,
|
||||
'importable' => true,
|
||||
'type' => $type
|
||||
'type' => $type,
|
||||
'stream' => $stream
|
||||
);
|
||||
$this->getMetadata()->set($scopeData, 'scopes', $name);
|
||||
|
||||
@@ -141,36 +145,19 @@ class EntityManager
|
||||
$clientDefsData = Json::decode($this->getFileManager()->getContents($filePath), true);
|
||||
$this->getMetadata()->set($clientDefsData, 'clientDefs', $name);
|
||||
|
||||
$this->getLanguage()->set($name, $labelSingular, 'scopeNames', 'Global');
|
||||
$this->getLanguage()->set($name, $labelPlural, 'scopeNamesPlural', 'Global');
|
||||
$this->getLanguage()->set('Create ' . $name, $labelCreate, 'labels', $name);
|
||||
$this->getLanguage()->save();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function update($name, $fieldDef, $scope)
|
||||
{
|
||||
/*Add option to metadata to identify the custom field*/
|
||||
if ($this->isCustom($name, $scope)) {
|
||||
$fieldDef['isCustom'] = true;
|
||||
}
|
||||
|
||||
$res = true;
|
||||
if (isset($fieldDef['label'])) {
|
||||
$this->setLabel($name, $fieldDef['label'], $scope);
|
||||
}
|
||||
|
||||
if (isset($fieldDef['type']) && $fieldDef['type'] == 'enum') {
|
||||
if (isset($fieldDef['translatedOptions'])) {
|
||||
$this->setTranslatedOptions($name, $fieldDef['translatedOptions'], $scope);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($fieldDef['label']) || isset($fieldDef['translatedOptions'])) {
|
||||
$res &= $this->getLanguage()->save();
|
||||
}
|
||||
|
||||
if ($this->isDefsChanged($name, $fieldDef, $scope)) {
|
||||
$res &= $this->setEntityDefs($name, $fieldDef, $scope);
|
||||
}
|
||||
|
||||
return (bool) $res;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete($name)
|
||||
@@ -195,141 +182,16 @@ class EntityManager
|
||||
$this->getFileManager()->removeFile("custom/Espo/Custom/Controllers/{$name}.php");
|
||||
$this->getFileManager()->removeFile("custom/Espo/Custom/Repositories/{$name}.php");
|
||||
|
||||
try {
|
||||
$this->getLanguage()->delete($name, 'scopeNames', 'Global');
|
||||
$this->getLanguage()->delete($name, 'scopeNamesPlural', 'Global');
|
||||
} catch (\Exception $e) {}
|
||||
|
||||
$this->getLanguage()->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function setEntityDefs($name, $fieldDef, $scope)
|
||||
{
|
||||
$fieldDef = $this->normalizeDefs($name, $fieldDef, $scope);
|
||||
|
||||
$data = Json::encode($fieldDef);
|
||||
$res = $this->getMetadata()->set($data, $this->metadataType, $scope);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function setTranslatedOptions($name, $value, $scope)
|
||||
{
|
||||
return $this->getLanguage()->set($name, $value, 'options', $scope);
|
||||
}
|
||||
|
||||
protected function setLabel($name, $value, $scope)
|
||||
{
|
||||
return $this->getLanguage()->set($name, $value, 'fields', $scope);
|
||||
}
|
||||
|
||||
protected function deleteLabel($name, $scope)
|
||||
{
|
||||
$this->getLanguage()->delete($name, 'fields', $scope);
|
||||
return $this->getLanguage()->save();
|
||||
}
|
||||
|
||||
protected function getFieldDef($name, $scope)
|
||||
{
|
||||
return $this->getMetadata()->get($this->metadataType.'.'.$scope.'.fields.'.$name);
|
||||
}
|
||||
|
||||
protected function getLinkDef($name, $scope)
|
||||
{
|
||||
return $this->getMetadata()->get($this->metadataType.'.'.$scope.'.links.'.$name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare input fieldDefs, remove unnecessary fields
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param array $fieldDef
|
||||
* @param string $scope
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareFieldDef($name, $fieldDef, $scope)
|
||||
{
|
||||
$unnecessaryFields = array(
|
||||
'name',
|
||||
'label',
|
||||
);
|
||||
|
||||
foreach ($unnecessaryFields as $fieldName) {
|
||||
if (isset($fieldDef[$fieldName])) {
|
||||
unset($fieldDef[$fieldName]);
|
||||
}
|
||||
}
|
||||
|
||||
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) ) {
|
||||
unset($fieldDef[$defName]);
|
||||
}
|
||||
}
|
||||
|
||||
return $fieldDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all needed block for a field defenition
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param array $fieldDef
|
||||
* @param string $scope
|
||||
* @return array
|
||||
*/
|
||||
protected function normalizeDefs($fieldName, array $fieldDef, $scope)
|
||||
{
|
||||
$fieldDef = $this->prepareFieldDef($fieldName, $fieldDef, $scope);
|
||||
|
||||
$metaFieldDef = $this->getMetadataUtils()->getFieldDefsInFieldMeta($fieldDef);
|
||||
if (isset($metaFieldDef)) {
|
||||
$fieldDef = Util::merge($metaFieldDef, $fieldDef);
|
||||
}
|
||||
|
||||
$defs = array(
|
||||
'fields' => array(
|
||||
$fieldName => $fieldDef,
|
||||
),
|
||||
);
|
||||
|
||||
/** Save links for a field. */
|
||||
$metaLinkDef = $this->getMetadataUtils()->getLinkDefsInFieldMeta($scope, $fieldDef);
|
||||
if (isset($linkDefs) || isset($metaLinkDef)) {
|
||||
$linkDefs = Util::merge((array) $metaLinkDef, (array) $linkDefs);
|
||||
$defs['links'] = array(
|
||||
$fieldName => $linkDefs,
|
||||
);
|
||||
}
|
||||
|
||||
return $defs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if changed metadata defenition for a field except 'label'
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isDefsChanged($name, $fieldDef, $scope)
|
||||
{
|
||||
$fieldDef = $this->prepareFieldDef($name, $fieldDef, $scope);
|
||||
$currentFieldDef = $this->getFieldDef($name, $scope);
|
||||
|
||||
$this->isChanged = Util::isEquals($fieldDef, $currentFieldDef) ? false : true;
|
||||
|
||||
return $this->isChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for update method
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isChanged()
|
||||
{
|
||||
return $this->isChanged;
|
||||
}
|
||||
|
||||
protected function isCustom($name)
|
||||
{
|
||||
return $this->getMetadata()->get('scopes.' . $name . '.isCustom');
|
||||
|
||||
@@ -187,7 +187,9 @@
|
||||
"modifiedAt": "Modified At",
|
||||
"createdBy": "Created By",
|
||||
"modifiedBy": "Modified By",
|
||||
"description": "Description"
|
||||
"description": "Description",
|
||||
"address": "Address",
|
||||
"phoneNumber": "Phone"
|
||||
},
|
||||
"links": {
|
||||
"assignedUser": "Assigned User",
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
namespace Espo\Custom\Controllers;
|
||||
class Test extends \Espo\Core\Templates\Controllers\Base
|
||||
{
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
namespace Espo\Custom\Entities;
|
||||
class Test extends \Espo\Core\Templates\Entities\Base
|
||||
{
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
namespace Espo\Custom\Repositories;
|
||||
class Test extends \Espo\Core\Templates\Repositories\Base
|
||||
{
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
namespace Espo\Custom\Services;
|
||||
class Test extends \Espo\Core\Templates\Services\Base
|
||||
{
|
||||
}
|
||||
@@ -12,15 +12,13 @@
|
||||
</tr>
|
||||
{{#each scopeDataList}}
|
||||
<tr data-scope="{{name}}">
|
||||
<td width="20%">
|
||||
<a href="javascript:" data-action="editEntity" data-scope="{{name}}">
|
||||
<td width="25%">
|
||||
{{name}}
|
||||
</a>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<td width="25%">
|
||||
{{translate name category='scopeNames'}}
|
||||
</td>
|
||||
<td width="15%">
|
||||
<td width="10%">
|
||||
{{#if type}}
|
||||
{{translateOption type field='type' scope='EntityManager'}}
|
||||
{{/if}}
|
||||
@@ -35,9 +33,16 @@
|
||||
<a href="#Admin/relationshipManager/scope={{name}}">{{translate 'Relationships' scope='EntityManager'}}</a>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td align="right" width="10%">
|
||||
<a href="javascript:" data-action="editEntity" data-scope="{{name}}" title="{{translate 'Edit'}}">
|
||||
{{translate 'Edit'}}
|
||||
</a>
|
||||
</td>
|
||||
<td align="right" width="10%">
|
||||
{{#if isCustom}}
|
||||
<a href="javascript:" class="btn btn-danger btn-sm" data-action="removeEntity" data-scope="{{name}}">{{translate 'Remove'}}</a>
|
||||
<a href="javascript:" data-action="removeEntity" data-scope="{{name}}">
|
||||
{{translate 'Remove'}}
|
||||
</a>
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -54,7 +54,7 @@ Espo.define('Views.Admin.EntityManager.Index', 'View', function (Dep) {
|
||||
}
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
setupScopeData: function () {
|
||||
this.scopeDataList = [];
|
||||
|
||||
var scopeList = Object.keys(this.getMetadata().get('scopes')).sort(function (v1, v2) {
|
||||
@@ -73,27 +73,27 @@ Espo.define('Views.Admin.EntityManager.Index', 'View', function (Dep) {
|
||||
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
this.scope = this.options.scope || null;
|
||||
|
||||
this.setupScopeData();
|
||||
|
||||
this.on('after:render', function () {
|
||||
this.renderHeader();
|
||||
if (!this.scope) {
|
||||
this.renderDefaultPage();
|
||||
} else {
|
||||
if (!this.field) {
|
||||
this.openScope(this.scope);
|
||||
} else {
|
||||
this.openField(this.scope, this.field);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
createEntity: function () {
|
||||
this.createView('edit', 'Admin.EntityManager.Modals.EditEntity', {}, function (view) {
|
||||
view.render();
|
||||
});
|
||||
|
||||
this.listenTo(view, 'after:save', function () {
|
||||
this.setupScopeData();
|
||||
this.render();
|
||||
}, this);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
editEntity: function (scope) {
|
||||
@@ -101,7 +101,12 @@ Espo.define('Views.Admin.EntityManager.Index', 'View', function (Dep) {
|
||||
scope: scope
|
||||
}, function (view) {
|
||||
view.render();
|
||||
});
|
||||
|
||||
this.listenTo(view, 'after:save', function () {
|
||||
this.setupScopeData();
|
||||
this.render();
|
||||
}, this);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
removeEntity: function (scope) {
|
||||
@@ -113,6 +118,12 @@ Espo.define('Views.Admin.EntityManager.Index', 'View', function (Dep) {
|
||||
})
|
||||
}).done(function () {
|
||||
this.$el.find('table tr[data-scope="'+scope+'"]').remove();
|
||||
this.getMetadata().load(function () {
|
||||
this.getConfig().load(function () {
|
||||
this.setupScopeData();
|
||||
this.render();
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ Espo.define('Views.Admin.EntityManager.Modals.EditEntity', 'Views.Modal', functi
|
||||
this.model.set('labelSingular', name);
|
||||
this.model.set('labelPlural', name + 's') ;
|
||||
if (name) {
|
||||
name = name.replace(/\-/g, ' ').replace(/_/g, ' ').replace(/[^\w\s]/gi, '').replace(/ (.)/g, function(match, g) {
|
||||
name = name.replace(/\-/g, ' ').replace(/_/g, ' ').replace(/[^\w\s]/gi, '').replace(/ (.)/g, function (match, g) {
|
||||
return g.toUpperCase();
|
||||
}).replace(' ', '');
|
||||
if (name.length) {
|
||||
@@ -187,14 +187,17 @@ Espo.define('Views.Admin.EntityManager.Modals.EditEntity', 'Views.Modal', functi
|
||||
url = 'EntityManager/action/updateEntity';
|
||||
}
|
||||
|
||||
var name = this.model.get('name');
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: JSON.stringify({
|
||||
name: this.model.get('name'),
|
||||
name: name,
|
||||
labelSingular: this.model.get('labelSingular'),
|
||||
labelPlural: this.model.get('labelPlural'),
|
||||
type: this.model.get('type')
|
||||
type: this.model.get('type'),
|
||||
stream: this.model.get('stream')
|
||||
}),
|
||||
error: function () {
|
||||
this.$el.find('button[data-name="save"]').removeClass('disabled');
|
||||
@@ -205,9 +208,17 @@ Espo.define('Views.Admin.EntityManager.Modals.EditEntity', 'Views.Modal', functi
|
||||
} else {
|
||||
Espo.Ui.success(this.translate('entityCreated', 'messages', 'EntityManager'));
|
||||
}
|
||||
this.trigger('saved');
|
||||
var global = (this.getLanguage().data || {}) || {};
|
||||
(global.scopeNames || {})[name] = this.model.get('labelSingular');
|
||||
(global.scopeNamesPlural || {})[name] = this.model.get('labelPlural');
|
||||
|
||||
this.getMetadata().load(function () {
|
||||
this.getConfig().load(function () {
|
||||
this.trigger('after:save');
|
||||
this.close();
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user