PageRenderTime 448ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/tine20/Addressbook/Controller/List.php

https://gitlab.com/rsilveira1987/Expresso
PHP | 448 lines | 240 code | 55 blank | 153 comment | 30 complexity | 05617383c48ea3a15bc99f948eb610b3 MD5 | raw file
  1. <?php
  2. /**
  3. * Tine 2.0
  4. *
  5. * @package Addressbook
  6. * @subpackage Controller
  7. * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
  8. * @author Lars Kneschke <l.kneschke@metaways.de>
  9. * @copyright Copyright (c) 2010-2012 Metaways Infosystems GmbH (http://www.metaways.de)
  10. *
  11. */
  12. /**
  13. * contact controller for Addressbook
  14. *
  15. * @package Addressbook
  16. * @subpackage Controller
  17. */
  18. class Addressbook_Controller_List extends Tinebase_Controller_Record_Abstract
  19. {
  20. /**
  21. * application name (is needed in checkRight())
  22. *
  23. * @var string
  24. */
  25. protected $_applicationName = 'Addressbook';
  26. /**
  27. * Model name
  28. *
  29. * @var string
  30. */
  31. protected $_modelName = 'Addressbook_Model_List';
  32. /**
  33. * @todo why is this needed???
  34. */
  35. protected $_omitModLog = true;
  36. /**
  37. * Backend Contacts
  38. * @var type
  39. */
  40. protected $_backendContactList = null;
  41. /**
  42. * the constructor
  43. *
  44. * don't use the constructor. use the singleton
  45. */
  46. private function __construct()
  47. {
  48. $this->_duplicateCheckFields = Addressbook_Config::getInstance()->get(Addressbook_Config::LIST_DUP_FIELDS, array(
  49. array('name')
  50. ));
  51. $this->_backend = new Addressbook_Backend_List();
  52. $this->_backendContactList = new Addressbook_Backend_ContactList();
  53. }
  54. /**
  55. * don't clone. Use the singleton.
  56. *
  57. */
  58. private function __clone()
  59. {
  60. }
  61. /**
  62. * holds the instance of the singleton
  63. *
  64. * @var Addressbook_Controller_List
  65. */
  66. private static $_instance = NULL;
  67. /**
  68. * the singleton pattern
  69. *
  70. * @return Addressbook_Controller_List
  71. */
  72. public static function getInstance()
  73. {
  74. if (self::$_instance === NULL) {
  75. self::$_instance = new Addressbook_Controller_List();
  76. }
  77. return self::$_instance;
  78. }
  79. /**
  80. * (non-PHPdoc)
  81. * @see Tinebase_Controller_Record_Abstract::get()
  82. */
  83. public function get($_id, $_containerId = NULL)
  84. {
  85. $result = new Tinebase_Record_RecordSet('Addressbook_Model_List', array(parent::get($_id, $_containerId)));
  86. $this->_removeHiddenListMembers($result);
  87. return $result->getFirstRecord();
  88. }
  89. /**
  90. * use contact search to remove hidden list members
  91. *
  92. * @param Tinebase_Record_RecordSet $lists
  93. */
  94. protected function _removeHiddenListMembers($lists)
  95. {
  96. if (count($lists) === 0) {
  97. return;
  98. }
  99. $allMemberIds = array();
  100. foreach ($lists as $list) {
  101. $allMemberIds = array_merge($list->members, $allMemberIds);
  102. }
  103. $allMemberIds = array_unique($allMemberIds);
  104. if (empty($allMemberIds)) {
  105. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
  106. . ' No members found.');
  107. return;
  108. }
  109. $allVisibleMemberIds = Addressbook_Controller_Contact::getInstance()->search(new Addressbook_Model_ContactFilter(array(array(
  110. 'field' => 'id',
  111. 'operator' => 'in',
  112. 'value' => $allMemberIds
  113. ))), NULL, FALSE, TRUE);
  114. $hiddenMemberids = array_diff($allMemberIds, $allVisibleMemberIds);
  115. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
  116. . ' Found ' . count($hiddenMemberids) . ' hidden members, removing them');
  117. if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
  118. . print_r($hiddenMemberids, TRUE));
  119. foreach ($lists as $list) {
  120. $list->members = array_diff($list->members, $hiddenMemberids);
  121. }
  122. }
  123. /**
  124. * (non-PHPdoc)
  125. * @see Tinebase_Controller_Record_Abstract::search()
  126. */
  127. public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Record_Interface $_pagination = NULL, $_getRelations = FALSE, $_onlyIds = FALSE, $_action = 'get')
  128. {
  129. $result = parent::search($_filter, $_pagination, $_getRelations, $_onlyIds, $_action);
  130. $this->_removeHiddenListMembers($result);
  131. return $result;
  132. }
  133. /**
  134. * (non-PHPdoc)
  135. * @see Tinebase_Controller_Record_Abstract::getMultiple()
  136. */
  137. public function getMultiple($_ids, $_ignoreACL = FALSE)
  138. {
  139. $result = parent::getMultiple($_ids, $_ignoreACL);
  140. $this->_removeHiddenListMembers($result);
  141. return $result;
  142. }
  143. /**
  144. * add new members to list
  145. *
  146. * @param mixed $_listId
  147. * @param mixed $_newMembers
  148. * @return Addressbook_Model_List
  149. */
  150. public function addListMember($_listId, $_newMembers)
  151. {
  152. try {
  153. $list = $this->get($_listId);
  154. } catch (Tinebase_Exception_AccessDenied $tead) {
  155. $list = $this->_fixEmptyContainerId($_listId);
  156. $list = $this->get($_listId);
  157. }
  158. $this->_checkGrant($list, 'update', TRUE, 'No permission to add list member.');
  159. $list = $this->_backend->addListMember($_listId, $_newMembers);
  160. return $this->get($list->getId());
  161. }
  162. /**
  163. * Search the List for it's contacts
  164. *
  165. * @param type $_listId
  166. * @param type $_paging
  167. * @return type
  168. */
  169. public function searchListContacts($_listId, $_paging)
  170. {
  171. return $this->_backendContactList->searchListContacts($_listId, $_paging);
  172. }
  173. /**
  174. * Search the List for it's contacts and return a comma separated list of it on the format
  175. * name <email>, name <email>, etc...
  176. *
  177. * @param string|array $_listId
  178. * @param type $_paging
  179. * @return array
  180. */
  181. public function searchListContactsFormated($_listId, $_paging = null)
  182. {
  183. $return = array();
  184. if (!(is_array($_listId))){
  185. $filters[] = $_listId;
  186. }else {
  187. $filters = $_listId;
  188. }
  189. foreach ($filters as $index=>$filter){
  190. if (is_string($filter)){
  191. $filter = array(array('field' => 'list_id', 'operator' => 'equals', 'value' => $filter));
  192. }
  193. $listContacts = $this->_backendContactList->searchListContacts($filter, $_paging);
  194. $return[$index] = '';
  195. if ($listContacts['totalcount'] > 0){
  196. $arrReturn = array();
  197. foreach ($listContacts['results'] as $contact){
  198. $arrReturn[] = $contact['n_fn']. ' <' .$contact['email'] . '>';
  199. }
  200. $return[$index] = implode(', ', $arrReturn);
  201. }
  202. $index++;
  203. }
  204. return $return;
  205. }
  206. /**
  207. * fixes empty container ids / perhaps this can be removed later as all lists should have a container id!
  208. *
  209. * @param mixed $_listId
  210. * @return Addressbook_Model_List
  211. */
  212. protected function _fixEmptyContainerId($_listId)
  213. {
  214. $list = $this->_backend->get($_listId);
  215. if (empty($list->container_id)) {
  216. $list->container_id = $this->_getDefaultInternalAddressbook();
  217. $list = $this->_backend->update($list);
  218. }
  219. return $list;
  220. }
  221. /**
  222. * get default internal adb id
  223. *
  224. * @return string
  225. */
  226. protected function _getDefaultInternalAddressbook()
  227. {
  228. $appConfigDefaults = Admin_Controller::getInstance()->getConfigSettings();
  229. $result = (isset($appConfigDefaults[Admin_Model_Config::DEFAULTINTERNALADDRESSBOOK])) ? $appConfigDefaults[Admin_Model_Config::DEFAULTINTERNALADDRESSBOOK] : NULL;
  230. if (empty($result)) {
  231. if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__
  232. . ' Default internal addressbook not found. Creating new config setting.');
  233. $result = Addressbook_Setup_Initialize::setDefaultInternalAddressbook()->getId();
  234. }
  235. return $result;
  236. }
  237. /**
  238. * remove members from list
  239. *
  240. * @param mixed $_listId
  241. * @param mixed $_newMembers
  242. * @return Addressbook_Model_List
  243. */
  244. public function removeListMember($_listId, $_newMembers)
  245. {
  246. $list = $this->get($_listId);
  247. $this->_checkGrant($list, 'update', TRUE, 'No permission to remove list member.');
  248. $list = $this->_backend->removeListMember($_listId, $_newMembers);
  249. return $this->get($list->getId());
  250. }
  251. /**
  252. * inspect creation of one record
  253. *
  254. * @param Tinebase_Record_Interface $_record
  255. * @return void
  256. */
  257. protected function _inspectBeforeCreate(Tinebase_Record_Interface $_record)
  258. {
  259. $_record = $this->_treatMembers($_record);
  260. if (isset($_record->type) && $_record->type == Addressbook_Model_List::LISTTYPE_GROUP) {
  261. throw new Addressbook_Exception_InvalidArgument('can not add list of type ' . Addressbook_Model_List::LISTTYPE_GROUP);
  262. }
  263. }
  264. /**
  265. * inspect update of one record
  266. *
  267. * @param Tinebase_Record_Interface $_record the update record
  268. * @param Tinebase_Record_Interface $_oldRecord the current persistent record
  269. * @return void
  270. */
  271. protected function _inspectBeforeUpdate($_record, $_oldRecord)
  272. {
  273. $_record = $this->_treatMembers($_record);
  274. if (isset($_record->type) && $_record->type == Addressbook_Model_List::LISTTYPE_GROUP) {
  275. throw new Addressbook_Exception_InvalidArgument('can not add list of type ' . Addressbook_Model_List::LISTTYPE_GROUP);
  276. }
  277. }
  278. /**
  279. * create or update list in addressbook sql backend
  280. *
  281. * @param Tinebase_Model_Group $group
  282. * @return Addressbook_Model_List
  283. */
  284. public function createOrUpdateByGroup(Tinebase_Model_Group $group)
  285. {
  286. if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($group->toArray(), TRUE));
  287. try {
  288. if (empty($group->list_id)) {
  289. $list = $this->_backend->getByGroupName($group->name);
  290. if (! $list) {
  291. // jump to catch block => no list_id provided and no existing list for group found
  292. throw new Tinebase_Exception_NotFound('list_id is empty');
  293. }
  294. $group->list_id = $list->getId();
  295. } else {
  296. $list = $this->_backend->get($group->list_id);
  297. }
  298. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
  299. . ' Update list ' . $group->name);
  300. $list->name = $group->name;
  301. $list->description = $group->description;
  302. $list->email = $group->email;
  303. $list->type = Addressbook_Model_List::LISTTYPE_GROUP;
  304. $list->container_id = (empty($group->container_id)) ? $this->_getDefaultInternalAddressbook() : $group->container_id;
  305. $list->members = (isset($group->members)) ? $this->_getContactIds($group->members) : array();
  306. // add modlog info
  307. Tinebase_Timemachine_ModificationLog::setRecordMetaData($list, 'update');
  308. $list = $this->_backend->update($list);
  309. $list = $this->get($list->getId());
  310. } catch (Tinebase_Exception_NotFound $tenf) {
  311. $list = $this->createByGroup($group);
  312. }
  313. return $list;
  314. }
  315. /**
  316. * create new list by group
  317. *
  318. * @param Tinebase_Model_Group $group
  319. * @return Addressbook_Model_List
  320. */
  321. public function createByGroup($group)
  322. {
  323. $list = new Addressbook_Model_List(array(
  324. 'name' => $group->name,
  325. 'description' => $group->description,
  326. 'email' => $group->email,
  327. 'type' => Addressbook_Model_List::LISTTYPE_GROUP,
  328. 'container_id' => (empty($group->container_id)) ? $this->_getDefaultInternalAddressbook() : $group->container_id,
  329. 'members' => (isset($group->members)) ? $this->_getContactIds($group->members) : array(),
  330. ));
  331. // add modlog info
  332. Tinebase_Timemachine_ModificationLog::setRecordMetaData($list, 'create');
  333. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
  334. . ' Add new list ' . $group->name);
  335. if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
  336. . ' ' . print_r($list->toArray(), TRUE));
  337. $list = $this->_backend->create($list);
  338. return $list;
  339. }
  340. /**
  341. * get contact_ids of users
  342. *
  343. * @param array $_userIds
  344. * @return array
  345. */
  346. protected function _getContactIds($_userIds)
  347. {
  348. $contactIds = array();
  349. if (empty($_userIds)) {
  350. return $contactIds;
  351. }
  352. foreach ($_userIds as $userId) {
  353. $fullUser = Tinebase_User::getInstance()->getUserById($userId, 'Tinebase_Model_FullUser');
  354. if (!empty($fullUser->contact_id)) {
  355. $contactIds[] = $fullUser->contact_id;
  356. }
  357. }
  358. return $contactIds;
  359. }
  360. /**
  361. * you can define default filters here
  362. *
  363. * @param Tinebase_Model_Filter_FilterGroup $_filter
  364. */
  365. protected function _addDefaultFilter(Tinebase_Model_Filter_FilterGroup $_filter = NULL)
  366. {
  367. if (! $_filter->isFilterSet('showHidden')) {
  368. $hiddenFilter = $_filter->createFilter('showHidden', 'equals', FALSE);
  369. $hiddenFilter->setIsImplicit(TRUE);
  370. $_filter->addFilter($hiddenFilter);
  371. }
  372. }
  373. /**
  374. * Treat the arrmembers to remove empty ones
  375. *
  376. * @param $_record
  377. */
  378. protected function _treatMembers($_record)
  379. {
  380. if (isset($_record->members)){
  381. $arrMembersOld = $_record->members;
  382. $arrMembersNew = array();
  383. foreach ($arrMembersOld as $member){
  384. $member = trim($member);
  385. if (!(empty($member))){
  386. $arrMembersNew[] = $member;
  387. }
  388. }
  389. $_record->members = $arrMembersNew;
  390. }
  391. return $_record;
  392. }
  393. }