Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd413a75a0 | |||
| 9bb0d123d3 | |||
| 59240fb090 | |||
| 598852484b | |||
| 18548c515e | |||
| 6190017919 | |||
| e49cbcad3f | |||
| 2a22b94b95 | |||
| 739374de59 | |||
| 03b8041acb | |||
| a31df6f2af | |||
| 64317389a8 | |||
| ab4552d064 | |||
| 20281f8cbb | |||
| fb7db0f91d | |||
| b3b0e9254f | |||
| 03ffc7727d | |||
| 59a4f88eeb | |||
| d504ab8f54 | |||
| 627c167ef7 | |||
| 656c9b1eee | |||
| 92f319a2d9 | |||
| da1f96595f | |||
| 21568efa2c | |||
| 8a75a5a71b | |||
| 012e4d609d | |||
| 5e66d2e2c1 | |||
| 49ae22e048 | |||
| 5d92d14125 | |||
| b6d52d3c97 | |||
| 7e2d445db8 | |||
| 2325ad695f | |||
| c499b06baa | |||
| a03a512846 | |||
| 1e6062bd10 | |||
| 2c90558785 | |||
| f6071bad41 | |||
| a09120f39e | |||
| 8fb7cbdfcf | |||
| 3e8da12410 | |||
| d60213e93f | |||
| 0864f7d604 | |||
| 6fb2112e40 | |||
| 65bb063c2c | |||
| 75b2c91baa | |||
| 530be71fdd | |||
| c064b8fa80 | |||
| b2b0ed82e5 | |||
| 71a5e1ab22 | |||
| 371b140056 | |||
| 5555383b1e | |||
| ffe824e405 | |||
| 6586785415 | |||
| 8a2554ef28 | |||
| ec2ddc429a | |||
| 1754b8e7b9 | |||
| 2e20b24d04 | |||
| 5da3df3cd2 | |||
| 61d428a4a5 | |||
| a941f0c5da | |||
| 199d0a956a | |||
| 105ec0f441 | |||
| 062effd39a | |||
| 3ac5c71736 | |||
| 97d7796f9d | |||
| 8cd4fe5891 | |||
| 77df445c03 | |||
| a510bb4ea0 | |||
| 48883211ee | |||
| 8b77f181da | |||
| 88dbc988ca | |||
| 0ecd387ef8 | |||
| 2c4cc20005 | |||
| b25c115913 | |||
| e46921ac33 | |||
| dab213ea01 | |||
| 7f058b8591 | |||
| 76cf945d40 | |||
| c5850d18da | |||
| 645cdc440c | |||
| 6e910e002e | |||
| cc4de320fd | |||
| 7565492666 | |||
| 878d74bfa5 | |||
| ee2d8b3f00 | |||
| ebd35638b2 | |||
| 6372c7a22e | |||
| a404f7f196 | |||
| 0013ca382a | |||
| a9c904afa7 | |||
| a0be338676 | |||
| 58d0f2bd98 | |||
| 4c92d54119 | |||
| 711b2df143 | |||
| 0307900942 | |||
| 4c60898002 | |||
| 4d350b256b | |||
| d41704f1b1 | |||
| 5bbb5ee937 | |||
| 50e825b7a0 | |||
| dc036225be | |||
| c5a8df84f7 | |||
| 7ad6c495a6 | |||
| e8c217e468 | |||
| 9e32298d42 | |||
| e4d833e49f | |||
| 8505f583f4 | |||
| c1de2d9bd5 | |||
| d192e0aabf | |||
| fb5b464bf6 | |||
| eb71379562 | |||
| b603543537 |
@@ -15,6 +15,7 @@ DirectoryIndex index.php index.html
|
||||
RewriteRule ^/?data/logs/ - [F]
|
||||
RewriteRule ^/?data/cache/ - [F]
|
||||
RewriteRule ^/?data/upload/ - [F]
|
||||
RewriteRule ^/?data/\.backup/ - [F]
|
||||
RewriteRule ^/?application/ - [F]
|
||||
RewriteRule ^/?custom/ - [F]
|
||||
RewriteRule ^/?vendor/ - [F]
|
||||
|
||||
+1
-27
@@ -36,34 +36,8 @@ module.exports = function (grunt) {
|
||||
'client/lib/bull.min.js',
|
||||
'client/src/namespace.js',
|
||||
'client/src/exceptions.js',
|
||||
'client/src/app.js',
|
||||
'client/src/utils.js',
|
||||
'client/src/storage.js',
|
||||
'client/src/loader.js',
|
||||
'client/src/pre-loader.js',
|
||||
'client/src/ui.js',
|
||||
'client/src/acl.js',
|
||||
'client/src/model.js',
|
||||
'client/src/model-offline.js',
|
||||
'client/src/metadata.js',
|
||||
'client/src/language.js',
|
||||
'client/src/cache.js',
|
||||
'client/src/controller.js',
|
||||
'client/src/router.js',
|
||||
'client/src/date-time.js',
|
||||
'client/src/field-manager.js',
|
||||
'client/src/search-manager.js',
|
||||
'client/src/collection.js',
|
||||
'client/src/multi-collection.js',
|
||||
'client/src/view-helper.js',
|
||||
'client/src/layout-manager.js',
|
||||
'client/src/model-factory.js',
|
||||
'client/src/collection-factory.js',
|
||||
'client/src/models/settings.js',
|
||||
'client/src/models/user.js',
|
||||
'client/src/models/preferences.js',
|
||||
'client/src/controllers/base.js',
|
||||
'client/src/view.js',
|
||||
'client/src/utils.js'
|
||||
];
|
||||
|
||||
grunt.initConfig({
|
||||
|
||||
@@ -38,6 +38,7 @@ class Stream extends \Espo\Core\Controllers\Base
|
||||
$offset = intval($request->get('offset'));
|
||||
$maxSize = intval($request->get('maxSize'));
|
||||
$after = $request->get('after');
|
||||
$filter = $request->get('filter');
|
||||
|
||||
$service = $this->getService('Stream');
|
||||
|
||||
@@ -52,6 +53,7 @@ class Stream extends \Espo\Core\Controllers\Base
|
||||
'offset' => $offset,
|
||||
'maxSize' => $maxSize,
|
||||
'after' => $after,
|
||||
'filter' => $filter
|
||||
));
|
||||
|
||||
return array(
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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\Controllers;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class Template extends \Espo\Core\Controllers\Record
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -53,7 +53,10 @@ class User extends \Espo\Core\Controllers\Record
|
||||
if (!$request->isPost()) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
return $this->getService('User')->changePassword($this->getUser()->id, $data['password']);
|
||||
if (!array_key_exists('password', $data) || !array_key_exists('currentPassword', $data)) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
return $this->getService('User')->changePassword($this->getUser()->id, $data['password'], true, $data['currentPassword']);
|
||||
}
|
||||
|
||||
public function actionChangePasswordByRequest($params, $data, $request)
|
||||
|
||||
@@ -105,7 +105,7 @@ class Base implements Injectable
|
||||
public function checkScope(User $user, $data, $scope, $action = null, $isOwner = null, $inTeam = null, Entity $entity = null)
|
||||
{
|
||||
if (is_null($data)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if ($data === false) {
|
||||
return false;
|
||||
|
||||
@@ -161,6 +161,14 @@ class Container
|
||||
);
|
||||
}
|
||||
|
||||
private function loadNumber()
|
||||
{
|
||||
return new \Espo\Core\Utils\Number(
|
||||
$this->get('config')->get('decimalMark'),
|
||||
$this->get('config')->get('thousandSeparator')
|
||||
);
|
||||
}
|
||||
|
||||
private function loadServiceFactory()
|
||||
{
|
||||
return new \Espo\Core\ServiceFactory(
|
||||
|
||||
@@ -67,6 +67,21 @@ abstract class Base
|
||||
return $this->getContainer()->get('metadata');
|
||||
}
|
||||
|
||||
protected function getDateTime()
|
||||
{
|
||||
return $this->getContainer()->get('dateTime');
|
||||
}
|
||||
|
||||
protected function getNumber()
|
||||
{
|
||||
return $this->getContainer()->get('number');
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
{
|
||||
return $this->getContainer()->get('fileManager');
|
||||
}
|
||||
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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\Core\Htmlizer;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
|
||||
use Espo\Core\Utils\File\Manager as FileManager;
|
||||
use Espo\Core\Utils\DateTime;
|
||||
use Espo\Core\Utils\Number;
|
||||
|
||||
require('vendor/zordius/lightncandy/src/lightncandy.php');
|
||||
|
||||
class Htmlizer
|
||||
{
|
||||
protected $fileManager;
|
||||
|
||||
protected $dateTime;
|
||||
|
||||
protected $config;
|
||||
|
||||
public function __construct(FileManager $fileManager, DateTime $dateTime, Number $number)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
$this->dateTime = $dateTime;
|
||||
$this->number = $number;
|
||||
}
|
||||
|
||||
protected function formatNumber($value)
|
||||
{
|
||||
return $this->number->format($value);
|
||||
}
|
||||
|
||||
protected function format($value)
|
||||
{
|
||||
if (is_float($value) || is_int($value)) {
|
||||
$value = $this->formatNumber($value);
|
||||
} else if (is_string($value)) {
|
||||
$value = nl2br($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function getDataFromEntity(Entity $entity)
|
||||
{
|
||||
$data = $entity->toArray();
|
||||
|
||||
|
||||
|
||||
$fieldDefs = $entity->getFields();
|
||||
$fieldList = array_keys($fieldDefs);
|
||||
|
||||
foreach ($fieldList as $field) {
|
||||
$type = null;
|
||||
if (!empty($fieldDefs[$field]['type'])) {
|
||||
$type = $fieldDefs[$field]['type'];
|
||||
}
|
||||
if ($type == Entity::DATETIME) {
|
||||
if (!empty($data[$field])) {
|
||||
$data[$field] = $this->dateTime->convertSystemDateTime($data[$field]);
|
||||
}
|
||||
} else if ($type == Entity::DATE) {
|
||||
if (!empty($data[$field])) {
|
||||
$data[$field] = $this->dateTime->convertSystemDate($data[$field]);
|
||||
}
|
||||
} else if ($type == Entity::JSON_ARRAY) {
|
||||
if (!empty($data[$field])) {
|
||||
$list = $data[$field];
|
||||
$newList = [];
|
||||
foreach ($list as $item) {
|
||||
$v = $item;
|
||||
if ($item instanceof \StdClass) {
|
||||
$v = get_object_vars($v);
|
||||
}
|
||||
foreach ($v as $k => $w) {
|
||||
$v[$k] = $this->format($v[$k]);
|
||||
}
|
||||
$newList[] = $v;
|
||||
}
|
||||
$data[$field] = $newList;
|
||||
}
|
||||
} else if ($type == Entity::JSON_OBJECT) {
|
||||
if (!empty($data[$field])) {
|
||||
$value = $data[$field];
|
||||
if ($value instanceof \StdClass) {
|
||||
$data[$field] = get_object_vars($value);
|
||||
}
|
||||
foreach ($data[$field] as $k => $w) {
|
||||
$data[$field][$k] = $this->format($data[$field][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists($field, $data)) {
|
||||
$data[$field] = $this->format($data[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function render(Entity $entity, $template)
|
||||
{
|
||||
$code = \LightnCandy::compile($template);
|
||||
$id = uniqid('', true);
|
||||
$fileName = 'data/cache/template-' . $id;
|
||||
$this->fileManager->putContents($fileName, $code);
|
||||
$renderer = include($fileName);
|
||||
$this->fileManager->removeFile($fileName);
|
||||
|
||||
$data = $this->getDataFromEntity($entity);
|
||||
|
||||
$html = $renderer($data);
|
||||
|
||||
$html = str_replace('?entryPoint=attachment&', '?entryPoint=attachment&', $html);
|
||||
$html = preg_replace('/\?entryPoint=attachment\&id=(.*)/', 'data/upload/$1', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@@ -10,37 +10,5 @@ use Zend\Loader\PluginClassLocator;
|
||||
|
||||
class Headers extends \Zend\Mail\Headers
|
||||
{
|
||||
public static function fromString($string, $EOL = self::EOL)
|
||||
{
|
||||
$headers = new static();
|
||||
$currentLine = '';
|
||||
|
||||
// iterate the header lines, some might be continuations
|
||||
foreach (explode($EOL, $string) as $line) {
|
||||
// check if a header name is present
|
||||
if (preg_match('/^(?P<name>[\x21-\x39\x3B-\x7E]+):.*$/', $line, $matches)) {
|
||||
if ($currentLine) {
|
||||
// a header name was present, then store the current complete line
|
||||
$headers->addHeaderLine($currentLine);
|
||||
}
|
||||
$currentLine = trim($line);
|
||||
} elseif (preg_match('/^\s+.*$/', $line, $matches)) {
|
||||
// continuation: append to current line
|
||||
$currentLine .= $line;
|
||||
} elseif (preg_match('/^\s*$/', $line)) {
|
||||
// empty line indicates end of headers
|
||||
break;
|
||||
} else {
|
||||
// Line does not match header format!
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
'Line "%s"does not match header format!',
|
||||
$line
|
||||
));
|
||||
}
|
||||
}
|
||||
if ($currentLine) {
|
||||
$headers->addHeaderLine($currentLine);
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ class Sender
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function send(Email $email, $params = array())
|
||||
public function send(Email $email, $params = array(), &$message = null)
|
||||
{
|
||||
$message = new Message();
|
||||
$config = $this->config;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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\Core\Pdf;
|
||||
|
||||
require "vendor/tecnick.com/tcpdf/tcpdf.php";
|
||||
|
||||
class Tcpdf extends \TCPDF
|
||||
{
|
||||
protected $footerHtml = '';
|
||||
|
||||
protected $footerPosition = 15;
|
||||
|
||||
public function setFooterHtml($html)
|
||||
{
|
||||
$this->footerHtml = $html;
|
||||
}
|
||||
|
||||
public function setFooterPosition($position)
|
||||
{
|
||||
$this->footerPosition = $position;
|
||||
}
|
||||
|
||||
public function Footer() {
|
||||
$this->SetY((-1) * $this->footerPosition);
|
||||
|
||||
$html = str_replace('{pageNumber}', '{:pnp:}', $this->footerHtml);
|
||||
$this->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, '', 0, false, 'T');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -134,6 +134,7 @@ class EntityManager
|
||||
$scopesData['stream'] = $stream;
|
||||
$scopesData['type'] = $type;
|
||||
$scopesData['module'] = 'Custom';
|
||||
$scopesData['object'] = true;
|
||||
$scopesData['isCustom'] = true;
|
||||
|
||||
$this->getMetadata()->set('scopes', $name, $scopesData);
|
||||
@@ -277,6 +278,12 @@ class EntityManager
|
||||
throw new Conflict('Link ['.$entityForeign.'::'.$linkForeign.'] already exists.');
|
||||
}
|
||||
|
||||
if ($entity === $entityForeign) {
|
||||
if ($link === ucfirst($entity) || $linkForeign === ucfirst($entity)) {
|
||||
throw new Conflict();
|
||||
}
|
||||
}
|
||||
|
||||
switch ($linkType) {
|
||||
case 'oneToMany':
|
||||
if ($this->getMetadata()->get('entityDefs.' . $entityForeign . '.field.' . $linkForeign)) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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\Core\Utils;
|
||||
|
||||
class Number
|
||||
{
|
||||
protected $decimalMark;
|
||||
|
||||
protected $thousandSeparator;
|
||||
|
||||
public function __construct($decimalMark = '.', $thousandSeparator = ',')
|
||||
{
|
||||
$this->decimalMark = $decimalMark;
|
||||
$this->thousandSeparator = $thousandSeparator;
|
||||
}
|
||||
|
||||
public function format($value, $decimals = null)
|
||||
{
|
||||
if (!is_null($decimals)) {
|
||||
return number_format($value, $decimals, $this->decimalMark, $this->thousandSeparator);
|
||||
} else {
|
||||
$s = strval($value);
|
||||
$arr = explode('.', $value);
|
||||
|
||||
$r = '0';
|
||||
if (!empty($arr[0])) {
|
||||
$r = number_format(intval($arr[0]), 0, '.', $this->thousandSeparator);
|
||||
}
|
||||
|
||||
if (!empty($arr[1])) {
|
||||
$r = $r . $this->decimalMark . $arr[1];
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +89,6 @@ return array (
|
||||
'adminItems' =>
|
||||
array (
|
||||
'devMode',
|
||||
'outboundEmailIsShared',
|
||||
'outboundEmailFromName',
|
||||
'outboundEmailFromAddress',
|
||||
'smtpServer',
|
||||
'smtpPort',
|
||||
'smtpAuth',
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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\Entities;
|
||||
|
||||
class Template extends \Espo\Core\ORM\Entity
|
||||
{
|
||||
|
||||
}
|
||||
@@ -43,10 +43,10 @@ class Download extends \Espo\Core\EntryPoints\Base
|
||||
|
||||
public function run()
|
||||
{
|
||||
$id = $_GET['id'];
|
||||
if (empty($id)) {
|
||||
if (empty($_GET['id'])) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
$id = $_GET['id'];
|
||||
|
||||
$attachment = $this->getEntityManager()->getEntity('Attachment', $id);
|
||||
|
||||
|
||||
@@ -30,13 +30,13 @@ use \Espo\Core\Exceptions\Error;
|
||||
class Image extends \Espo\Core\EntryPoints\Base
|
||||
{
|
||||
public static $authRequired = true;
|
||||
|
||||
|
||||
protected $allowedFileTypes = array(
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
);
|
||||
|
||||
|
||||
protected $imageSizes = array(
|
||||
'xxx-small' => array(18, 18),
|
||||
'xx-small' => array(32, 32),
|
||||
@@ -47,59 +47,58 @@ class Image extends \Espo\Core\EntryPoints\Base
|
||||
'x-large' => array(864, 864),
|
||||
'xx-large' => array(1024, 1024),
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
public function run()
|
||||
{
|
||||
if (empty($_GET['id'])) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$id = $_GET['id'];
|
||||
|
||||
|
||||
$size = null;
|
||||
if (!empty($_GET['size'])) {
|
||||
$size = $_GET['size'];
|
||||
}
|
||||
|
||||
|
||||
$this->show($id, $size);
|
||||
}
|
||||
|
||||
|
||||
protected function show($id, $size)
|
||||
{
|
||||
$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'));
|
||||
if ($parent && !$this->getAcl()->check($parent)) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$filePath = "data/upload/{$attachment->id}";
|
||||
|
||||
|
||||
$fileType = $attachment->get('type');
|
||||
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
|
||||
if (!in_array($fileType, $this->allowedFileTypes)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
|
||||
if (!empty($size)) {
|
||||
if (!empty($this->imageSizes[$size])) {
|
||||
$thumbFilePath = "data/upload/thumbs/{$attachment->id}_{$size}";
|
||||
|
||||
|
||||
if (!file_exists($thumbFilePath)) {
|
||||
$targetImage = $this->getThumbImage($filePath, $fileType, $size);
|
||||
ob_start();
|
||||
|
||||
|
||||
switch ($fileType) {
|
||||
case 'image/jpeg':
|
||||
imagejpeg($targetImage);
|
||||
@@ -117,12 +116,12 @@ class Image extends \Espo\Core\EntryPoints\Base
|
||||
$this->getContainer()->get('fileManager')->putContents($thumbFilePath, $contents);
|
||||
}
|
||||
$filePath = $thumbFilePath;
|
||||
|
||||
|
||||
} else {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!empty($size)) {
|
||||
$fileName = $attachment->id . '_' . $size . '.jpg';
|
||||
} else {
|
||||
@@ -143,12 +142,12 @@ class Image extends \Espo\Core\EntryPoints\Base
|
||||
readfile($filePath);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
protected function getThumbImage($filePath, $fileType, $size)
|
||||
{
|
||||
list($originalWidth, $originalHeight) = getimagesize($filePath);
|
||||
list($width, $height) = $this->imageSizes[$size];
|
||||
|
||||
|
||||
if ($originalWidth <= $width && $originalHeight <= $height) {
|
||||
$targetWidth = $originalWidth;
|
||||
$targetHeight = $originalHeight;
|
||||
@@ -169,7 +168,7 @@ class Image extends \Espo\Core\EntryPoints\Base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
|
||||
switch ($fileType) {
|
||||
case 'image/jpeg':
|
||||
@@ -189,8 +188,8 @@ class Image extends \Espo\Core\EntryPoints\Base
|
||||
imagecopyresampled($targetImage, $sourceImage, 0, 0, 0, 0, $targetWidth, $targetHeight, $originalWidth, $originalHeight);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return $targetImage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
use \Espo\Core\Exceptions\NotFound;
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
use \Espo\Core\Exceptions\BadRequest;
|
||||
use \Espo\Core\Htmlizer\Htmlizer;
|
||||
|
||||
|
||||
class Pdf extends \Espo\Core\EntryPoints\Base
|
||||
{
|
||||
public static $authRequired = true;
|
||||
|
||||
public function run()
|
||||
{
|
||||
|
||||
if (empty($_GET['entityId']) || empty($_GET['entityType']) || empty($_GET['templateId'])) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
$entityId = $_GET['entityId'];
|
||||
$entityType = $_GET['entityType'];
|
||||
$templateId = $_GET['templateId'];
|
||||
|
||||
$entity = $this->getEntityManager()->getEntity($entityType, $entityId);
|
||||
$template = $this->getEntityManager()->getEntity('Template', $templateId);
|
||||
|
||||
$this->getContainer()->get('serviceFactory')->create($entityType)->loadAdditionalFields($entity);
|
||||
|
||||
if (!$entity || !$template) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
if ($template->get('entityType') !== $entityType) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
if (!$this->getAcl()->check($entity, 'read') || !$this->getAcl()->check($template, 'read')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$fileName = $entity->get('name') . '.pdf';
|
||||
|
||||
$htmlizer = new Htmlizer($this->getFileManager(), $this->getDateTime(), $this->getNumber());
|
||||
|
||||
$pdf = new \Espo\Core\Pdf\Tcpdf();
|
||||
$pdf->setFont('freesans', '', 12, '', true);
|
||||
$pdf->setPrintHeader(false);
|
||||
|
||||
$pdf->setAutoPageBreak(true, $template->get('bottomMargin'));
|
||||
$pdf->setMargins($template->get('leftMargin'), $template->get('topMargin'), $template->get('rightMargin'));
|
||||
|
||||
|
||||
if ($template->get('printFooter')) {
|
||||
$htmlFooter = $htmlizer->render($entity, $template->get('footer'));
|
||||
$pdf->setFooterPosition($template->get('footerPosition'));
|
||||
$pdf->setFooterHtml($htmlFooter);
|
||||
} else {
|
||||
$pdf->setPrintFooter(false);
|
||||
}
|
||||
|
||||
$pdf->addPage();
|
||||
|
||||
$htmlHeader = $htmlizer->render($entity, $template->get('header'));
|
||||
$pdf->writeHTML($htmlHeader, true, false, true, false, '');
|
||||
|
||||
$htmlBody = $htmlizer->render($entity, $template->get('body'));
|
||||
$pdf->writeHTML($htmlBody, true, false, true, false, '');
|
||||
|
||||
$pdf->output($fileName);
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
@@ -27,16 +27,16 @@ use \Espo\ORM\Entity;
|
||||
class EmailReminder
|
||||
{
|
||||
protected $entityManager;
|
||||
|
||||
|
||||
protected $mailSender;
|
||||
|
||||
|
||||
protected $config;
|
||||
|
||||
|
||||
protected $dateTime;
|
||||
|
||||
|
||||
protected $language;
|
||||
|
||||
|
||||
|
||||
|
||||
public function __construct($entityManager, $mailSender, $config, $dateTime, $language)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
@@ -45,17 +45,17 @@ class EmailReminder
|
||||
$this->dateTime = $dateTime;
|
||||
$this->language = $language;
|
||||
}
|
||||
|
||||
|
||||
protected function getEntityManager()
|
||||
{
|
||||
return $this->entityManager;
|
||||
}
|
||||
|
||||
|
||||
protected function parseInvitationTemplate($contents, $entity, $user = null)
|
||||
{
|
||||
|
||||
|
||||
$contents = str_replace('{eventType}', strtolower($this->language->translate($entity->getEntityName(), 'scopeNames')), $contents);
|
||||
|
||||
|
||||
$preferences = $this->getEntityManager()->getEntity('Preferences', $user->id);
|
||||
$timezone = $preferences->get('timeZone');
|
||||
|
||||
@@ -103,7 +103,7 @@ class EmailReminder
|
||||
|
||||
return file_get_contents($fileName);
|
||||
}
|
||||
|
||||
|
||||
public function send(Entity $reminder)
|
||||
{
|
||||
$user = $this->getEntityManager()->getEntity('User', $reminder->get('userId'));
|
||||
@@ -123,7 +123,7 @@ class EmailReminder
|
||||
|
||||
$subject = $this->parseInvitationTemplate($subjectTpl, $entity, $user);
|
||||
$subject = str_replace(array("\n", "\r"), '', $subject);
|
||||
|
||||
|
||||
$body = $this->parseInvitationTemplate($bodyTpl, $entity, $user);
|
||||
|
||||
$email->set('subject', $subject);
|
||||
@@ -134,7 +134,7 @@ class EmailReminder
|
||||
$emailSender = $this->mailSender;
|
||||
|
||||
$emailSender->send($email);
|
||||
|
||||
|
||||
$this->getEntityManager()->removeEntity($email);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,8 +91,6 @@ class Meeting extends \Espo\Core\ORM\Repositories\RDB
|
||||
}
|
||||
|
||||
return $reminders;
|
||||
|
||||
$entity->set('reminders', $reminders);
|
||||
}
|
||||
|
||||
protected function afterSave(Entity $entity, array $options)
|
||||
|
||||
@@ -11,11 +11,14 @@
|
||||
"source": "Fuente",
|
||||
"publishDate": "Publicar Fecha",
|
||||
"expirationDate": "Fecha de Expiración",
|
||||
"description": "Descripción"
|
||||
"description": "Descripción",
|
||||
"folder": "Carpeta"
|
||||
},
|
||||
"links": {
|
||||
"accounts": "Cuentas",
|
||||
"opportunities": "Oportunidades"
|
||||
"opportunities": "Oportunidades",
|
||||
"accounts": "Cuentas",
|
||||
"folder": "Carpeta"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
[{"label":"","rows":[[{"name":"name"}],[{"name":"website"}],[{"name":"emailAddress"}],[{"name":"phoneNumber"}]]}]
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"website"}],
|
||||
[{"name":"emailAddress"}],
|
||||
[{"name":"phoneNumber"}],
|
||||
[{"name":"type"}, {"name":"industry"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
"createdAt",
|
||||
"emailAddress",
|
||||
"industry",
|
||||
"type",
|
||||
"name"
|
||||
"phoneNumber",
|
||||
"type"
|
||||
]
|
||||
@@ -3,8 +3,7 @@
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"direction"}],
|
||||
[{"name":"status"}, {"name":"direction"}],
|
||||
[{"name":"dateStart"}],
|
||||
[{"name":"duration"}],
|
||||
[{"name":"parent"}],
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
"label": "",
|
||||
"rows": [
|
||||
[{"name":"name"}],
|
||||
[{"name":"type"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"type"}, {"name":"status"}],
|
||||
[{"name":"endDate"}]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"priority"}],
|
||||
[{"name":"type"}],
|
||||
[{"name":"status"}, {"name":"priority"}],
|
||||
[{"name":"type"}, {"name":"number"}],
|
||||
[{"name":"account"}],
|
||||
[{"name":"description"}]
|
||||
]
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
[
|
||||
"account",
|
||||
"address",
|
||||
"assignedUser",
|
||||
"createdAt",
|
||||
"emailAddress",
|
||||
"phoneNumber",
|
||||
"title",
|
||||
"address",
|
||||
"targetLists"
|
||||
]
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
{
|
||||
"label": false,
|
||||
"rows": [
|
||||
[{"name":"source"}],
|
||||
[{"name":"file"}],
|
||||
[{"name":"file"}, {"name":"source"}],
|
||||
[{"name":"name"}],
|
||||
[{"name":"folder"}],
|
||||
[{"name":"type"}],
|
||||
[{"name":"status"}]
|
||||
[{"name":"status"}, {"name":"folder"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
{"name":"phoneNumber"}
|
||||
],
|
||||
[
|
||||
{"name":"status"}
|
||||
{"name":"accountName"}
|
||||
],
|
||||
[
|
||||
{"name":"status"}, {"name":"source"}
|
||||
],
|
||||
[
|
||||
{"name":"description"}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"status",
|
||||
"source",
|
||||
"opportunityAmountConverted",
|
||||
"phoneNumber",
|
||||
"targetLists",
|
||||
"teams",
|
||||
"createdAccount"
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
[{"label":"","rows":[[{"name":"name"}],[{"name":"account"}],[{"name":"stage"}],[{"name":"amount"}],[{"name":"closeDate"}]]}]
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name", "fullWidth": true}],
|
||||
[{"name":"account", "fullWidth": true}],
|
||||
[{"name":"stage"}, {"name":"closeDate"}],
|
||||
[{"name":"amount"}],
|
||||
[{"name":"description"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -3,8 +3,7 @@
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"priority"}],
|
||||
[{"name":"status"}, {"name":"priority"}],
|
||||
[{"name":"dateStart"}],
|
||||
[{"name":"dateEnd"}],
|
||||
[{"name":"parent"}],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"views":{
|
||||
"detail":"Crm:Account.Detail"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"views":{
|
||||
"detail":"Crm:Call.Detail"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"menu": {
|
||||
"list": {
|
||||
"buttons": [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"bottomPanels":{
|
||||
"detail":[
|
||||
]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"views":{
|
||||
"detail":"Crm:Contact.Detail"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"views": {
|
||||
"list": "Crm:Document.List"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"controller": "Controllers.RecordTree",
|
||||
"collection": "Collections.Tree",
|
||||
"controller": "controllers/record-tree",
|
||||
"collection": "collections/tree",
|
||||
"menu": {
|
||||
"listTree": {
|
||||
"buttons": [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Crm:Controllers.Lead",
|
||||
"controller": "crm:controllers/lead",
|
||||
"views":{
|
||||
"detail":"Crm:Lead.Detail"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"views":{
|
||||
"detail":"Crm:Meeting.Detail"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"views":{
|
||||
"detail":"Crm:Opportunity.Detail"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"views":{
|
||||
"detail":"Crm:Target.Detail"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"boolFilterList": ["onlyMy"],
|
||||
"sidePanels":{
|
||||
"detail":[
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"controller": "Controllers.Record",
|
||||
"controller": "controllers/record",
|
||||
"recordViews":{
|
||||
"list": "Crm:Task.Record.List",
|
||||
"detail": "Crm:Task.Record.Detail"
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.Calendar"}
|
||||
{
|
||||
"view":"Crm:Dashlets.Calendar",
|
||||
"aclScope": "Calendar"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.Calls"}
|
||||
{
|
||||
"view":"Crm:Dashlets.Calls",
|
||||
"aclScope": "Call"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.Cases"}
|
||||
{
|
||||
"view":"Crm:Dashlets.Cases",
|
||||
"aclScope": "Case"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.Leads"}
|
||||
{
|
||||
"view":"Crm:Dashlets.Leads",
|
||||
"aclScope": "Lead"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.Meetings"}
|
||||
{
|
||||
"view":"Crm:Dashlets.Meetings",
|
||||
"aclScope": "Meeting"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.Opportunities"}
|
||||
{
|
||||
"view":"Crm:Dashlets.Opportunities",
|
||||
"aclScope": "Opportunity"
|
||||
}
|
||||
|
||||
+4
-1
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.OpportunitiesByLeadSource"}
|
||||
{
|
||||
"view":"Crm:Dashlets.OpportunitiesByLeadSource",
|
||||
"aclScope": "Opportunity"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.OpportunitiesByStage"}
|
||||
{
|
||||
"view":"Crm:Dashlets.OpportunitiesByStage",
|
||||
"aclScope": "Opportunity"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.SalesByMonth"}
|
||||
{
|
||||
"view":"Crm:Dashlets.SalesByMonth",
|
||||
"aclScope": "Opportunity"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.SalesPipeline"}
|
||||
{
|
||||
"view":"Crm:Dashlets.SalesPipeline",
|
||||
"aclScope": "Opportunity"
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
{"view":"Crm:Dashlets.Tasks"}
|
||||
{
|
||||
"view":"Crm:Dashlets.Tasks",
|
||||
"aclScope": "Task"
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
"type": "text"
|
||||
},
|
||||
"parent": {
|
||||
"type": "linkParent"
|
||||
"type": "linkParent",
|
||||
"entityList": ["Account", "Lead", "Opportunity", "Case"]
|
||||
},
|
||||
"account": {
|
||||
"type": "link",
|
||||
@@ -170,7 +171,6 @@
|
||||
},
|
||||
"parent": {
|
||||
"type": "belongsToParent",
|
||||
"entityList": ["Account", "Lead", "Opportunity", "Case"],
|
||||
"foreign": "calls"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
"account": {
|
||||
"type": "link",
|
||||
"disabled": true
|
||||
},
|
||||
"parent": {
|
||||
"entityList": ["Account", "Lead", "Opportunity", "Case"]
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"account": {
|
||||
"type": "belongsTo",
|
||||
"entity": "Account"
|
||||
},
|
||||
"parent": {
|
||||
"entityList": ["Account", "Lead", "Opportunity", "Case"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
"type": "text"
|
||||
},
|
||||
"parent": {
|
||||
"type": "linkParent"
|
||||
"type": "linkParent",
|
||||
"entityList": ["Account", "Lead", "Opportunity", "Case"]
|
||||
},
|
||||
"account": {
|
||||
"type": "link",
|
||||
@@ -165,7 +166,6 @@
|
||||
},
|
||||
"parent": {
|
||||
"type": "belongsToParent",
|
||||
"entityList": ["Account", "Lead", "Opportunity", "Case"],
|
||||
"foreign": "meetings"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
"type": "text"
|
||||
},
|
||||
"parent": {
|
||||
"type": "linkParent"
|
||||
"type": "linkParent",
|
||||
"entityList": ["Account", "Contact", "Lead", "Opportunity", "Case"]
|
||||
},
|
||||
"account": {
|
||||
"type": "link",
|
||||
@@ -108,7 +109,6 @@
|
||||
},
|
||||
"parent": {
|
||||
"type": "belongsToParent",
|
||||
"entityList": ["Account", "Contact", "Lead", "Opportunity", "Case"],
|
||||
"foreign": "tasks"
|
||||
},
|
||||
"account": {
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"customizable": true,
|
||||
"stream": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
"module": "Crm",
|
||||
"customizable": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
"module": "Crm",
|
||||
"customizable": true,
|
||||
"stream": false,
|
||||
"importable": false
|
||||
"importable": false,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"customizable": true,
|
||||
"stream": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"customizable": true,
|
||||
"stream": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
"module": "Crm",
|
||||
"customizable": true,
|
||||
"importable": false,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"customizable": true,
|
||||
"stream": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
"module": "Crm",
|
||||
"customizable": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"customizable": true,
|
||||
"stream": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
"module": "Crm",
|
||||
"customizable": false,
|
||||
"importable": false,
|
||||
"notifications": false
|
||||
"notifications": false,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"customizable": false,
|
||||
"stream": false,
|
||||
"importable": false,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
"module": "Crm",
|
||||
"customizable": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
"notifications": true,
|
||||
"object": true
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ use \Espo\ORM\Entity;
|
||||
|
||||
class Campaign extends \Espo\Services\Record
|
||||
{
|
||||
protected function loadAdditionalFields($entity)
|
||||
public function loadAdditionalFields($entity)
|
||||
{
|
||||
parent::loadAdditionalFields($entity);
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class Meeting extends \Espo\Services\Record
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function loadAdditionalFields(Entity $entity)
|
||||
public function loadAdditionalFields(Entity $entity)
|
||||
{
|
||||
parent::loadAdditionalFields($entity);
|
||||
$this->loadRemindersField($entity);
|
||||
|
||||
@@ -26,7 +26,7 @@ use \Espo\ORM\Entity;
|
||||
|
||||
class TargetList extends \Espo\Services\Record
|
||||
{
|
||||
protected function loadAdditionalFields(Entity $entity)
|
||||
public function loadAdditionalFields(Entity $entity)
|
||||
{
|
||||
parent::loadAdditionalFields($entity);
|
||||
$this->loadEntryCountField($entity);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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\Modules\Crm\Services;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class Task extends \Espo\Services\Record
|
||||
{
|
||||
public function loadAdditionalFields(Entity $entity)
|
||||
{
|
||||
parent::loadAdditionalFields($entity);
|
||||
|
||||
if ($entity->id) {
|
||||
$this->loadAttachmentsTypes($entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadAttachmentsTypes(Entity $entity)
|
||||
{
|
||||
$types = new \stdClass();
|
||||
|
||||
$attachmentsIds = $entity->get('attachmentsIds');
|
||||
if (!empty($attachmentsIds)) {
|
||||
foreach ($attachmentsIds as $id) {
|
||||
$attachment = $this->getEntityManager()->getEntity('Attachment', $id);
|
||||
if ($attachment) {
|
||||
$types->$id = $attachment->get('type');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$entity->set('attachmentsTypes', $types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,9 +756,9 @@ abstract class Mapper implements IMapper
|
||||
|
||||
protected function prepareValueForInsert($type, $value) {
|
||||
if ($type == IEntity::JSON_ARRAY && is_array($value)) {
|
||||
$value = json_encode($value);
|
||||
$value = json_encode($value, \JSON_UNESCAPED_UNICODE);
|
||||
} else if ($type == IEntity::JSON_OBJECT && (is_array($value) || $value instanceof \stdClass)) {
|
||||
$value = json_encode($value);
|
||||
$value = json_encode($value, \JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
|
||||
@@ -161,13 +161,17 @@ class Email extends \Espo\Core\ORM\Repositories\RDB
|
||||
if (!empty($parentId) || !empty($parentType)) {
|
||||
$parent = $this->getEntityManager()->getEntity($parentType, $parentId);
|
||||
if (!empty($parent)) {
|
||||
if ($parent->getEntityName() == 'Account') {
|
||||
if ($parent->getEntityType() == 'Account') {
|
||||
$accountId = $parent->id;
|
||||
} else if ($parent->has('accountId')) {
|
||||
$accountId = $parent->get('accountId');
|
||||
}
|
||||
if (!empty($accountId)) {
|
||||
$entity->set('accountId', $accountId);
|
||||
$account = $this->getEntityManager()->getEntity('Account', $accountId);
|
||||
if ($account) {
|
||||
$entity->set('accountId', $accountId);
|
||||
$entity->set('accountName', $account->get('name'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@
|
||||
"previewSize": "Preview Size",
|
||||
"noEmptyString": "No Empty String",
|
||||
"defaultType": "Default Type",
|
||||
"seeMoreDisabled": "Disable Text Cut"
|
||||
"seeMoreDisabled": "Disable Text Cut",
|
||||
"entityList": "Entity List"
|
||||
},
|
||||
"messages": {
|
||||
"upgradeVersion": "Your EspoCRM will be upgraded to version <strong>{version}</strong>. This can take some time.",
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"Original message": "Original message",
|
||||
"Forwarded message": "Forwarded message",
|
||||
"Email Accounts": "Email Accounts",
|
||||
"Email Templates": "Email Templates",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send": "Send",
|
||||
"Email Address": "Email Address",
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
"monitoredFolders": "Monitored Folders",
|
||||
"ssl": "SSL",
|
||||
"fetchSince": "Fetch Since",
|
||||
"emailAddress": "Email Address"
|
||||
"emailAddress": "Email Address",
|
||||
"sentFolder": "Sent Folder",
|
||||
"storeSentEmails": "Store Sent Emails"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
@@ -30,6 +32,7 @@
|
||||
"connectionIsOk": "Connection is Ok"
|
||||
},
|
||||
"tooltips": {
|
||||
"monitoredFolders": "You can add 'Sent' folder to sync emails sent from external email client."
|
||||
"monitoredFolders": "You can add 'Sent' folder to sync emails sent from external email client.",
|
||||
"storeSentEmails": "Sent emails will be stored on IMAP server. Email Address should much address an email is being sent from."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
},
|
||||
"messages": {
|
||||
"entityCreated": "Entity has been created",
|
||||
"linkAlreadyExists": "Conflict: link already exists."
|
||||
"linkAlreadyExists": "Link name conflict."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"Dashboard": "Dashboard",
|
||||
"InboundEmail": "Inbound Email Account",
|
||||
"Stream": "Stream",
|
||||
"Import": "Import"
|
||||
"Import": "Import",
|
||||
"Template": "Template"
|
||||
},
|
||||
"scopeNamesPlural": {
|
||||
"Email": "Emails",
|
||||
@@ -31,7 +32,8 @@
|
||||
"Dashboard": "Dashboard",
|
||||
"InboundEmail": "Inbound Email Accounts",
|
||||
"Stream": "Stream",
|
||||
"Import": "Import Results"
|
||||
"Import": "Import Results",
|
||||
"Template": "Templates"
|
||||
},
|
||||
"labels": {
|
||||
"Misc": "Misc",
|
||||
@@ -157,7 +159,8 @@
|
||||
"List View": "List View",
|
||||
"Tree View": "Tree View",
|
||||
"Unlink All": "Unlink All",
|
||||
"Total": "Total"
|
||||
"Total": "Total",
|
||||
"Print to PDF": "Print to PDF"
|
||||
},
|
||||
"messages": {
|
||||
"pleaseWait": "Please wait...",
|
||||
|
||||
@@ -2,5 +2,10 @@
|
||||
"fields": {
|
||||
"post": "Post",
|
||||
"attachments": "Attachments"
|
||||
},
|
||||
"filters": {
|
||||
"all": "All",
|
||||
"posts": "Posts",
|
||||
"updates": "Updates"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Name",
|
||||
"body": "Body",
|
||||
"entityType": "Entity Type",
|
||||
"header": "Header",
|
||||
"footer": "Footer",
|
||||
"leftMargin": "Left Margin",
|
||||
"topMargin": "Top Margin",
|
||||
"rightMargin": "Right Margin",
|
||||
"bottomMargin": "Bottom Margin",
|
||||
"printFooter": "Print Footer",
|
||||
"footerPosition": "Footer Position"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"labels": {
|
||||
"Create Template": "Create Template"
|
||||
},
|
||||
"tooltips": {
|
||||
"footer": "Use {pageNumber} to print page number."
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
"roles": "Roles",
|
||||
"teamRole": "Position",
|
||||
"password": "Password",
|
||||
"currentPassword": "Current Password",
|
||||
"passwordConfirm": "Confirm Password",
|
||||
"newPassword": "New Password",
|
||||
"newPasswordConfirm": "Confirm New Password",
|
||||
|
||||
@@ -218,11 +218,11 @@
|
||||
"emailReceivedInitialThis": "Email {email} has been received and created this {entityType}"
|
||||
},
|
||||
"lists": {
|
||||
"monthNames": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
"monthNamesShort": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
"dayNames": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
||||
"dayNamesShort": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
"dayNamesMin": ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
|
||||
"monthNames": ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "ноябрь", "Декабрь"],
|
||||
"monthNamesShort": ["Янв", "Февр", "Март", "Апр", "Май", "Июнь", "Июль", "Авг", "Сент", "Окт", "Нояб", "Дек"],
|
||||
"dayNames": ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"],
|
||||
"dayNamesShort": ["Вскр", "Пнд", "Вт", "Ср", "Чтв", "Птн", "Сб"],
|
||||
"dayNamesMin": ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"]
|
||||
},
|
||||
"options": {
|
||||
"salutationName": {
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
[
|
||||
{"name":"monitoredFolders"},{"name":"password"}
|
||||
],
|
||||
[{"name": "testConnection", "customLabel": null, "view": "EmailAccount.Fields.TestConnection"}]
|
||||
[
|
||||
{"name": "testConnection", "customLabel": null, "view": "EmailAccount.Fields.TestConnection"}, false
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[
|
||||
{
|
||||
"name":"name"
|
||||
}
|
||||
},
|
||||
false
|
||||
],
|
||||
[{"name":"subject","fullWidth":true}],
|
||||
[
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[
|
||||
{"name": "name", "width": 90, "link": true}
|
||||
]
|
||||
@@ -11,7 +11,8 @@
|
||||
{"name":"replyToAddress"}
|
||||
],
|
||||
[
|
||||
{"name":"assignToUser"}
|
||||
{"name":"assignToUser"},
|
||||
false
|
||||
]
|
||||
]
|
||||
},
|
||||
@@ -27,7 +28,7 @@
|
||||
[
|
||||
{"name":"monitoredFolders"},{"name":"password"}
|
||||
],
|
||||
[{"name": "testConnection", "customLabel": null, "view": "InboundEmail.Fields.TestConnection"}]
|
||||
[{"name": "testConnection", "customLabel": null, "view": "InboundEmail.Fields.TestConnection"}, false]
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"rows": [
|
||||
[{"name": "dateFormat"}, {"name": "timeFormat"}],
|
||||
[{"name": "timeZone"}, {"name": "weekStart"}],
|
||||
[{"name": "defaultCurrency"}],
|
||||
[{"name": "defaultCurrency"}, false],
|
||||
[{"name": "thousandSeparator"}, {"name": "decimalMark"}],
|
||||
[{"name": "language"}]
|
||||
[{"name": "language"}, false]
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -15,12 +15,12 @@
|
||||
[
|
||||
{
|
||||
"name": "smtpEmailAddress"
|
||||
}
|
||||
}, false
|
||||
],
|
||||
[{"name": "smtpServer"}, {"name": "smtpPort"}],
|
||||
[{"name": "smtpAuth"}, {"name": "smtpSecurity"}],
|
||||
[{"name": "smtpUsername"}, {"name": "testSend", "customLabel": null, "view": "Preferences.Fields.TestSend"}],
|
||||
[{"name": "smtpPassword"}]
|
||||
[{"name": "smtpPassword"}, false]
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
"label": "Notifications",
|
||||
"rows": [
|
||||
[{"name": "receiveAssignmentEmailNotifications"}]
|
||||
[{"name": "receiveAssignmentEmailNotifications"}, false]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
[{"name": "smtpServer"}, {"name": "smtpPort"}],
|
||||
[{"name": "smtpAuth"}, {"name": "smtpSecurity"}],
|
||||
[{"name": "smtpUsername"}, {"name": "testSend", "customLabel": null, "view": "OutboundEmail.Fields.TestSend"}],
|
||||
[{"name": "smtpPassword"}]
|
||||
[{"name": "smtpPassword"}, false]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Configuration",
|
||||
"rows": [
|
||||
[{"name": "outboundEmailFromAddress"}, {"name": "outboundEmailIsShared"}],
|
||||
[{"name": "outboundEmailFromName"}]
|
||||
[{"name": "outboundEmailFromName"}, false]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"rows": [
|
||||
[{"name": "useCache"},{"name": "companyLogo"}],
|
||||
[{"name": "disableExport"},{"name": "globalSearchEntityList"}],
|
||||
[{"name": "followCreatedEntities"}]
|
||||
[{"name": "followCreatedEntities"}, false]
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -13,7 +13,7 @@
|
||||
[{"name": "dateFormat"}, {"name": "timeZone"}],
|
||||
[{"name": "timeFormat"}, {"name": "weekStart"}],
|
||||
[{"name": "thousandSeparator"}, {"name": "decimalMark"}],
|
||||
[{"name": "language"}]
|
||||
[{"name": "language"}, false]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[
|
||||
{
|
||||
"name":"name"
|
||||
},
|
||||
{
|
||||
"name":"entityType"
|
||||
}
|
||||
],
|
||||
[{"name":"variables","fullWidth":true,"customLabel":"","view": "Template.Fields.Variables"}],
|
||||
[{"name":"header","fullWidth":true}],
|
||||
[{"name":"body","fullWidth":true}],
|
||||
[{"name":"topMargin"}, false],
|
||||
[{"name":"leftMargin"}, {"name":"rightMargin"}],
|
||||
[{"name":"bottomMargin"}, false],
|
||||
[{"name":"printFooter"}, false],
|
||||
[{"name":"footer","fullWidth":true}],
|
||||
[{"name":"footerPosition"}, false]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"entityType"}, false],
|
||||
[{"name":"header","fullWidth":true}],
|
||||
[{"name":"body","fullWidth":true}]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,3 @@
|
||||
[
|
||||
"entityType"
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
{"name": "name", "width": 50, "link": true},
|
||||
{"name": "entityType"}
|
||||
]
|
||||
@@ -4,8 +4,9 @@
|
||||
"rows": [
|
||||
[{"name":"name"}],
|
||||
[{"name":"userName"}],
|
||||
[{"name":"isAdmin"}],
|
||||
[{"name":"emailAddress"}]
|
||||
[{"name":"teams"}, {"name":"isAdmin"}],
|
||||
[{"name":"emailAddress"}],
|
||||
[{"name":"phoneNumber"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user