6 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
7 * @author Lars Kneschke <l.kneschke@metaways.de>
8 * @copyright Copyright (c) 2007-2010 Metaways Infosystems GmbH (http://www.metaways.de)
10 * @todo move visibility='displayed' check from getSelect to contact filter
14 * sql backend class for the addressbook
16 * @package Addressbook
18 class Addressbook_Backend_List extends Tinebase_Backend_Sql_Abstract
21 * Table name without prefix
25 protected $_tableName = 'addressbook_lists';
32 protected $_modelName = 'Addressbook_Model_List';
35 * if modlog is active, we add 'is_deleted = 0' to select object in _getSelect()
39 protected $_modlogActive = TRUE;
42 * default column(s) for count
46 protected $_defaultCountCol = 'id';
50 * name => array(table, joinOn, field)
54 protected $_foreignTables = array(
56 'table' => 'addressbook_list_members',
57 'field' => 'contact_id',
58 'joinOn' => 'list_id',
63 'joinOn' => 'list_id',
64 // use first element of result array
65 'singleValue' => TRUE,
78 * @param Zend_Db_Adapter_Abstract $_db (optional)
79 * @param array $_options (optional)
80 * @throws Tinebase_Exception_Backend_Database
82 public function __construct($_dbAdapter = NULL, $_options = array())
84 parent::__construct($_dbAdapter, $_options);
87 * TODO move this code somewhere and make it optionally. Maybe even make it a new controller / frontend action and request the data async
89 if (Addressbook_Config::getInstance()->featureEnabled(Addressbook_Config::FEATURE_LIST_VIEW)) {
90 $this->_additionalColumns['emails'] = new Zend_Db_Expr('(' .
92 ->from($this->_tablePrefix . 'addressbook', array($this->_dbCommand->getAggregate('email')))
93 ->where($this->_db->quoteIdentifier('id') . ' IN ?', $this->_db->select()
94 ->from(array('addressbook_list_members' => $this->_tablePrefix . 'addressbook_list_members'), array('contact_id'))
95 ->where($this->_db->quoteIdentifier('addressbook_list_members.list_id') . ' = ' . $this->_db->quoteIdentifier('addressbook_lists.id'))
102 * converts record into raw data for adapter
104 * @param Tinebase_Record_Abstract $_record
107 protected function _recordToRawData($_record)
109 $result = parent::_recordToRawData($_record);
111 // stored in foreign key
112 unset($result['members']);
113 unset($result['group_id']);
119 * add new members to list
121 * @param mixed $_listId
122 * @param mixed $_newMembers
123 * @return Addressbook_Model_List
125 public function addListMember($_listId, $_newMembers)
127 $list = $this->get($_listId);
129 if (empty($_newMembers)) {
133 $newMembers = Tinebase_Record_RecordSet::getIdsFromMixed($_newMembers);
134 $idsToAdd = array_diff($newMembers, $list->members);
136 $listId = Tinebase_Record_Abstract::convertId($_listId, $this->_modelName);
138 $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
140 foreach ($idsToAdd as $id) {
141 $recordArray = array (
142 $this->_foreignTables['members']['joinOn'] => $listId,
143 $this->_foreignTables['members']['field'] => $id
145 $this->_db->insert($this->_tablePrefix . $this->_foreignTables['members']['table'], $recordArray);
148 Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId);
150 return $this->get($_listId);
154 * Delete all lists returned by {@see getAll()} using {@see delete()}
157 public function deleteAllLists()
159 $lists = $this->getAll();
161 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Deleting ' . count($lists) .' lists');
163 if(count($lists) > 0) {
164 $this->delete($lists->getArrayOfIds());
169 * remove members from list
171 * @param mixed $_listId
172 * @param mixed $_membersToRemove
173 * @return Addressbook_Model_List
175 public function removeListMember($_listId, $_membersToRemove)
177 $list = $this->get($_listId);
179 if (empty($_membersToRemove)) {
183 $removeMembers = Tinebase_Record_RecordSet::getIdsFromMixed($_membersToRemove);
184 $idsToRemove = array_intersect($list->members, $removeMembers);
185 $listId = Tinebase_Record_Abstract::convertId($_listId, $this->_modelName);
187 $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
189 if (!empty($idsToRemove)) {
191 $this->_db->quoteInto($this->_db->quoteIdentifier($this->_tablePrefix . $this->_foreignTables['members']['table'] . '.' . $this->_foreignTables['members']['joinOn']) . ' = ?', $listId) .
193 $this->_db->quoteInto($this->_db->quoteIdentifier($this->_tablePrefix . $this->_foreignTables['members']['table'] . '.' . $this->_foreignTables['members']['field']) . ' IN (?)', $idsToRemove) .
196 $this->_db->delete($this->_tablePrefix . $this->_foreignTables['members']['table'], $where);
199 Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId);
201 return $this->get($_listId);
205 * set all lists an user is member of
207 * @param string $contactId
208 * @param mixed $listIds
211 public function setMemberships($contactId, $listIds)
213 $contactId = Tinebase_Record_Abstract::convertId($contactId, 'Addressbook_Model_Contact');
215 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
216 . ' Set ' . count($listIds) . ' list memberships for contact ' . $contactId);
218 if ($listIds instanceof Tinebase_Record_RecordSet) {
219 $listIds = $listIds->getArrayOfIds();
222 $listMemberships = $this->getMemberships($contactId);
224 $removeListMemberships = array_diff($listMemberships, $listIds);
225 $addListMemberships = array_diff($listIds, $listMemberships);
227 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' current memberships: ' . print_r($listMemberships, true));
228 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' new memberships: ' . print_r($listIds, true));
229 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' added memberships: ' . print_r($addListMemberships, true));
230 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' removed memberships: ' . print_r($removeListMemberships, true));
232 foreach ($addListMemberships as $listId) {
233 $this->addListMember($listId, $contactId);
236 foreach ($removeListMemberships as $listId) {
237 $this->removeListMember($listId, $contactId);
240 return $this->getMemberships($contactId);
244 * get group memberships of contact id
246 * @param mixed $contactId
249 public function getMemberships($contactId)
251 $contactId = Tinebase_Record_Abstract::convertId($contactId, 'Addressbook_Model_Contact');
253 $select = $this->_db->select()
254 ->from($this->_tablePrefix . $this->_foreignTables['members']['table'], 'list_id')
255 ->where($this->_db->quoteIdentifier('contact_id') . ' = ?', $contactId);
257 $stmt = $this->_db->query($select);
258 $rows = (array) $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
261 foreach ($rows as $membership) {
262 $result[] = $membership['list_id'];
269 * get list by group name
271 * @param string $groupName
272 * @return NULL|Addressbook_Model_List
274 public function getByGroupName($groupName)
276 $filter = new Addressbook_Model_ListFilter(array(
277 array('field' => 'name', 'operator' => 'equals', 'value' => $groupName),
278 array('field' => 'type', 'operator' => 'equals', 'value' => Addressbook_Model_List::LISTTYPE_GROUP)
281 $existingLists = $this->search($filter);
283 return $existingLists->getFirstRecord();