From 5b308e820e4d6c76ed91f08ba917755b3ee2f05d Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Mon, 30 Dec 2013 16:38:02 +0200 Subject: [PATCH] dev --- application/Espo/Controllers/Admin.php | 16 +- application/Espo/Controllers/Layout.php | 1 - application/Espo/Core/Base/RecordService.php | 67 ----- application/Espo/Core/Base/Service.php | 9 - application/Espo/Core/Controllers/Base.php | 35 +-- application/Espo/Core/Controllers/Record.php | 43 ++- application/Espo/Core/ServiceFactory.php | 3 +- application/Espo/Core/Services/Base.php | 7 + .../Modules/Crm/Controllers/Activities.php | 42 +++ .../Espo/Modules/Crm/Controllers/Email.php | 8 + .../Espo/Modules/Crm/Entities/Email.php | 8 + .../Crm/Resources/layouts/Email/detail.json | 2 +- .../Resources/layouts/Email/detailSmall.json | 2 +- .../Resources/metadata/entityDefs/Email.json | 2 +- .../Resources/metadata/scopes/Activities.json | 8 + .../Espo/Modules/Crm/Resources/routes.json | 14 +- .../Espo/Modules/Crm/Services/Activities.php | 257 ++++++++++++++++++ application/Espo/ORM/DB/Mapper.php | 4 +- application/Espo/ORM/Entity.php | 4 +- application/Espo/Services/Record.php | 38 +-- 20 files changed, 399 insertions(+), 171 deletions(-) delete mode 100644 application/Espo/Core/Base/RecordService.php delete mode 100644 application/Espo/Core/Base/Service.php create mode 100644 application/Espo/Modules/Crm/Controllers/Activities.php create mode 100644 application/Espo/Modules/Crm/Controllers/Email.php create mode 100644 application/Espo/Modules/Crm/Entities/Email.php create mode 100644 application/Espo/Modules/Crm/Resources/metadata/scopes/Activities.json create mode 100644 application/Espo/Modules/Crm/Services/Activities.php diff --git a/application/Espo/Controllers/Admin.php b/application/Espo/Controllers/Admin.php index eb9a3486fe..c42a790af3 100644 --- a/application/Espo/Controllers/Admin.php +++ b/application/Espo/Controllers/Admin.php @@ -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); } - } + diff --git a/application/Espo/Controllers/Layout.php b/application/Espo/Controllers/Layout.php index 17af149a95..35a59e5b85 100644 --- a/application/Espo/Controllers/Layout.php +++ b/application/Espo/Controllers/Layout.php @@ -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']); diff --git a/application/Espo/Core/Base/RecordService.php b/application/Espo/Core/Base/RecordService.php deleted file mode 100644 index 84ee22e2f9..0000000000 --- a/application/Espo/Core/Base/RecordService.php +++ /dev/null @@ -1,67 +0,0 @@ -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(); - - - } - - -} diff --git a/application/Espo/Core/Base/Service.php b/application/Espo/Core/Base/Service.php deleted file mode 100644 index 2456af6b5f..0000000000 --- a/application/Espo/Core/Base/Service.php +++ /dev/null @@ -1,9 +0,0 @@ -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; - } - } + diff --git a/application/Espo/Core/Controllers/Record.php b/application/Espo/Core/Controllers/Record.php index d1f27dd497..6f0aa77d30 100644 --- a/application/Espo/Core/Controllers/Record.php +++ b/application/Espo/Core/Controllers/Record.php @@ -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(); } } + diff --git a/application/Espo/Core/ServiceFactory.php b/application/Espo/Core/ServiceFactory.php index 7aadf2a652..76daa7ed70 100644 --- a/application/Espo/Core/ServiceFactory.php +++ b/application/Espo/Core/ServiceFactory.php @@ -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; } diff --git a/application/Espo/Core/Services/Base.php b/application/Espo/Core/Services/Base.php index c4b1f88601..6d77de97ff 100644 --- a/application/Espo/Core/Services/Base.php +++ b/application/Espo/Core/Services/Base.php @@ -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; + } } diff --git a/application/Espo/Modules/Crm/Controllers/Activities.php b/application/Espo/Modules/Crm/Controllers/Activities.php new file mode 100644 index 0000000000..531046c31d --- /dev/null +++ b/application/Espo/Modules/Crm/Controllers/Activities.php @@ -0,0 +1,42 @@ +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, + )); + } +} + diff --git a/application/Espo/Modules/Crm/Controllers/Email.php b/application/Espo/Modules/Crm/Controllers/Email.php new file mode 100644 index 0000000000..4d0ef13a4b --- /dev/null +++ b/application/Espo/Modules/Crm/Controllers/Email.php @@ -0,0 +1,8 @@ +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; + } +} + diff --git a/application/Espo/ORM/DB/Mapper.php b/application/Espo/ORM/DB/Mapper.php index 47b212e6a6..0dc4d0950f 100644 --- a/application/Espo/ORM/DB/Mapper.php +++ b/application/Espo/ORM/DB/Mapper.php @@ -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']; } diff --git a/application/Espo/ORM/Entity.php b/application/Espo/ORM/Entity.php index 85c7f09240..f8e450f913 100644 --- a/application/Espo/ORM/Entity.php +++ b/application/Espo/ORM/Entity.php @@ -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; diff --git a/application/Espo/Services/Record.php b/application/Espo/Services/Record.php index 0e4f37e673..5d20ff5a15 100644 --- a/application/Espo/Services/Record.php +++ b/application/Espo/Services/Record.php @@ -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()