From 838a47f973879412e215331120d65e0eecb28286 Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Sun, 11 Apr 2010 11:19:48 -0400 Subject: [PATCH] Add support for synching tasks --- .../lib/Horde/ActiveSync/Connector/Exporter.php | 2 +- .../lib/Horde/ActiveSync/Driver/Horde.php | 51 +++++- .../ActiveSync/Driver/Horde/Connector/Registry.php | 36 +++- .../lib/Horde/ActiveSync/Message/Appointment.php | 8 - .../lib/Horde/ActiveSync/Message/Base.php | 9 + .../lib/Horde/ActiveSync/Message/Task.php | 193 ++++++++++++++++++++- .../ActiveSync/lib/Horde/ActiveSync/State/File.php | 3 +- 7 files changed, 281 insertions(+), 21 deletions(-) diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter.php b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter.php index f286a81e7..c32d6510b 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter.php @@ -91,7 +91,7 @@ class Horde_ActiveSync_Connector_Exporter { /* Just ignore any messages that are not from this collection */ if ($message->getClass() != $this->_class) { - return true; + return true; } /* Prevent sending the same object twice in one request */ diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde.php b/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde.php index 5b1b942dd..62d764019 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde.php @@ -241,7 +241,13 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base break; case self::TASKS_FOLDER: - // @TODO? + $tasks = $this->_connector->tasks_listTasks(); + foreach ($tasks as $task) + { + $messages[] = $this->_smartStatMessage($folderid, $task, true); + } + break; + default: return false; } @@ -274,7 +280,7 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base /** * Get a message from the backend - * + * * @see framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde_ActiveSync_Driver_Base#GetMessage($folderid, $id, $truncsize, $mimesupport) */ public function GetMessage($folderid, $id, $truncsize, $mimesupport = 0) @@ -290,8 +296,6 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base $this->_logger->err($e->GetMessage()); return false; } - //$message = self::_fromVCalendar($event); - break; case self::CONTACTS_FOLDER: @@ -302,17 +306,20 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base return false; } - $message = self::_fromHash($contact); + return self::_fromHash($contact); break; case self::TASKS_FOLDER: - // @TODO + try { + return $this->_connector->tasks_export($id); + } catch (Horde_Exception $e) { + $this->_logger->err($e->GetMessage()); + return false; + } break; default: return false; } - - return $message; } /** @@ -355,6 +362,12 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base break; case self::TASKS_FOLDER: + try { + $status = $this->_connector->tasks_delete($id); + } catch (Horde_Exception $e) { + $this->_logger->err($e->getMessage()); + return false; + } break; default: return false; @@ -421,10 +434,30 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base $stat = $this->_smartStatMessage($folderid, $id, false); } case self::TASKS_FOLDER: + if (!$id) { + try { + $id = $this->_connector->tasks_import($message); + } catch (Horde_Exception $e) { + $this->_logger->err($e->getMessage()); + return false; + } + + $stat = $this->_smartStatMessage($folderid, $id, false); + } else { + try { + $this->_connector->tasks_replace($id, $message); + } catch (Horde_Exception $e) { + $this->_logger->err($e->getMessage()); + return false; + } + $stat = $this->_smartStatMessage($folderid, $id, false); + } + break; default: return false; } + return $stat; } @@ -504,6 +537,8 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base $mod = $this->_connector->contacts_getActionTimestamp($id, 'modify'); break; case self::TASKS_FOLDER: + $mod = $this->_connector->tasks_getActionTimestamp($id, 'modify'); + break; default: return false; diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde/Connector/Registry.php b/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde/Connector/Registry.php index 2a4cd89ae..7a901e4be 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde/Connector/Registry.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde/Connector/Registry.php @@ -216,7 +216,34 @@ class Horde_ActiveSync_Driver_Horde_Connector_Registry public function tasks_listTasks() { - return $this->_registry->tasks->listTasks(); + $app = $this->horde_hasInterface('tasks'); + $tasklist = $this->horde_getPref($app, 'default_tasklist'); + return $this->_registry->tasks->listTaskUids($tasklist); + } + + public function tasks_export($uid) + { + return $this->_registry->tasks->export($uid, 'activesync'); + } + + public function tasks_import($message) + { + return $this->_registry->tasks->import($message, 'activesync'); + } + + public function tasks_replace($uid, $message) + { + return $this->_registry->tasks->replace($uid, $message, 'activesync'); + } + + public function tasks_delete($id) + { + return $this->_registry->tasks->delete($id); + } + + public function tasks_getActionTimestamp($uid, $action) + { + return $this->_registry->tasks->getActionTimestamp($uid, $action); } public function horde_listApis() @@ -226,7 +253,12 @@ class Horde_ActiveSync_Driver_Horde_Connector_Registry public function horde_getPref($app, $pref) { - return $this->_registry->horde->getPref($app, $pref); + return $this->_registry->horde->getPreference($app, $pref); + } + + public function horde_hasInterface($api) + { + return $this->_registry->hasInterface($api); } } \ No newline at end of file diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php index f946a9196..b12e7a7ec 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php @@ -720,12 +720,4 @@ class Horde_ActiveSync_Message_Appointment extends Horde_ActiveSync_Message_Base return 'Calendar'; } - protected function _getAttribute($name, $default = null) - { - if (!empty($this->_properties[$name])) { - return $this->_properties[$name]; - } else { - return $default; - } - } } \ No newline at end of file diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Base.php b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Base.php index af412223c..81127f953 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Base.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Base.php @@ -329,6 +329,15 @@ class Horde_ActiveSync_Message_Base } } + protected function _getAttribute($name, $default = null) + { + if (!empty($this->_properties[$name])) { + return $this->_properties[$name]; + } else { + return $default; + } + } + /** * Oh yeah. This is beautiful. Exchange outputs date fields differently in * calendar items and emails. We could just always send one or the other, diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Task.php b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Task.php index ee555ecb1..acee8a1bb 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Task.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Task.php @@ -42,6 +42,16 @@ class Horde_ActiveSync_Message_Task extends Horde_ActiveSync_Message_Base const POOMTASKS_SUBJECT = 'POOMTASKS:Subject'; const POOMTASKS_RTF = 'POOMTASKS:Rtf'; + const TASK_COMPLETE_TRUE = 1; + const TASK_COMPLETE_FALSE = 0; + + const IMPORTANCE_LOW = 0; + const IMPORTANCE_NORMAL = 1; + const IMPORTANCE_HIGH = 2; + + const REMINDER_SET_FALSE = 0; + const REMINDER_SET_TRUE = 1; + /** * Const'r * @@ -70,5 +80,186 @@ class Horde_ActiveSync_Message_Task extends Horde_ActiveSync_Message_Base parent::__construct($mapping, $params); } - + + /** + * Sets the task subject + * + * @param string $subject + */ + public function setSubject($subject) + { + $this->_properties['subject'] = $subject; + } + + /** + * Get the task subject/title + * + * @return string The task subject + */ + public function getSubject() + { + return $this->_getAttribute('subject'); + } + + /** + * Returns the body of the task. + * + * @return string The descriptive body. + */ + public function getBody() + { + return $this->_getAttribute('body'); + } + + /** + * Set the task body element. + * + * @param string $body The task body + */ + public function setBody($body) + { + $this->_properties['body'] = $body; + } + + /** + * Set the task completion flag + * + * @param integer $flag TASK_COMPLETE constant + */ + public function setComplete($flag) + { + $this->_properties['complete'] = $flag; + } + + /** + * Get the completion flag + * + * @return integer A TASK_COMPLETE constant + */ + public function getComplete() + { + return $this->_getAttribute('complete'); + } + + /** + * Set the date the task was completed. + * + * @param Horde_Date $date The date in local tz. + */ + public function setDateCompleted($date) + { + $this->_properties['datecompleted'] = $date; + } + + /** + * Get the date completed. + * + * @return Horde_Date The date in the local tz. + */ + public function getDateCompleted() + { + return $this->_getAttribute('datecompleted'); + } + + /** + * Set the due date. Note that even though the property is called UTCDueDate + * we still pass a Horde_Date in the user's timezone since the dates are + * transformed to UTC during encoding. Yay consistency... + * + * + */ + public function setDueDate($date) + { + $this->_properties['utcduedate'] = $date; + } + + /** + * Get the task due date. + * + * @return Horde_Date Date in local tz + */ + public function getDueDate() + { + return $this->_getAttribute('utcduedate'); + } + + /** + * Set the importance + * + * @param integer $importance A IMPORTANCE_* flag + */ + public function setImportance($importance) + { + if (is_null($importance)) { + $importance = self::IMPORTANCE_NORMAL; + } + + $this->_properties['importance'] = $importance; + } + + /** + * Get the task importance level + * + * @return integer A IMPORTANCE_* constant + */ + public function getImportance() + { + return $this->_getAttribute('importance', self::IMPORTANCE_NORMAL); + } + + /** + * Set the reminder datetime + * + * @param Horde_Date $datetime The time to trigger the alarm in local tz. + */ + public function setReminder($datetime) + { + $this->_properties['remindertime'] = $datetime; + $this->_properties['reminderset'] = self::REMINDER_SET_TRUE; + } + + /** + * Get the reminder time. + * + * @return Horde_Date in local tz + */ + public function getReminder() + { + if (!$this->_getAttribute('reminderset')) { + return false; + } + + return $this->_getAttribute('remindertime'); + } + + /** + * Set the task start datetime + * + * @param Horde_Date $date Date in local tz + */ + public function setStartDate($date) + { + $this->_properties['utcstartdate'] = $date; + } + + /** + * Get the task start datetime + * + * @return Horde_Date + */ + public function getStartDate() + { + return $this->_getAttribute('utcstartdate'); + } + + /** + * Return this object's folder class + * + * @return string + */ + public function getClass() + { + return 'Tasks'; + } + } \ No newline at end of file diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/State/File.php b/framework/ActiveSync/lib/Horde/ActiveSync/State/File.php index 7b15725e1..d4d437b7f 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/State/File.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/State/File.php @@ -445,7 +445,8 @@ class Horde_ActiveSync_State_File extends Horde_ActiveSync_State_Base case 'change': $stat = $this->_backend->StatMessage($this->_collection['id'], $change['id']); if (!$message = $this->_backend->GetMessage($this->_collection['id'], $change['id'], 0)) { - throw new Horde_ActiveSync_Exception('Message not found'); + continue; + //throw new Horde_ActiveSync_Exception('Message not found'); } if ($stat && $message) { $this->updateState('change', $stat); -- 2.11.0