This commit is contained in:
Yuri Kuznetsov
2013-12-30 16:38:02 +02:00
parent 15f808f588
commit 5b308e820e
20 changed files with 399 additions and 171 deletions

View File

@@ -6,21 +6,17 @@ use \Espo\Core\Exceptions\Error,
\Espo\Core\Exceptions\Forbidden;
class Admin extends \Espo\Core\Controllers\Base
{
public function __construct(\Espo\Core\Container $container, \Espo\Core\ServiceFactory $serviceFactory)
{
protected function checkGlobalAccess()
{
parent::__construct($container, $serviceFactory);
if (!$this->getUser()->isAdmin()) {
throw new Forbidden("You do not have access to this area");
throw new Forbidden();
}
}
}
public function actionRebuild($params, $data)
{
try{
try {
$result = $this->getContainer()->get('schema')->rebuild();
} catch (\Exception $e) {
$result = false;
@@ -33,5 +29,5 @@ class Admin extends \Espo\Core\Controllers\Base
return json_encode($result);
}
}

View File

@@ -8,7 +8,6 @@ use \Espo\Core\Exceptions\Error;
class Layout extends \Espo\Core\Controllers\Base
{
public function actionRead($params, $data)
{
$data = $this->getContainer()->get('layout')->get($params['controller'], $params['name']);

View File

@@ -1,67 +0,0 @@
<?php
namespace Espo\Core\Base;
abstract class RecordService
{
public static $dependencies = array(
'config',
'entityManager',
'datetime',
);
private $config;
private $entityManager;
private $datetime;
public function setConfig($config)
{
$this->config = $config;
}
protected function getConfig()
{
return $this->config;
}
public function setEntityManager($entityManager)
{
$this->entityManager = $entityManager;
}
protected function getEntityManager()
{
return $this->entityManager;
}
public function setDatetime($datetime)
{
$this->datetime = $datetime;
}
protected function getDatetime()
{
return $this->datetime;
}
protected function fetch($id)
{
return $this->getEntityManager()->findById($id);
}
protected function save($entity)
{
$this->getEntityManager()->save($entity);
}
protected function findAssociated($entity, $link)
{
return array();
}
}

View File

@@ -1,9 +0,0 @@
<?php
namespace Espo\Core\Base;
abstract class Service
{
public static $dependencies = array();
}

View File

@@ -14,10 +14,6 @@ abstract class Base
private $serviceFactory;
protected $serviceClassName = null;
protected $service = null;
public $defaultAction = 'index';
public function __construct(Container $container, ServiceFactory $serviceFactory)
@@ -31,16 +27,14 @@ abstract class Base
$name = $matches[1];
}
$this->name = $name;
}
if (empty($this->serviceClassName)) {
$moduleName = $this->getMetadata()->getScopeModuleName($this->name);
if ($moduleName) {
$className = '\\Espo\\Modules\\' . $moduleName . '\\Services\\' . Util::normilizeClassName($this->name);
} else {
$className = '\\Espo\\Services\\' . Util::normilizeClassName($this->name);
}
}
$this->checkGlobalAccess();
}
protected function checkGlobalAccess()
{
return;
}
protected function getContainer()
@@ -73,18 +67,9 @@ abstract class Base
return $this->serviceFactory;
}
protected function loadService()
protected function getService($className)
{
$this->service = $this->getServiceFactory()->createByClassName($this->serviceClassName);
return $this->getServiceFactory()->createByClassName($className);
}
protected function getService()
{
if (!empty($this->service)) {
return $this->service;
}
$this->loadService();
return $this->service;
}
}

View File

@@ -5,23 +5,35 @@ namespace Espo\Core\Controllers;
use \Espo\Core\Exceptions\Error;
use \Espo\Core\Exceptions\Forbidden;
use \Espo\Core\Exceptions\NotFound;
use \Espo\Core\Utils\Util;
abstract class Record extends Base
{
protected $serviceClassName = '\\Espo\\Services\\Record';
public $defaultAction = 'list';
public $defaultAction = 'list';
protected function loadService()
public function getRecordService()
{
parent::loadService();
$this->service->setEntityName($this->name);
$moduleName = $this->getMetadata()->getScopeModuleName($this->name);
if ($moduleName) {
$className = '\\Espo\\Modules\\' . $moduleName . '\\Services\\' . Util::normilizeClassName($this->name);
} else {
$className = '\\Espo\\Services\\' . Util::normilizeClassName($this->name);
}
if (!class_exists($className)) {
$className = '\\Espo\\Services\\Record';
}
$service = $this->getService($className);
$service->setEntityName($this->name);
return $service;
}
public function actionRead($params)
{
$id = $params['id'];
$service = $this->getService();
$service = $this->getRecordService();
$entity = $service->getEntity($id);
if (empty($entity)) {
@@ -46,7 +58,7 @@ abstract class Record extends Base
throw new Forbidden();
}
$service = $this->getService();
$service = $this->getRecordService();
if ($entity = $service->createEntity($data)) {
return $entity->toArray();
@@ -63,7 +75,7 @@ abstract class Record extends Base
$id = $params['id'];
if ($entity = $this->getService()->updateEntity($id, $data)) {
if ($entity = $this->getRecordService()->updateEntity($id, $data)) {
return $entity->toArray();
}
@@ -82,7 +94,7 @@ abstract class Record extends Base
$asc = $request->get('asc') === 'true';
$sortBy = $request->get('sortBy');
$result = $this->getService()->findEntities(array(
$result = $this->getRecordService()->findEntities(array(
'where' => $where,
'offset' => $offset,
'maxSize' => $maxSize,
@@ -107,7 +119,7 @@ abstract class Record extends Base
$asc = $request->get('asc') === 'true';
$sortBy = $request->get('sortBy');
$result = $this->getService()->findLinkedEntities($id, $link, array(
$result = $this->getRecordService()->findLinkedEntities($id, $link, array(
'where' => $where,
'offset' => $offset,
'maxSize' => $maxSize,
@@ -125,7 +137,7 @@ abstract class Record extends Base
{
$id = $params['id'];
if ($this->getService()->deleteEntity($id)) {
if ($this->getRecordService()->deleteEntity($id)) {
return true;
}
throw new Error();
@@ -140,7 +152,7 @@ abstract class Record extends Base
$ids = $data['ids'];
$where = $data['where'];
$idsUpdated = $this->getService()->massUpdate($ids, $where);
$idsUpdated = $this->getRecordService()->massUpdate($ids, $where);
return $idsUpdated;
}
@@ -154,7 +166,7 @@ abstract class Record extends Base
$ids = $data['ids'];
$where = $data['where'];
$idsDeleted = $this->getService()->massDelete($ids, $where);
$idsDeleted = $this->getRecordService()->massDelete($ids, $where);
return $idsDeleted;
}
@@ -176,7 +188,7 @@ abstract class Record extends Base
$result = false;
foreach ($foreignIds as $foreignId) {
if ($this->getService()->linkEntity($id, $link, $foreignId)) {
if ($this->getRecordService()->linkEntity($id, $link, $foreignId)) {
$result = $result || true;
}
if ($result) {
@@ -204,7 +216,7 @@ abstract class Record extends Base
$result = false;
foreach ($foreignIds as $foreignId) {
if ($this->getService()->unlinkEntity($id, $link, $foreignId)) {
if ($this->getRecordService()->unlinkEntity($id, $link, $foreignId)) {
$result = $result || true;
}
if ($result) {
@@ -215,3 +227,4 @@ abstract class Record extends Base
throw new Error();
}
}

View File

@@ -22,8 +22,7 @@ class ServiceFactory
$service = new $className();
$dependencies = $service::$dependencies;
foreach ($dependencies as $name) {
$setMethod = 'set' . ucfirst($name);
$service->$setMethod($this->container->get($name));
$service->inject($name, $this->container->get($name));
}
return $service;
}

View File

@@ -5,5 +5,12 @@ namespace Espo\Core\Services;
abstract class Base
{
static public $dependencies = array();
protected $injections = array();
public function inject($name, $object)
{
$this->injections[$name] = $object;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Espo\Modules\Crm\Controllers;
use \Espo\Core\Exceptions\Error,
\Espo\Core\Exceptions\Forbidden;
class Activities extends \Espo\Core\Controllers\Base
{
protected $serviceClassName = '\\Espo\\Modules\\Crm\\Services\\Activities';
public function actionList($params, $data, $request)
{
$name = $params['name'];
$entityName = $params['scope'];
$id = $params['id'];
$offset = intval($request->get('offset'));
$maxSize = intval($request->get('maxSize'));
$asc = $request->get('asc') === 'true';
$sortBy = $request->get('sortBy');
$where = $request->get('where');
$scope = null;
if (!empty($where) && !empty($where['scope']) && $where['scope'] !== 'false') {
$scope = $where['scope'];
}
$service = $this->getService($this->serviceClassName);
$methodName = 'get' . ucfirst($name);
return $service->$methodName($entityName, $id, array(
'scope' => $scope,
'offset' => $offset,
'maxSize' => $maxSize,
'asc' => $asc,
'sortBy' => $sortBy,
));
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Espo\Modules\Crm\Controllers;
class Email extends \Espo\Core\Controllers\Record
{
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Espo\Modules\Crm\Entities;
class Email extends \Espo\Core\ORM\Entity
{
}

View File

@@ -5,7 +5,7 @@
[{"name":"dateSent"},{"name":"parent"}],
[{"name":"from"},{"name":"cc"}],
[{"name":"to"},{"name":"bcc"}],
[{"name":"subject"}],
[{"name":"name"}],
[{"name":"body"}],
[{"name":"attachments"}]
]

View File

@@ -4,7 +4,7 @@
"rows":[
[{"name":"from"}],
[{"name":"to"}],
[{"name":"subject"}],
[{"name":"name"}],
[{"name":"body"}]
]
}

View File

@@ -1,6 +1,6 @@
{
"fields": {
"subject": {
"name": {
"type": "varchar",
"required": true
},

View File

@@ -0,0 +1,8 @@
{
"entity": false,
"layouts": false,
"tab": false,
"acl": false,
"module": "Crm",
"customizable": false
}

View File

@@ -1,2 +1,14 @@
[
]
{
"route":"/Activities/:scope/:id/:name",
"method":"get",
"params":{
"controller":"Activities",
"action":"list",
"scope":":scope",
"id":":id",
"name":":name"
}
}
]

View File

@@ -0,0 +1,257 @@
<?php
namespace Espo\Modules\Crm\Services;
use \Espo\Core\Exceptions\Error;
use \PDO;
class Activities extends \Espo\Core\Services\Base
{
static public $dependencies = array(
'entityManager',
'user',
'metadata',
'acl'
);
protected function getPDO()
{
return $this->getEntityManager()->getPDO();
}
protected function getEntityManager()
{
return $this->injections['entityManager'];
}
protected function getUser()
{
return $this->injections['user'];
}
protected function getAcl()
{
return $this->injections['acl'];
}
protected function getMetadata()
{
return $this->injections['metadata'];
}
protected function isPerson($scope)
{
return in_array($scope, array('Contact', 'Lead', 'User'));
}
protected function getMeetingQuery($scope, $id, $op = 'IN', $notIn = array())
{
$qu = "
SELECT meeting.id AS 'id', meeting.name AS 'name', meeting.date_start AS 'dateStart', meeting.date_end AS 'dateEnd', 'Meeting' AS '_scope',
meeting.assigned_user_id AS assignedUserId, TRIM(CONCAT(user.first_name, ' ', user.last_name)) AS assignedUserName,
meeting.parent_type AS 'parentType', meeting.parent_id AS 'parentId'
FROM `meeting`
LEFT JOIN `user` ON user.id = meeting.assigned_user_id
";
if ($this->isPerson($scope)) {
switch ($scope) {
case 'Contact':
$joinTable = 'contact_meeting';
$key = 'contact_id';
break;
case 'Lead':
$joinTable = 'lead_meeting';
$key = 'lead_id';
break;
case 'User':
$joinTable = 'meeting_user';
$key = 'user_id';
break;
}
$qu .= "
JOIN `{$joinTable}` ON meeting.id = {$joinTable}.meeting_id AND {$joinTable}.deleted = 0 AND {$joinTable}.{$key} = ".$this->getPDO()->quote($id)."
";
}
$qu .= "
WHERE meeting.deleted = 0
";
if (!$this->isPerson($scope)) {
$qu .= "
AND meeting.parent_type = ".$this->getPDO()->quote($scope)." AND meeting.parent_id = ".$this->getPDO()->quote($id)."
";
}
if (!empty($notIn)) {
$qu .= "
AND meeting.status {$op} ('". implode("', '", $notIn) . "')
";
}
return $qu;
}
protected function getCallQuery($scope, $id, $op = 'IN', $notIn = array())
{
$qu = "
SELECT call.id AS 'id', call.name AS 'name', call.date_start AS 'dateStart', call.date_end AS 'dateEnd', 'Call' AS '_scope',
call.assigned_user_id AS assignedUserId, TRIM(CONCAT(user.first_name, ' ', user.last_name)) AS assignedUserName,
call.parent_type AS 'parentType', call.parent_id AS 'parentId'
FROM `call`
LEFT JOIN `user` ON user.id = call.assigned_user_id
";
if ($this->isPerson($scope)) {
switch ($scope) {
case 'Contact':
$joinTable = 'call_contact';
$key = 'contact_id';
break;
case 'Lead':
$joinTable = 'call_lead';
$key = 'lead_id';
break;
case 'User':
$joinTable = 'call_user';
$key = 'user_id';
break;
}
$qu .= "
JOIN `{$joinTable}` ON call.id = {$joinTable}.call_id AND {$joinTable}.deleted = 0 AND {$joinTable}.{$key} = ".$this->getPDO()->quote($id)."
";
}
$qu .= "
WHERE call.deleted = 0
";
if (!$this->isPerson($scope)) {
$qu .= "
AND call.parent_type = ".$this->getPDO()->quote($scope)." AND call.parent_id = ".$this->getPDO()->quote($id)."
";
}
if (!empty($notIn)) {
$qu .= "
AND call.status {$op} ('". implode("', '", $notIn) . "')
";
}
return $qu;
}
protected function getEmailQuery($scope, $id, $op = 'IN', $notIn = array())
{
$qu = "
SELECT email.id AS 'id', email.name AS 'name', email.date_sent AS 'dateStart', '' AS 'dateEnd', 'Email' AS '_scope',
email.assigned_user_id AS assignedUserId, TRIM(CONCAT(user.first_name, ' ', user.last_name)) AS assignedUserName,
email.parent_type AS 'parentType', email.parent_id AS 'parentId'
FROM `email`
LEFT JOIN `user` ON user.id = email.assigned_user_id
";
$qu .= "
WHERE email.deleted = 0
";
$qu .= "
AND email.parent_type = ".$this->getPDO()->quote($scope)." AND email.parent_id = ".$this->getPDO()->quote($id)."
";
if (!empty($notIn)) {
$qu .= "
AND email.status {$op} ('". implode("', '", $notIn) . "')
";
}
return $qu;
}
protected function getResult($parts, $scope, $id, $params)
{
$pdo = $this->getEntityManager()->getPDO();
$onlyScope = false;
if (!empty($params['scope'])) {
$onlyScope = $params['scope'];
}
if (!$onlyScope) {
$qu = implode(" UNION ", $parts);
} else {
$qu = $parts[$onlyScope];
}
$countQu = "SELECT COUNT(*) AS 'count' FROM ({$qu}) AS c";
$sth = $pdo->prepare($countQu);
$sth->execute();
$row = $sth->fetch(PDO::FETCH_ASSOC);
$totalCount = $row['count'];
if (!empty($params['maxSize'])) {
$qu .= "
LIMIT :offset, :maxSize
";
}
/*$qu .= "
ORDER BY dateStart DESC
";*/
$sth = $pdo->prepare($qu);
if (!empty($params['maxSize'])) {
$offset = 0;
if (!empty($params['offset'])) {
$offset = $params['offset'];
}
$sth->bindParam(':offset', $offset, PDO::PARAM_INT);
$sth->bindParam(':maxSize', $params['maxSize'], PDO::PARAM_INT);
}
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
$list = array();
foreach ($rows as $row) {
$list[] = $row;
}
return array(
'list' => $rows,
'total' => $totalCount
);
}
public function getActivities($scope, $id, $params = array())
{
$parts = array(
'Meeting' => $this->getMeetingQuery($scope, $id, 'NOT IN', array('Held', 'Not Held')),
'Call' => $this->getCallQuery($scope, $id, 'NOT IN', array('Held', 'Not Held')),
);
return $this->getResult($parts, $scope, $id, $params);
}
public function getHistory($scope, $id, $params)
{
$parts = array(
'Meeting' => $this->getMeetingQuery($scope, $id, 'IN', array('Held')),
'Call' => $this->getCallQuery($scope, $id, 'IN', array('Held')),
'Email' => $this->getEmailQuery($scope, $id, 'IN', array('Archived', 'Sent')),
);
$result = $this->getResult($parts, $scope, $id, $params);
foreach ($result['list'] as &$item) {
if ($item['_scope'] == 'Email') {
$item['dateSent'] = $item['dateStart'];
}
}
return $result;
}
}

View File

@@ -136,7 +136,7 @@ abstract class Mapper implements IMapper
protected function createSelectQuery(IEntity $entity, $params = array(), $aggregation = null, $aggregationBy = null, $deleted = false)
{
$whereClause = array();
if (isset($params['whereClause'])) {
if (array_key_exists('whereClause', $params)) {
$whereClause = $params['whereClause'];
}
@@ -218,7 +218,7 @@ abstract class Mapper implements IMapper
$relEntity = $this->entityFactory->create($relEntityName);
$whereClause = array();
if (isset($params['whereClause'])) {
if (array_key_exists('whereClause', $params)) {
$whereClause = $params['whereClause'];
}

View File

@@ -116,7 +116,7 @@ abstract class Entity implements IEntity
if ($name == 'id') {
return isset($this->id);
}
if (isset($this->valuesContainer[$name])) {
if (array_key_exists($name, $this->valuesContainer)) {
return true;
}
return false;
@@ -129,7 +129,7 @@ abstract class Entity implements IEntity
}
foreach ($this->fields as $field => $fieldDefs) {
if (isset($arr[$field])) {
if (array_key_exists($field, $arr)) {
if ($field == 'id') {
$this->id = $arr[$field];
continue;

View File

@@ -15,59 +15,29 @@ class Record extends \Espo\Core\Services\Base
protected $entityName;
private $user;
private $entityManager;
private $metadata;
private $selectManager;
private $acl;
public function setEntityName($entityName)
{
$this->entityName = $entityName;
}
public function setEntityManager($entityManager)
{
$this->entityManager = $entityManager;
}
public function setUser($user)
{
$this->user = $user;
}
public function setAcl($acl)
{
$this->acl = $acl;
}
public function setMetadata($metadata)
{
$this->metadata = $metadata;
}
protected function getEntityManager()
{
return $this->entityManager;
return $this->injections['entityManager'];
}
protected function getUser()
{
return $this->user;
return $this->injections['user'];
}
protected function getAcl()
{
return $this->acl;
return $this->injections['acl'];
}
protected function getMetadata()
{
return $this->metadata;
return $this->injections['metadata'];
}
protected function getRepository()