mirror of
https://github.com/espocrm/espocrm.git
synced 2026-03-10 07:07:02 +00:00
Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28eafdbc6c | ||
|
|
0036ab1ed2 | ||
|
|
30b246f67c | ||
|
|
1063aa74dd | ||
|
|
0a2469aaa4 | ||
|
|
e7e15a32bf | ||
|
|
fc3fa53dba | ||
|
|
4604f27176 | ||
|
|
b7b118c122 | ||
|
|
ea2934129a | ||
|
|
ba2d72dff9 | ||
|
|
7312988057 | ||
|
|
de12418a8f | ||
|
|
b4c7075331 | ||
|
|
355ec4398f | ||
|
|
2c681ede52 | ||
|
|
cb2df7b6a2 | ||
|
|
f2a5474b4a | ||
|
|
1fc8921a18 | ||
|
|
0458544bbb | ||
|
|
c09c4b2035 | ||
|
|
176c77ec96 | ||
|
|
7b032802e9 | ||
|
|
8a7a317252 | ||
|
|
3ef01a4639 | ||
|
|
e27edf5b0d | ||
|
|
fe0f5b3886 | ||
|
|
9836517c6c | ||
|
|
c143ba47d2 | ||
|
|
64a8ccf787 | ||
|
|
31eafca88f | ||
|
|
80e440c875 | ||
|
|
92451934af | ||
|
|
7e2ad2ae94 | ||
|
|
c410e47d6b | ||
|
|
7bb3780277 | ||
|
|
d734b8b3d2 | ||
|
|
2acc245100 | ||
|
|
fac477330c | ||
|
|
7993a65939 | ||
|
|
1285008af7 | ||
|
|
a67d43edbb | ||
|
|
d326925e06 | ||
|
|
13d65c7535 | ||
|
|
e5762b96d2 | ||
|
|
180983940e | ||
|
|
31f36caffa | ||
|
|
6f76efee36 | ||
|
|
44792d1a35 | ||
|
|
3f824be525 | ||
|
|
fbed072a80 | ||
|
|
f92da57b4d | ||
|
|
9059ce615f | ||
|
|
c13cc2a798 | ||
|
|
17bf3b017f | ||
|
|
9e04d2f2f0 | ||
|
|
98e998dc34 | ||
|
|
3155947795 | ||
|
|
fa6f471be9 | ||
|
|
865f87018a | ||
|
|
8da5ba8961 | ||
|
|
9842ebcc4a | ||
|
|
787d47c2aa | ||
|
|
ee3cbc2358 | ||
|
|
87caba2646 | ||
|
|
c45b614270 | ||
|
|
eccef0b92f | ||
|
|
f9b68fcbba | ||
|
|
776acd9b64 | ||
|
|
60b11cb11e | ||
|
|
defa3b5cfc | ||
|
|
f89ff39dbb | ||
|
|
6284b56718 | ||
|
|
5d78730dde | ||
|
|
bfba129846 | ||
|
|
b48bf2685c | ||
|
|
c5549000b4 | ||
|
|
fe88d10e35 | ||
|
|
4dd85eb97d | ||
|
|
245e99ef9f | ||
|
|
3478cf2d8c | ||
|
|
da1feee303 | ||
|
|
9fdd0b9a86 | ||
|
|
d4f2975f0d | ||
|
|
47ce2f587e | ||
|
|
0a25c0dbc2 | ||
|
|
7aeaa153ae | ||
|
|
5c4afa8a23 | ||
|
|
0a7e442194 | ||
|
|
6b8a05cd4e | ||
|
|
946a7a65f7 | ||
|
|
b68946375f | ||
|
|
463299c3ab | ||
|
|
34f81f4831 | ||
|
|
72ba8892b7 | ||
|
|
3ece40f9de | ||
|
|
f392c1da04 | ||
|
|
589b8f3210 | ||
|
|
ff6fd2698d | ||
|
|
6b22c8e370 | ||
|
|
340eb6d004 | ||
|
|
071e5fb85d | ||
|
|
a21469846b | ||
|
|
32ce8629a1 | ||
|
|
93be4a43d0 | ||
|
|
e21f5daa59 | ||
|
|
5cae7dff68 | ||
|
|
4cd08fc8ad | ||
|
|
c065b95f48 | ||
|
|
23d0620890 | ||
|
|
620510b6cd | ||
|
|
31690f2199 | ||
|
|
3972269738 |
@@ -4,5 +4,7 @@ RedirectMatch 403 \.config$
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteRule .* - [E=HTTP_ESPO_CGI_AUTH:%{HTTP:Authorization}]
|
||||
|
||||
RewriteRule reset/?$ reset.html [QSA,L]
|
||||
</IfModule>
|
||||
35
Gruntfile.js
35
Gruntfile.js
@@ -134,6 +134,7 @@ module.exports = function (grunt) {
|
||||
'vendor/**',
|
||||
'bootstrap.php',
|
||||
'cron.php',
|
||||
'rebuild.php',
|
||||
'index.php',
|
||||
'LICENSE.txt',
|
||||
'.htaccess',
|
||||
@@ -146,9 +147,30 @@ module.exports = function (grunt) {
|
||||
dot: true,
|
||||
src: '**',
|
||||
cwd: 'build/tmp',
|
||||
dest: 'build/EspoCRM-<%= pkg.espoVersion %>/',
|
||||
dest: 'build/EspoCRM-<%= pkg.version %>/',
|
||||
},
|
||||
},
|
||||
chmod: {
|
||||
options: {
|
||||
mode: '755'
|
||||
},
|
||||
php: {
|
||||
options: {
|
||||
mode: '644'
|
||||
},
|
||||
src: [
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.php',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.json',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.config',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/.htaccess',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.js',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.css',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.tpl',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.html',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.txt',
|
||||
]
|
||||
}
|
||||
},
|
||||
replace: {
|
||||
timestamp: {
|
||||
options: {
|
||||
@@ -171,7 +193,7 @@ module.exports = function (grunt) {
|
||||
patterns: [
|
||||
{
|
||||
match: 'version',
|
||||
replacement: '<%= pkg.espoVersion %>'
|
||||
replacement: '<%= pkg.version %>'
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -186,12 +208,12 @@ module.exports = function (grunt) {
|
||||
compress: {
|
||||
final: {
|
||||
options: {
|
||||
archive: 'build/EspoCRM-<%= pkg.espoVersion %>.zip',
|
||||
archive: 'build/EspoCRM-<%= pkg.version %>.zip',
|
||||
mode: 'zip'
|
||||
},
|
||||
src: ['**'],
|
||||
cwd: 'build/EspoCRM-<%= pkg.espoVersion %>',
|
||||
dest: 'EspoCRM-<%= pkg.espoVersion %>'
|
||||
cwd: 'build/EspoCRM-<%= pkg.version %>',
|
||||
dest: 'EspoCRM-<%= pkg.version %>'
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -204,6 +226,7 @@ module.exports = function (grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-replace');
|
||||
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||
grunt.loadNpmTasks('grunt-chmod');
|
||||
|
||||
grunt.registerTask('default', [
|
||||
'clean:start',
|
||||
@@ -217,8 +240,8 @@ module.exports = function (grunt) {
|
||||
'copy:backend',
|
||||
'replace',
|
||||
'copy:final',
|
||||
'chmod',
|
||||
'clean:final',
|
||||
//'compress',
|
||||
]);
|
||||
|
||||
};
|
||||
|
||||
@@ -6,5 +6,7 @@ RewriteEngine On
|
||||
#
|
||||
# RewriteBase /
|
||||
|
||||
RewriteRule .* - [E=HTTP_ESPO_CGI_AUTH:%{HTTP:Authorization}]
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [QSA,L]
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
namespace Espo\Controllers;
|
||||
|
||||
use \Espo\Core\Exceptions\BadRequest;
|
||||
|
||||
class App extends \Espo\Core\Controllers\Record
|
||||
{
|
||||
public function actionUser()
|
||||
@@ -29,7 +31,20 @@ class App extends \Espo\Core\Controllers\Record
|
||||
return array(
|
||||
'user' => $this->getUser()->toArray(),
|
||||
'acl' => $this->getAcl()->toArray(),
|
||||
'preferences' => $this->getPreferences()->toArray()
|
||||
'preferences' => $this->getPreferences()->toArray(),
|
||||
'token' => $this->getUser()->get('token')
|
||||
);
|
||||
}
|
||||
|
||||
public function actionDestroyAuthToken($params, $data)
|
||||
{
|
||||
$token = $data['token'];
|
||||
if (empty($token)) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$auth = new \Espo\Core\Utils\Auth($this->getContainer());
|
||||
return $auth->destroyAuthToken($token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,12 @@ class FieldManager extends \Espo\Core\Controllers\Base
|
||||
$fieldManager = $this->getContainer()->get('fieldManager');
|
||||
$fieldManager->create($data['name'], $data, $params['scope']);
|
||||
|
||||
$this->getContainer()->get('dataManager')->rebuild($params['scope']);
|
||||
try {
|
||||
$this->getContainer()->get('dataManager')->rebuild($params['scope']);
|
||||
} catch (Error $e) {
|
||||
$fieldManager->delete($data['name'], $params['scope']);
|
||||
throw new Error($e->getMessage());
|
||||
}
|
||||
|
||||
return $fieldManager->read($data['name'], $params['scope']);
|
||||
}
|
||||
|
||||
@@ -23,12 +23,27 @@
|
||||
namespace Espo\Controllers;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
|
||||
class Settings extends \Espo\Core\Controllers\Base
|
||||
{
|
||||
public function actionRead($params, $data)
|
||||
protected function getConfigData()
|
||||
{
|
||||
return $this->getConfig()->getData($this->getUser()->isAdmin());
|
||||
$data = $this->getConfig()->getData($this->getUser()->isAdmin());
|
||||
|
||||
$fieldDefs = $this->getMetadata()->get('entityDefs.Settings.fields');
|
||||
|
||||
foreach ($fieldDefs as $field => $d) {
|
||||
if ($d['type'] == 'password') {
|
||||
unset($data[$field]);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function actionRead($params, $data)
|
||||
{
|
||||
return $this->getConfigData();
|
||||
}
|
||||
|
||||
public function actionUpdate($params, $data)
|
||||
@@ -37,12 +52,16 @@ class Settings extends \Espo\Core\Controllers\Base
|
||||
}
|
||||
|
||||
public function actionPatch($params, $data)
|
||||
{
|
||||
$result = $this->getConfig()->setData($data, $this->getUser()->isAdmin());
|
||||
if ($result === false) {
|
||||
throw new Error('Cannot save settings');
|
||||
}
|
||||
{
|
||||
if (!$this->getUser()->isAdmin()) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$result = $this->getConfig()->setData($data, $this->getUser()->isAdmin());
|
||||
if ($result === false) {
|
||||
throw new Error('Cannot save settings');
|
||||
}
|
||||
|
||||
return $this->getConfig()->getData($this->getUser()->isAdmin());
|
||||
return $this->getConfigData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,4 +48,10 @@ class User extends \Espo\Core\Controllers\Record
|
||||
|
||||
return $acl->toArray();
|
||||
}
|
||||
|
||||
public function actionChangeOwnPassword($params, $data)
|
||||
{
|
||||
return $this->getService('User')->changePassword($this->getUser()->id, $data['password']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ class Acl
|
||||
|
||||
if ($config && $config->get('useCache') && file_exists($this->cacheFile)) {
|
||||
$cached = include $this->cacheFile;
|
||||
$this->data = $cached;
|
||||
$this->initSolid();
|
||||
} else {
|
||||
$this->load();
|
||||
$this->initSolid();
|
||||
@@ -62,7 +64,6 @@ class Acl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function checkScope($scope, $action = null, $isOwner = null, $inTeam = null)
|
||||
@@ -217,6 +218,11 @@ class Acl
|
||||
'edit' => 'no',
|
||||
'delete' => 'no',
|
||||
);
|
||||
$this->data['Note'] = array(
|
||||
'read' => 'all',
|
||||
'edit' => 'own',
|
||||
'delete' => 'own',
|
||||
);
|
||||
}
|
||||
|
||||
private function merge($tables)
|
||||
|
||||
@@ -128,6 +128,15 @@ class Application
|
||||
$cronManager = new \Espo\Core\CronManager($this->container);
|
||||
$cronManager->run();
|
||||
}
|
||||
|
||||
public function runRebuild()
|
||||
{
|
||||
$auth = $this->getAuth();
|
||||
$auth->useNoAuth(true);
|
||||
|
||||
$dataManager = $this->getContainer()->get('dataManager');
|
||||
$dataManager->rebuild();
|
||||
}
|
||||
|
||||
public function isInstalled()
|
||||
{
|
||||
|
||||
@@ -76,9 +76,7 @@ class Container
|
||||
private function loadFileManager()
|
||||
{
|
||||
return new \Espo\Core\Utils\File\Manager(
|
||||
array(
|
||||
'defaultPermissions' => $this->get('config')->get('defaultPermissions'),
|
||||
)
|
||||
$this->get('config')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class DataManager
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rebuild($entityList = array())
|
||||
public function rebuild($entityList = null)
|
||||
{
|
||||
$result = $this->clearCache();
|
||||
|
||||
@@ -78,7 +78,7 @@ class DataManager
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rebuildDatabase($entityList = array())
|
||||
public function rebuildDatabase($entityList = null)
|
||||
{
|
||||
try {
|
||||
$result = $this->getContainer()->get('schema')->rebuild($entityList);
|
||||
|
||||
@@ -31,7 +31,9 @@ class Person extends \Espo\Core\ORM\Entity
|
||||
$this->setValue('lastName', $value);
|
||||
|
||||
$firstName = $this->get('firstName');
|
||||
if (!empty($firstName)) {
|
||||
if (empty($firstName)) {
|
||||
$this->setValue('name', $value);
|
||||
} else {
|
||||
$this->setValue('name', $firstName . ' ' . $value);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +43,9 @@ class Person extends \Espo\Core\ORM\Entity
|
||||
$this->setValue('firstName', $value);
|
||||
|
||||
$lastName = $this->get('lastName');
|
||||
if (!empty($lastName)) {
|
||||
if (empty($lastName)) {
|
||||
$this->setValue('name', $value);
|
||||
} else {
|
||||
$this->setValue('name', $value . ' ' . $lastName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ class EntityManager
|
||||
|
||||
$params = array(
|
||||
'host' => $config->get('database.host'),
|
||||
'port' => $config->get('database.port'),
|
||||
'dbname' => $config->get('database.dbname'),
|
||||
'user' => $config->get('database.user'),
|
||||
'password' => $config->get('database.password'),
|
||||
|
||||
@@ -178,50 +178,9 @@ class RDB extends \Espo\ORM\Repositories\RDB implements Injectable
|
||||
}
|
||||
|
||||
protected function handleEmailAddressSave(Entity $entity)
|
||||
{
|
||||
if ($entity->hasRelation('emailAddresses') && $entity->hasField('emailAddress')) {
|
||||
$email = $entity->get('emailAddress');
|
||||
$pdo = $this->getPDO();
|
||||
|
||||
$emailAddressRepository = $this->getEntityManager()->getRepository('EmailAddress');
|
||||
|
||||
if (!empty($email)) {
|
||||
if ($email != $entity->getFetched('emailAddress')) {
|
||||
|
||||
$emailAddressNew = $emailAddressRepository->where(array('lower' => strtolower($email)))->findOne();
|
||||
$isNewEmailAddress = false;
|
||||
if (!$emailAddressNew) {
|
||||
$emailAddressNew = $emailAddressRepository->get();
|
||||
$emailAddressNew->set('name', $email);
|
||||
$emailAddressRepository->save($emailAddressNew);
|
||||
$isNewEmailAddress = true;
|
||||
}
|
||||
|
||||
$emailOld = $entity->getFetched('emailAddress');
|
||||
if (!empty($emailOld)) {
|
||||
$emailAddressOld = $emailAddressRepository->where(array('lower' => strtolower($emailOld)))->findOne();
|
||||
$this->unrelate($entity, 'emailAddresses', $emailAddressOld);
|
||||
}
|
||||
$this->relate($entity, 'emailAddresses', $emailAddressNew);
|
||||
|
||||
$query = "
|
||||
UPDATE entity_email_address
|
||||
SET `primary` = 1
|
||||
WHERE
|
||||
entity_id = ".$pdo->quote($entity->id)." AND
|
||||
entity_type = ".$pdo->quote($this->entityName)." AND
|
||||
email_address_id = ".$pdo->quote($emailAddressNew->id)."
|
||||
";
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
}
|
||||
} else {
|
||||
$emailOld = $entity->getFetched('emailAddress');
|
||||
if (!empty($emailOld)) {
|
||||
$emailAddressOld = $emailAddressRepository->where(array('lower' => strtolower($emailOld)))->findOne();
|
||||
$this->unrelate($entity, 'emailAddresses', $emailAddressOld);
|
||||
}
|
||||
}
|
||||
{
|
||||
if ($entity->hasRelation('emailAddresses') && $entity->hasField('emailAddress')) {
|
||||
$emailAddressRepository = $this->getEntityManager()->getRepository('EmailAddress')->storeEntityEmailAddress($entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ class Base
|
||||
return $part;
|
||||
}
|
||||
|
||||
protected function getBoolFilterWhere($filterName, $entityName)
|
||||
protected function getBoolFilterWhere($filterName)
|
||||
{
|
||||
$method = 'getBoolFilterWhere' . ucfirst($filterName);
|
||||
if (method_exists($this, $method)) {
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
namespace Espo\Core;
|
||||
|
||||
use Espo\Core\Exceptions\Error;
|
||||
|
||||
class UpgradeManager extends Upgrades\Base
|
||||
{
|
||||
protected $packagePath = 'data/upload/upgrades';
|
||||
@@ -31,6 +33,4 @@ class UpgradeManager extends Upgrades\Base
|
||||
'after' => 'AfterUpgrade',
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -255,7 +255,7 @@ abstract class Base
|
||||
return;
|
||||
}
|
||||
|
||||
$beforeInstallScript = Util::concatPath( array($upgradePath, $this->paths['scripts'], $scriptName) );
|
||||
$beforeInstallScript = Util::concatPath( array($upgradePath, $this->paths['scripts'], $scriptName) ) . '.php';
|
||||
|
||||
if (file_exists($beforeInstallScript)) {
|
||||
require_once($beforeInstallScript);
|
||||
|
||||
@@ -51,9 +51,12 @@ class Auth extends \Slim\Middleware
|
||||
|
||||
$espoAuth = $req->headers('HTTP_ESPO_AUTHORIZATION');
|
||||
if (isset($espoAuth)) {
|
||||
$credentials = explode(':', base64_decode($espoAuth));
|
||||
$authUsername = $credentials[0];
|
||||
$authPassword = $credentials[1];
|
||||
list($authUsername, $authPassword) = explode(':', base64_decode($espoAuth));
|
||||
}
|
||||
|
||||
$espoCgiAuth = $req->headers('HTTP_ESPO_CGI_AUTH');
|
||||
if ( !isset($authUsername) && !isset($authPassword) && isset($espoCgiAuth) ) {
|
||||
list($authUsername, $authPassword) = explode(':' , base64_decode(substr($espoCgiAuth, 6)));
|
||||
}
|
||||
|
||||
if (is_null($this->authRequired)) {
|
||||
|
||||
@@ -51,21 +51,59 @@ class Auth
|
||||
{
|
||||
$GLOBALS['log']->debug('AUTH: Try to authenticate');
|
||||
|
||||
$hash = md5($password);
|
||||
|
||||
$entityManager = $this->container->get('entityManager');
|
||||
|
||||
$authToken = $entityManager->getRepository('AuthToken')->where(array('token' => $password))->findOne();
|
||||
if ($authToken) {
|
||||
$hash = $authToken->get('hash');
|
||||
}
|
||||
|
||||
$user = $entityManager->getRepository('User')->findOne(array(
|
||||
'whereClause' => array(
|
||||
'userName' => $username,
|
||||
'password' => md5($password)
|
||||
'password' => $hash
|
||||
),
|
||||
));
|
||||
|
||||
if ($user instanceof \Espo\Entities\User) {
|
||||
if ($user) {
|
||||
$entityManager->setUser($user);
|
||||
$this->container->setUser($user);
|
||||
$GLOBALS['log']->debug('AUTH: Result of authenticate is [true]');
|
||||
|
||||
if (!$authToken) {
|
||||
$authToken = $entityManager->getEntity('AuthToken');
|
||||
$token = $this->createToken($user);
|
||||
$authToken->set('token', $token);
|
||||
$authToken->set('hash', $user->get('password'));
|
||||
$authToken->set('ipAddress', $_SERVER['REMOTE_ADDR']);
|
||||
$authToken->set('userId', $user->id);
|
||||
}
|
||||
|
||||
$authToken->set('lastAccess', date('Y-m-d H:i:s'));
|
||||
|
||||
$entityManager->saveEntity($authToken);
|
||||
$user->set('token', $authToken->get('token'));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function createToken($user)
|
||||
{
|
||||
return md5(uniqid($user->get('password')));
|
||||
}
|
||||
|
||||
public function destroyAuthToken($token)
|
||||
{
|
||||
$entityManager = $this->container->get('entityManager');
|
||||
|
||||
$authToken = $entityManager->getRepository('AuthToken')->where(array('token' => $token))->findOne();
|
||||
if ($authToken) {
|
||||
$entityManager->removeEntity($authToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ class Config
|
||||
*/
|
||||
private $defaultConfigPath = 'application/Espo/Core/defaults/config.php';
|
||||
|
||||
private $systemConfigPath = 'application/Espo/Core/defaults/systemConfig.php';
|
||||
|
||||
protected $configPath = 'data/config.php';
|
||||
|
||||
private $cacheTimestamp = 'cacheTimestamp';
|
||||
@@ -153,6 +155,9 @@ class Config
|
||||
|
||||
$this->configData = $this->getFileManager()->getContents($configPath);
|
||||
|
||||
$systemConfig = $this->getFileManager()->getContents($this->systemConfigPath);
|
||||
$this->configData = Util::merge($systemConfig, $this->configData);
|
||||
|
||||
return $this->configData;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class Converter
|
||||
}
|
||||
|
||||
|
||||
public function getSchemaFromMetadata($entityList = array())
|
||||
public function getSchemaFromMetadata($entityList = null)
|
||||
{
|
||||
$ormMeta = $this->getMetadata()->getOrmMetadata();
|
||||
$entityDefs = $this->getMetadata()->get('entityDefs');
|
||||
|
||||
@@ -31,4 +31,9 @@ class JsonArray extends \Doctrine\DBAL\Types\JsonArrayType
|
||||
return self::JSON_ARRAY;
|
||||
}
|
||||
|
||||
public static function getDbTypeName()
|
||||
{
|
||||
return 'TEXT';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,10 @@ class Email extends \Espo\Core\Utils\Database\Orm\Base
|
||||
),
|
||||
'orderBy' => 'email_address.name {direction}',
|
||||
),
|
||||
$field['name'] .'Data' => array(
|
||||
'type' => 'text',
|
||||
'notStorable' => true
|
||||
),
|
||||
),
|
||||
'relations' => array(
|
||||
$field['name'].'es' => array(
|
||||
@@ -69,4 +73,4 @@ class Email extends \Espo\Core\Utils\Database\Orm\Base
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +49,4 @@ class EmailEmailAddress extends \Espo\Core\Utils\Database\Orm\Relations\HasMany
|
||||
return $relation;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014 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\Database\Orm\Relations;
|
||||
|
||||
class NoteAttachments extends \Espo\Core\Utils\Database\Orm\Relations\HasChildren
|
||||
{
|
||||
public function load($params, $foreignParams)
|
||||
{
|
||||
$parentRelation = parent::load($params, $foreignParams);
|
||||
$relation = array(
|
||||
$params['entityName'] => array (
|
||||
'fields' => array(
|
||||
$params['link']['name'].'Types' => array(
|
||||
'type' => 'varchar',
|
||||
'notStorable' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$relation = \Espo\Core\Utils\Util::merge($parentRelation, $relation);
|
||||
return $relation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ class Converter
|
||||
}
|
||||
|
||||
|
||||
public function process(array $ormMeta, $entityDefs, $entityList = array())
|
||||
public function process(array $ormMeta, $entityDefs, $entityList = null)
|
||||
{
|
||||
$GLOBALS['log']->debug('Schema\Converter - Start: building schema');
|
||||
|
||||
@@ -97,7 +97,7 @@ class Converter
|
||||
unset($ormMeta['unset']);
|
||||
} //END: unset some keys in orm
|
||||
|
||||
if (!empty($entityList)) {
|
||||
if (isset($entityList)) {
|
||||
$entityList = is_string($entityList) ? (array) $entityList : $entityList;
|
||||
|
||||
$dependentEntities = $this->getDependentEntities($entityList, $ormMeta);
|
||||
@@ -203,7 +203,6 @@ class Converter
|
||||
}
|
||||
//END: check and create columns/tables for relations
|
||||
|
||||
|
||||
$GLOBALS['log']->debug('Schema\Converter - End: building schema');
|
||||
|
||||
return $schema;
|
||||
|
||||
@@ -181,7 +181,7 @@ class Schema
|
||||
/*
|
||||
* Rebuild database schema
|
||||
*/
|
||||
public function rebuild($entityList = array())
|
||||
public function rebuild($entityList = null)
|
||||
{
|
||||
if ($this->getConverter()->process() === false) {
|
||||
return false;
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
namespace Espo\Core\Utils;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
use \Espo\Core\Exceptions\Error,
|
||||
\Espo\Core\Exceptions\Conflict;
|
||||
|
||||
class FieldManager
|
||||
{
|
||||
@@ -74,7 +75,7 @@ class FieldManager
|
||||
{
|
||||
$existingField = $this->getFieldDef($name, $scope);
|
||||
if (isset($existingField)) {
|
||||
throw new Error('Field ['.$name.'] exists in '.$scope);
|
||||
throw new Conflict('Field ['.$name.'] exists in '.$scope);
|
||||
}
|
||||
|
||||
return $this->update($name, $fieldDef, $scope);
|
||||
|
||||
@@ -29,9 +29,17 @@ class Manager
|
||||
{
|
||||
private $permission;
|
||||
|
||||
public function __construct(array $params = null)
|
||||
public function __construct(\Espo\Core\Utils\Config $config = null)
|
||||
{
|
||||
$this->permission = new Permission($params);
|
||||
$params = null;
|
||||
if (isset($config)) {
|
||||
$params = array(
|
||||
'defaultPermissions' => $config->get('defaultPermissions'),
|
||||
'permissionMap' => $config->get('permissionMap'),
|
||||
);
|
||||
}
|
||||
|
||||
$this->permission = new Permission($this, $params);
|
||||
}
|
||||
|
||||
public function getPermissionUtils()
|
||||
@@ -39,8 +47,6 @@ class Manager
|
||||
return $this->permission;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of files in specified directory
|
||||
*
|
||||
@@ -173,7 +179,12 @@ class Manager
|
||||
throw new Error('Permission denied in '. $path);
|
||||
}
|
||||
|
||||
return (file_put_contents($fullPath, $data, $flags, $context) !== FALSE);
|
||||
$res = (file_put_contents($fullPath, $data, $flags, $context) !== FALSE);
|
||||
if ($res && function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate($fullPath);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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\Core\Utils\File;
|
||||
|
||||
@@ -27,71 +27,119 @@ use Espo\Core\Utils,
|
||||
|
||||
class Permission
|
||||
{
|
||||
private $fileManager;
|
||||
|
||||
/**
|
||||
* Last permission error
|
||||
*
|
||||
* @var array | string
|
||||
*/
|
||||
protected $permissionError = null;
|
||||
|
||||
protected $permissionErrorRules = null;
|
||||
|
||||
protected $params = array(
|
||||
'defaultPermissions' => array (
|
||||
'dir' => '0775',
|
||||
'file' => '0664',
|
||||
'user' => '',
|
||||
'group' => '',
|
||||
'dir' => '0775',
|
||||
'file' => '0664',
|
||||
'user' => '',
|
||||
'group' => '',
|
||||
),
|
||||
'permissionMap' => array(
|
||||
|
||||
/** array('0664', '0775') */
|
||||
'writable' => array(
|
||||
'data',
|
||||
'custom',
|
||||
),
|
||||
|
||||
/** array('0644', '0755') */
|
||||
'readable' => array(
|
||||
'api',
|
||||
'application',
|
||||
'client',
|
||||
'vendor',
|
||||
'index.php',
|
||||
'cron.php',
|
||||
'rebuild.php',
|
||||
'main.html',
|
||||
'reset.html',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
protected $permissionRules = array(
|
||||
'writable' => array('0664', '0775'),
|
||||
'readable' => array('0644', '0755'),
|
||||
);
|
||||
|
||||
public function __construct(array $params = null)
|
||||
|
||||
public function __construct(Manager $fileManager, array $params = null)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
if (isset($params)) {
|
||||
$this->params = $params;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
{
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get default settings
|
||||
/**
|
||||
* Get default settings
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getDefaultPermissions()
|
||||
public function getDefaultPermissions()
|
||||
{
|
||||
$params = $this->getParams();
|
||||
return $params['defaultPermissions'];
|
||||
}
|
||||
|
||||
|
||||
public function getPermissionRules()
|
||||
{
|
||||
return $this->permissionRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default permission
|
||||
* Set default permission
|
||||
*
|
||||
* @param string $path
|
||||
* @param bool $recurse
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setDefaultPermissions($path, $recurse = false)
|
||||
public function setDefaultPermissions($path, $recurse = false)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$permission = $this->getDefaultPermissions();
|
||||
$permission = $this->getDefaultPermissions();
|
||||
|
||||
$result = $this->chmod($path, array($permission['file'], $permission['dir']), $recurse);
|
||||
$result = $this->chmod($path, array($permission['file'], $permission['dir']), $recurse);
|
||||
if (!empty($permission['user'])) {
|
||||
$result &= $this->chown($path, $permission['user'], $recurse);
|
||||
$result &= $this->chown($path, $permission['user'], $recurse);
|
||||
}
|
||||
if (!empty($permission['group'])) {
|
||||
$result &= $this->chgrp($path, $permission['group'], $recurse);
|
||||
$result &= $this->chgrp($path, $permission['group'], $recurse);
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get current permissions
|
||||
* Get current permissions
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string | bool
|
||||
@@ -108,7 +156,7 @@ class Permission
|
||||
}
|
||||
|
||||
/**
|
||||
* Change permissions
|
||||
* Change permissions
|
||||
*
|
||||
* @param string $filename
|
||||
* @param int | array $octal - ex. 0755, array(0644, 0755), array('file'=>0644, 'dir'=>0755)
|
||||
@@ -118,7 +166,7 @@ class Permission
|
||||
*/
|
||||
public function chmod($path, $octal, $recurse = false)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -130,17 +178,17 @@ class Permission
|
||||
foreach ($octal as $key => $val) {
|
||||
$pKey= strval($key);
|
||||
if (!in_array($pKey, $rule)) {
|
||||
$pKey= $rule[$count];
|
||||
$pKey= $rule[$count];
|
||||
}
|
||||
|
||||
if (!empty($pKey)) {
|
||||
$permission[$pKey]= $val;
|
||||
$permission[$pKey]= $val;
|
||||
}
|
||||
$count++;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
elseif (is_int((int)$octal)) {
|
||||
$permission= array(
|
||||
$permission= array(
|
||||
'file' => $octal,
|
||||
'dir' => $octal,
|
||||
);
|
||||
@@ -152,25 +200,25 @@ class Permission
|
||||
//conver to octal value
|
||||
foreach($permission as $key => $val) {
|
||||
if (is_string($val)) {
|
||||
$permission[$key]= base_convert($val,8,10);
|
||||
$permission[$key]= base_convert($val,8,10);
|
||||
}
|
||||
}
|
||||
|
||||
//Set permission for non-recursive request
|
||||
if (!$recurse) {
|
||||
if (is_dir($path)) {
|
||||
return $this->chmodReal($path, $permission['dir']);
|
||||
return $this->chmodReal($path, $permission['dir']);
|
||||
}
|
||||
return $this->chmodReal($path, $permission['file']);
|
||||
return $this->chmodReal($path, $permission['file']);
|
||||
}
|
||||
|
||||
//Recursive permission
|
||||
return $this->chmodRecurse($path, $permission['file'], $permission['dir']);
|
||||
return $this->chmodRecurse($path, $permission['file'], $permission['dir']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change permissions recursive
|
||||
/**
|
||||
* Change permissions recursive
|
||||
*
|
||||
* @param string $filename
|
||||
* @param int $fileOctal - ex. 0644
|
||||
@@ -189,8 +237,7 @@ class Permission
|
||||
}
|
||||
|
||||
if (is_dir($path)) {
|
||||
$allFiles = scandir($path);
|
||||
$items = array_slice($allFiles, 2);
|
||||
$allFiles = $this->getFileManager()->getFileList($path);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$this->chmodRecurse($path. Utils\Util::getSeparator() .$item, $fileOctal, $dirOctal);
|
||||
@@ -203,11 +250,11 @@ class Permission
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Change owner permission
|
||||
* Change owner permission
|
||||
*
|
||||
* @param string $path
|
||||
* @param int | string $user
|
||||
@@ -217,7 +264,7 @@ class Permission
|
||||
*/
|
||||
public function chown($path, $user='', $recurse=false)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -227,15 +274,15 @@ class Permission
|
||||
|
||||
//Set chown for non-recursive request
|
||||
if (!$recurse) {
|
||||
return $this->chownReal($path, $user);
|
||||
return $this->chownReal($path, $user);
|
||||
}
|
||||
|
||||
//Recursive chown
|
||||
return $this->chownRecurse($path, $user);
|
||||
return $this->chownRecurse($path, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change owner permission recursive
|
||||
* Change owner permission recursive
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $user
|
||||
@@ -248,8 +295,7 @@ class Permission
|
||||
return false;
|
||||
}
|
||||
|
||||
$allFiles = scandir($path);
|
||||
$items = array_slice($allFiles, 2);
|
||||
$allFiles = $this->getFileManager()->getFileList($path);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$this->chownRecurse($path. Utils\Util::getSeparator() .$item, $user);
|
||||
@@ -259,7 +305,7 @@ class Permission
|
||||
}
|
||||
|
||||
/**
|
||||
* Change group permission
|
||||
* Change group permission
|
||||
*
|
||||
* @param string $path
|
||||
* @param int | string $group
|
||||
@@ -269,7 +315,7 @@ class Permission
|
||||
*/
|
||||
public function chgrp($path, $group = null, $recurse = false)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -279,15 +325,15 @@ class Permission
|
||||
|
||||
//Set chgrp for non-recursive request
|
||||
if (!$recurse) {
|
||||
return $this->chgrpReal($path, $group);
|
||||
return $this->chgrpReal($path, $group);
|
||||
}
|
||||
|
||||
//Recursive chown
|
||||
return $this->chgrpRecurse($path, $group);
|
||||
return $this->chgrpRecurse($path, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change group permission recursive
|
||||
* Change group permission recursive
|
||||
*
|
||||
* @param string $filename
|
||||
* @param int $fileOctal - ex. 0644
|
||||
@@ -301,8 +347,7 @@ class Permission
|
||||
return false;
|
||||
}
|
||||
|
||||
$allFiles = scandir($path);
|
||||
$items = array_slice($allFiles, 2);
|
||||
$allFiles = $this->getFileManager()->getFileList($path);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$this->chgrpRecurse($path. Utils\Util::getSeparator() .$item, $group);
|
||||
@@ -313,17 +358,17 @@ class Permission
|
||||
|
||||
|
||||
/**
|
||||
* Change permissions recursive
|
||||
* Change permissions recursive
|
||||
*
|
||||
* @param string $filename
|
||||
* @param int $mode - ex. 0644
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function chmodReal($filename, $mode)
|
||||
protected function chmodReal($filename, $mode)
|
||||
{
|
||||
try {
|
||||
$result = chmod($filename, $mode);
|
||||
$result = chmod($filename, $mode);
|
||||
} catch (\Exception $e) {
|
||||
$result = false;
|
||||
}
|
||||
@@ -333,39 +378,39 @@ class Permission
|
||||
$this->chgrp($filename, $this->getDefaultGroup(true));
|
||||
|
||||
try {
|
||||
$result = chmod($filename, $mode);
|
||||
$result = chmod($filename, $mode);
|
||||
} catch (\Exception $e) {
|
||||
throw new Error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function chownReal($path, $user)
|
||||
{
|
||||
try {
|
||||
$result = chown($path, $user);
|
||||
$result = chown($path, $user);
|
||||
} catch (\Exception $e) {
|
||||
throw new Error($e->getMessage());
|
||||
throw new Error($e->getMessage());
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function chgrpReal($path, $group)
|
||||
{
|
||||
try {
|
||||
$result = chgrp($path, $group);
|
||||
$result = chgrp($path, $group);
|
||||
} catch (\Exception $e) {
|
||||
throw new Error($e->getMessage());
|
||||
throw new Error($e->getMessage());
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default owner user
|
||||
* Get default owner user
|
||||
*
|
||||
* @return int - owner id
|
||||
*/
|
||||
@@ -374,19 +419,19 @@ class Permission
|
||||
$defaultPermissions = $this->getDefaultPermissions();
|
||||
|
||||
$owner = $defaultPermissions['user'];
|
||||
if (empty($owner) && $usePosix) {
|
||||
$owner = posix_getuid();
|
||||
}
|
||||
if (empty($owner) && $usePosix) {
|
||||
$owner = posix_getuid();
|
||||
}
|
||||
|
||||
if (empty($owner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $owner;
|
||||
return $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default group user
|
||||
* Get default group user
|
||||
*
|
||||
* @return int - group id
|
||||
*/
|
||||
@@ -395,15 +440,98 @@ class Permission
|
||||
$defaultPermissions = $this->getDefaultPermissions();
|
||||
|
||||
$group = $defaultPermissions['group'];
|
||||
if (empty($group) && $usePosix) {
|
||||
$group = posix_getegid();
|
||||
}
|
||||
if (empty($group) && $usePosix) {
|
||||
$group = posix_getegid();
|
||||
}
|
||||
|
||||
if (empty($group)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $group;
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set permission regarding defined in permissionMap
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMapPermission($mode = null)
|
||||
{
|
||||
$this->permissionError = array();
|
||||
$this->permissionErrorRules = array();
|
||||
|
||||
$params = $this->getParams();
|
||||
|
||||
$permissionRules = $this->permissionRules;
|
||||
if (isset($mode)) {
|
||||
foreach ($permissionRules as &$value) {
|
||||
$value = $mode;
|
||||
}
|
||||
}
|
||||
|
||||
$result = true;
|
||||
foreach ($params['permissionMap'] as $type => $items) {
|
||||
|
||||
$permission = $permissionRules[$type];
|
||||
|
||||
foreach ($items as $item) {
|
||||
|
||||
if (file_exists($item)) {
|
||||
|
||||
try {
|
||||
$res = $this->chmod($item, $permission, true);
|
||||
} catch (\Exception $e) {
|
||||
$res = false;
|
||||
}
|
||||
|
||||
/** check is wtitable */
|
||||
if ($type == 'writable') {
|
||||
|
||||
$res &= is_writable($item);
|
||||
|
||||
if (is_dir($item)) {
|
||||
$name = uniqid();
|
||||
|
||||
try {
|
||||
$res &= $this->getFileManager()->putContents(array($item, $name), 'test');
|
||||
$res &= $this->getFileManager()->removeFile($name, $item);
|
||||
} catch (\Exception $e) {
|
||||
$res = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$res) {
|
||||
$result = false;
|
||||
$this->permissionError[] = $item;
|
||||
$this->permissionErrorRules[$item] = $permission;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last permission error
|
||||
*
|
||||
* @return array | string
|
||||
*/
|
||||
public function getLastError()
|
||||
{
|
||||
return $this->permissionError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last permission error rules
|
||||
*
|
||||
* @return array | string
|
||||
*/
|
||||
public function getLastErrorRules()
|
||||
{
|
||||
return $this->permissionErrorRules;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -142,6 +142,8 @@ class Language
|
||||
|
||||
if (is_array($translated) && isset($requiredOptions)) {
|
||||
|
||||
$translated = array_intersect_key($translated, array_flip($requiredOptions));
|
||||
|
||||
$optionKeys = array_keys($translated);
|
||||
foreach ($requiredOptions as $option) {
|
||||
if (!in_array($option, $optionKeys)) {
|
||||
@@ -152,6 +154,15 @@ class Language
|
||||
|
||||
return $translated;
|
||||
}
|
||||
|
||||
public function translateOption($value, $field, $scope)
|
||||
{
|
||||
$options = $this->get($scope. '.options.' . $field);
|
||||
if (array_key_exists($value, $options)) {
|
||||
return $options[$value];
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
public function get($key = null, $returns = null)
|
||||
|
||||
@@ -25,6 +25,7 @@ return array (
|
||||
array (
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => 'localhost',
|
||||
'port' => '',
|
||||
'dbname' => '',
|
||||
'user' => '',
|
||||
'password' => '',
|
||||
@@ -40,6 +41,7 @@ return array (
|
||||
'weekStart' => 0,
|
||||
'thousandSeparator' => ',',
|
||||
'decimalMark' => '.',
|
||||
'exportDelimiter' => ',',
|
||||
'currencyList' =>
|
||||
array (
|
||||
),
|
||||
@@ -62,6 +64,7 @@ return array (
|
||||
'languageList' => array(
|
||||
'en_US',
|
||||
'de_DE',
|
||||
'es_ES',
|
||||
),
|
||||
'language' => 'en_US',
|
||||
'logger' =>
|
||||
@@ -71,18 +74,6 @@ return array (
|
||||
'isRotate' => true, /** rotate log files every day */
|
||||
'maxRotateFiles' => 30, /** max number of rotate files */
|
||||
),
|
||||
'defaultPermissions' =>
|
||||
array (
|
||||
'dir' => '0775',
|
||||
'file' => '0664',
|
||||
'user' => '',
|
||||
'group' => '',
|
||||
),
|
||||
'cron' => array(
|
||||
'maxJobNumber' => 15, /** Max number of jobs per one execution */
|
||||
'jobPeriod' => 7800, /** Period for jobs, ex. if cron executed at 15:35, it will execute all pending jobs for times from 14:05 to 15:35 */
|
||||
'minExecutionTime' => 50, /** to avoid too frequency execution **/
|
||||
),
|
||||
'globalSearchEntityList' =>
|
||||
array (
|
||||
0 => 'Account',
|
||||
@@ -93,46 +84,6 @@ return array (
|
||||
),
|
||||
"tabList" => array("Account", "Contact", "Lead", "Opportunity", "Calendar", "Meeting", "Call", "Task", "Case", "Prospect", "Email"),
|
||||
"quickCreateList" => array("Account", "Contact", "Lead", "Opportunity", "Meeting", "Call", "Task", "Case", "Prospect"),
|
||||
'crud' => array(
|
||||
'get' => 'read',
|
||||
'post' => 'create',
|
||||
'put' => 'update',
|
||||
'patch' => 'patch',
|
||||
'delete' => 'delete',
|
||||
),
|
||||
'systemUser' => array(
|
||||
'id' => 'system',
|
||||
'userName' => 'system',
|
||||
'firstName' => '',
|
||||
'lastName' => 'System',
|
||||
),
|
||||
'systemItems' =>
|
||||
array (
|
||||
'systemItems',
|
||||
'adminItems',
|
||||
'configPath',
|
||||
'cachePath',
|
||||
'database',
|
||||
'crud',
|
||||
'logger',
|
||||
'isInstalled',
|
||||
'defaultPermissions',
|
||||
'systemUser',
|
||||
),
|
||||
'adminItems' =>
|
||||
array (
|
||||
'devMode',
|
||||
'outboundEmailIsShared',
|
||||
'outboundEmailFromName',
|
||||
'outboundEmailFromAddress',
|
||||
'smtpServer',
|
||||
'smtpPort',
|
||||
'smtpAuth',
|
||||
'smtpSecurity',
|
||||
'smtpUsername',
|
||||
'smtpPassword',
|
||||
'cron',
|
||||
),
|
||||
'isInstalled' => false,
|
||||
);
|
||||
|
||||
|
||||
102
application/Espo/Core/defaults/systemConfig.php
Normal file
102
application/Espo/Core/defaults/systemConfig.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014 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/.
|
||||
************************************************************************/
|
||||
|
||||
return array (
|
||||
'defaultPermissions' =>
|
||||
array (
|
||||
'dir' => '0775',
|
||||
'file' => '0664',
|
||||
'user' => '',
|
||||
'group' => '',
|
||||
),
|
||||
|
||||
'permissionMap' => array(
|
||||
|
||||
/** array('0664', '0775') */
|
||||
'writable' => array(
|
||||
'data',
|
||||
'custom',
|
||||
),
|
||||
|
||||
/** array('0644', '0755') */
|
||||
'readable' => array(
|
||||
'api',
|
||||
'application',
|
||||
'client',
|
||||
'vendor',
|
||||
'index.php',
|
||||
'cron.php',
|
||||
'rebuild.php',
|
||||
'main.html',
|
||||
'reset.html',
|
||||
),
|
||||
),
|
||||
'cron' => array(
|
||||
'maxJobNumber' => 15, /** Max number of jobs per one execution */
|
||||
'jobPeriod' => 7800, /** Period for jobs, ex. if cron executed at 15:35, it will execute all pending jobs for times from 14:05 to 15:35 */
|
||||
'minExecutionTime' => 50, /** to avoid too frequency execution **/
|
||||
),
|
||||
'crud' => array(
|
||||
'get' => 'read',
|
||||
'post' => 'create',
|
||||
'put' => 'update',
|
||||
'patch' => 'patch',
|
||||
'delete' => 'delete',
|
||||
),
|
||||
'systemUser' => array(
|
||||
'id' => 'system',
|
||||
'userName' => 'system',
|
||||
'firstName' => '',
|
||||
'lastName' => 'System',
|
||||
),
|
||||
'systemItems' =>
|
||||
array (
|
||||
'systemItems',
|
||||
'adminItems',
|
||||
'configPath',
|
||||
'cachePath',
|
||||
'database',
|
||||
'crud',
|
||||
'logger',
|
||||
'isInstalled',
|
||||
'defaultPermissions',
|
||||
'systemUser',
|
||||
'permissionMap',
|
||||
'permissionRules',
|
||||
),
|
||||
'adminItems' =>
|
||||
array (
|
||||
'devMode',
|
||||
'outboundEmailIsShared',
|
||||
'outboundEmailFromName',
|
||||
'outboundEmailFromAddress',
|
||||
'smtpServer',
|
||||
'smtpPort',
|
||||
'smtpAuth',
|
||||
'smtpSecurity',
|
||||
'smtpUsername',
|
||||
'smtpPassword',
|
||||
'cron',
|
||||
),
|
||||
'isInstalled' => false,
|
||||
);
|
||||
|
||||
@@ -18,21 +18,12 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
************************************************************************/
|
||||
************************************************************************/
|
||||
|
||||
ob_start();
|
||||
$result = array('success' => false, 'errors' => array());
|
||||
namespace Espo\Entities;
|
||||
|
||||
class AuthToken extends \Espo\Core\ORM\Entity
|
||||
{
|
||||
|
||||
if (!empty($_REQUEST['url'])) {
|
||||
if ($installer->fixAjaxPermission($_REQUEST['url'])) {
|
||||
$result['success'] = true;
|
||||
}
|
||||
else {
|
||||
$result['success'] = false;
|
||||
$result['errorMsg'] = $_REQUEST['url'];
|
||||
$result['errorFixInstruction'] = $systemHelper->getPermissionCommands('', array('644', '755'));
|
||||
}
|
||||
}
|
||||
|
||||
ob_clean();
|
||||
echo json_encode($result);
|
||||
@@ -24,5 +24,21 @@ namespace Espo\Entities;
|
||||
|
||||
class Note extends \Espo\Core\ORM\Entity
|
||||
{
|
||||
|
||||
public function loadAttachments()
|
||||
{
|
||||
$collection = $this->get('attachments');
|
||||
$ids = array();
|
||||
$names = new \stdClass();
|
||||
$types = new \stdClass();
|
||||
foreach ($collection as $e) {
|
||||
$id = $e->id;
|
||||
$ids[] = $id;
|
||||
$names->$id = $e->get('name');
|
||||
$types->$id = $e->get('type');
|
||||
}
|
||||
$this->set('attachmentsIds', $ids);
|
||||
$this->set('attachmentsNames', $names);
|
||||
$this->set('attachmentsTypes', $types);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,19 +25,45 @@ namespace Espo\EntryPoints;
|
||||
use \Espo\Core\Exceptions\NotFound;
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
use \Espo\Core\Exceptions\BadRequest;
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class Image extends \Espo\Core\EntryPoints\Base
|
||||
{
|
||||
public static $authRequired = false;
|
||||
public static $authRequired = true;
|
||||
|
||||
protected $allowedFileTypes = array(
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
);
|
||||
|
||||
protected $imageSizes = array(
|
||||
'x-small' => array(64, 64),
|
||||
'small' => array(128, 128),
|
||||
'medium' => array(256, 256),
|
||||
'large' => array(512, 512),
|
||||
'x-large' => array(864, 864),
|
||||
'xx-large' => array(1024, 1024),
|
||||
);
|
||||
|
||||
|
||||
public function run()
|
||||
{
|
||||
|
||||
{
|
||||
$id = $_GET['id'];
|
||||
if (empty($id)) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
}
|
||||
|
||||
$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) {
|
||||
@@ -51,29 +77,118 @@ class Image extends \Espo\Core\EntryPoints\Base
|
||||
}
|
||||
}
|
||||
|
||||
$fileName = "data/upload/{$attachment->id}";
|
||||
$filePath = "data/upload/{$attachment->id}";
|
||||
|
||||
if (!file_exists($fileName)) {
|
||||
$fileType = $attachment->get('type');
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
if (!$attachment->get('global')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($attachment->get('type')) {
|
||||
header('Content-Type: ' . $attachment->get('type'));
|
||||
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);
|
||||
break;
|
||||
case 'image/png':
|
||||
imagepng($targetImage);
|
||||
break;
|
||||
case 'image/gif':
|
||||
imagegif($targetImage);
|
||||
break;
|
||||
}
|
||||
$contents = ob_get_contents();
|
||||
ob_end_clean();
|
||||
imagedestroy($targetImage);
|
||||
$this->getContainer()->get('fileManager')->putContents($thumbFilePath, $contents);
|
||||
}
|
||||
$filePath = $thumbFilePath;
|
||||
|
||||
} else {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($size)) {
|
||||
$fileName = $attachment->id . '_' . $size . '.jpg';
|
||||
} else {
|
||||
$fileName = $attachment->get('name');
|
||||
}
|
||||
header('Content-Disposition:inline;filename="'.$fileName.'"');
|
||||
if (!empty($fileType)) {
|
||||
header('Content-Type: ' . $fileType);
|
||||
}
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($fileName));
|
||||
$fileSize = filesize($filePath);
|
||||
if ($fileSize) {
|
||||
header('Content-Length: ' . $fileSize);
|
||||
}
|
||||
ob_clean();
|
||||
flush();
|
||||
readfile($fileName);
|
||||
exit;
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
if ($originalWidth > $originalHeight) {
|
||||
$targetWidth = $width;
|
||||
$targetHeight = $originalHeight / ($originalWidth / $width);
|
||||
if ($targetHeight > $height) {
|
||||
$targetHeight = $height;
|
||||
$targetWidth = $originalWidth / ($originalHeight / $height);
|
||||
}
|
||||
} else {
|
||||
$targetHeight = $height;
|
||||
$targetWidth = $originalWidth / ($originalHeight / $height);
|
||||
if ($targetWidth > $width) {
|
||||
$targetWidth = $width;
|
||||
$targetHeight = $originalHeight / ($originalWidth / $width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
|
||||
switch ($fileType) {
|
||||
case 'image/jpeg':
|
||||
$sourceImage = imagecreatefromjpeg($filePath);
|
||||
imagecopyresized($targetImage, $sourceImage, 0, 0, 0, 0, $targetWidth, $targetHeight, $originalWidth, $originalHeight);
|
||||
break;
|
||||
case 'image/png':
|
||||
$sourceImage = imagecreatefrompng($filePath);
|
||||
imagealphablending($targetImage, false);
|
||||
imagesavealpha($targetImage, true);
|
||||
$transparent = imagecolorallocatealpha($targetImage, 255, 255, 255, 127);
|
||||
imagefilledrectangle($targetImage, 0, 0, $targetWidth, $targetHeight, $transparent);
|
||||
imagecopyresampled($targetImage, $sourceImage, 0, 0, 0, 0, $targetWidth, $targetHeight, $originalWidth, $originalHeight);
|
||||
break;
|
||||
case 'image/gif':
|
||||
$sourceImage = imagecreatefromgif($filePath);
|
||||
imagecopyresized($targetImage, $sourceImage, 0, 0, 0, 0, $targetWidth, $targetHeight, $originalWidth, $originalHeight);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return $targetImage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
52
application/Espo/EntryPoints/LogoImage.php
Normal file
52
application/Espo/EntryPoints/LogoImage.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014 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\Exceptions\Error;
|
||||
|
||||
class LogoImage extends Image
|
||||
{
|
||||
public static $authRequired = false;
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->imageSizes['small-logo'] = array(173, 38);
|
||||
|
||||
$id = $this->getConfig()->get('companyLogoId');
|
||||
|
||||
if (empty($id)) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
$size = null;
|
||||
if (!empty($_GET['size'])) {
|
||||
$size = $_GET['size'];
|
||||
}
|
||||
|
||||
$this->show($id, $size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,13 +32,14 @@ class InboundEmail extends \Espo\Core\Controllers\Record
|
||||
}
|
||||
|
||||
public function actionGetFolders($params, $data, $request)
|
||||
{
|
||||
{
|
||||
return $this->getRecordService()->getFolders(array(
|
||||
'host' => $request->get('host'),
|
||||
'port' => $request->get('port'),
|
||||
'ssl' => $request->get('ssl'),
|
||||
'username' => $request->get('username'),
|
||||
'password' => $request->get('password'),
|
||||
'id' => $request->get('id')
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
@@ -36,5 +36,8 @@
|
||||
"IMAP": "IMAP",
|
||||
"Actions": "Actions",
|
||||
"Main": "Main"
|
||||
},
|
||||
"messages": {
|
||||
"couldNotConnectToImap": "Could not connect to IMAP server"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"account": "Account",
|
||||
"stage": "Stage",
|
||||
"amount": "Amount",
|
||||
"probability": "Probability",
|
||||
"probability": "Probability, %",
|
||||
"leadSource": "Lead Source",
|
||||
"doNotCall": "Do Not Call",
|
||||
"closeDate": "Close Date",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"website": "Sito Web",
|
||||
"phone": "Teléfono",
|
||||
"fax": "Fax",
|
||||
"billingAddress": "Dirección de Facturación",
|
||||
"shippingAddress": "Dirección de Envío",
|
||||
"description": "Descripción",
|
||||
"sicCode": "Sic Code",
|
||||
"industry": "Industria",
|
||||
"type": "Tipo"
|
||||
},
|
||||
"links": {
|
||||
"contacts": "Contactos",
|
||||
"opportunities": "Oportunidades",
|
||||
"cases": "Casos"
|
||||
},
|
||||
"options": {
|
||||
"type": {
|
||||
"Customer": "Cliente",
|
||||
"Investor": "Inversor",
|
||||
"Partner": "Partner",
|
||||
"Reseller": "REvendedor"
|
||||
},
|
||||
"industry": {
|
||||
"Apparel": "Apparel",
|
||||
"Banking": "Banking",
|
||||
"Computer Software": "Software",
|
||||
"Education": "Educación",
|
||||
"Electronics": "Electrónicos",
|
||||
"Finance": "Finanzas",
|
||||
"Insurance": "Seguros"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create Account": "Crear Cuenta"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"modes": {
|
||||
"month": "Mes",
|
||||
"week": "Semana",
|
||||
"day": "Día",
|
||||
"agendaWeek": "Semana",
|
||||
"agendaDay": "Día"
|
||||
},
|
||||
"labels": {
|
||||
"Today": "Hoy",
|
||||
"Create": "Crear"
|
||||
}
|
||||
}
|
||||
34
application/Espo/Modules/Crm/Resources/i18n/es_ES/Call.json
Normal file
34
application/Espo/Modules/Crm/Resources/i18n/es_ES/Call.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"parent": "Padre",
|
||||
"status": "Estado",
|
||||
"dateStart": "Fecha de Comienzo",
|
||||
"dateEnd": "Fecha de Finalización",
|
||||
"direction": "Dirección",
|
||||
"duration": "Duración",
|
||||
"description": "Descripción",
|
||||
"users": "Usuarios",
|
||||
"contacts": "Contactos",
|
||||
"leads": "Potenciales"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Planeada",
|
||||
"Held": "Celebrada",
|
||||
"Not Held": "Sin Celebrar"
|
||||
},
|
||||
"direction": {
|
||||
"Outbound": "Saliente",
|
||||
"Inbound": "Entrante"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create Call": "Crear Llamada",
|
||||
"Set Held": "Establecer Celebrada",
|
||||
"Set Not Held": "Establecer no Celebrada",
|
||||
"Send Invitations": "Enviar Invitaciones"
|
||||
}
|
||||
}
|
||||
38
application/Espo/Modules/Crm/Resources/i18n/es_ES/Case.json
Normal file
38
application/Espo/Modules/Crm/Resources/i18n/es_ES/Case.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"number": "Número",
|
||||
"status": "Estado",
|
||||
"account": "Cuenta",
|
||||
"contact": "Contacto",
|
||||
"priority": "Prioridad",
|
||||
"type": "Tipo",
|
||||
"description": "Descripción"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"New": "Nuevo",
|
||||
"Assigned": "Asignado",
|
||||
"Pending": "Pendiente",
|
||||
"Closed": "Cerrado",
|
||||
"Rejected": "Rechazado",
|
||||
"Duplicate": "Duplicado"
|
||||
},
|
||||
"priority" : {
|
||||
"Low": "Baja",
|
||||
"Normal": "Normal",
|
||||
"High": "Alta",
|
||||
"Urgent": "Urgente"
|
||||
},
|
||||
"type": {
|
||||
"Question": "Pregunta",
|
||||
"Incident": "Incidente",
|
||||
"Problem": "Problema"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create Case": "Crear Caso"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"title": "Título",
|
||||
"account": "Cuenta",
|
||||
"phone": "Teléfono",
|
||||
"phoneOffice": "Phone (Office)",
|
||||
"fax": "Fax",
|
||||
"accountType": "Cuenta Tipo",
|
||||
"doNotCall": "No Llamar",
|
||||
"address": "Dirección",
|
||||
"description": "Descripción"
|
||||
},
|
||||
"links": {
|
||||
"opportunities": "Oportunidades",
|
||||
"cases": "Casos"
|
||||
},
|
||||
"labels": {
|
||||
"Create Contact": "Crear Contacto"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"scopeNames": {
|
||||
"Account": "Cuenta",
|
||||
"Contact": "Contacto",
|
||||
"Lead": "Potenciales",
|
||||
"Prospect": "Prospecto",
|
||||
"Opportunity": "Opportunidad",
|
||||
"Meeting": "Reunión",
|
||||
"Calendar": "Calendario",
|
||||
"Call": "Llamada",
|
||||
"Task": "Tarea",
|
||||
"Case": "Caso",
|
||||
"InboundEmail": "Correo Entrante"
|
||||
},
|
||||
"scopeNamesPlural": {
|
||||
"Account": "Cuentas",
|
||||
"Contact": "Contactos",
|
||||
"Lead": "Potenciales",
|
||||
"Prospect": "Prospectos",
|
||||
"Opportunity": "Oportunidades",
|
||||
"Meeting": "Reuniones",
|
||||
"Calendar": "Calendario",
|
||||
"Call": "Llamadas",
|
||||
"Task": "Tareas",
|
||||
"Case": "Casos",
|
||||
"InboundEmail": "Correos Entrantes"
|
||||
},
|
||||
"dashlets": {
|
||||
"Leads": "Mis potenciales",
|
||||
"Opportunities": "Mis Opportunidades",
|
||||
"Tasks": "Mis Tareas",
|
||||
"Cases": "Mis Casos",
|
||||
"Calendar": "Calendario",
|
||||
"OpportunitiesByStage": "Oportunidades por Etapa",
|
||||
"OpportunitiesByLeadSource": "Oportunidades de origen de cliente potencial",
|
||||
"SalesByMonth": "Ventas por Mes",
|
||||
"SalesPipeline": "Canalización de ventas"
|
||||
},
|
||||
"labels": {
|
||||
"Create InboundEmail": "Crear Correo Entrante",
|
||||
"Activities": "Actividades",
|
||||
"History": "Historia",
|
||||
"Attendees": "Los asistentes",
|
||||
"Schedule Meeting": "Reunión Programada",
|
||||
"Schedule Call": "Llamada Programada",
|
||||
"Compose Email": "Componer Correo",
|
||||
"Log Meeting": "Log de Reunión",
|
||||
"Log Call": "Log de Llamada",
|
||||
"Archive Email": "Archivar Correo",
|
||||
"Create Task": "Crear Tarea",
|
||||
"Tasks": "Tareas"
|
||||
},
|
||||
"fields": {
|
||||
"billingAddressCity": "Ciudad",
|
||||
"billingAddressCountry": "país",
|
||||
"billingAddressPostalCode": "Código Postal",
|
||||
"billingAddressState": "Estado/Distrito",
|
||||
"billingAddressStreet": "Calle",
|
||||
"addressCity": "Ciudad",
|
||||
"addressStreet": "Calle",
|
||||
"addressCountry": "país",
|
||||
"addressState": "Estado/Distrito",
|
||||
"addressPostalCode": "Código Postal",
|
||||
"shippingAddressCity": "City (Shipping)",
|
||||
"shippingAddressStreet": "Street (Shipping)",
|
||||
"shippingAddressCountry": "Country (Shipping)",
|
||||
"shippingAddressState": "State (Shipping)",
|
||||
"shippingAddressPostalCode": "Postal Code (Shipping)"
|
||||
},
|
||||
"links": {
|
||||
"contacts": "Contactos",
|
||||
"opportunities": "Oportunidades",
|
||||
"leads": "Potenciales",
|
||||
"meetings": "Reuniones",
|
||||
"calls": "Llamadas",
|
||||
"tasks": "Tareas",
|
||||
"emails": "Correos"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"team": "Equipo",
|
||||
"status": "Estado",
|
||||
"assignToUser": "Asignado a Usuario",
|
||||
"host": "Host",
|
||||
"username": "Nombre de Usuario",
|
||||
"password": "Contraseña",
|
||||
"port": "Puerto",
|
||||
"monitoredFolders": "Carpetas supervisadas",
|
||||
"trashFolder": "Carpeta Basura",
|
||||
"ssl": "SSL",
|
||||
"createCase": "Crear Caso",
|
||||
"reply": "Responder",
|
||||
"caseDistribution": "Caso Distribución",
|
||||
"replyEmailTemplate": "Responder De Plantilla",
|
||||
"replyFromAddress": "Responder De Dirección",
|
||||
"replyFromName": "Responder De Nombre"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Active": "Activo",
|
||||
"Inactive": "Inactivo"
|
||||
},
|
||||
"caseDistribution": {
|
||||
"Direct-Assignment": "Asignación-Directa",
|
||||
"Round-Robin": "Round-Robin",
|
||||
"Least-Busy": "Least-Busy"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create InboundEmail": "Crear Correo Entrante",
|
||||
"IMAP": "IMAP",
|
||||
"Actions": "Acciones",
|
||||
"Main": "Principal"
|
||||
},
|
||||
"messages": {
|
||||
"couldNotConnectToImap": "No se pudo conectar con el servidor IMAP"
|
||||
}
|
||||
}
|
||||
48
application/Espo/Modules/Crm/Resources/i18n/es_ES/Lead.json
Normal file
48
application/Espo/Modules/Crm/Resources/i18n/es_ES/Lead.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"labels": {
|
||||
"Converted To": "Convertido a",
|
||||
"Create Lead": "Crear Principal",
|
||||
"Convert": "Convertir"
|
||||
},
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"title": "Título",
|
||||
"website": "Sito Web",
|
||||
"phone": "Teléfono",
|
||||
"phoneOffice": "Phone (Office)",
|
||||
"fax": "Fax",
|
||||
"accountName": "Nombre de Cuenta",
|
||||
"doNotCall": "No Llamar",
|
||||
"address": "Dirección",
|
||||
"status": "Estado",
|
||||
"source": "Fuente",
|
||||
"opportunityAmount": "Oportunidad Cantidad",
|
||||
"description": "Descripción",
|
||||
"createdAccount": "Cuenta",
|
||||
"createdContact": "Contacto",
|
||||
"createdOpportunity": "Opportunidad"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"New": "Nuevo",
|
||||
"Assigned": "Asignado",
|
||||
"In Process": "En Proceso",
|
||||
"Converted": "Convertido",
|
||||
"Recycled": "Reciclado",
|
||||
"Dead": "Muerto"
|
||||
},
|
||||
"source": {
|
||||
"Call": "Llamada",
|
||||
"Email": "Correo electrónico",
|
||||
"Existing Customer": "Cliente Existente",
|
||||
"Partner": "Partner",
|
||||
"Public Relations": "Relaciones Públicas",
|
||||
"Web Site": "Sitio Web",
|
||||
"Campaign": "Campaña",
|
||||
"Other": "Otro"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"parent": "Padre",
|
||||
"status": "Estado",
|
||||
"dateStart": "Fecha de Comienzo",
|
||||
"dateEnd": "Fecha de Finalización",
|
||||
"duration": "Duración",
|
||||
"description": "Descripción",
|
||||
"users": "Usuarios",
|
||||
"contacts": "Contactos",
|
||||
"leads": "Potenciales"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Planeada",
|
||||
"Held": "Celebrada",
|
||||
"Not Held": "Sin Celebrar"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create Meeting": "Crear Reunión",
|
||||
"Set Held": "Establecer Celebrada",
|
||||
"Set Not Held": "Establecer no Celebrada",
|
||||
"Send Invitations": "Enviar Invitaciones"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"account": "Cuenta",
|
||||
"stage": "Etapa",
|
||||
"amount": "Cantidad",
|
||||
"probability": "Probabilidad, %",
|
||||
"leadSource": "Fuente Principal",
|
||||
"doNotCall": "No Llamar",
|
||||
"closeDate": "Fecha de cierre",
|
||||
"description": "Descripción"
|
||||
},
|
||||
"links": {
|
||||
"contacts": "Contactos"
|
||||
},
|
||||
"options": {
|
||||
"stage": {
|
||||
"Prospecting": "Prospección",
|
||||
"Qualification": "Calificación",
|
||||
"Needs Analysis": "Análisis de Necesidades",
|
||||
"Value Proposition": "Valor de la Propuesta",
|
||||
"Id. Decision Makers": "Id. Tomadores de Decisiones",
|
||||
"Perception Analysis": "Análisis de la Percepción",
|
||||
"Proposal/Price Quote": "Propuesta/precio Presupuesto",
|
||||
"Negotiation/Review": "Negociación/Revisión",
|
||||
"Closed Won": "Cerrado Ganado",
|
||||
"Closed Lost": "Cerrado Perdido"
|
||||
},
|
||||
"leadSource": {
|
||||
"Call": "Llamada",
|
||||
"Email": "Correo electrónico",
|
||||
"Existing Customer": "Cliente Existente",
|
||||
"Partner": "Partner",
|
||||
"Public Relations": "Relaciones Públicas",
|
||||
"Web Site": "Sitio Web",
|
||||
"Campaign": "Campaña",
|
||||
"Other": "Otro"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create Opportunity": "Crear Oportunidad"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"title": "Título",
|
||||
"website": "Sito Web",
|
||||
"accountName": "Nombre de Cuenta",
|
||||
"phone": "Teléfono",
|
||||
"phoneOffice": "Phone (Office)",
|
||||
"fax": "Fax",
|
||||
"doNotCall": "No Llamar",
|
||||
"address": "Dirección",
|
||||
"description": "Descripción"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"labels": {
|
||||
"Create Prospect": "Crear Prospecto",
|
||||
"Convert to Lead": "Convertir en Lider"
|
||||
}
|
||||
}
|
||||
31
application/Espo/Modules/Crm/Resources/i18n/es_ES/Task.json
Normal file
31
application/Espo/Modules/Crm/Resources/i18n/es_ES/Task.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"parent": "Padre",
|
||||
"status": "Estado",
|
||||
"dateStart": "Fecha de Comienzo",
|
||||
"dateEnd": "Fecha de vencimiento",
|
||||
"priority": "Prioridad",
|
||||
"description": "Descripción",
|
||||
"isOverdue": "Atrasado"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Not Started": "Sin Empezar",
|
||||
"Started": "Comenzado",
|
||||
"Completed": "Completado",
|
||||
"Canceled": "Cancelado"
|
||||
},
|
||||
"priority" : {
|
||||
"Low": "Baja",
|
||||
"Normal": "Normal",
|
||||
"High": "Alta",
|
||||
"Urgent": "Urgente"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create Task": "Crear Tarea"
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,9 @@
|
||||
"type": "address"
|
||||
},
|
||||
"billingAddressStreet": {
|
||||
"type": "varchar"
|
||||
"type": "text",
|
||||
"maxLength": 255,
|
||||
"dbType": "varchar"
|
||||
},
|
||||
"billingAddressCity": {
|
||||
"type": "varchar"
|
||||
@@ -50,7 +52,9 @@
|
||||
"type": "address"
|
||||
},
|
||||
"shippingAddressStreet": {
|
||||
"type": "varchar"
|
||||
"type": "text",
|
||||
"maxLength": 255,
|
||||
"dbType": "varchar"
|
||||
},
|
||||
"shippingAddressCity": {
|
||||
"type": "varchar"
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
"type": "address"
|
||||
},
|
||||
"addressStreet": {
|
||||
"type": "varchar"
|
||||
"type": "text",
|
||||
"maxLength": 255,
|
||||
"dbType": "varchar"
|
||||
},
|
||||
"addressCity": {
|
||||
"type": "varchar"
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
"type": "address"
|
||||
},
|
||||
"addressStreet": {
|
||||
"type": "varchar"
|
||||
"type": "text",
|
||||
"maxLength": 255,
|
||||
"dbType": "varchar"
|
||||
},
|
||||
"addressCity": {
|
||||
"type": "varchar"
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
"type": "address"
|
||||
},
|
||||
"addressStreet": {
|
||||
"type": "varchar"
|
||||
"type": "text",
|
||||
"maxLength": 255,
|
||||
"dbType": "varchar"
|
||||
},
|
||||
"addressCity": {
|
||||
"type": "varchar"
|
||||
|
||||
@@ -30,6 +30,38 @@ use \Zend\Mime\Mime as Mime;
|
||||
class InboundEmail extends \Espo\Services\Record
|
||||
{
|
||||
|
||||
public function createEntity($data)
|
||||
{
|
||||
$entity = parent::createEntity($data);
|
||||
$entity->clear('password');
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public function getEntity($id = null)
|
||||
{
|
||||
$entity = parent::getEntity($id);
|
||||
$entity->clear('password');
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public function updateEntity($id, $data)
|
||||
{
|
||||
$entity = parent::updateEntity($id, $data);
|
||||
$entity->clear('password');
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public function findEntities($params)
|
||||
{
|
||||
$result = parent::findEntities($params);
|
||||
|
||||
foreach ($result['collection'] as $entity) {
|
||||
$entity->clear('password');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$this->dependencies[] = 'fileManager';
|
||||
@@ -58,12 +90,20 @@ class InboundEmail extends \Espo\Services\Record
|
||||
|
||||
public function getFolders($params)
|
||||
{
|
||||
$password = $params['password'];
|
||||
|
||||
if (!empty($params['id'])) {
|
||||
$entity = $this->getEntityManager()->getEntity('InboundEmail', $params['id']);
|
||||
if ($entity) {
|
||||
$password = $entity->get('password');
|
||||
}
|
||||
}
|
||||
|
||||
$imapParams = array(
|
||||
'host' => $params['host'],
|
||||
'port' => $params['port'],
|
||||
'user' => $params['username'],
|
||||
'password' => $params['password'],
|
||||
'password' => $password,
|
||||
);
|
||||
|
||||
if (!empty($params['ssl'])) {
|
||||
@@ -83,7 +123,7 @@ class InboundEmail extends \Espo\Services\Record
|
||||
|
||||
public function fetchFromMailServer($id)
|
||||
{
|
||||
$inboundEmail = $this->getEntity($id);
|
||||
$inboundEmail = $this->getEntityManager()->getEntity('InboundEmail', $id);
|
||||
|
||||
if ($inboundEmail->get('status') != 'Active') {
|
||||
throw new Error();
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Espo\Modules\Crm\Services;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class Prospect extends \Espo\Services\Record
|
||||
{
|
||||
|
||||
@@ -282,27 +282,7 @@ abstract class Mapper implements IMapper
|
||||
if (!$totalCount) {
|
||||
$selectPart = $this->getSelect($relEntity);
|
||||
$joinsPart = $this->getBelongsToJoins($relEntity);
|
||||
$orderPart = $this->getOrder($relEntity, $orderBy, $order);
|
||||
|
||||
if (!empty($joins) && is_array($joins)) {
|
||||
$joinsRelated = $this->getJoins($relEntity, $joins, false, $joinConditions);
|
||||
if (!empty($joinsRelated)) {
|
||||
if (!empty($joinsPart)) {
|
||||
$joinsPart .= ' ';
|
||||
}
|
||||
$joinsPart .= $joinsRelated;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($leftJoins) && is_array($leftJoins)) {
|
||||
$joinsRelated = $this->getJoins($relEntity, $leftJoins, true, $joinConditions);
|
||||
if (!empty($joinsRelated)) {
|
||||
if (!empty($joinsPart)) {
|
||||
$joinsPart .= ' ';
|
||||
}
|
||||
$joinsPart .= $joinsRelated;
|
||||
}
|
||||
}
|
||||
$orderPart = $this->getOrder($relEntity, $orderBy, $order);
|
||||
|
||||
} else {
|
||||
$selectPart = $this->getAggregationSelect($relEntity, 'COUNT', 'id');
|
||||
@@ -312,6 +292,26 @@ abstract class Mapper implements IMapper
|
||||
$limit = null;
|
||||
}
|
||||
|
||||
if (!empty($joins) && is_array($joins)) {
|
||||
$joinsRelated = $this->getJoins($relEntity, $joins, false, $joinConditions);
|
||||
if (!empty($joinsRelated)) {
|
||||
if (!empty($joinsPart)) {
|
||||
$joinsPart .= ' ';
|
||||
}
|
||||
$joinsPart .= $joinsRelated;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($leftJoins) && is_array($leftJoins)) {
|
||||
$joinsRelated = $this->getJoins($relEntity, $leftJoins, true, $joinConditions);
|
||||
if (!empty($joinsRelated)) {
|
||||
if (!empty($joinsPart)) {
|
||||
$joinsPart .= ' ';
|
||||
}
|
||||
$joinsPart .= $joinsRelated;
|
||||
}
|
||||
}
|
||||
|
||||
$relType = $relOpt['type'];
|
||||
|
||||
$keySet = $this->getKeys($entity, $relationName);
|
||||
|
||||
@@ -245,7 +245,9 @@ abstract class Entity implements IEntity
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
$arr[$field] = $this->get($field);
|
||||
if ($this->has($field)) {
|
||||
$arr[$field] = $this->get($field);
|
||||
}
|
||||
|
||||
}
|
||||
return $arr;
|
||||
|
||||
@@ -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\ORM;
|
||||
|
||||
@@ -36,7 +36,7 @@ class EntityManager
|
||||
protected $metadata;
|
||||
|
||||
protected $repositoryHash = array();
|
||||
|
||||
|
||||
protected $params = array();
|
||||
|
||||
public function __construct($params)
|
||||
@@ -54,17 +54,17 @@ class EntityManager
|
||||
$entityFactoryClassName = $params['entityFactoryClassName'];
|
||||
}
|
||||
$this->entityFactory = new $entityFactoryClassName($this, $this->metadata);
|
||||
|
||||
|
||||
|
||||
$repositoryFactoryClassName = '\\Espo\\ORM\\RepositoryFactory';
|
||||
if (!empty($params['repositoryFactoryClassName'])) {
|
||||
$repositoryFactoryClassName = $params['repositoryFactoryClassName'];
|
||||
}
|
||||
$this->repositoryFactory = new $repositoryFactoryClassName($this, $this->entityFactory);
|
||||
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
|
||||
public function getMapper($className)
|
||||
{
|
||||
if (empty($this->mappers[$className])) {
|
||||
@@ -77,7 +77,9 @@ class EntityManager
|
||||
{
|
||||
$params = $this->params;
|
||||
|
||||
$this->pdo = new \PDO('mysql:host='.$params['host'].';dbname=' . $params['dbname'] . ';charset=utf8', $params['user'], $params['password']);
|
||||
$port = empty($params['port']) ? '' : 'port=' . $params['port'] . ';';
|
||||
|
||||
$this->pdo = new \PDO('mysql:host='.$params['host'].';'.$port.'dbname=' . $params['dbname'] . ';charset=utf8', $params['user'], $params['password']);
|
||||
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
|
||||
@@ -85,13 +87,13 @@ class EntityManager
|
||||
{
|
||||
return $this->getRepository($name)->get($id);
|
||||
}
|
||||
|
||||
|
||||
public function saveEntity(Entity $entity)
|
||||
{
|
||||
$entityName = $entity->getEntityName();
|
||||
return $this->getRepository($entityName)->save($entity);
|
||||
}
|
||||
|
||||
|
||||
public function removeEntity(Entity $entity)
|
||||
{
|
||||
$entityName = $entity->getEntityName();
|
||||
@@ -110,7 +112,7 @@ class EntityManager
|
||||
{
|
||||
$this->metadata->setData($data);
|
||||
}
|
||||
|
||||
|
||||
public function getMetadata()
|
||||
{
|
||||
return $this->metadata;
|
||||
@@ -133,14 +135,14 @@ class EntityManager
|
||||
{
|
||||
return $name;
|
||||
}
|
||||
|
||||
|
||||
public function createCollection($entityName, $data = array())
|
||||
{
|
||||
$seed = $this->getEntity($entityName);
|
||||
$collection = new EntityCollection($data, $seed, $this->entityFactory);
|
||||
$seed = $this->getEntity($entityName);
|
||||
$collection = new EntityCollection($data, $seed, $this->entityFactory);
|
||||
return $collection;
|
||||
}
|
||||
|
||||
|
||||
protected function init()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,5 +58,255 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
public function getEmailAddressData(Entity $entity)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
$sql = "
|
||||
SELECT email_address.name, email_address.invalid, email_address.opt_out AS optOut, entity_email_address.primary
|
||||
FROM entity_email_address
|
||||
JOIN email_address ON email_address.id = entity_email_address.email_address_id AND email_address.deleted = 0
|
||||
WHERE
|
||||
entity_email_address.entity_id = ".$pdo->quote($entity->id)." AND
|
||||
entity_email_address.entity_type = ".$pdo->quote($entity->getEntityName())." AND
|
||||
entity_email_address.deleted = 0
|
||||
ORDER BY entity_email_address.primary DESC
|
||||
";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute();
|
||||
if ($rows = $sth->fetchAll()) {
|
||||
foreach ($rows as $row) {
|
||||
$obj = new \StdClass();
|
||||
$obj->emailAddress = $row['name'];
|
||||
$obj->primary = ($row['primary'] == '1') ? true : false;
|
||||
$obj->optOut = ($row['optOut'] == '1') ? true : false;
|
||||
$obj->invalid = ($row['invalid'] == '1') ? true : false;
|
||||
$data[] = $obj;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getByAddress($address)
|
||||
{
|
||||
return $this->where(array('lower' => strtolower($address)))->findOne();
|
||||
}
|
||||
|
||||
public function storeEntityEmailAddress(Entity $entity)
|
||||
{
|
||||
$email = trim($entity->get('emailAddress'));
|
||||
$emailAddressData = null;
|
||||
|
||||
if ($entity->has('emailAddressData')) {
|
||||
$emailAddressData = $entity->get('emailAddressData');
|
||||
}
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
|
||||
if ($emailAddressData !== null && is_array($emailAddressData)) {
|
||||
$previousEmailAddressData = array();
|
||||
if (!$entity->isNew()) {
|
||||
$previousEmailAddressData = $this->getEmailAddressData($entity);
|
||||
}
|
||||
|
||||
$hash = array();
|
||||
foreach ($emailAddressData as $row) {
|
||||
$key = $row->emailAddress;
|
||||
if (!empty($key)) {
|
||||
$hash[$key] = array(
|
||||
'primary' => $row->primary ? true : false,
|
||||
'optOut' => $row->optOut ? true : false,
|
||||
'invalid' => $row->invalid ? true : false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$hashPrev = array();
|
||||
foreach ($previousEmailAddressData as $row) {
|
||||
$key = $row->emailAddress;
|
||||
if (!empty($key)) {
|
||||
$hashPrev[$key] = array(
|
||||
'primary' => $row->primary ? true : false,
|
||||
'optOut' => $row->optOut ? true : false,
|
||||
'invalid' => $row->invalid ? true : false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$primary = false;
|
||||
$toCreate = array();
|
||||
$toUpdate = array();
|
||||
$toRemove = array();
|
||||
|
||||
|
||||
foreach ($hash as $key => $data) {
|
||||
$new = true;
|
||||
$changed = false;
|
||||
|
||||
if ($hash[$key]['primary']) {
|
||||
$primary = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $hashPrev)) {
|
||||
$new = false;
|
||||
$changed = $hash[$key]['optOut'] != $hashPrev[$key]['optOut'] || $hash[$key]['invalid'] != $hashPrev[$key]['invalid'];
|
||||
if ($hash[$key]['primary']) {
|
||||
if ($hash[$key]['primary'] == $hashPrev[$key]['primary']) {
|
||||
$primary = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($new) {
|
||||
$toCreate[] = $key;
|
||||
}
|
||||
if ($changed) {
|
||||
$toUpdate[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($hashPrev as $key => $data) {
|
||||
if (!array_key_exists($key, $hash)) {
|
||||
$toRemove[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($toRemove as $address) {
|
||||
$emailAddress = $this->getByAddress($address);
|
||||
if ($emailAddress) {
|
||||
$query = "
|
||||
UPDATE entity_email_address
|
||||
SET `deleted` = 1, `primary` = 0
|
||||
WHERE
|
||||
entity_id = ".$pdo->quote($entity->id)." AND
|
||||
entity_type = ".$pdo->quote($entity->getEntityName())." AND
|
||||
email_address_id = ".$pdo->quote($emailAddress->id)."
|
||||
";
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($toUpdate as $address) {
|
||||
$emailAddress = $this->getByAddress($address);
|
||||
if ($emailAddress) {
|
||||
$emailAddress->set(array(
|
||||
'optOut' => $hash[$address]['optOut'],
|
||||
'invalid' => $hash[$address]['invalid'],
|
||||
));
|
||||
$this->save($emailAddress);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($toCreate as $address) {
|
||||
$emailAddress = $this->getByAddress($address);
|
||||
if (!$emailAddress) {
|
||||
$emailAddress = $this->get();
|
||||
|
||||
$emailAddress->set(array(
|
||||
'name' => $address,
|
||||
'optOut' => $hash[$address]['optOut'],
|
||||
'invalid' => $hash[$address]['invalid'],
|
||||
));
|
||||
$this->save($emailAddress);
|
||||
} else {
|
||||
if ($emailAddress->get('optOut') != $hash[$address]['optOut'] || $emailAddress->get('invalid') != $hash[$address]['invalid']) {
|
||||
$emailAddress->set(array(
|
||||
'optOut' => $hash[$address]['optOut'],
|
||||
'invalid' => $hash[$address]['invalid'],
|
||||
));
|
||||
$this->save($emailAddress);
|
||||
}
|
||||
}
|
||||
|
||||
$query = "
|
||||
INSERT entity_email_address
|
||||
(entity_id, entity_type, email_address_id, `primary`)
|
||||
VALUES
|
||||
(
|
||||
".$pdo->quote($entity->id).",
|
||||
".$pdo->quote($entity->getEntityName()).",
|
||||
".$pdo->quote($emailAddress->id).",
|
||||
".$pdo->quote($address === $primary)."
|
||||
)
|
||||
";
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
}
|
||||
|
||||
if ($primary) {
|
||||
$emailAddress = $this->getByAddress($primary);
|
||||
if ($emailAddress) {
|
||||
$query = "
|
||||
UPDATE entity_email_address
|
||||
SET `primary` = 0
|
||||
WHERE
|
||||
entity_id = ".$pdo->quote($entity->id)." AND
|
||||
entity_type = ".$pdo->quote($entity->getEntityName())." AND
|
||||
`primary` = 1 AND
|
||||
deleted = 0
|
||||
";
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
|
||||
$query = "
|
||||
UPDATE entity_email_address
|
||||
SET `primary` = 1
|
||||
WHERE
|
||||
entity_id = ".$pdo->quote($entity->id)." AND
|
||||
entity_type = ".$pdo->quote($entity->getEntityName())." AND
|
||||
email_address_id = ".$pdo->quote($emailAddress->id)." AND
|
||||
deleted = 0
|
||||
";
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
$entityRepository = $this->getEntityManager()->getRepository($entity->getEntityName());
|
||||
if (!empty($email)) {
|
||||
if ($email != $entity->getFetched('emailAddress')) {
|
||||
|
||||
$emailAddressNew = $this->where(array('lower' => strtolower($email)))->findOne();
|
||||
$isNewEmailAddress = false;
|
||||
if (!$emailAddressNew) {
|
||||
$emailAddressNew = $this->get();
|
||||
$emailAddressNew->set('name', $email);
|
||||
$this->save($emailAddressNew);
|
||||
$isNewEmailAddress = true;
|
||||
}
|
||||
|
||||
$emailOld = $entity->getFetched('emailAddress');
|
||||
if (!empty($emailOld)) {
|
||||
$emailAddressOld = $this->getByAddress($emailOld);
|
||||
$entityRepository->unrelate($entity, 'emailAddresses', $emailAddressOld);
|
||||
}
|
||||
$entityRepository->relate($entity, 'emailAddresses', $emailAddressNew);
|
||||
|
||||
$query = "
|
||||
UPDATE entity_email_address
|
||||
SET `primary` = 1
|
||||
WHERE
|
||||
entity_id = ".$pdo->quote($entity->id)." AND
|
||||
entity_type = ".$pdo->quote($entity->getEntityName())." AND
|
||||
email_address_id = ".$pdo->quote($emailAddressNew->id)."
|
||||
";
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
}
|
||||
} else {
|
||||
$emailOld = $entity->getFetched('emailAddress');
|
||||
if (!empty($emailOld)) {
|
||||
$emailAddressOld = $this->getByAddress($emailOld);
|
||||
$entityRepository->unrelate($entity, 'emailAddresses', $emailAddressOld);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,19 @@ class Preferences extends \Espo\Core\ORM\Repository
|
||||
protected $dependencies = array(
|
||||
'fileManager',
|
||||
'metadata',
|
||||
'config',
|
||||
);
|
||||
|
||||
protected $defaultAttributesFromSettings = array(
|
||||
'defaultCurrency',
|
||||
'dateFormat',
|
||||
'timeFormat',
|
||||
'decimalMark',
|
||||
'thousandSeparator',
|
||||
'weekStart',
|
||||
'timeZone',
|
||||
'language',
|
||||
'exportDelimiter'
|
||||
);
|
||||
|
||||
protected $data = array();
|
||||
@@ -45,6 +58,11 @@ class Preferences extends \Espo\Core\ORM\Repository
|
||||
return $this->getInjection('metadata');
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
{
|
||||
return $this->getInjection('config');
|
||||
}
|
||||
|
||||
protected function getFilePath($id)
|
||||
{
|
||||
return 'data/preferences/' . $id . '.json';
|
||||
@@ -69,6 +87,10 @@ class Preferences extends \Espo\Core\ORM\Repository
|
||||
$defaults[$field] = $d['default'];
|
||||
}
|
||||
}
|
||||
foreach ($this->defaultAttributesFromSettings as $attr) {
|
||||
$defaults[$attr] = $this->getConfig()->get($attr);
|
||||
}
|
||||
|
||||
$this->data[$id] = $defaults;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,8 @@
|
||||
"First Name": "Vorname",
|
||||
"Last Name": "Nachname",
|
||||
"You": "Sie",
|
||||
"you": "Sie"
|
||||
"you": "Sie",
|
||||
"change": "ändern"
|
||||
},
|
||||
"messages": {
|
||||
"notModified": "Sie haben den Datensatz nicht geändert",
|
||||
|
||||
@@ -63,7 +63,9 @@
|
||||
"phone": "Phone",
|
||||
"text": "Text",
|
||||
"url": "Url",
|
||||
"varchar": "Varchar"
|
||||
"varchar": "Varchar",
|
||||
"file": "File",
|
||||
"image": "Image"
|
||||
},
|
||||
"fields": {
|
||||
"type": "Type",
|
||||
@@ -79,7 +81,8 @@
|
||||
"field": "Field",
|
||||
"min": "Min",
|
||||
"max": "Max",
|
||||
"translation": "Translation"
|
||||
"translation": "Translation",
|
||||
"previewSize": "Preview Size"
|
||||
},
|
||||
"messages": {
|
||||
"upgradeVersion": "Your EspoCRM will be upgraded to version <strong>{version}</strong>. This can take some time.",
|
||||
@@ -107,5 +110,13 @@
|
||||
"layoutManager": "Customize layouts (list, detail, edit, search, mass update).",
|
||||
"fieldManager": "Create new fields or customize existing ones.",
|
||||
"userInterface": "Configure UI."
|
||||
},
|
||||
"options": {
|
||||
"previewSize": {
|
||||
"x-small": "X-Small",
|
||||
"small": "Small",
|
||||
"medium": "Medium",
|
||||
"large": "Large"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
7
application/Espo/Resources/i18n/en_US/EmailAddress.json
Normal file
7
application/Espo/Resources/i18n/en_US/EmailAddress.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"labels": {
|
||||
"Primary": "Primary",
|
||||
"Opted Out": "Opted Out",
|
||||
"Invalid": "Invalid"
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
"ScheduledJob": "Scheduled Jobs"
|
||||
},
|
||||
"labels": {
|
||||
"Misc": "Misc",
|
||||
"Merge": "Merge",
|
||||
"None": "None",
|
||||
"by": "by",
|
||||
@@ -103,8 +104,10 @@
|
||||
"Person": "Person",
|
||||
"First Name": "First Name",
|
||||
"Last Name": "Last Name",
|
||||
"Original": "Original",
|
||||
"You": "You",
|
||||
"you": "you"
|
||||
"you": "you",
|
||||
"change": "change"
|
||||
},
|
||||
"messages": {
|
||||
"notModified": "You have not modified the record",
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
"smtpUsername": "Username",
|
||||
"emailAddress": "Email",
|
||||
"smtpPassword": "Password",
|
||||
"smtpEmailAddress": "Email Address"
|
||||
"smtpEmailAddress": "Email Address",
|
||||
|
||||
"exportDelimiter": "Export Delimiter"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
"currencyList": "Currency List",
|
||||
"language": "Language",
|
||||
|
||||
"companyLogo": "Company Logo",
|
||||
|
||||
"smtpServer": "Server",
|
||||
"smtpPort": "Port",
|
||||
"smtpAuth": "Auth",
|
||||
@@ -25,7 +27,9 @@
|
||||
"recordsPerPage": "Records Per Page",
|
||||
"recordsPerPageSmall": "Records Per Page (Small)",
|
||||
"tabList": "Tab List",
|
||||
"quickCreateList": "Quick Create List"
|
||||
"quickCreateList": "Quick Create List",
|
||||
|
||||
"exportDelimiter": "Export Delimiter"
|
||||
},
|
||||
"options": {
|
||||
"weekStart": {
|
||||
|
||||
@@ -7,15 +7,26 @@
|
||||
"defaultTeam": "Default Team",
|
||||
"emailAddress": "Email",
|
||||
"phone": "Phone",
|
||||
"roles": "Roles",
|
||||
"roles": "Roles",
|
||||
"password": "Password",
|
||||
"passwordConfirm": "Confirm Password"
|
||||
"passwordConfirm": "Confirm Password",
|
||||
"newPassword": "New Password"
|
||||
},
|
||||
"links": {
|
||||
"teams": "Teams",
|
||||
"roles": "Roles"
|
||||
},
|
||||
"labels": {
|
||||
"Create User": "Create User"
|
||||
"Create User": "Create User",
|
||||
"Generate": "Generate",
|
||||
"Access": "Access",
|
||||
"Preferences": "Preferences",
|
||||
"Change Password": "Change Password"
|
||||
},
|
||||
"messages": {
|
||||
"passwordWillBeSent": "Password will be sent to user's email address.",
|
||||
"accountInfoEmailSubject": "Account info",
|
||||
"accountInfoEmailBody": "Your account information:\n\nUsername: {userName}\nPassword: {password}\n\n{siteUrl}",
|
||||
"passwordChanged": "Password has been changed"
|
||||
}
|
||||
}
|
||||
|
||||
122
application/Espo/Resources/i18n/es_ES/Admin.json
Normal file
122
application/Espo/Resources/i18n/es_ES/Admin.json
Normal file
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"labels": {
|
||||
"Enabled": "Activado",
|
||||
"Disabled": "Desactivado",
|
||||
"System": "Sistema",
|
||||
"Users": "Usuarios",
|
||||
"Email": "Correo electrónico",
|
||||
"Data": "Datos",
|
||||
"Customization": "Personalizar",
|
||||
"Available Fields": "Campos Disponibles",
|
||||
"Layout": "Diseño",
|
||||
"Enabled": "Activado",
|
||||
"Disabled": "Desactivado",
|
||||
"Add Panel": "Añadir Panel",
|
||||
"Add Field": "Añadir Campo",
|
||||
"Settings": "Opciones",
|
||||
"Scheduled Jobs": "Tareas Programadas",
|
||||
"Upgrade": "Actualizar",
|
||||
"Clear Cache": "Limpiar Cache",
|
||||
"Rebuild": "Reconstruir",
|
||||
"Users": "Usuarios",
|
||||
"Teams": "Equipos",
|
||||
"Roles": "Roles",
|
||||
"Outbound Emails": "Correos Salientes",
|
||||
"Inbound Emails": "Correos Entrantes",
|
||||
"Email Templates": "Platillas de Correo",
|
||||
"Import": "Importar",
|
||||
"Layout Manager": "Administrador de Diseño",
|
||||
"Field Manager": "Administrador de Campos",
|
||||
"User Interface": "Interfaz de Usuario"
|
||||
},
|
||||
"layouts": {
|
||||
"list": "Lista",
|
||||
"detail": "Detalle",
|
||||
"listSmall": "List (Small)",
|
||||
"detailSmall": "Detail (Small)",
|
||||
"filters": "Filtros de Búsqueda",
|
||||
"massUpdate": "Actualización Masiva",
|
||||
"relationships": "Relaciones"
|
||||
},
|
||||
"fieldTypes": {
|
||||
"address": "Dirección",
|
||||
"array": "Array",
|
||||
"foreign": "Foreign",
|
||||
"duration": "Duración",
|
||||
"password": "Contraseña",
|
||||
"parsonName": "Nombre",
|
||||
"autoincrement": "Auto incrementar",
|
||||
"bool": "Booleano",
|
||||
"currency": "Moneda",
|
||||
"date": "Fecha",
|
||||
"datetime": "Fecha/Hora",
|
||||
"email": "Correo electrónico",
|
||||
"enum": "Enum",
|
||||
"enumInt": "Enum Integer",
|
||||
"enumFloat": "Enum Float",
|
||||
"float": "Float",
|
||||
"int": "Int",
|
||||
"link": "Enlace",
|
||||
"linkMultiple": "Enlace Múltiple",
|
||||
"linkParent": "Enlace Padre",
|
||||
"multienim": "Multienum",
|
||||
"phone": "Teléfono",
|
||||
"text": "Texto",
|
||||
"url": "Url",
|
||||
"varchar": "Varchar",
|
||||
"file": "Archivo",
|
||||
"image": "Imagen"
|
||||
},
|
||||
"fields": {
|
||||
"type": "Tipo",
|
||||
"name": "Nombre",
|
||||
"label": "Etiqueta",
|
||||
"required": "Requerido",
|
||||
"default": "Por Defecto",
|
||||
"maxLength": "Longitud máxima",
|
||||
"options": "Options (raw values, not translated)",
|
||||
"after": "After (field)",
|
||||
"before": "Before (field)",
|
||||
"link": "Enlace",
|
||||
"field": "Campo",
|
||||
"min": "Mínimo",
|
||||
"max": "Máximo",
|
||||
"translation": "Traducción",
|
||||
"previewSize": "Tamaño de vista previa"
|
||||
},
|
||||
"messages": {
|
||||
"upgradeVersion": "Su EspoCRM será actualizado a la versión <strong>{version}</strong>. Tomará algún tiempo.",
|
||||
"upgradeDone": "Su EspoCRM ha sido actualizado a la versión <strong>{version}</strong>. Refresque su ventana del navegador.",
|
||||
"upgradeBackup": "Le recomendamos que haga copias de seguridad de sus archivos y datos EspoCRM antes de la actualización.",
|
||||
"thousandSeparatorEqualsDecimalMark": "El separador de miles no puede ser la misma que marca decimal",
|
||||
"userHasNoEmailAddress": "El usuario no tiene la dirección de correo electrónico.",
|
||||
"selectEntityType": "Seleccione el tipo de entidad en el menú de la izquierda.",
|
||||
"selectUpgradePackage": "Seleccione Actualizar Paquete",
|
||||
"selectLayout": "Seleccione el diseño necesario en el menú de la izquierda y editarlo."
|
||||
},
|
||||
"descriptions": {
|
||||
"settings": "Configuración del sistema de aplicación.",
|
||||
"scheduledJob": "Trabajos que se ejecutan por cron.(cron Jobs)",
|
||||
"upgrade": "Actualiza EspoCRM.",
|
||||
"clearCache": "Limpiar cache de Administración.",
|
||||
"rebuild": "Reconstruir y limpiar el cache de Administración.",
|
||||
"users": "Gestión de usuarios.",
|
||||
"teams": "Gestión de Equipos",
|
||||
"roles": "Gestión de Roles",
|
||||
"outboundEmails": "Opciones SMTP para correo saliente.",
|
||||
"inboundEmails": "Cuentas de correo IMAP Grupo. Importación-correo y dirección de correo electrónico a la sentencia.",
|
||||
"emailTemplates": "Plantillas para mensajes de correo electrónico salientes.",
|
||||
"import": "Importar datos desde CSV.",
|
||||
"layoutManager": "Customize layouts (list, detail, edit, search, mass update).",
|
||||
"fieldManager": "Crear nuevos campos o personalizar los ya existentes.",
|
||||
"userInterface": "Configurar UI."
|
||||
},
|
||||
"options": {
|
||||
"previewSize": {
|
||||
"x-small": "X-Small",
|
||||
"small": "Pequeño",
|
||||
"medium": "Mediano",
|
||||
"large": "Grande"
|
||||
}
|
||||
}
|
||||
}
|
||||
32
application/Espo/Resources/i18n/es_ES/Email.json
Normal file
32
application/Espo/Resources/i18n/es_ES/Email.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Asunto",
|
||||
"parent": "Padre",
|
||||
"status": "Estado",
|
||||
"dateSent": "Enviado",
|
||||
"from": "De",
|
||||
"to": "a",
|
||||
"cc": "CC",
|
||||
"bcc": "BCC",
|
||||
"isHtml": "Es Html",
|
||||
"body": "Cuerpo",
|
||||
"subject": "Asunto",
|
||||
"attachments": "Adjuntos",
|
||||
"selectTemplate": "Seleccione una Plantilla",
|
||||
"fromEmailAddress": "De la dirección",
|
||||
"toEmailAddresses": "a la Dirección",
|
||||
"emailAddress": "Correo Electrónico"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"Draft": "Borrador",
|
||||
"Sending": "Enviando",
|
||||
"Sent": "Enviado",
|
||||
"Archived": "Archivado"
|
||||
},
|
||||
"labels": {
|
||||
"Create Email": "Archivar Correo",
|
||||
"Compose": "Componer"
|
||||
}
|
||||
}
|
||||
7
application/Espo/Resources/i18n/es_ES/EmailAddress.json
Normal file
7
application/Espo/Resources/i18n/es_ES/EmailAddress.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"labels": {
|
||||
"Primary": "Primario",
|
||||
"Opted Out": "optado por no",
|
||||
"Invalid": "Inválido"
|
||||
}
|
||||
}
|
||||
16
application/Espo/Resources/i18n/es_ES/EmailTemplate.json
Normal file
16
application/Espo/Resources/i18n/es_ES/EmailTemplate.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"status": "Estado",
|
||||
"isHtml": "Es Html",
|
||||
"body": "Cuerpo",
|
||||
"subject": "Asunto",
|
||||
"attachments": "Adjuntos",
|
||||
"insertField": ""
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"labels": {
|
||||
"Create EmailTemplate": "Crear Plantilla de Correo"
|
||||
}
|
||||
}
|
||||
395
application/Espo/Resources/i18n/es_ES/Global.json
Normal file
395
application/Espo/Resources/i18n/es_ES/Global.json
Normal file
@@ -0,0 +1,395 @@
|
||||
{
|
||||
"scopeNames": {
|
||||
"Email": "Correo electrónico",
|
||||
"User": "Usuario",
|
||||
"Team": "Equipo",
|
||||
"Role": "Rol",
|
||||
"EmailTemplate": "Plantilla de Correo",
|
||||
"OutboundEmail": "Correo Saliente",
|
||||
"ScheduledJob": "Tarea Programada"
|
||||
},
|
||||
"scopeNamesPlural": {
|
||||
"Email": "Correos",
|
||||
"User": "Usuarios",
|
||||
"Team": "Equipos",
|
||||
"Role": "Roles",
|
||||
"EmailTemplate": "Platillas de Correo",
|
||||
"OutboundEmail": "Correos Salientes",
|
||||
"ScheduledJob": "Tareas Programadas"
|
||||
},
|
||||
"labels": {
|
||||
"Misc": "Misc",
|
||||
"Merge": "Fundir",
|
||||
"None": "Ninguno",
|
||||
"by": "por",
|
||||
"Saved": "Guardado",
|
||||
"Error": "Error",
|
||||
"Select": "Seleccionar",
|
||||
"Not valid": "Inválido",
|
||||
"Please wait...": "Por favor espere...",
|
||||
"Please wait": "Por favor espere",
|
||||
"Loading...": "Cargando...",
|
||||
"Uploading...": "Subiendo...",
|
||||
"Sending...": "Enviando...",
|
||||
"Posted": "Publicado",
|
||||
"Linked": "Enlazado",
|
||||
"Unlinked": "Desenlazado",
|
||||
"Access denied": "Acceso denegado",
|
||||
"Access": "Acceso",
|
||||
"Are you sure?": "Are you sure?",
|
||||
"Record has been removed": "Registro Eliminado",
|
||||
"Wrong username/password": "Nombre de usuario/contraseña incorrectos",
|
||||
"Post cannot be empty": "La entrada no puede estar vacia",
|
||||
"Removing...": "Removiendo...",
|
||||
"Unlinking...": "Desenlazando...",
|
||||
"Posting...": "Publicando...",
|
||||
"Username can not be empty!": "Nombre de usuario no puede estar vacío!",
|
||||
"Cache is not enabled": "Cache no está habilitado",
|
||||
"Cache has been cleared": "Cache Limpiado Correctamente",
|
||||
"Rebuild has been done": "Se ha reconstruido",
|
||||
"Saving...": "Guardando...",
|
||||
"Modified": "Modificado",
|
||||
"Created": "Creado",
|
||||
"Create": "Crear",
|
||||
"create": "crear",
|
||||
"Overview": "Vista",
|
||||
"Details": "Detalles",
|
||||
"Add Filter": "Añadir Filtro",
|
||||
"Add Dashlet": "Añadir Dashlet",
|
||||
"Add": "Añadir",
|
||||
"Reset": "Resetear",
|
||||
"Menu": "Menú",
|
||||
"More": "Más",
|
||||
"Search": "Buscar",
|
||||
"Only My": "Solo Yo",
|
||||
"Open": "Abrir",
|
||||
"Admin": "Administrador",
|
||||
"About": "Acerca",
|
||||
"Refresh": "Refrescar",
|
||||
"Remove": "Remover",
|
||||
"Options": "Optiones",
|
||||
"Username": "Nombre de Usuario",
|
||||
"Password": "Contraseña",
|
||||
"Login": "Entrar",
|
||||
"Log Out": "Salir",
|
||||
"Preferences": "Preferencias",
|
||||
"State": "Estado/Distrito",
|
||||
"Street": "Calle",
|
||||
"Country": "país",
|
||||
"City": "Ciudad",
|
||||
"PostalCode": "Código Postal",
|
||||
"Followed": "Seguido",
|
||||
"Follow": "Seguir",
|
||||
"Clear Local Cache": "Borrar Cache Local",
|
||||
"Actions": "Acciones",
|
||||
"Delete": "Borrar",
|
||||
"Update": "Actualizar",
|
||||
"Save": "Guardar",
|
||||
"Edit": "Editar",
|
||||
"Cancel": "Cancelar",
|
||||
"Unlink": "Desenlazar",
|
||||
"Mass Update": "Actualización Masiva",
|
||||
"Export": "Exportar",
|
||||
"No Data": "Sin Datos",
|
||||
"All": "Todos",
|
||||
"Active": "Activo",
|
||||
"Inactive": "Inactivo",
|
||||
"Write your comment here": "Escriba su comentario aquí",
|
||||
"Post": "Entrada",
|
||||
"Stream": "Stream",
|
||||
"Show more": "Mostrar mas",
|
||||
"Dashlet Options": "Opciones Dashlet",
|
||||
"Full Form": "Formulario Completo",
|
||||
"Insert": "Insertar",
|
||||
"Person": "Persona",
|
||||
"First Name": "Primer Nombre",
|
||||
"Last Name": "Apellidos",
|
||||
"Original": "Original",
|
||||
"You": "Tu",
|
||||
"you": "tu",
|
||||
"change": "cambiar"
|
||||
},
|
||||
"messages": {
|
||||
"notModified": "Usted no ha modificado el registro",
|
||||
"duplicate": "El registro que está creando parece ser un duplicado",
|
||||
"fieldIsRequired": "{field} es requerido",
|
||||
"fieldShouldBeEmail": "{field} debe se un correo electrónico válido",
|
||||
"fieldShouldBeFloat": "{field} debe se un decimal válido",
|
||||
"fieldShouldBeInt": "{field} debe se un entero válido",
|
||||
"fieldShouldBeDate": "{field} debe se una fecha válida",
|
||||
"fieldShouldBeDatetime": "{field} debe se una fecha válida fecha/hora",
|
||||
"fieldShouldAfter": "{field} debe estar después {otherField}",
|
||||
"fieldShouldBefore": "{field} debe estar antes {otherField}",
|
||||
"fieldShouldBeBetween": "{field} debe estar entre {min} and {max}",
|
||||
"fieldShouldBeLess": "{field} debe ser menor que {value}",
|
||||
"fieldShouldBeGreater": "{field} debe ser mayor que {value}",
|
||||
"fieldBadPasswordConfirm": "{field} confirmado de forma incorrecta"
|
||||
},
|
||||
"boolFilters": {
|
||||
"onlyMy": "Solo Yo",
|
||||
"open": "Abrir",
|
||||
"active": "Activo"
|
||||
},
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"firstName": "Primer Nombre",
|
||||
"lastName": "Apellidos",
|
||||
"salutationName": "Saludo",
|
||||
"assignedUser": "Usuario Asignado",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"assignedUserName": "Nombre de Usuario Asignado",
|
||||
"teams": "Equipos",
|
||||
"createdAt": "Creado el",
|
||||
"modifiedAt": "Modificado el",
|
||||
"createdBy": "Creado Por",
|
||||
"modifiedBy": "Modificado Por",
|
||||
"title": "Título",
|
||||
"dateFrom": "Fecha de",
|
||||
"dateTo": "Fecha Para",
|
||||
"autorefreshInterval": "Intervalo de Auto-Refrescar",
|
||||
"displayRecords": "Mostrar Registros"
|
||||
},
|
||||
"links": {
|
||||
"teams": "Equipos",
|
||||
"users": "Usuarios"
|
||||
},
|
||||
"dashlets": {
|
||||
"Stream": "Stream"
|
||||
},
|
||||
"streamMessages": {
|
||||
"create": "{user} creado {entityType} {entity}",
|
||||
"createAssigned": "{user} creado {entityType} {entity} asignado a {assignee}",
|
||||
"assign": "{user} asignado {entityType} {entity} a {assignee}",
|
||||
"post": "{user} publicado en {entityType} {entity}",
|
||||
"attach": "{user} adjunto en {entityType} {entity}",
|
||||
"status": "{user} actualizado {field} on {entityType} {entity}",
|
||||
"update": "{user} actualizado {entityType} {entity}",
|
||||
"createRelated": "{user} creado {relatedEntityType} {relatedEntity} enlazado a {entityType} {entity}",
|
||||
"emailReceived": "{entity} ha sido recibido por {entityType} {entity}",
|
||||
|
||||
"createThis": "{user} crear este {entityType}",
|
||||
"createAssignedThis": "{user} crear este {entityType} asignado a {assignee}",
|
||||
"assignThis": "{user} asignar este {entityType} a {assignee}",
|
||||
"postThis": "{user} publicado",
|
||||
"attachThis": "{user} adjunto",
|
||||
"statusThis": "{user} actualizado {field}",
|
||||
"updateThis": "{user} actualizado a este {entityType}",
|
||||
"createRelatedThis": "{user} creado {relatedEntityType} {relatedEntity} enlazado a este {entityType}",
|
||||
"emailReceivedThis": "{entity} se ha recibido"
|
||||
},
|
||||
"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"]
|
||||
},
|
||||
"options": {
|
||||
"salutationName": {
|
||||
"Mr.": "Sr.",
|
||||
"Mrs.": "Sra.",
|
||||
"Dr.": "Dr.",
|
||||
"Drs.": "Drs."
|
||||
},
|
||||
"language": {
|
||||
"af_ZA": "Afrikaans",
|
||||
"az_AZ": "Azerbaijani",
|
||||
"be_BY": "Belarusian",
|
||||
"bg_BG": "Bulgarian",
|
||||
"bn_IN": "Bengali",
|
||||
"bs_BA": "Bosnian",
|
||||
"ca_ES": "Catalan",
|
||||
"cs_CZ": "Czech",
|
||||
"cy_GB": "Welsh",
|
||||
"da_DK": "Danish",
|
||||
"de_DE": "German",
|
||||
"el_GR": "Greek",
|
||||
"en_GB":"English (UK)",
|
||||
"en_US":"English (US)",
|
||||
"es_ES":"Spanish (Spain)",
|
||||
"et_EE": "Estonian",
|
||||
"eu_ES": "Basque",
|
||||
"fa_IR": "Persian",
|
||||
"fi_FI": "Finnish",
|
||||
"fo_FO": "Faroese",
|
||||
"fr_CA":"French (Canada)",
|
||||
"fr_FR":"French (France)",
|
||||
"ga_IE": "Irish",
|
||||
"gl_ES": "Galician",
|
||||
"gn_PY": "Guarani",
|
||||
"he_IL": "Hebrew",
|
||||
"hi_IN": "Hindi",
|
||||
"hr_HR": "Croatian",
|
||||
"hu_HU": "Hungarian",
|
||||
"hy_AM": "Armenian",
|
||||
"id_ID": "Indonesian",
|
||||
"is_IS": "Icelandic",
|
||||
"it_IT": "Italian",
|
||||
"ja_JP": "Japanese",
|
||||
"ka_GE": "Georgian",
|
||||
"km_KH": "Khmer",
|
||||
"ko_KR": "Korean",
|
||||
"ku_TR": "Kurdish",
|
||||
"lt_LT": "Lithuanian",
|
||||
"lv_LV": "Latvian",
|
||||
"mk_MK": "Macedonian",
|
||||
"ml_IN": "Malayalam",
|
||||
"ms_MY": "Malay",
|
||||
"nb_NO":"Norwegian Bokmål",
|
||||
"nn_NO": "Norwegian Nynorsk",
|
||||
"ne_NP": "Nepali",
|
||||
"nl_NL": "Dutch",
|
||||
"pa_IN": "Punjabi",
|
||||
"pl_PL": "Polish",
|
||||
"ps_AF": "Pashto",
|
||||
"pt_BR":"Portuguese (Brazil)",
|
||||
"pt_PT":"Portuguese (Portugal)",
|
||||
"ro_RO": "Romanian",
|
||||
"ru_RU": "Russian",
|
||||
"sk_SK": "Slovak",
|
||||
"sl_SI": "Slovene",
|
||||
"sq_AL": "Albanian",
|
||||
"sr_RS": "Serbian",
|
||||
"sv_SE": "Swedish",
|
||||
"sw_KE": "Swahili",
|
||||
"ta_IN": "Tamil",
|
||||
"te_IN": "Telugu",
|
||||
"th_TH": "Thai",
|
||||
"tl_PH": "Tagalog",
|
||||
"tr_TR": "Turkish",
|
||||
"uk_UA": "Ukrainian",
|
||||
"ur_PK": "Urdu",
|
||||
"vi_VN": "Vietnamese",
|
||||
"zh_CN":"Simplified Chinese (China)",
|
||||
"zh_HK":"Traditional Chinese (Hong Kong)",
|
||||
"zh_TW":"Traditional Chinese (Taiwan)"
|
||||
},
|
||||
"dateSearchRanges": {
|
||||
"on": "Está en",
|
||||
"notOn": "No está en",
|
||||
"after": "Después",
|
||||
"before": "Antes",
|
||||
"between": "Entre"
|
||||
},
|
||||
"intSearchRanges": {
|
||||
"equals": "Iguales",
|
||||
"notEquals": "Diferentes",
|
||||
"greaterThan": "Mayor que",
|
||||
"lessThan": "Menor que",
|
||||
"greaterThanOrEquals": "Mayor o igual que",
|
||||
"lessThanOrEquals": "Menor o igual que",
|
||||
"between": "Entre"
|
||||
},
|
||||
"autorefreshInterval": {
|
||||
"0": "Ninguno",
|
||||
"0.5": "30 segundos",
|
||||
"1": "1 minuto",
|
||||
"2": "2 minutos",
|
||||
"5": "5 minutos",
|
||||
"10": "10 minutos"
|
||||
}
|
||||
},
|
||||
"sets": {
|
||||
"summernote": {
|
||||
"NOTICE": "Usted puede encontrar aquí la traducción: https://github.com/HackerWins/summernote/tree/master/lang",
|
||||
"font":{
|
||||
"bold": "Negrita",
|
||||
"italic": "Itálico",
|
||||
"underline": "Subrayado",
|
||||
"strike": "Tachado",
|
||||
"clear": "Quitar Estilo de Fuente",
|
||||
"height": "Alto de línea",
|
||||
"name": "Familia de Fuente",
|
||||
"size": "Tamaño de Fuente"
|
||||
},
|
||||
"image":{
|
||||
"image": "Imagen",
|
||||
"insert": "Insertar Imagen",
|
||||
"resizeFull": "Cambiar el tamaño a completo",
|
||||
"resizeHalf": "Cambiar el tamaño a la mitad",
|
||||
"resizeQuarter": "Cambiar el tamaño a un cuarto",
|
||||
"floatLeft": "Flotar Izquierda",
|
||||
"floatRight": "Flotar Derecha",
|
||||
"floatNone": "Sin Flotar",
|
||||
"dragImageHere": "Arrastrar una imagen aquí",
|
||||
"selectFromFiles": "Seleccionar desde Archivo",
|
||||
"url": "Url de Imagen",
|
||||
"remove": "Remover Imagen"
|
||||
},
|
||||
"link":{
|
||||
"link": "Enlace",
|
||||
"insert": "Insertar Enlace",
|
||||
"unlink": "Desenlazar",
|
||||
"edit": "Editar",
|
||||
"textToDisplay": "TExto a mostrar",
|
||||
"url":"To what URL should this link go?",
|
||||
"openInNewWindow": "Abrir en nueva ventana"
|
||||
},
|
||||
"video":{
|
||||
"video": "Vídeo",
|
||||
"videoLink": "Enlace al Vídeo",
|
||||
"insert": "Insertar Vídeo",
|
||||
"url":"Video URL?",
|
||||
"providers":"(YouTube, Vimeo, Vine, Instagram, or DailyMotion)"
|
||||
},
|
||||
"table":{
|
||||
"table": "Tabla"
|
||||
},
|
||||
"hr":{
|
||||
"insert": "Insertar regla horizontal"
|
||||
},
|
||||
"style":{
|
||||
"style": "Estilo",
|
||||
"normal": "Normal",
|
||||
"blockquote": "Cita",
|
||||
"pre": "Código",
|
||||
"h1": "Header 1",
|
||||
"h2": "Header 2",
|
||||
"h3": "Header 3",
|
||||
"h4": "Header 4",
|
||||
"h5": "Header 5",
|
||||
"h6": "Header 6"
|
||||
},
|
||||
"lists":{
|
||||
"unordered": "Lista sin Ordenar",
|
||||
"ordered": "Lista Ordenada"
|
||||
},
|
||||
"options":{
|
||||
"help": "Ayuda",
|
||||
"fullscreen": "Pantalla Completa",
|
||||
"codeview": "Ver Código"
|
||||
},
|
||||
"paragraph":{
|
||||
"paragraph": "Párrafo",
|
||||
"outdent": "Anular sangría",
|
||||
"indent": "Sangría",
|
||||
"left": "Alinear Izquierda",
|
||||
"center": "Alinear Centro",
|
||||
"right": "Alinear Derecha",
|
||||
"justify": "Justificado"
|
||||
},
|
||||
"color":{
|
||||
"recent": "Color Reciente",
|
||||
"more": "Mas Colores",
|
||||
"background": "Color de Fondo",
|
||||
"foreground": "Color de Fuente",
|
||||
"transparent": "Transparente",
|
||||
"setTransparent": "Establecer transparente",
|
||||
"reset": "Resetear",
|
||||
"resetToDefault": "Restablecer a (por defecto)"
|
||||
},
|
||||
"shortcut":{
|
||||
"shortcuts": "Atajos de teclado",
|
||||
"close": "Cerrar",
|
||||
"textFormatting": "Formato de texto",
|
||||
"action": "Acción",
|
||||
"paragraphFormatting": "Formato de párrafo",
|
||||
"documentStyle": "Estilo de Documento"
|
||||
},
|
||||
"history":{
|
||||
"undo": "Deshacer",
|
||||
"redo": "Rehacer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
application/Espo/Resources/i18n/es_ES/Note.json
Normal file
6
application/Espo/Resources/i18n/es_ES/Note.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"fields": {
|
||||
"post": "Entrada",
|
||||
"attachments": "Adjuntos"
|
||||
}
|
||||
}
|
||||
32
application/Espo/Resources/i18n/es_ES/Preferences.json
Normal file
32
application/Espo/Resources/i18n/es_ES/Preferences.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"fields": {
|
||||
"dateFormat": "Formato de fecha",
|
||||
"timeFormat": "Formato de tiempo",
|
||||
"timeZone": "Zona Horaria",
|
||||
"weekStart": "Primer día de la semana",
|
||||
"thousandSeparator": "Separador de miles",
|
||||
"decimalMark": "Separador decimal",
|
||||
"defaultCurrency": "Moneda por Defecto",
|
||||
"currencyList": "Lista de Moneda",
|
||||
"language": "Lenguaje",
|
||||
|
||||
"smtpServer": "Servidor",
|
||||
"smtpPort": "Puerto",
|
||||
"smtpAuth": "Autenticación",
|
||||
"smtpSecurity": "Securidad",
|
||||
"smtpUsername": "Nombre de Usuario",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"smtpPassword": "Contraseña",
|
||||
"smtpEmailAddress": "Correo Electrónico",
|
||||
|
||||
"exportDelimiter": "Export Delimiter"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
"options": {
|
||||
"weekStart": {
|
||||
"0": "Domingo",
|
||||
"1": "Lunes"
|
||||
}
|
||||
}
|
||||
}
|
||||
32
application/Espo/Resources/i18n/es_ES/Role.json
Normal file
32
application/Espo/Resources/i18n/es_ES/Role.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"roles": "Roles"
|
||||
},
|
||||
"links": {
|
||||
"users": "Usuarios",
|
||||
"teams": "Equipos"
|
||||
},
|
||||
"labels": {
|
||||
"Access": "Acceso",
|
||||
"Create Role": "Crear Rol"
|
||||
},
|
||||
"options": {
|
||||
"accessList": {
|
||||
"not-set": "sin establecer",
|
||||
"enabled": "activado",
|
||||
"disabled": "desactivado"
|
||||
},
|
||||
"levelList": {
|
||||
"all": "todos",
|
||||
"team": "equipo",
|
||||
"own": "propio",
|
||||
"no": "no"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"read": "Leer",
|
||||
"edit": "Editar",
|
||||
"delete": "Borrar"
|
||||
}
|
||||
}
|
||||
30
application/Espo/Resources/i18n/es_ES/ScheduledJob.json
Normal file
30
application/Espo/Resources/i18n/es_ES/ScheduledJob.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"status": "Estado",
|
||||
"job": "Trabajo",
|
||||
"scheduling": "Scheduling (crontab notation)"
|
||||
},
|
||||
"links": {
|
||||
"log": "Registro de Log"
|
||||
},
|
||||
"labels": {
|
||||
"Create ScheduledJob": "Crear Tarea programado"
|
||||
},
|
||||
"options": {
|
||||
"job": {
|
||||
"CheckInboundEmails": "Comprobar Correos Entrantes",
|
||||
"Cleanup": "Limpiar"
|
||||
},
|
||||
"cronSetup": {
|
||||
"linux": "Nota: Añada esta línea al archivo crontab para ejecutar trabajos Espo programadas:",
|
||||
"mac": "Nota: Añada esta línea al archivo crontab para ejecutar trabajos Espo programadas:",
|
||||
"windows": "Nota: Crear un archivo por lotes con los siguientes comandos para ejecutar tareas programadas usando Espo tareas programadas de Windows:",
|
||||
"default": "Note: Add this command to Cron Job (Scheduled Task):"
|
||||
},
|
||||
"status": {
|
||||
"Active": "Activo",
|
||||
"Inactive": "Inactivo"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"fields": {
|
||||
"status": "Estado",
|
||||
"executionTime": "Tiempo de Ejecución"
|
||||
}
|
||||
}
|
||||
44
application/Espo/Resources/i18n/es_ES/Settings.json
Normal file
44
application/Espo/Resources/i18n/es_ES/Settings.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"fields": {
|
||||
"useCache": "Usar Cache",
|
||||
"dateFormat": "Formato de fecha",
|
||||
"timeFormat": "Formato de tiempo",
|
||||
"timeZone": "Zona Horaria",
|
||||
"weekStart": "Primer día de la semana",
|
||||
"thousandSeparator": "Separador de miles",
|
||||
"decimalMark": "Separador decimal",
|
||||
"defaultCurrency": "Moneda por Defecto",
|
||||
"currencyList": "Lista de Moneda",
|
||||
"language": "Lenguaje",
|
||||
|
||||
"smtpServer": "Servidor",
|
||||
"smtpPort": "Puerto",
|
||||
"smtpAuth": "Autenticación",
|
||||
"smtpSecurity": "Securidad",
|
||||
"smtpUsername": "Nombre de Usuario",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"smtpPassword": "Contraseña",
|
||||
"outboundEmailFromName": "De Nombre",
|
||||
"outboundEmailFromAddress": "De la dirección",
|
||||
"outboundEmailIsShared": "Es Compartido",
|
||||
|
||||
"recordsPerPage": "Registros por Página",
|
||||
"recordsPerPageSmall": "Records Per Page (Small)",
|
||||
"tabList": "Lista Pestaña",
|
||||
"quickCreateList": "Crear Lista Rápido",
|
||||
|
||||
"exportDelimiter": "Export Delimiter"
|
||||
},
|
||||
"options": {
|
||||
"weekStart": {
|
||||
"0": "Domingo",
|
||||
"1": "Lunes"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"System": "Sistema",
|
||||
"Locale": "Localización",
|
||||
"SMTP": "SMTP",
|
||||
"Configuration": "Configuración"
|
||||
}
|
||||
}
|
||||
12
application/Espo/Resources/i18n/es_ES/Team.json
Normal file
12
application/Espo/Resources/i18n/es_ES/Team.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"roles": "Roles"
|
||||
},
|
||||
"links": {
|
||||
"users": "Usuarios"
|
||||
},
|
||||
"labels": {
|
||||
"Create Team": "Crear Equipo"
|
||||
}
|
||||
}
|
||||
21
application/Espo/Resources/i18n/es_ES/User.json
Normal file
21
application/Espo/Resources/i18n/es_ES/User.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": "Nombre",
|
||||
"userName": "Nombre de Usuario",
|
||||
"title": "Título",
|
||||
"isAdmin": "Es Administrador",
|
||||
"defaultTeam": "Equipo por Defecto",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"phone": "Teléfono",
|
||||
"roles": "Roles",
|
||||
"password": "Contraseña",
|
||||
"passwordConfirm": "Confirmar Contraseña"
|
||||
},
|
||||
"links": {
|
||||
"teams": "Equipos",
|
||||
"roles": "Roles"
|
||||
},
|
||||
"labels": {
|
||||
"Create User": "Crear Usuario"
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
{"name":"post"}
|
||||
],
|
||||
[
|
||||
{"name":"attachments","type": "attachmentMultiple"}
|
||||
{"name":"attachments"}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{"name":"post"}
|
||||
],
|
||||
[
|
||||
{"name":"attachments","type": "attachmentMultiple"}
|
||||
{"name":"attachments"}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,5 +22,11 @@
|
||||
[{"name": "smtpUsername"}],
|
||||
[{"name": "smtpPassword"}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Misc",
|
||||
"rows": [
|
||||
[{"name": "exportDelimiter"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
{
|
||||
"label": "System",
|
||||
"rows": [
|
||||
[{"name": "useCache"}]
|
||||
[{"name": "useCache"},{"name": "companyLogo"}]
|
||||
]
|
||||
},{
|
||||
},
|
||||
{
|
||||
"label": "Locale",
|
||||
"rows": [
|
||||
[{"name": "dateFormat"}, {"name": "timeZone"}],
|
||||
|
||||
@@ -1 +1,11 @@
|
||||
[{"label":"Overview","rows":[[{"name":"userName"},{"name":"isAdmin"}],[{"name":"name"},{"name":"title"}],[{"name":"defaultTeam"}],[{"name":"emailAddress"},{"name":"phone"}]]}]
|
||||
[
|
||||
{
|
||||
"label":"Overview",
|
||||
"rows":[
|
||||
[{"name":"userName"},{"name":"isAdmin"}],
|
||||
[{"name":"name"},{"name":"title"}],
|
||||
[{"name":"defaultTeam"}],
|
||||
[{"name":"emailAddress"},{"name":"phone"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"fields": {
|
||||
"token": {
|
||||
"type": "varchar",
|
||||
"maxLength": "36"
|
||||
},
|
||||
"hash": {
|
||||
"type": "varchar",
|
||||
"maxLength": "36",
|
||||
"index": true
|
||||
},
|
||||
"userId": {
|
||||
"type": "varchar",
|
||||
"maxLength": "36"
|
||||
},
|
||||
"ipAddress": {
|
||||
"type": "varchar",
|
||||
"maxLength": "36"
|
||||
},
|
||||
"lastAccess": {
|
||||
"type": "datetime"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
"readOnly": true
|
||||
},
|
||||
"modifiedAt": {
|
||||
"type": "datetime",
|
||||
"readOnly": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,8 @@
|
||||
"type": "linkParent"
|
||||
},
|
||||
"attachments": {
|
||||
"type": "linkMultiple"
|
||||
"type": "linkMultiple",
|
||||
"view": "Stream.Fields.AttachmentMultiple"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
@@ -44,6 +45,7 @@
|
||||
"attachments": {
|
||||
"type": "hasChildren",
|
||||
"entity": "Attachment",
|
||||
"relationName": "NoteAttachments",
|
||||
"foreign": "parent"
|
||||
},
|
||||
"parent": {
|
||||
|
||||
@@ -74,6 +74,12 @@
|
||||
"language": {
|
||||
"type": "enum",
|
||||
"default": "en_US"
|
||||
},
|
||||
"exportDelimiter": {
|
||||
"type": "varchar",
|
||||
"default": ",",
|
||||
"required": true,
|
||||
"maxLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,15 @@
|
||||
"type": "enum",
|
||||
"options": ["en_US"],
|
||||
"default": "en_US"
|
||||
},
|
||||
"exportDelimiter": {
|
||||
"type": "varchar",
|
||||
"default": ",",
|
||||
"required": true,
|
||||
"maxLength": 1
|
||||
},
|
||||
"companyLogo": {
|
||||
"type": "image"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
"type": "phone",
|
||||
"maxLength": 50
|
||||
},
|
||||
"token": {
|
||||
"type": "varchar",
|
||||
"notStorable": true
|
||||
},
|
||||
"defaultTeam": {
|
||||
"type": "link"
|
||||
},
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
],
|
||||
"fields":{
|
||||
"street":{
|
||||
"type":"varchar"
|
||||
"type": "text",
|
||||
"maxLength": 255,
|
||||
"dbType": "varchar"
|
||||
},
|
||||
"city":{
|
||||
"type":"varchar"
|
||||
@@ -24,7 +26,7 @@
|
||||
}
|
||||
},
|
||||
"mergable":false,
|
||||
"notCreatable": true,
|
||||
"notCreatable": false,
|
||||
"search":{
|
||||
"basic":false,
|
||||
"advanced":true
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"notCreatable": true,
|
||||
"fieldDefs": {
|
||||
"type": "linkMultiple"
|
||||
},
|
||||
"linkDefs": {
|
||||
"type": "hasChildren",
|
||||
"entity": "Attachment",
|
||||
"foreign": "parent"
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,6 @@
|
||||
"name":"required",
|
||||
"type":"bool",
|
||||
"default":false
|
||||
},
|
||||
{
|
||||
"name":"maxLength",
|
||||
"type":"int"
|
||||
}
|
||||
],
|
||||
"notCreatable": true,
|
||||
|
||||
26
application/Espo/Resources/metadata/fields/file.json
Normal file
26
application/Espo/Resources/metadata/fields/file.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"params":[
|
||||
{
|
||||
"name":"required",
|
||||
"type":"bool",
|
||||
"default":false
|
||||
}
|
||||
],
|
||||
"actualFields":[
|
||||
"id"
|
||||
],
|
||||
"notActualFields":[
|
||||
"name"
|
||||
],
|
||||
"fieldDefs":{
|
||||
"skip":true
|
||||
},
|
||||
"search":{
|
||||
"basic":false,
|
||||
"advanced":false
|
||||
},
|
||||
"linkDefs": {
|
||||
"type": "belongsTo",
|
||||
"entity": "Attachment"
|
||||
}
|
||||
}
|
||||
32
application/Espo/Resources/metadata/fields/image.json
Normal file
32
application/Espo/Resources/metadata/fields/image.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"params":[
|
||||
{
|
||||
"name":"required",
|
||||
"type":"bool",
|
||||
"default":false
|
||||
},
|
||||
{
|
||||
"name":"previewSize",
|
||||
"type":"enum",
|
||||
"default":"small",
|
||||
"options": ["x-small", "small", "medium", "large"]
|
||||
}
|
||||
],
|
||||
"actualFields":[
|
||||
"id"
|
||||
],
|
||||
"notActualFields":[
|
||||
"name"
|
||||
],
|
||||
"fieldDefs":{
|
||||
"skip":true
|
||||
},
|
||||
"search":{
|
||||
"basic":false,
|
||||
"advanced":false
|
||||
},
|
||||
"linkDefs": {
|
||||
"type": "belongsTo",
|
||||
"entity": "Attachment"
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,10 @@
|
||||
{
|
||||
"name":"default",
|
||||
"type":"text"
|
||||
},
|
||||
{
|
||||
"name":"maxLength",
|
||||
"type":"int"
|
||||
}
|
||||
],
|
||||
"search":{
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"entity": true,
|
||||
"layouts": false,
|
||||
"tab": false,
|
||||
"acl": false,
|
||||
"customizable":false
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user