diff --git a/application/Espo/Core/ServiceFactory.php b/application/Espo/Core/ServiceFactory.php index fd38987532..963a69ce03 100644 --- a/application/Espo/Core/ServiceFactory.php +++ b/application/Espo/Core/ServiceFactory.php @@ -67,13 +67,10 @@ class ServiceFactory protected function getClassName($name) { - $name = Util::normilizeClassName($name); - if (!isset($this->data)) { $this->init(); } - $name = ucfirst($name); if (isset($this->data[$name])) { return $this->data[$name]; } diff --git a/application/Espo/EntryPoints/Download.php b/application/Espo/EntryPoints/Download.php index a2660b1ca2..a631f7bf64 100644 --- a/application/Espo/EntryPoints/Download.php +++ b/application/Espo/EntryPoints/Download.php @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ + ************************************************************************/ namespace Espo\EntryPoints; @@ -29,45 +29,49 @@ use \Espo\Core\Exceptions\BadRequest; class Download extends \Espo\Core\EntryPoints\Base { public static $authRequired = true; - + protected $fileTypesToShowInline = array( 'application/pdf', + 'application/vnd.ms-word', + 'application/vnd.ms-excel', + 'application/vnd.oasis.opendocument.text', + 'application/vnd.oasis.opendocument.spreadsheet', + 'text/plain', ); - + public function run() - { + { $id = $_GET['id']; if (empty($id)) { throw new BadRequest(); } - + $attachment = $this->getEntityManager()->getEntity('Attachment', $id); - + if (!$attachment) { throw new NotFound(); - } - + } + if ($attachment->get('parentId') && $attachment->get('parentType')) { - $parent = $this->getEntityManager()->getEntity($attachment->get('parentType'), $attachment->get('parentId')); + $parent = $this->getEntityManager()->getEntity($attachment->get('parentType'), $attachment->get('parentId')); if (!$this->getAcl()->check($parent)) { throw new Forbidden(); } } - + $fileName = "data/upload/{$attachment->id}"; - + if (!file_exists($fileName)) { throw new NotFound(); } - + $type = $attachment->get('type'); - + $disposition = 'attachment'; if (in_array($type, $this->fileTypesToShowInline)) { $disposition = 'inline'; } - - + header('Content-Description: File Transfer'); if ($type) { header('Content-Type: ' . $type); @@ -80,7 +84,7 @@ class Download extends \Espo\Core\EntryPoints\Base ob_clean(); flush(); readfile($fileName); - exit; - } + exit; + } } diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Reminder.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Reminder.json index 199c6d9a65..c907e5998d 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Reminder.json +++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Reminder.json @@ -17,7 +17,7 @@ }, "seconds": { "type": "enumInt", - "options": [0, 60, 120, 300, 900, 1800, 3600, 7200, 10800, 18000, 86400], + "options": [0, 60, 120, 300, 600, 900, 1800, 3600, 7200, 10800, 18000, 86400], "default": 0 }, "entityType": { diff --git a/application/Espo/Modules/Crm/Services/CaseObj.php b/application/Espo/Modules/Crm/Services/CaseObj.php index 111865649b..1d41fe9452 100644 --- a/application/Espo/Modules/Crm/Services/CaseObj.php +++ b/application/Espo/Modules/Crm/Services/CaseObj.php @@ -26,7 +26,6 @@ use \Espo\ORM\Entity; class CaseObj extends \Espo\Services\Record { - protected $mergeLinkList = array( 'tasks', 'meetings', diff --git a/application/Espo/Resources/i18n/en_US/Global.json b/application/Espo/Resources/i18n/en_US/Global.json index 906b6082b4..aac87ab56f 100644 --- a/application/Espo/Resources/i18n/en_US/Global.json +++ b/application/Espo/Resources/i18n/en_US/Global.json @@ -44,6 +44,7 @@ "Uploading...": "Uploading...", "Sending...": "Sending...", "Merging...": "Merging...", + "Merged": "Merged", "Removed": "Removed", "Posted": "Posted", "Linked": "Linked", diff --git a/application/Espo/Resources/metadata/scopes/User.json b/application/Espo/Resources/metadata/scopes/User.json index 38a0ecc2bc..40469e6b74 100644 --- a/application/Espo/Resources/metadata/scopes/User.json +++ b/application/Espo/Resources/metadata/scopes/User.json @@ -1 +1,7 @@ -{"entity":true,"layouts":true,"tab":false,"acl":false,"customizable":true} +{ + "entity": true, + "layouts": true, + "tab": true, + "acl": false, + "customizable": true +} diff --git a/application/Espo/Services/Record.php b/application/Espo/Services/Record.php index c6ba7e0a14..de07006aa5 100644 --- a/application/Espo/Services/Record.php +++ b/application/Espo/Services/Record.php @@ -72,7 +72,7 @@ class Record extends \Espo\Core\Services\Base $name = $matches[1]; } if ($name != 'Record') { - $this->entityName = $name; + $this->entityName = Util::normilizeScopeName($name); } } } @@ -763,8 +763,7 @@ class Record extends \Espo\Core\Services\Base UPDATE `note` SET `parent_id` = " . $pdo->quote($entity->id) . ", - `parent_type` = " . $pdo->quote($entity->getEntityName()) . ", - + `parent_type` = " . $pdo->quote($entity->getEntityName()) . " WHERE `type` IN ('Post', 'EmailSent', 'EmailReceived') AND `parent_id` = " . $pdo->quote($source->id) . " AND @@ -774,16 +773,18 @@ class Record extends \Espo\Core\Services\Base $pdo->query($sql); } + $repository = $this->getEntityManager()->getRepository($entity->getEntityName()); + foreach ($sourceList as $source) { foreach ($this->mergeLinkList as $link) { - $linkedList = $this->getEntityManager()->getRepository($this->name)->findRelated($source, $link); + $linkedList = $repository->findRelated($source, $link); foreach ($linkedList as $linked) { - $this->getEntityManager()->getRepository()->relate($entity, $link, $linked); - $this->getEntityManager()->getRepository()->unrelate($source, $link, $linked); + $repository->relate($entity, $link, $linked); } } } + foreach ($sourceList as $source) { $this->getEntityManager()->removeEntity($source); } diff --git a/frontend/client/modules/crm/src/views/meeting/fields/reminders.js b/frontend/client/modules/crm/src/views/meeting/fields/reminders.js index 8a282e3fc3..7d34ea1ac6 100644 --- a/frontend/client/modules/crm/src/views/meeting/fields/reminders.js +++ b/frontend/client/modules/crm/src/views/meeting/fields/reminders.js @@ -22,7 +22,7 @@ Espo.define('Crm:Views.Meeting.Fields.Reminders', 'Views.Fields.Base', function (Dep) { return Dep.extend({ - + detailTemplate: 'crm:meeting.fields.reminders.detail', listTemplate: 'crm:meeting.fields.reminders.detail', @@ -33,7 +33,7 @@ Espo.define('Crm:Views.Meeting.Fields.Reminders', 'Views.Fields.Base', function 'click [data-action="addReminder"]': function () { var type = this.getMetadata().get('entityDefs.Reminder.fields.type.default'); var seconds = this.getMetadata().get('entityDefs.Reminder.fields.seconds.default'); - + var item = { type: type, seconds: seconds @@ -66,7 +66,7 @@ Espo.define('Crm:Views.Meeting.Fields.Reminders', 'Views.Fields.Base', function }, this); this.typeList = this.getMetadata().get('entityDefs.Reminder.fields.type.options'); - this.secondsList = this.getMetadata().get('entityDefs.Reminder.fields.seconds.options');; + this.secondsList = this.getMetadata().get('entityDefs.Reminder.fields.seconds.options'); }, afterRender: function () { diff --git a/frontend/client/res/templates/fields/url/detail.tpl b/frontend/client/res/templates/fields/url/detail.tpl index c9d6d662d6..4ff7c7f725 100644 --- a/frontend/client/res/templates/fields/url/detail.tpl +++ b/frontend/client/res/templates/fields/url/detail.tpl @@ -1 +1 @@ -{{value}} +{{value}} diff --git a/frontend/client/src/views/admin/extensions/index.js b/frontend/client/src/views/admin/extensions/index.js index c428716fb8..dc4e4ae853 100644 --- a/frontend/client/src/views/admin/extensions/index.js +++ b/frontend/client/src/views/admin/extensions/index.js @@ -17,16 +17,16 @@ * * 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.Extensions.Index', 'View', function (Dep) { +Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) { return Dep.extend({ - + template: "admin.extensions.index", - + packageContents: null, - + events: { 'change input[name="package"]': function (e) { this.$el.find('button[data-action="upload"]').addClass('disabled'); @@ -41,22 +41,22 @@ Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) { }, 'click [data-action="install"]': function (e) { var id = $(e.currentTarget).data('id'); - + var name = this.collection.get(id).get('name'); var version = this.collection.get(id).get('version'); - + this.run(id, name, version); - + }, 'click [data-action="uninstall"]': function (e) { var id = $(e.currentTarget).data('id'); - + var name = this.collection.get(id).get('name'); - + var self = this; - if (confirm(this.translate('uninstallConfirmation', 'messages', 'Admin'))) { + if (confirm(this.translate('uninstallConfirmation', 'messages', 'Admin'))) { Espo.Ui.notify(this.translate('Uninstalling...', 'labels', 'Admin')); - + $.ajax({ url: 'Extension/action/uninstall', type: 'POST', @@ -67,25 +67,25 @@ Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) { var msg = xhr.getResponseHeader('X-Status-Reason'); this.showErrorNotification(this.translate('Error') + ': ' + msg); }.bind(this) - }).done(function () { + }).done(function () { this.listenToOnce(this.collection, 'sync', function () { Espo.Ui.success(this.translate('uninstalled', 'messages', 'Extension').replace('{name}', name)); }, this); this.collection.fetch(); - + }.bind(this)); } } }, - + setup: function () { this.getCollectionFactory().create('Extension', function (collection) { this.collection = collection; - + collection.maxSize = this.getConfig().get('recordsPerPage'); - + this.wait(true); - this.listenToOnce(collection, 'sync', function () { + this.listenToOnce(collection, 'sync', function () { this.createView('list', 'Extension.Record.List', { collection: collection, el: this.options.el + ' > .list-container', @@ -97,36 +97,36 @@ Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) { } this.wait(false); }); - + collection.fetch(); - + }, this); }, - + selectFile: function (file) { var fileReader = new FileReader(); - fileReader.onload = function (e) { + fileReader.onload = function (e) { this.packageContents = e.target.result; this.$el.find('button[data-action="upload"]').removeClass('disabled'); }.bind(this); fileReader.readAsDataURL(file); }, - + showError: function (msg) { msg = this.translate(msg, 'errors', 'Admin'); this.$el.find('.message-container').html(msg); }, - + showErrorNotification: function (msg) { if (!msg) { this.$el.find('.notify-text').addClass('hidden'); - } else { + } else { msg = this.translate(msg, 'errors', 'Admin'); this.$el.find('.notify-text').html(msg); this.$el.find('.notify-text').removeClass('hidden'); } }, - + upload: function () { this.$el.find('button[data-action="upload"]').addClass('disabled'); this.notify('Uploading...'); @@ -134,9 +134,9 @@ Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) { url: 'Extension/action/upload', type: 'POST', contentType: 'application/zip', - timeout: 0, + timeout: 0, data: this.packageContents, - error: function (xhr, t, e) { + error: function (xhr, t, e) { this.showError(xhr.getResponseHeader('X-Status-Reason')); this.notify(false); }.bind(this) @@ -151,23 +151,23 @@ Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) { }, function (view) { view.render(); this.$el.find('button[data-action="upload"]').removeClass('disabled'); - + view.once('run', function () { view.close(); this.$el.find('.panel.upload').addClass('hidden'); this.run(data.id, data.version, data.name); }, this); - }.bind(this)); + }.bind(this)); }.bind(this)).error; - }, - - run: function (id, version, name) { + }, + + run: function (id, version, name) { var msg = this.translate('Installing...', 'labels', 'Admin'); this.notify('Please wait...'); - + this.showError(false); - this.showErrorNotification(false); - + this.showErrorNotification(false); + $.ajax({ url: 'Extension/action/install', type: 'POST', @@ -178,26 +178,26 @@ Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) { this.$el.find('.panel.upload').removeClass('hidden'); var msg = xhr.getResponseHeader('X-Status-Reason'); this.showErrorNotification(this.translate('Error') + ': ' + msg); - }.bind(this) + }.bind(this) }).done(function () { var cache = this.getCache(); if (cache) { - cache.clear(); + cache.clear(); } this.createView('popup', 'Admin.Extensions.Done', { version: version, name: name }, function (view) { this.collection.fetch(); - this.$el.find('.list-container').removeClass('hidden'); - this.$el.find('.panel.upload').removeClass('hidden'); + this.$el.find('.list-container').removeClass('hidden'); + this.$el.find('.panel.upload').removeClass('hidden'); this.notify(false); - view.render(); + view.render(); }.bind(this)); }.bind(this)); }, - - }); - + + }); + }); diff --git a/frontend/client/src/views/admin/upgrade/index.js b/frontend/client/src/views/admin/upgrade/index.js index dbc5cfb92d..c59852dd6f 100644 --- a/frontend/client/src/views/admin/upgrade/index.js +++ b/frontend/client/src/views/admin/upgrade/index.js @@ -17,14 +17,14 @@ * * 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.Upgrade.Index', 'View', function (Dep) { return Dep.extend({ template: 'admin.upgrade.index', - + packageContents: null, data: function () { @@ -50,21 +50,21 @@ Espo.define('Views.Admin.Upgrade.Index', 'View', function (Dep) { setup: function () { }, - + selectFile: function (file) { var fileReader = new FileReader(); - fileReader.onload = function (e) { + fileReader.onload = function (e) { this.packageContents = e.target.result; this.$el.find('button[data-action="upload"]').removeClass('disabled'); }.bind(this); fileReader.readAsDataURL(file); }, - + showError: function (msg) { msg = this.translate(msg, 'errors', 'Admin'); this.$el.find('.message-container').html(msg); }, - + upload: function () { this.$el.find('button[data-action="upload"]').addClass('disabled'); this.notify('Uploading...'); @@ -72,11 +72,11 @@ Espo.define('Views.Admin.Upgrade.Index', 'View', function (Dep) { url: 'Admin/action/uploadUpgradePackage', type: 'POST', contentType: 'application/zip', - timeout: 0, + timeout: 0, data: this.packageContents, - error: function (xhr, t, e) { + error: function (xhr, t, e) { this.showError(xhr.getResponseHeader('X-Status-Reason')); - this.notify(false); + this.notify(false); }.bind(this) }).done(function (data) { if (!data.id) { @@ -89,25 +89,25 @@ Espo.define('Views.Admin.Upgrade.Index', 'View', function (Dep) { }, function (view) { view.render(); this.$el.find('button[data-action="upload"]').removeClass('disabled'); - + view.once('run', function () { view.close(); this.$el.find('.panel.upload').addClass('hidden'); this.run(data.id, data.version); }, this); - }.bind(this)); + }.bind(this)); }.bind(this)).error; }, - + textNotification: function (text) { - this.$el.find('.notify-text').html(text); + this.$el.find('.notify-text').html(text); }, - - run: function (id, version) { + + run: function (id, version) { var msg = this.translate('Upgrading...', 'labels', 'Admin'); this.notify('Please wait...'); - this.textNotification(msg); - + this.textNotification(msg); + $.ajax({ url: 'Admin/action/runUpgrade', type: 'POST', @@ -118,17 +118,17 @@ Espo.define('Views.Admin.Upgrade.Index', 'View', function (Dep) { this.$el.find('.panel.upload').removeClass('hidden'); var msg = xhr.getResponseHeader('X-Status-Reason'); this.textNotification(this.translate('Error') + ': ' + msg); - }.bind(this) + }.bind(this) }).done(function () { var cache = this.getCache(); if (cache) { - cache.clear(); + cache.clear(); } this.createView('popup', 'Admin.Upgrade.Done', { version: version }, function (view) { this.notify(false); - view.render(); + view.render(); }.bind(this)); }.bind(this)); }, diff --git a/frontend/client/src/views/record/merge.js b/frontend/client/src/views/record/merge.js index 3db66ffea1..8ef426e776 100644 --- a/frontend/client/src/views/record/merge.js +++ b/frontend/client/src/views/record/merge.js @@ -108,26 +108,11 @@ Espo.define('Views.Record.Merge', 'View', function (Dep) { }) }) }).done(function () { - return; model.once('sync', function () { this.notify('Merged', 'success'); this.getRouter().navigate('#' + this.scope + '/view/' + model.id, {trigger: true}); - /*var i = 0; - var count = this.models.length; - this.models.forEach(function (m) { - if (m.id != model.id) { - m.once('destroy', function () { - i++; - if (i == count - 1) { - this.notify('Merged', 'success'); - this.getRouter().navigate('#' + this.scope + '/view/' + model.id, {trigger: true}); - } - }, this); - m.destroy(); - } - }, this);*/ }, this); model.save(attributes, {