Merge branch 'release/1.2' into stable

This commit is contained in:
Yuri Kuznetsov
2014-06-13 12:34:42 +03:00
93 changed files with 2145 additions and 194 deletions
+23 -1
View File
@@ -150,6 +150,27 @@ module.exports = function (grunt) {
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: {
@@ -205,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',
@@ -218,8 +240,8 @@ module.exports = function (grunt) {
'copy:backend',
'replace',
'copy:final',
'chmod',
'clean:final',
//'compress',
]);
};
+6
View File
@@ -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']);
}
}
+5
View File
@@ -218,6 +218,11 @@ class Acl
'edit' => 'no',
'delete' => 'no',
);
$this->data['Note'] = array(
'read' => 'all',
'edit' => 'own',
'delete' => 'own',
);
}
private function merge($tables)
+6 -2
View File
@@ -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'),
@@ -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)) {
+1 -1
View File
@@ -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);
+9
View File
@@ -154,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' =>
+54 -16
View File
@@ -37,7 +37,7 @@ class Image extends \Espo\Core\EntryPoints\Base
'image/gif',
);
protected $imageSizes = array(
protected $imageSizes = array(
'x-small' => array(64, 64),
'small' => array(128, 128),
'medium' => array(256, 256),
@@ -46,15 +46,24 @@ class Image extends \Espo\Core\EntryPoints\Base
'xx-large' => array(1024, 1024),
);
public function run()
{
$id = $_GET['id'];
if (empty($id)) {
throw new BadRequest();
}
$size = $_GET['size'];
}
$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) {
@@ -87,7 +96,18 @@ class Image extends \Espo\Core\EntryPoints\Base
if (!file_exists($thumbFilePath)) {
$targetImage = $this->getThumbImage($filePath, $fileType, $size);
ob_start();
imagejpeg($targetImage);
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);
@@ -117,7 +137,7 @@ class Image extends \Espo\Core\EntryPoints\Base
ob_clean();
flush();
readfile($filePath);
exit;
exit;
}
protected function getThumbImage($filePath, $fileType, $size)
@@ -125,30 +145,48 @@ class Image extends \Espo\Core\EntryPoints\Base
list($originalWidth, $originalHeight) = getimagesize($filePath);
list($width, $height) = $this->imageSizes[$size];
if ($originalWidth > $width && ($originalHeight <= $height || $originalWidth > $originalHeight)) {
$targetWidth = $width;
$targetHeight = $originalHeight * ($width / $originalWidth);
} else if ($originalHeight > $height && ($originalWidth <= $width || $originalHeight > $originalWidth)) {
$targetHeight = $height;
$targetWidth = $originalWidth * ($height / $originalHeight);
} else {
if ($originalWidth <= $width && $originalHeight <= $height) {
$targetWidth = $originalWidth;
$targetHeight = $originalHeight;
}
$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;
}
imagecopyresized($targetImage, $sourceImage, 0, 0, 0, 0, $targetWidth, $targetHeight, $originalWidth, $originalHeight);
return $targetImage;
}
@@ -18,21 +18,35 @@
*
* 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\EntryPoints;
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'));
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);
}
}
ob_clean();
echo json_encode($result);
@@ -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"
}
}
@@ -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"
}
}
@@ -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"
}
}
@@ -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"
}
}
@@ -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"
+15 -13
View File
@@ -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()
{
}
@@ -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;
}
}
@@ -18,6 +18,7 @@
"ScheduledJob": "Scheduled Jobs"
},
"labels": {
"Misc": "Misc",
"Merge": "Merge",
"None": "None",
"by": "by",
@@ -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"
}
}
@@ -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"
}
}
}
@@ -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"
}
}
@@ -0,0 +1,7 @@
{
"labels": {
"Primary": "Primario",
"Opted Out": "optado por no",
"Invalid": "Inválido"
}
}
@@ -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"
}
}
@@ -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"
}
}
}
}
@@ -0,0 +1,6 @@
{
"fields": {
"post": "Entrada",
"attachments": "Adjuntos"
}
}
@@ -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"
}
}
}
@@ -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"
}
}
@@ -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"
}
}
@@ -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"
}
}
@@ -0,0 +1,12 @@
{
"fields": {
"name": "Nombre",
"roles": "Roles"
},
"links": {
"users": "Usuarios"
},
"labels": {
"Create Team": "Crear Equipo"
}
}
@@ -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"
}
}
@@ -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"}]
]
}
]
@@ -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"
}
}
}
@@ -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
@@ -8,6 +8,10 @@
{
"name":"default",
"type":"text"
},
{
"name":"maxLength",
"type":"int"
}
],
"search":{
+15
View File
@@ -37,5 +37,20 @@ class Note extends Record
}
return $entity;
}
public function createEntity($data)
{
if (!empty($data['parentType']) && !empty($data['parentId'])) {
$entity = $this->getEntityManager()->getEntity($data['parentType'], $data['parentId']);
if ($entity) {
if (!$this->getAcl()->check($entity, 'read')) {
throw new Forbidden();
}
}
}
return parent::createEntity($data);
}
}
+13 -2
View File
@@ -42,6 +42,7 @@ class Record extends \Espo\Core\Services\Base
'serviceFactory',
'fileManager',
'selectManagerFactory',
'preferences'
);
protected $entityName;
@@ -104,6 +105,11 @@ class Record extends \Espo\Core\Services\Base
return $this->injections['config'];
}
protected function getPreferences()
{
return $this->injections['preferences'];
}
protected function getMetadata()
{
return $this->injections['metadata'];
@@ -531,12 +537,17 @@ class Record extends \Espo\Core\Services\Base
$row[$field] = $entity->get($field);
}
$arr[] = $row;
}
$delimiter = $this->getPreferences()->get('exportDelimiter');
if (empty($delimiter)) {
$delimiter = ',';
}
$fp = fopen('php://temp', 'w');
fputcsv($fp, array_keys($arr[0]));
fputcsv($fp, array_keys($arr[0]), $delimiter);
foreach ($arr as $row) {
fputcsv($fp, $row);
fputcsv($fp, $row, $delimiter);
}
rewind($fp);
$csv = stream_get_contents($fp);
+86 -18
View File
@@ -23,9 +23,27 @@
namespace Espo\Services;
use \Espo\Core\Exceptions\Forbidden;
use \Espo\Core\Exceptions\Error;
use \Espo\Core\Exceptions\NotFound;
class User extends Record
{
protected function init()
{
$this->dependencies[] = 'mailSender';
$this->dependencies[] = 'language';
}
protected function getMailSender()
{
return $this->injections['mailSender'];
}
protected function getLanguage()
{
return $this->injections['language'];
}
public function getEntity($id)
{
if ($id == 'system') {
@@ -53,32 +71,44 @@ class User extends Record
$entity->clear('password');
}
return $result;
}
public function changePassword($userId, $password)
{
$user = $this->getEntityManager()->getEntity('User', $userId);
if (!$user) {
throw new NotFound();
}
if (empty($password)) {
throw new Error('Password can\'t be empty.');
}
$user->set('password', $this->hashPassword($password));
$this->getEntityManager()->saveEntity($user);
return true;
}
protected function createDefaultPreferences(\Espo\Entities\User $user)
protected function hashPassword($password)
{
$preferences = $this->getEntityManager()->getEntity('Preferences', $user->id);
$config = $this->getConfig();
$defaults = array(
'timeZone' => $config->get('timeZone'),
'language' => $config->get('language'),
'dateFormat' => $config->get('dateFormat'),
'timeFormat' => $config->get('timeFormat'),
'weekStart' => $config->get('weekStart'),
'thousandSeparator' => $config->get('thousandSeparator'),
'decimalMark' => $config->get('decimalMark'),
);
$preferences->set($defaults);
$this->getEntityManager()->saveEntity($preferences);
return md5($password);
}
public function createEntity($data)
{
$newPassword = null;
if (array_key_exists('password', $data)) {
$data['password'] = md5($data['password']);
$newPassword = $data['password'];
$data['password'] = $this->hashPassword($data['password']);
}
$user = parent::createEntity($data);
$this->createDefaultPreferences($user);
if (!is_null($newPassword)) {
$this->sendPassword($user, $newPassword);
}
return $user;
}
@@ -87,10 +117,48 @@ class User extends Record
if ($id == 'system') {
throw new Forbidden();
}
$newPassword = null;
if (array_key_exists('password', $data)) {
$data['password'] = md5($data['password']);
$newPassword = $data['password'];
$data['password'] = $this->hashPassword($data['password']);
}
return parent::updateEntity($id, $data);
$user = parent::updateEntity($id, $data);
if (!is_null($newPassword)) {
$this->sendPassword($user, $newPassword);
}
return $user;
}
protected function sendPassword(Entity $user, $password)
{
// TODO use cron job
$emailAddress = $user->get('emailAddress');
if (empty($emailAddress)) {
return;
}
$email = $this->getEntityManager()->getEntity('Email');
$subject = $this->getLanguage()->translate('accountInfoEmailSubject', 'messages', 'User');
$body = $this->getLanguage()->translate('accountInfoEmailBody', 'messages', 'User');
$body = str_replace('{userName}', $user->get('userName'), $body);
$body = str_replace('{password}', $password, $body);
$body = str_replace('{siteUrl}', $this->getConfig()->get('siteUrl'), $body);
$email->set(array(
'subject' => $subject,
'body' => $body,
'isHtml' => false,
'to' => $emailAddress
));
$this->getMailSender()->send($email);
}
public function deleteEntity($id)
@@ -1,4 +1,4 @@
{{#if streetValue}}{{streetValue}}<br>{{/if}}
{{#if streetValue}}{{complexText streetValue}}<br>{{/if}}
{{cityValue}}{{#if stateValue}}, {{stateValue}}{{/if}}{{#if postalCodeValue}} {{postalCodeValue}}{{/if}}
{{#if countryValue}}<br>{{countryValue}}{{/if}}
@@ -1,4 +1,4 @@
<input type="text" class="form-control" name="{{name}}Street" value="{{streetValue}}" placeholder="{{translate 'Street'}}">
<textarea class="form-control" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<div class="row">
<div class="col-sm-4">
<input type="text" class="form-control" name="{{name}}City" value="{{cityValue}}" placeholder="{{translate 'City'}}">
@@ -1,2 +1,2 @@
<textarea class="main-element form-control" name="{{name}}" {{#if params.cols}} size="{{params.cols}}"{{/if}} {{#if params.rows}} rows="{{params.rows}}"{{/if}}>{{value}}</textarea>
<textarea class="main-element form-control" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} {{#if params.rows}} rows="{{params.rows}}"{{/if}}>{{value}}</textarea>
@@ -2,4 +2,4 @@
<link href="client/css/font-awesome.min.css" rel="stylesheet">
<link href="client/css/summernote.css" rel="stylesheet">
<textarea class="main-element form-control summernote" name="{{name}}" {{#if params.cols}} size="{{params.cols}}"{{/if}} {{#if params.rows}} rows="{{params.rows}}"{{/if}}>{{value}}</textarea>
<textarea class="main-element form-control summernote" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} {{#if params.rows}} rows="{{params.rows}}"{{/if}}>{{value}}</textarea>
+1 -1
View File
@@ -2,7 +2,7 @@
<div class="col-md-4 col-md-offset-4">
<div id="login" class="panel panel-default">
<div class="panel-heading" style="background-color: #4A6492; padding: 3px 10px;">
<img src="client/img/logo.png"></img>
<img src="{{logoSrc}}"></img>
</div>
<div class="panel-body">
<div>
@@ -0,0 +1,9 @@
<div class="cell cell-password form-group">
<label class="field-label-password control-label">{{translate 'newPassword' scope='User' category='fields'}}</label>
<div class="field field-password">{{{password}}}</div>
</div>
<div class="cell cell-passwordConfirm form-group">
<label class="field-label-passwordConfirm control-label">{{translate 'passwordConfirm' scope='User' category='fields'}}</label>
<div class="field field-passwordConfirm">{{{passwordConfirm}}}</div>
</div>
@@ -1,7 +1,7 @@
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#"><img src="client/img/logo.png"></a>
<a class="navbar-brand" href="#"><img src="{{logoSrc}}"></a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-body">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
+4 -1
View File
@@ -182,6 +182,7 @@ _.extend(Espo.App.prototype, {
_initBaseController: function () {
this.baseController = new Espo['Controllers.Base']({}, this._getControllerInjection());
this._viewHelper.baseController = this.baseController;
},
_getControllerInjection: function () {
@@ -430,7 +431,9 @@ _.extend(Espo.App.prototype, {
case 401:
if (!options.login) {
Espo.Ui.error(self.language.translate('Auth error'));
self.logout();
if (self.auth) {
self.logout();
}
}
break;
case 403:
+3 -3
View File
@@ -80,9 +80,9 @@ _.extend(Espo.LayoutManager.prototype, {
this.cache.set('app-layout', key, layout);
}
}.bind(this),
error: function () {
throw new Error('Could not load layout ' + controller + '#' + type);
},
/*error: function () {
console.error('Could not load layout ' + controller + '#' + type);
},*/
});
},
+6
View File
@@ -131,6 +131,12 @@
return this._helper.fieldManager;
}
},
getBaseController: function () {
if (this._helper) {
return this._helper.baseController;
}
},
updatePageTitle: function () {
var title = this.getConfig().get('applicationTitle') || 'EspoCRM';
@@ -51,6 +51,20 @@ Espo.define('Views.Fields.Address', 'Views.Fields.Base', function (Dep) {
this.$state = this.$el.find('[name="' + this.stateField + '"]');
this.$city = this.$el.find('[name="' + this.cityField + '"]');
this.$country = this.$el.find('[name="' + this.countryField + '"]');
this.$street.on('input', function (e) {
var numberOfLines = e.currentTarget.value.split('\n').length;
var numberOfRows = this.$street.prop('rows');
if (numberOfRows < numberOfLines) {
this.$street.prop('rows', numberOfLines);
} else if (numberOfRows > numberOfLines) {
this.$street.prop('rows', numberOfLines);
}
}.bind(this));
var numberOfLines = this.$street.val().split('\n').length;
this.$street.prop('rows', numberOfLines);
}
},
+14
View File
@@ -43,6 +43,20 @@ Espo.define('Views.Login', 'View', function (Dep) {
},
},
data: function () {
return {
logoSrc: this.getLogoSrc()
};
},
getLogoSrc: function () {
var companyLogoId = this.getConfig().get('companyLogoId');
if (!companyLogoId) {
return 'client/img/logo.png';
}
return '?entryPoint=LogoImage&size=small-logo';
},
login: function () {
var userName = $("#field-userName").val();
var password = $("#field-password").val();
+3
View File
@@ -47,6 +47,9 @@ Espo.define('Views.Modal', 'View', function (Dep) {
var id = this.cssName + '-container-' + Math.floor((Math.random() * 10000) + 1).toString();
var containerSelector = this.containerSelector = '#' + id;
this.options = this.options || {};
this.options.el = this.containerSelector;
this.on('render', function () {
$(containerSelector).remove();
$('<div />').css('display', 'none').attr('id', id).appendTo('body');
@@ -0,0 +1,116 @@
/************************************************************************
* 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/.
************************************************************************/
Espo.define('Views.Modals.ChangePassword', 'Views.Modal', function (Dep) {
return Dep.extend({
cssName: 'change-password',
template: 'modals.change-password',
setup: function () {
this.buttons = [
{
name: 'change',
label: 'Change',
style: 'danger',
onClick: function (dialog) {
this.changePassword();
}.bind(this)
},
{
name: 'cancel',
label: 'Cancel',
onClick: function (dialog) {
dialog.close();
}
}
];
this.header = this.translate('Change Password', 'labels', 'User');
this.wait(true);
this.getModelFactory().create('User', function (user) {
this.model = user;
this.createView('password', 'Fields.Password', {
model: user,
mode: 'edit',
el: this.options.el + ' .field-password',
defs: {
name: 'password',
params: {
required: true,
}
}
});
this.createView('passwordConfirm', 'Fields.Password', {
model: user,
mode: 'edit',
el: this.options.el + ' .field-passwordConfirm',
defs: {
name: 'passwordConfirm',
params: {
required: true,
}
}
});
this.wait(false);
}, this);
},
changePassword: function () {
this.getView('password').fetchToModel();
this.getView('passwordConfirm').fetchToModel();
var notValid = this.getView('password').validate() || this.getView('passwordConfirm').validate();
if (notValid) {
return;
}
this.$el.find('button[data-name="change"]').addClass('disabled');
$.ajax({
url: 'User/action/changeOwnPassword',
type: 'POST',
data: JSON.stringify({
password: this.model.get('password')
}),
error: function () {
this.$el.find('button[data-name="change"]').removeClass('disabled');
}.bind(this)
}).done(function () {
Espo.Ui.success(this.translate('passwordChanged', 'messages', 'User'));
this.trigger('changed');
this.close();
}.bind(this));
},
});
});
@@ -33,6 +33,8 @@ Espo.define('Views.Record.ListExpanded', 'Views.Record.List', function (Dep) {
_internalLayoutType: 'list-row-expanded',
presentationType: 'expanded',
pagination: false,
header: false,
+4 -2
View File
@@ -26,11 +26,13 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
template: 'record.list',
/**
* @param {String} Type of the list. Can be 'list', 'related-list', 'dashlet-list'.
* @param {String} Type of the list. Can be 'list', 'listSmall'.
*/
type: 'list',
name: 'list',
presentationType: 'table',
/**
* @param {Bool} If true checkboxes will be shown.
@@ -545,7 +547,7 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
this.rows.push(key);
this.getInternalLayout(function (internalLayout) {
if (this.type == 'list' && Object.prototype.toString.call(internalLayout) === '[object Array]') {
if (this.presentationType == 'table' && Object.prototype.toString.call(internalLayout) === '[object Array]') {
internalLayout.forEach(function (item) {
item.el = this.options.el + ' tr[data-id="' + model.id + '"] td.cell-' + item.name;
}, this);
+10 -1
View File
@@ -36,6 +36,7 @@ Espo.define('Views.Site.Navbar', 'View', function (Dep) {
enableQuickCreate: this.quickCreateList.length > 0,
userName: this.getUser().get('name'),
userId: this.getUser().id,
logoSrc: this.getLogoSrc()
};
},
@@ -59,9 +60,17 @@ Espo.define('Views.Site.Navbar', 'View', function (Dep) {
});
},
},
getLogoSrc: function () {
var companyLogoId = this.getConfig().get('companyLogoId');
if (!companyLogoId) {
return 'client/img/logo.png';
}
return '?entryPoint=LogoImage&size=small-logo';
},
setup: function () {
this.getRouter().on('routed', function (e) {
this.getRouter().on('routed', function (e) {
if (e.controller) {
this.selectTab(e.controller);
} else {
+1 -1
View File
@@ -35,7 +35,7 @@ Espo.define('Views.Stream.List', 'Views.Record.ListExpanded', function (Dep) {
this.createView(key, viewName, {
model: model,
acl: {
edit: this.getUser().isAdmin() || model.get('createdById') == this.getUser().id
edit: this.getAcl().checkModel(model)// this.getUser().isAdmin() || model.get('createdById') == this.getUser().id
},
isUserStream: this.options.isUserStream,
optionsToPass: ['acl'],
+5 -1
View File
@@ -168,7 +168,11 @@ Espo.define('Views.Stream.Panel', 'Views.Record.Panels.Relationship', function (
model.set('type', 'Post');
this.notify('Posting...');
model.save();
model.save(null, {
error: function () {
this.$textarea.prop('disabled', false);
}.bind(this)
});
}.bind(this));
},
@@ -0,0 +1,41 @@
/************************************************************************
* 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/.
************************************************************************/
Espo.define('Views.User.Fields.GeneratePassword', 'Views.Fields.Base', function (Dep) {
return Dep.extend({
_template: '<button type="button" class="btn" data-action="generatePassword">{{translate \'Generate\' scope=\'User\'}}</button>',
events: {
'click [data-action="generatePassword"]': function () {
var password = Math.random().toString(36).slice(-8);
$('input[name="password"]').val(password);
$('input[name="passwordConfirm"]').val(password);
}
},
fetch: function () {
return {};
},
});
});
@@ -46,6 +46,14 @@ Espo.define('Views.User.Record.Detail', 'Views.Record.Detail', function (Dep) {
style: 'default'
});
}
if (this.model.id == this.getUser().id) {
this.buttons.push({
name: 'changePassword',
label: 'Change Password',
style: 'default'
});
}
}
if (this.model.id == this.getUser().id) {
@@ -55,6 +63,24 @@ Espo.define('Views.User.Record.Detail', 'Views.Record.Detail', function (Dep) {
}
},
actionChangePassword: function () {
this.notify('Loading...');
this.createView('changePassword', 'Modals.ChangePassword', {
userId: this.model.id
}, function (view) {
view.render();
this.notify(false);
this.listenToOnce(view, 'changed', function () {
setTimeout(function () {
this.getBaseController().logout();
}.bind(this), 2000);
}, this);
}.bind(this));
},
actionPreferences: function () {
this.getRouter().navigate('#Preferences/edit/' + this.model.id, {trigger: true});
},
@@ -74,7 +100,7 @@ Espo.define('Views.User.Record.Detail', 'Views.Record.Detail', function (Dep) {
model: this.model,
}, function (view) {
this.notify(false);
view.render();
view.render();
}.bind(this));
}.bind(this));
+32 -21
View File
@@ -43,32 +43,43 @@ Espo.define('Views.User.Record.Edit', 'Views.Record.Edit', function (Dep) {
var layout = _.clone(simpleLayout);
layout.push({
label: 'Password',
rows: [
[{
name: 'password',
type: 'password',
params: {
required: self.isNew,
readyToChange: true
}
}],
[{
name: 'passwordConfirm',
type: 'password',
params: {
required: self.isNew,
readyToChange: true
}
}]
],
});
if (this.type == 'edit') {
layout.push({
label: 'Password',
rows: [
[{
name: 'password',
type: 'password',
params: {
required: self.isNew,
readyToChange: true
}
},{
name: 'generatePassword',
view: 'User.Fields.GeneratePassword',
customLabel: ''
}],
[{
name: 'passwordConfirm',
type: 'password',
params: {
required: self.isNew,
readyToChange: true
}
},{
name: 'passwordInfo',
customLabel: '',
customCode: '{{translate "passwordWillBeSent" scope="User" category="messages"}}'
}]
],
});
}
var gridLayout = {
type: 'record',
layout: this.convertDetailLayout(layout),
};
callback(gridLayout);
}.bind(this));
},
-42
View File
@@ -35,17 +35,6 @@ class Installer
protected $permissionError;
/**
* Ajax Urls, pairs: url:directory (if bad permission)
*
* @var array
*/
protected $ajaxUrls = array(
'api/v1/Settings' => 'api',
'client/res/templates/login.tpl' => 'client/res/templates',
);
protected $settingList = array(
'dateFormat',
'timeFormat',
@@ -59,7 +48,6 @@ class Installer
);
public function __construct()
{
$this->app = new \Espo\Core\Application();
@@ -172,10 +160,6 @@ class Installer
$data = array_merge($data, $initData);
$result = $this->saveConfig($data);
/*if ($result) {
$this->app = new \Espo\Core\Application();
}*/
return $result;
}
@@ -327,32 +311,6 @@ class Installer
return $this->getFileManager()->getPermissionUtils()->getLastErrorRules();
}
public function getAjaxUrls()
{
return array_keys($this->ajaxUrls);
}
public function fixAjaxPermission($url = null)
{
$permission = array(0644, 0755);
$fileManager = $this->getFileManager();
$result = false;
if (!isset($url)) {
$uniqueList = array_unique($this->ajaxUrls);
foreach ($uniqueList as $url => $path) {
$result = $fileManager->getPermissionUtils()->chmod($path, $permission, true);
}
} else {
if (isset($this->ajaxUrls[$url])) {
$path = $this->ajaxUrls[$url];
$result = $fileManager->getPermissionUtils()->chmod($path, $permission, true);
}
}
return $result;
}
public function setSuccess()
{
$config = $this->app->getContainer()->get('config');
+1 -1
View File
@@ -234,7 +234,7 @@ class SystemHelper extends \Espo\Core\Utils\System
$commands[] = $chown;
}
return implode(' ' . $this->combineOperator . ' ', $commands);
return implode(' ' . $this->combineOperator . ' ', $commands).';';
}
protected function getCd($isCombineOperator = false)
+1
View File
@@ -27,6 +27,7 @@ $result = array('success' => true, 'errorMsg' => '');
$data = array(
'driver' => 'pdo_mysql',
'host' => $_SESSION['install']['host-name'],
'port' => $_SESSION['install']['port'],
'dbname' => $_SESSION['install']['db-name'],
'user' => $_SESSION['install']['db-user-name'],
'password' => $_SESSION['install']['db-user-password'],
+2 -2
View File
@@ -34,8 +34,8 @@ if (!$installer->checkPermission()) {
$instruction = '';
$instructionSU = '';
foreach($group as $permission => $folders) {
$instruction .= $systemHelper->getPermissionCommands(array($folders, ''), explode('-', $permission)) . ";<br>";
$instructionSU .= "&nbsp;&nbsp;" . $systemHelper->getPermissionCommands(array($folders, ''), explode('-', $permission), true) . ";<br>";
$instruction .= $systemHelper->getPermissionCommands(array($folders, ''), explode('-', $permission)) . "<br>";
$instructionSU .= "&nbsp;&nbsp;" . $systemHelper->getPermissionCommands(array($folders, ''), explode('-', $permission), true) . "<br>";
}
$result['errorMsg'] = $langs['messages']['Permission denied to'] . ':<br><pre>/'.implode('<br>/', $urls).'</pre>';
$result['errorFixInstruction'] = str_replace( '"{C}"' , $instruction, $langs['messages']['permissionInstruction']) . "<br>" .
+1
View File
@@ -24,6 +24,7 @@ $fields = array(
'db-name' => array(),
'host-name' => array(
'default' => (isset($langs['labels']['localhost']))? $langs['labels']['localhost'] : '',),
'port' => array(),
'db-user-name' => array(),
'db-user-password' => array(),
'db-driver' => array()
+110
View File
@@ -0,0 +1,110 @@
{
"labels": {
"Main page title": "Welcome to EspoCRM",
"Main page header": "",
"Start page title": "License Agreement",
"Step1 page title": "License Agreement",
"License Agreement": "License Agreement",
"I accept the agreement": "I accept the agreement",
"Step2 page title": "Database configuration",
"Step3 page title": "Administrator Setup",
"Step4 page title": "System settings",
"Step5 page title": "SMTP settings for outgoing emails",
"Errors page title": "Errors",
"Finish page title": "Installation is complete",
"Congratulation! Welcome to EspoCRM!": "Congratulation! EspoCRM has been successfully installed.",
"admin": "admin",
"localhost": "localhost",
"port": "3306",
"Locale": "Locale",
"Outbound Email Configuration": "Outbound Email Configuration",
"SMTP": "SMTP",
"Start": "Start",
"Back": "Back",
"Next": "Next",
"Go to EspoCRM": "Go to EspoCRM",
"Re-check": "Re-check",
"Test settings": "Test Connection"
},
"fields": {
"Choose your language:": "Choose your language:",
"Database Name": "Database Name",
"Host Name": "Host Name",
"Port": "Port",
"Database User Name": "Database User Name",
"Database User Password": "Database User Password",
"Database driver": "Database driver",
"User Name": "User Name",
"Password": "Password",
"Confirm Password": "Confirm your Password",
"From Address": "From Address",
"From Name": "From Name",
"Is Shared": "Is Shared",
"Date Format": "Date Format",
"Time Format": "Time Format",
"Time Zone": "Time Zone",
"First Day of Week": "First Day of Week",
"Thousand Separator": "Thousand Separator",
"Decimal Mark": "Decimal Mark",
"Default Currency": "Default Currency",
"Currency List": "Currency List",
"Language": "Language",
"smtpServer": "Server",
"smtpPort": "Port",
"smtpAuth": "Auth",
"smtpSecurity": "Security",
"smtpUsername": "Username",
"emailAddress": "Email",
"smtpPassword": "Password"
},
"messages": {
"Bad init Permission": "Permission denied for \"{*}\" directory. Please set 775 for \"{*}\" or just execute this command in the terminal <pre><b>{C}<\/b><\/pre>\n\tOperation not permitted? Try this one: {CSU}",
"Some errors occurred!": "Some errors occurred!",
"Supported php version >=": "Supported php version >=",
"The PHP extension was not found...": "The <b>{extName}<\/b> PHP extension was not found...",
"All Settings correct": "All Settings are correct",
"Failed to connect to database": "Failed to connect to database",
"PHP version:": "PHP version:",
"You must agree to the license agreement": "You must agree to the license agreement",
"Passwords do not match": "Passwords do not match",
"Enable mod_rewrite in Apache server": "Enable mod_rewrite in Apache server",
"checkWritable error": "checkWritable error",
"applySett error": "applySett error",
"buildDatabse error": "buildDatabse error",
"createUser error": "createUser error",
"checkAjaxPermission error": "checkAjaxPermission error",
"Ajax failed": "Ajax failed",
"Cannot create user": "Cannot create user",
"Permission denied": "Permission denied",
"permissionInstruction": "<br>Run this in Terminal<pre><b>\"{C}\"<\/b><\/pre>",
"operationNotPermitted" : "Operation not permitted? Try this: <br>{CSU}",
"Permission denied to": "Permission denied",
"Can not save settings": "Can not save settings",
"Cannot save preferences": "Cannot save preferences",
"Thousand Separator and Decimal Mark equal": "Thousand Separator and Decimal Mark cannot be equal",
"1049": "Unknown database",
"2005": "Unknown MySQL server host",
"1045": "Access denied for user"
},
"options": {
"db driver": {
"mysqli": "MySQLi",
"pdo_mysql": "PDO MySQL"
},
"modRewriteInstruction": {
"apache": {
"linux": "<br><br>To enable .htaccess support add/edit the Server configuration settings inside your &#60;VirtualHost&#62; section (httpd.conf):<pre>&#60;Directory \/PATH_TO_ESPO\/&#62;\n <b>AllowOverride All<\/b>\n&#60;\/Directory&#62;<\/pre>\n Afterwards run this command in a Terminal:<pre><b>service apache2 restart<\/b><\/pre><br>To enable \"mod_rewrite\" run those commands in a Terminal:<pre><b>a2enmod rewrite <br>service apache2 restart<\/b><\/pre>",
"windows": "<br> <pre>1. Find the httpd.conf file (usually you will find it in a folder called conf, config or something along those lines)<br>\n2. Inside the httpd.conf file uncomment the line LoadModule rewrite_module modules\/mod_rewrite.so (remove the pound '#' sign from in front of the line)<br>\n3. Also find the line ClearModuleList is uncommented then find and make sure that the line AddModule mod_rewrite.c is not commented out.\n<\/pre>"
},
"microsoft-iis": {
"windows": ""
}
},
"modRewriteHelp": {
"apache": "API Error: EspoCRM API unavailable.<br> Possible problems: disabled \"mod_rewrite\" in Apache server or .htaccess support.",
"nginx": "API Error: EspoCRM API unavailable.<br> Add this code to Nginx Host Config (inside \"server\" block):<br>\n<pre>\nlocation \/api\/v1\/ {\n if (!-e $request_filename){\n rewrite ^\/api\/v1\/(.*)$ \/api\/v1\/index.php last; break;\n }\n}\n\nlocation \/ {\n rewrite reset\/?$ reset.html break;\n}<\/pre>",
"microsoft-iis": "API Error: EspoCRM API unavailable.<br> Possible problem: disabled \"URL Rewrite\". Please check and enable \"URL Rewrite\" Module in IIS server",
"default": "API Error: EspoCRM API unavailable.<br> Possible problem: disabled Rewrite Module. Please check and enable Rewrite Module in your server (e.g. mod_rewrite in Apache) and .htaccess support."
}
}
}
+2
View File
@@ -15,6 +15,7 @@
"Congratulation! Welcome to EspoCRM!": "Congratulation! EspoCRM has been successfully installed.",
"admin": "admin",
"localhost": "localhost",
"port": "3306",
"Locale": "Locale",
"Outbound Email Configuration": "Outbound Email Configuration",
"SMTP": "SMTP",
@@ -29,6 +30,7 @@
"Choose your language:": "Choose your language:",
"Database Name": "Database Name",
"Host Name": "Host Name",
"Port": "Port",
"Database User Name": "Database User Name",
"Database User Password": "Database User Password",
"Database driver": "Database driver",
+109
View File
@@ -0,0 +1,109 @@
{
"labels": {
"Main page title": "Bienvenido a EspoCRM(Español)",
"Main page header": "",
"Start page title": "Contrato de licencia",
"Step1 page title": "Contrato de licencia",
"License Agreement": "Contrato de licencia",
"I accept the agreement": "Acepto el contrato",
"Step2 page title": "Configuración de la Base de Datos",
"Step3 page title": "Configuración de administrador",
"Step4 page title": "Opciones de Sistema",
"Step5 page title": "Configuración SMTP para los correos salientes",
"Errors page title": "Errores",
"Finish page title": "La instalación ha finalizado",
"Congratulation! Welcome to EspoCRM!": "¡Enhorabuena! EspoCRM(Español) se ha instalado correctamente.",
"admin": "admin",
"localhost": "localhost",
"Locale": "Localización",
"Outbound Email Configuration": "Configuración de Correo Saliente",
"SMTP": "SMTP",
"Start": "Comenzar",
"Back": "Anterior",
"Next": "Siguiente",
"Go to EspoCRM": "Ir a EspoCRM(Español)",
"Re-check": "Revisar otra vez",
"Test settings": "Test de conexión"
},
"fields": {
"Choose your language:": "Seleccione un lenguaje:",
"Database Name": "Nombre de la Base de Datos",
"Host Name": "Hostname usualmente(localhost)",
"Port": "Puerto",
"Database User Name": "Usuario de la Base de Datos",
"Database User Password": "Contraseña de la Base de Datos",
"Database driver": "Controlador de base de datos",
"User Name": "Nombre de Usuario",
"Password": "Contraseña",
"Confirm Password": "Confirme su contraseña",
"From Address": "De la dirección",
"From Name": "De Nombre",
"Is Shared": "Es Compartido",
"Date Format": "Formato de fecha",
"Time Format": "Formato de tiempo",
"Time Zone": "Zona Horaria",
"First Day of Week": "Primer día de la semana",
"Thousand Separator": "Separador de miles",
"Decimal Mark": "Separador decimal",
"Default Currency": "Moneda por Defecto",
"Currency List": "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"
},
"messages": {
"Bad init Permission": "Permission denied for \"{*}\" directory. Please set 775 for \"{*}\" or just execute this command in the terminal <pre><b>{C}<\/b><\/pre>\n\tOperation not permitted? Try this one: {CSU}",
"Some errors occurred!": "Some errors occurred!",
"Supported php version >=": "Supported php version >=",
"The PHP extension was not found...": "The <b>{extName}<\/b> PHP extension was not found...",
"All Settings correct": "All Settings are correct",
"Failed to connect to database": "Failed to connect to database",
"PHP version: ": "PHP version:",
"You must agree to the license agreement": "Usted debe aceptar el acuerdo de licencia",
"Passwords do not match": "Passwords do not match",
"Enable mod_rewrite in Apache server": "Enable mod_rewrite in Apache server",
"checkWritable error": "checkWritable error",
"applySett error": "applySett error",
"buildDatabse error": "buildDatabse error",
"createUser error": "createUser error",
"checkAjaxPermission error": "checkAjaxPermission error",
"Ajax failed": "Ajax failed",
"Cannot create user": "Cannot create user",
"Permission denied": "Permission denied",
"permissionInstruction": "<br>Run this in Terminal<pre><b>\"{C}\"<\/b><\/pre>",
"operationNotPermitted" : "Operation not permitted? Try this: <br>{CSU}",
"Permission denied to": "Permission denied",
"Can not save settings": "Can not save settings",
"Cannot save preferences": "Cannot save preferences",
"Thousand Separator and Decimal Mark equal": "Thousand Separator and Decimal Mark cannot be equal",
"1049": "Unknown database",
"2005": "Unknown MySQL server host",
"1045": "Access denied for user"
},
"options": {
"db driver": {
"mysqli": "MySQLi",
"pdo_mysql": "PDO MySQL"
},
"modRewriteInstruction": {
"apache": {
"linux": "<br><br>To enable .htaccess support add/edit the Server configuration settings inside your &#60;VirtualHost&#62; section (httpd.conf):<pre>&#60;Directory \/PATH_TO_ESPO\/&#62;\n <b>AllowOverride All<\/b>\n&#60;\/Directory&#62;<\/pre>\n Afterwards run this command in a Terminal:<pre><b>service apache2 restart<\/b><\/pre><br>To enable \"mod_rewrite\" run those commands in a Terminal:<pre><b>a2enmod rewrite <br>service apache2 restart<\/b><\/pre>",
"windows": "<br> <pre>1. Find the httpd.conf file (usually you will find it in a folder called conf, config or something along those lines)<br>\n2. Inside the httpd.conf file uncomment the line LoadModule rewrite_module modules\/mod_rewrite.so (remove the pound '#' sign from in front of the line)<br>\n3. Also find the line ClearModuleList is uncommented then find and make sure that the line AddModule mod_rewrite.c is not commented out.\n<\/pre>"
},
"microsoft-iis": {
"windows": ""
}
},
"modRewriteHelp": {
"apache": "API Error: EspoCRM API unavailable.<br> Possible problems: disabled \"mod_rewrite\" in Apache server or .htaccess support.",
"nginx": "API Error: EspoCRM API unavailable.<br> Add this code to Nginx Host Config (inside \"server\" block):<br>\n<pre>\nlocation \/api\/v1\/ {\n if (!-e $request_filename){\n rewrite ^\/api\/v1\/(.*)$ \/api\/v1\/index.php last; break;\n }\n}\n\nlocation \/ {\n rewrite reset\/?$ reset.html break;\n}<\/pre>",
"microsoft-iis": "API Error: EspoCRM API unavailable.<br> Possible problem: disabled \"URL Rewrite\". Please check and enable \"URL Rewrite\" Module in IIS server",
"default": "API Error: EspoCRM API unavailable.<br> Possible problem: disabled Rewrite Module. Please check and enable Rewrite Module in your server (e.g. mod_rewrite in Apache) and .htaccess support."
}
}
}
-1
View File
@@ -23,7 +23,6 @@
var opt = {
action: 'errors',
langs: {$langsJs},
ajaxUrls: {$ajaxUrls},
modRewriteUrl: '{$modRewriteUrl}',
serverType: '{$serverType}',
OS: '{$OS}'
+15 -3
View File
@@ -10,9 +10,21 @@
<div class=" col-md-6">
<div class="row">
<div class="cell cell-website col-sm-12 form-group">
<label class="field-label-website control-label">{$langs['fields']['Host Name']} *</label>
<div class="field field-website">
<input type="text" value="{$fields['host-name'].value}" name="host-name" class="main-element form-control">
<div class="host-name-c cell">
<label class="field-label-website control-label">{$langs['fields']['Host Name']} *</label>
<div class="field field-website">
<input type="text" value="{$fields['host-name'].value}" name="host-name" class="main-element form-control">
</div>
</div>
<div class="semicolon-sign-c cell">
<label class="field-label-website control-label">&nbsp;</label>
<div class="semicolon-sign">:</div>
</div>
<div class="port-c cell">
<label class="field-label-website control-label">{$langs['fields']['Port']}</label>
<div class="field field-website">
<input type="text" value="{$fields['port'].value}" name="port" class="main-element form-control">
</div>
</div>
</div>
</div>
+6 -7
View File
@@ -4,9 +4,9 @@
<div class="panel-body body">
<div id="msg-box" class="alert hide"></div>
<div class="loading-icon hide"></div>
<form id="nav">
<form id="nav">
<div class="row">
<div class=" col-md-6">
<div class="row">
<div class="cell cell-website col-sm-12 form-group">
@@ -16,7 +16,7 @@
</div>
</div>
</div>
<div class="row">
<div class="cell cell-website col-sm-12 form-group">
<label class="field-label-website control-label">{$langs['fields']['Password']} *</label>
@@ -25,7 +25,7 @@
</div>
</div>
</div>
<div class="row">
<div class="cell cell-website col-sm-12 form-group">
<label class="field-label-website control-label">{$langs['fields']['Confirm Password']} *</label>
@@ -35,9 +35,9 @@
</div>
</div>
</div>
</div>
</form>
</form>
</div>
<footer class="modal-footer">
<button class="btn btn-default" type="button" id="back">{$langs['labels']['Back']}</button>
@@ -50,7 +50,6 @@
var opt = {
action: 'step3',
langs: {$langsJs},
ajaxUrls: {$ajaxUrls},
modRewriteUrl: '{$modRewriteUrl}',
serverType: '{$serverType}',
OS: '{$OS}'
+21
View File
@@ -46,3 +46,24 @@ select[name="user-lang"] {
min-height: 50px;
}
.host-name-c {
width: 65%;
float: left;
}
.port-c {
width: 30%;
float: right;
}
.semicolon-sign-c {
text-align: center;
width: 4%;
float: left;
}
.semicolon-sign {
margin-top: 5px;
}
+11 -11
View File
@@ -24,6 +24,17 @@ session_start();
require_once('../bootstrap.php');
// temp save all settings
$ignore = array('desc', 'dbName', 'hostName', 'dbUserName', 'dbUserPass', 'dbDriver');
if (!empty($_REQUEST)) {
foreach ($_REQUEST as $key => $val) {
if (!in_array($val, $ignore))
$_SESSION['install'][$key] = trim($val);
}
}
// get user selected language
$userLang = (!empty($_SESSION['install']['user-lang']))? $_SESSION['install']['user-lang'] : 'en_US';
$langFileName = 'core/i18n/'.$userLang.'/install.json';
@@ -72,15 +83,6 @@ else {
$smarty->caching = false;
$smarty->setTemplateDir('install/core/tpl');
// temp save all settings
$ignore = array('desc', 'dbName', 'hostName', 'dbUserName', 'dbUserPass', 'dbDriver');
if (!empty($_REQUEST)) {
foreach ($_REQUEST as $key => $val) {
if (!in_array($val, $ignore))
$_SESSION['install'][$key] = trim($val);
}
}
$smarty->assign("langs", $langs);
$smarty->assign("langsJs", json_encode($langs));
@@ -98,8 +100,6 @@ switch ($action) {
case 'step3':
case 'errors':
$ajaxUrls = $installer->getAjaxUrls();
$smarty->assign("ajaxUrls", json_encode($ajaxUrls));
$modRewriteUrl = $systemHelper->getModRewriteUrl();
$smarty->assign("modRewriteUrl", $modRewriteUrl);
$serverType = $systemHelper->getServerType();
+1 -5
View File
@@ -31,10 +31,6 @@ var InstallScript = function(opt) {
this.langs = opt.langs;
}
if (typeof(opt.ajaxUrls) !== 'undefined') {
this.ajaxUrls = opt.ajaxUrls;
}
if (typeof(opt.modRewriteUrl) !== 'undefined') {
this.modRewriteUrl = opt.modRewriteUrl;
}
@@ -72,7 +68,7 @@ var InstallScript = function(opt) {
'action': 'createUser',
'break': true,
},
];
this.checkIndex = 0;
this.checkError = false;
+4 -3
View File
@@ -1,6 +1,6 @@
{
"name": "espocrm",
"version": "1.1.2",
"version": "1.2.0",
"description": "",
"main": "index.php",
"repository": "",
@@ -8,7 +8,7 @@
"license": "GPL",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-clean": "~0.5.0",
"grunt-replace": "~0.5.1",
"grunt-contrib-concat": "~0.3.0",
@@ -16,6 +16,7 @@
"grunt-contrib-cssmin": "~0.6.2",
"grunt-contrib-less": "~0.7.0",
"grunt-mkdir": "~0.1.1",
"grunt-contrib-compress": "~0.8.0"
"grunt-contrib-compress": "~0.8.0",
"grunt-chmod": "~1.0.3"
}
}