diff --git a/lib/kolab_sync_backend_device.php b/lib/kolab_sync_backend_device.php index 952efa3..57d3174 100644 --- a/lib/kolab_sync_backend_device.php +++ b/lib/kolab_sync_backend_device.php @@ -1,322 +1,323 @@ | | | | This program is free software: you can redistribute it and/or modify | | it under the terms of the GNU Affero General Public License as published | | by the Free Software Foundation, either version 3 of the License, or | | (at your option) any later version. | | | | This program is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | GNU Affero General Public License for more details. | | | | You should have received a copy of the GNU Affero General Public License | | along with this program. If not, see | +--------------------------------------------------------------------------+ | Author: Aleksander Machniak | +--------------------------------------------------------------------------+ */ /** * Kolab backend class for device storage */ class kolab_sync_backend_device extends kolab_sync_backend_common implements Syncroton_Backend_IDevice { protected $table_name = 'syncroton_device'; protected $interface_name = 'Syncroton_Model_IDevice'; /** * Kolab Sync backend * * @var kolab_sync_backend */ protected $backend; /** * Constructor */ public function __construct() { parent::__construct(); $this->backend = kolab_sync_backend::get_instance(); } /** * Create (register) a new device * * @param Syncroton_Model_IDevice $device Device object * * @return Syncroton_Model_IDevice Device object */ public function create($device) { $device = parent::create($device); // Create device entry in kolab backend $created = $this->backend->device_create(array( 'ID' => $device->id, 'TYPE' => $device->devicetype, 'ALIAS' => $device->friendlyname, ), $device->deviceid); if (!$created) { throw new Syncroton_Exception_NotFound('Device creation failed'); } return $device; } /** * Delete a device * * @param Syncroton_Model_IDevice $device Device object * * @return bool True on success, False on failure */ public function delete($device) { // Update IMAP annotation $this->backend->device_delete($device->deviceid); return parent::delete($device); } /** * Return device for a given user * * @param string $ownerid User identifier * @param string $deviceid Device identifier * * @throws Syncroton_Exception_NotFound * @return Syncroton_Model_Device Device object */ public function getUserDevice($ownerid, $deviceid) { $where[] = $this->db->quote_identifier('deviceid') . ' = ' . $this->db->quote($deviceid); $where[] = $this->db->quote_identifier('owner_id') . ' = ' . $this->db->quote($ownerid); $select = $this->db->query('SELECT * FROM ' . $this->table_name . ' WHERE ' . implode(' AND ', $where)); $device = $this->db->fetch_assoc($select); if (empty($device)) { throw new Syncroton_Exception_NotFound('Device not found'); } $device = $this->get_object($device); // Make sure device exists (could be deleted by the user) $dev = $this->backend->device_get($deviceid); if (empty($dev)) { // Remove the device (and related cached data) from database $this->delete($device); throw new Syncroton_Exception_NotFound('Device not found'); } return $device; } /** * Returns list of user accounts * * @param Syncroton_Model_Device $device The device * * @return array List of Syncroton_Model_Account objects */ public function userAccounts($device) { $engine = kolab_sync::get_instance(); $identities = $engine->user->list_identities(); $email = $engine->get_user_email(); $addresses = array(); + $displayname = null; // read email addresses and display name (default ident comes first) foreach ((array)$identities as $ident) { if ($ident['name'] && !isset($displayname)) { $displayname = $ident['name']; } $addresses[] = $ident['email']; } if (empty($displayname) && empty($email) && empty($addresses)) { return array(); } $account = new Syncroton_Model_Account; if ($email) { $addresses = array_diff($addresses, array($email)); } $account->userDisplayName = $displayname; $account->primaryAddress = $email; $account->addresses = array_unique($addresses); return array($account); } /** * Returns OOF information * * @param array $request Oof/Get request data * * @return Syncroton_Model_Oof Response object or NULL if OOF is not supported * @throws Syncroton_Exception_Status */ public function getOOF($request) { $vacation_engine = $this->vacation_engine(); if (!$vacation_engine) { return; } $vacation = $vacation_engine->get_vacation(); if (!$vacation['enabled']) { $status = Syncroton_Model_Oof::STATUS_DISABLED; $vacation['start'] = $vacation['end'] = null; } else if ($vacation['start'] || $vacation['end']) { // in Activesync both or none time are required if (!$vacation['start'] && $vacation['end']) { $vacation['start'] = new DateTime('1970-01-01', new DateTimeZone('UTC')); } if (!$vacation['end'] && $vacation['start']) { $vacation['end'] = new DateTime('2100-01-01', new DateTimeZone('UTC')); } // convert timezone to UTC if ($vacation['start']) { $vacation['start']->setTimezone(new DateTimeZone('UTC')); } if ($vacation['end']) { $vacation['end']->setTimezone(new DateTimeZone('UTC')); } $status = Syncroton_Model_Oof::STATUS_TIME_BASED; } else { $status = Syncroton_Model_Oof::STATUS_GLOBAL; } $message = null; if ($vacation['message']) { $message = array(); // convert message format, Roundcube supports plain text only if ($request['bodyType'] == 'HTML') { $text2html = new rcube_text2html($vacation['message']); $vacation['message'] = $text2html->get_html(); } foreach (array('Internal', 'ExternalKnown', 'ExternalUnknown') as $type) { $message[] = new Syncroton_Model_OofMessage(array( "appliesTo$type" => true, 'enabled' => 1, 'bodyType' => 'Text', 'replyMessage' => rcube_charset::clean($vacation['message']), )); } } return new Syncroton_Model_Oof(array( 'oofState' => $status, 'startTime' => $vacation['start'], 'endTime' => $vacation['end'], 'oofMessage' => $message, )); } /** * Sets OOF information * * @param Syncroton_Model_Oof $request Request object * * @throws Syncroton_Exception_Status */ public function setOOF($request) { $vacation_engine = $this->vacation_engine(); if (!$vacation_engine) { return; } $vacation = $vacation_engine->get_vacation(); // enable out-of-office if (!empty($request->oofState)) { if ($request->oofState == Syncroton_Model_Oof::STATUS_TIME_BASED) { $vacation['start'] = $request->startTime; $vacation['end'] = $request->endTime; if (empty($vacation['start']) || empty($vacation['end'])) { throw new Syncroton_Exception_Status_Settings(Syncroton_Exception_Status_Settings::INVALID_ARGUMENTS); } } else { $vacation['start'] = $vacation['end'] = null; } foreach ($request->oofMessage as $msg) { if ($msg->enabled && ($message = $msg->replyMessage)) { $message_type = $msg->bodyType; // convert message format, Roundcube supports plain text only if ($message_type == 'HTML') { $html2text = new rcube_html2text($message, false, true); $message = $html2text->get_text(); } break; } } if (empty($message)) { throw new Syncroton_Exception_Status_Settings(Syncroton_Exception_Status_Settings::INVALID_ARGUMENTS); } $vacation['message'] = $message; $vacation['subject'] = null; $vacation['enabled'] = true; $vacation_engine->set_vacation($vacation); } // disable out-of-office else if (isset($request->oofState)) { if ($vacation['enabled']) { $vacation['enabled'] = false; $vacation_engine->set_vacation($vacation); } } } /** * Load managesieve plugin and return vacation engine class */ private function vacation_engine() { $engine = kolab_sync::get_instance(); $engine->plugins->load_plugin('managesieve', true, false); if (class_exists('managesieve')) { $plugin = $engine->plugins->get_plugin('managesieve'); $vacation = $plugin->get_engine('vacation'); if ($vacation->connect($engine->username, $engine->password)) { throw new Exception("Connection to managesieve server failed"); } return $vacation; } } }