PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/application/Espo/Core/Controllers/Record.php

https://gitlab.com/johanlindberg/irvato-crm
PHP | 427 lines | 325 code | 75 blank | 27 comment | 69 complexity | eb31e31487abbf5e055a30e94f1028b2 MD5 | raw file
  1. <?php
  2. /************************************************************************
  3. * This file is part of EspoCRM.
  4. *
  5. * EspoCRM - Open Source CRM application.
  6. * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
  7. * Website: http://www.espocrm.com
  8. *
  9. * EspoCRM is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * EspoCRM is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with EspoCRM. If not, see http://www.gnu.org/licenses/.
  21. *
  22. * The interactive user interfaces in modified source and object code versions
  23. * of this program must display Appropriate Legal Notices, as required under
  24. * Section 5 of the GNU General Public License version 3.
  25. *
  26. * In accordance with Section 7(b) of the GNU General Public License version 3,
  27. * these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
  28. ************************************************************************/
  29. namespace Espo\Core\Controllers;
  30. use \Espo\Core\Exceptions\Error;
  31. use \Espo\Core\Exceptions\Forbidden;
  32. use \Espo\Core\Exceptions\NotFound;
  33. use \Espo\Core\Exceptions\BadRequest;
  34. use \Espo\Core\Utils\Util;
  35. class Record extends Base
  36. {
  37. const MAX_SIZE_LIMIT = 200;
  38. public static $defaultAction = 'list';
  39. protected $defaultRecordServiceName = 'Record';
  40. protected function getEntityManager()
  41. {
  42. return $this->getContainer()->get('entityManager');
  43. }
  44. protected function getRecordService($name = null)
  45. {
  46. if (empty($name)) {
  47. $name = $this->name;
  48. }
  49. if ($this->getServiceFactory()->checkExists($name)) {
  50. $service = $this->getServiceFactory()->create($name);
  51. } else {
  52. $service = $this->getServiceFactory()->create($this->defaultRecordServiceName);
  53. $service->setEntityType($name);
  54. }
  55. return $service;
  56. }
  57. public function actionRead($params, $data, $request)
  58. {
  59. $id = $params['id'];
  60. $entity = $this->getRecordService()->getEntity($id);
  61. if (empty($entity)) {
  62. throw new NotFound();
  63. }
  64. return $entity->toArray();
  65. }
  66. public function actionPatch($params, $data, $request)
  67. {
  68. return $this->actionUpdate($params, $data, $request);
  69. }
  70. public function actionCreate($params, $data, $request)
  71. {
  72. if (!$request->isPost()) {
  73. throw new BadRequest();
  74. }
  75. if (!$this->getAcl()->check($this->name, 'create')) {
  76. throw new Forbidden();
  77. }
  78. $service = $this->getRecordService();
  79. if ($entity = $service->createEntity($data)) {
  80. return $entity->toArray();
  81. }
  82. throw new Error();
  83. }
  84. public function actionUpdate($params, $data, $request)
  85. {
  86. if (!$request->isPut() && !$request->isPatch()) {
  87. throw new BadRequest();
  88. }
  89. if (!$this->getAcl()->check($this->name, 'edit')) {
  90. throw new Forbidden();
  91. }
  92. $id = $params['id'];
  93. if ($entity = $this->getRecordService()->updateEntity($id, $data)) {
  94. return $entity->toArray();
  95. }
  96. throw new Error();
  97. }
  98. public function actionList($params, $data, $request)
  99. {
  100. if (!$this->getAcl()->check($this->name, 'read')) {
  101. throw new Forbidden();
  102. }
  103. $where = $request->get('where');
  104. $offset = $request->get('offset');
  105. $maxSize = $request->get('maxSize');
  106. $asc = $request->get('asc', 'true') === 'true';
  107. $sortBy = $request->get('sortBy');
  108. $q = $request->get('q');
  109. $textFilter = $request->get('textFilter');
  110. if (empty($maxSize)) {
  111. $maxSize = self::MAX_SIZE_LIMIT;
  112. }
  113. if (!empty($maxSize) && $maxSize > self::MAX_SIZE_LIMIT) {
  114. throw new Forbidden("Max should should not exceed " . self::MAX_SIZE_LIMIT . ". Use pagination (offset, limit).");
  115. }
  116. $params = array(
  117. 'where' => $where,
  118. 'offset' => $offset,
  119. 'maxSize' => $maxSize,
  120. 'asc' => $asc,
  121. 'sortBy' => $sortBy,
  122. 'q' => $q,
  123. 'textFilter' => $textFilter
  124. );
  125. $this->fetchListParamsFromRequest($params, $request, $data);
  126. $result = $this->getRecordService()->findEntities($params);
  127. return array(
  128. 'total' => $result['total'],
  129. 'list' => isset($result['collection']) ? $result['collection']->toArray() : $result['list']
  130. );
  131. }
  132. protected function fetchListParamsFromRequest(&$params, $request, $data)
  133. {
  134. if ($request->get('primaryFilter')) {
  135. $params['primaryFilter'] = $request->get('primaryFilter');
  136. }
  137. if ($request->get('boolFilterList')) {
  138. $params['boolFilterList'] = $request->get('boolFilterList');
  139. }
  140. }
  141. public function actionListLinked($params, $data, $request)
  142. {
  143. $id = $params['id'];
  144. $link = $params['link'];
  145. $where = $request->get('where');
  146. $offset = $request->get('offset');
  147. $maxSize = $request->get('maxSize');
  148. $asc = $request->get('asc', 'true') === 'true';
  149. $sortBy = $request->get('sortBy');
  150. $q = $request->get('q');
  151. $textFilter = $request->get('textFilter');
  152. if (empty($maxSize)) {
  153. $maxSize = self::MAX_SIZE_LIMIT;
  154. }
  155. if (!empty($maxSize) && $maxSize > self::MAX_SIZE_LIMIT) {
  156. throw new Forbidden();
  157. }
  158. $params = array(
  159. 'where' => $where,
  160. 'offset' => $offset,
  161. 'maxSize' => $maxSize,
  162. 'asc' => $asc,
  163. 'sortBy' => $sortBy,
  164. 'q' => $q,
  165. 'textFilter' => $textFilter
  166. );
  167. $this->fetchListParamsFromRequest($params, $request, $data);
  168. $result = $this->getRecordService()->findLinkedEntities($id, $link, $params);
  169. return array(
  170. 'total' => $result['total'],
  171. 'list' => isset($result['collection']) ? $result['collection']->toArray() : $result['list']
  172. );
  173. }
  174. public function actionDelete($params, $data, $request)
  175. {
  176. if (!$request->isDelete()) {
  177. throw new BadRequest();
  178. }
  179. $id = $params['id'];
  180. if ($this->getRecordService()->deleteEntity($id)) {
  181. return true;
  182. }
  183. throw new Error();
  184. }
  185. public function actionExport($params, $data, $request)
  186. {
  187. if ($this->getConfig()->get('exportDisabled') && !$this->getUser()->isAdmin()) {
  188. throw new Forbidden();
  189. }
  190. if (!$this->getAcl()->check($this->name, 'read')) {
  191. throw new Forbidden();
  192. }
  193. $ids = $request->get('ids');
  194. $where = $request->get('where');
  195. $byWhere = $request->get('byWhere');
  196. $params = array();
  197. if ($byWhere) {
  198. $params['where'] = $where;
  199. } else {
  200. $params['ids'] = $ids;
  201. }
  202. return array(
  203. 'id' => $this->getRecordService()->export($params)
  204. );
  205. }
  206. public function actionMassUpdate($params, $data, $request)
  207. {
  208. if (!$request->isPut()) {
  209. throw new BadRequest();
  210. }
  211. if (!$this->getAcl()->check($this->name, 'edit')) {
  212. throw new Forbidden();
  213. }
  214. if (empty($data['attributes'])) {
  215. throw new BadRequest();
  216. }
  217. $params = array();
  218. if (array_key_exists('where', $data) && !empty($data['byWhere'])) {
  219. $params['where'] = json_decode(json_encode($data['where']), true);
  220. } else if (array_key_exists('ids', $data)) {
  221. $params['ids'] = $data['ids'];
  222. }
  223. $attributes = $data['attributes'];
  224. $idsUpdated = $this->getRecordService()->massUpdate($attributes, $params);
  225. return $idsUpdated;
  226. }
  227. public function actionMassDelete($params, $data, $request)
  228. {
  229. if (!$request->isPost()) {
  230. throw new BadRequest();
  231. }
  232. if (!$this->getAcl()->check($this->name, 'delete')) {
  233. throw new Forbidden();
  234. }
  235. $params = array();
  236. if (array_key_exists('where', $data) && !empty($data['byWhere'])) {
  237. $where = json_decode(json_encode($data['where']), true);
  238. $params['where'] = $where;
  239. }
  240. if (array_key_exists('ids', $data)) {
  241. $params['ids'] = $data['ids'];
  242. }
  243. $idsRemoved = $this->getRecordService()->massRemove($params);
  244. return $idsRemoved;
  245. }
  246. public function actionCreateLink($params, $data, $request)
  247. {
  248. if (!$request->isPost()) {
  249. throw new BadRequest();
  250. }
  251. if (empty($params['id']) || empty($params['link'])) {
  252. throw new BadRequest();
  253. }
  254. $id = $params['id'];
  255. $link = $params['link'];
  256. if (!empty($data['massRelate'])) {
  257. if (!is_array($data['where'])) {
  258. throw new BadRequest();
  259. }
  260. $where = json_decode(json_encode($data['where']), true);
  261. return $this->getRecordService()->linkEntityMass($id, $link, $where);
  262. } else {
  263. $foreignIdList = array();
  264. if (isset($data['id'])) {
  265. $foreignIdList[] = $data['id'];
  266. }
  267. if (isset($data['ids']) && is_array($data['ids'])) {
  268. foreach ($data['ids'] as $foreignId) {
  269. $foreignIdList[] = $foreignId;
  270. }
  271. }
  272. $result = false;
  273. foreach ($foreignIdList as $foreignId) {
  274. if ($this->getRecordService()->linkEntity($id, $link, $foreignId)) {
  275. $result = true;
  276. }
  277. }
  278. if ($result) {
  279. return true;
  280. }
  281. }
  282. throw new Error();
  283. }
  284. public function actionRemoveLink($params, $data, $request)
  285. {
  286. if (!$request->isDelete()) {
  287. throw new BadRequest();
  288. }
  289. $id = $params['id'];
  290. $link = $params['link'];
  291. if (empty($params['id']) || empty($params['link'])) {
  292. throw new BadRequest();
  293. }
  294. $foreignIds = array();
  295. if (isset($data['id'])) {
  296. $foreignIds[] = $data['id'];
  297. }
  298. if (isset($data['ids']) && is_array($data['ids'])) {
  299. foreach ($data['ids'] as $foreignId) {
  300. $foreignIds[] = $foreignId;
  301. }
  302. }
  303. $result = false;
  304. foreach ($foreignIds as $foreignId) {
  305. if ($this->getRecordService()->unlinkEntity($id, $link, $foreignId)) {
  306. $result = $result || true;
  307. }
  308. }
  309. if ($result) {
  310. return true;
  311. }
  312. throw new Error();
  313. }
  314. public function actionFollow($params, $data, $request)
  315. {
  316. if (!$request->isPut()) {
  317. throw new BadRequest();
  318. }
  319. if (!$this->getAcl()->check($this->name, 'stream')) {
  320. throw new Forbidden();
  321. }
  322. $id = $params['id'];
  323. return $this->getRecordService()->follow($id);
  324. }
  325. public function actionUnfollow($params, $data, $request)
  326. {
  327. if (!$request->isDelete()) {
  328. throw new BadRequest();
  329. }
  330. if (!$this->getAcl()->check($this->name, 'read')) {
  331. throw new Forbidden();
  332. }
  333. $id = $params['id'];
  334. return $this->getRecordService()->unfollow($id);
  335. }
  336. public function actionMerge($params, $data, $request)
  337. {
  338. if (!$request->isPost()) {
  339. throw new BadRequest();
  340. }
  341. if (empty($data['targetId']) || empty($data['sourceIds']) || !is_array($data['sourceIds']) || !($data['attributes'] instanceof \StdClass)) {
  342. throw new BadRequest();
  343. }
  344. $targetId = $data['targetId'];
  345. $sourceIds = $data['sourceIds'];
  346. $attributes = get_object_vars($data['attributes']);
  347. if (!$this->getAcl()->check($this->name, 'edit')) {
  348. throw new Forbidden();
  349. }
  350. return $this->getRecordService()->merge($targetId, $sourceIds, $attributes);
  351. }
  352. }