Finish up the SUPPORTED/GHOSTED implementation
authorMichael J. Rubinsky <mrubinsk@horde.org>
Mon, 26 Apr 2010 14:23:52 +0000 (10:23 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Mon, 26 Apr 2010 14:25:35 +0000 (10:25 -0400)
framework/ActiveSync/lib/Horde/ActiveSync/Connector/Importer.php
framework/ActiveSync/lib/Horde/ActiveSync/Driver/Base.php
framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde.php
framework/ActiveSync/lib/Horde/ActiveSync/Message/Base.php
framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php
framework/ActiveSync/lib/Horde/ActiveSync/State/History.php

index 65cc34b..88078fc 100644 (file)
@@ -94,7 +94,7 @@ class Horde_ActiveSync_Connector_Importer
      *
      * @return mixed The server message id or false
      */
-    public function importMessageChange($id, $message)
+    public function importMessageChange($id, $message, $device)
     {
         /* do nothing if it is in a dummy folder */
         if ($this->_folderId == Horde_ActiveSync::FOLDER_TYPE_DUMMY) {
@@ -126,7 +126,7 @@ class Horde_ActiveSync_Connector_Importer
         }
 
         /* Tell the backend about the change */
-        $stat = $this->_backend->changeMessage($this->_folderId, $id, $message);
+        $stat = $this->_backend->changeMessage($this->_folderId, $id, $message, $device);
         $stat['parent'] = $this->_folderId;
         if (!is_array($stat)) {
             return $stat;
index 292e2c2..3e17853 100644 (file)
@@ -256,15 +256,16 @@ abstract class Horde_ActiveSync_Driver_Base
     abstract public function deleteMessage($folderid, $id);
 
     /**
-     * Change (i.e. add or edit) a message on the backend
+     * Add/Edit a message
      *
-     * @param string $folderId  Folderid
-     * @param string $id        Message id (maybe reorder parameteres since this may be null)
-     * @param Horde_ActiveSync_Message_Base $message
-     *
-     * @return a stat array of the new message
+     * @param string $folderid  The server id for the folder the message belongs
+     *                          to.
+     * @param string $id        The server's uid for the message if this is a
+     *                          change to an existing message.
+     * @param Horde_ActiveSync_Message_Base $message  The activesync message
+     * @param stdClass $device  The device information
      */
-    abstract public function changeMessage($folderid, $id, $message);
+    abstract public function changeMessage($folderid, $id, $message, $device);
 
     /**
      * Any code needed to authenticate to backend as the actual user.
index 2e6e769..edaefe6 100644 (file)
@@ -433,13 +433,16 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base
     /**
      * Add/Edit a message
      *
-     * @param string $folderid
-     * @param string $id
-     * @param Horde_ActiveSync_Message_Base $message
+     * @param string $folderid  The server id for the folder the message belongs
+     *                          to.
+     * @param string $id        The server's uid for the message if this is a
+     *                          change to an existing message.
+     * @param Horde_ActiveSync_Message_Base $message  The activesync message
+     * @param stdClass $device  The device information
      *
      * @see framework/ActiveSync/lib/Horde/ActiveSync/Driver/Horde_ActiveSync_Driver_Base#changeMessage($folderid, $id, $message)
      */
-    public function changeMessage($folderid, $id, $message)
+    public function changeMessage($folderid, $id, $message, $device)
     {
         $this->_logger->debug('Horde::changeMessage(' . $folderid . ', ' . $id . ')');
 
@@ -462,6 +465,9 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base
                 // ActiveSync messages do NOT contain the serverUID value, put
                 // it in ourselves so we can have it during import/change.
                 $message->setServerUID($id);
+                if (!empty($device->supported[self::APPOINTMENTS_FOLDER])) {
+                    $message->setSupported($device->supported[self::APPOINTMENTS_FOLDER]);
+                }
                 try {
                     $this->_connector->calendar_replace($id, $message);
                 } catch (Horde_Exception $e) {
@@ -483,6 +489,9 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base
                 $stat = $this->_smartStatMessage($folderid, $id, false);
                 $stat['mod'] = time();
             } else {
+                if (!empty($device->supported[self::CONTACTS_FOLDER])) {
+                    $message->setSupported($device->supported[self::CONTACTS_FOLDER]);
+                }
                 try {
                     $this->_connector->contacts_replace($id, $message);
                 } catch (Horde_Exception $e) {
@@ -504,6 +513,9 @@ class Horde_ActiveSync_Driver_Horde extends Horde_ActiveSync_Driver_Base
                 $stat = $this->_smartStatMessage($folderid, $id, false);
                 $stat['mod'] = time();
             } else {
+                if (!empty($device->supported[self::TASKS_FOLDER])) {
+                    $message->setSupported($device->supported[self::TASKS_FOLDER]);
+                }
                 try {
                     $this->_connector->tasks_replace($id, $message);
                 } catch (Horde_Exception $e) {
index 9ca0af0..10f4c55 100644 (file)
@@ -70,6 +70,14 @@ class Horde_ActiveSync_Message_Base
     protected $_logger;
 
     /**
+     * An array describing the non-ghosted elements this message supports.
+     *
+     * @var array
+     */
+    protected $_supported = array();
+    protected $_exists = array();
+
+    /**
      * Const'r
      *
      * @param array $mapping  A mapping array from constants -> property names
@@ -107,6 +115,7 @@ class Horde_ActiveSync_Message_Base
             throw new InvalidArgumentException('Unknown property: ' . $property);
         }
         $this->_properties[$property] = $value;
+        $this->_exists[$property] = true;
     }
 
     public function __call($method, $arg)
@@ -122,14 +131,46 @@ class Horde_ActiveSync_Message_Base
         throw new BadMethodCallException('Unknown method: ' . $method . ' in class: ' . __CLASS__);
     }
 
-
-
     public function __isset($property)
     {
         return !empty($this->_properties[$property]);
     }
 
     /**
+     * Set the list of non-ghosted fields for this message.
+     *
+     * @param array $fields  The array of fields.
+     */
+    public function setSupported($fields)
+    {
+        $this->_supported = array();
+        foreach ($fields as $field) {
+            $this->_supported[] = $this->_mapping[$field][self::KEY_ATTRIBUTE];
+        }
+    }
+
+    /**
+     * Get the list of non-ghosted properties for this message.
+     *
+     * @return array  The array of non-ghosted properties
+     */
+    public function getSupported()
+    {
+        return $this->_supported;
+    }
+
+    public function isGhosted($property)
+    {
+        if (array_search($property, $this->_supported) !== false) {
+            return false;
+        } elseif (empty($this->_exists[$property])) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
      * Recursively decodes the WBXML from input stream. This means that if this
      * message contains complex types (like Appointment.Recuurence for example)
      * the sub-objects are auto-instantiated and decoded as well. Places the
index aeb7ca3..edd645a 100644 (file)
@@ -98,11 +98,11 @@ class Horde_ActiveSync_Request_Sync extends Horde_ActiveSync_Request_Base
                     exit;
                 }
                 while (1) {
-                    $el = $this->_decoder->getElementContent();
-                    $collection['supported'][] = $el;
+                    $el = $this->_decoder->getElement();
                     if ($el[Horde_ActiveSync_Wbxml::EN_TYPE] == Horde_ActiveSync_Wbxml::EN_TYPE_ENDTAG) {
                         break;
                     }
+                    $collection['supported'][] = $el[2];
                 }
             }
 
@@ -295,14 +295,14 @@ class Horde_ActiveSync_Request_Sync extends Horde_ActiveSync_Request_Base
                             if (isset($appdata->read)) {
                                 $importer->importMessageReadFlag($serverid, $appdata->read);
                             } else {
-                                $importer->importMessageChange($serverid, $appdata);
+                                $importer->importMessageChange($serverid, $appdata, $device);
                             }
                             $collection['importedchanges'] = true;
                         }
                         break;
                     case Horde_ActiveSync::SYNC_ADD:
                         if (isset($appdata)) {
-                            $id = $importer->importMessageChange(false, $appdata);
+                            $id = $importer->importMessageChange(false, $appdata, $device);
                             if ($clientid && $id) {
                                 $collection['clientids'][$clientid] = $id;
                                 $collection['importedchanges'] = true;
index 3ee5907..c81a8ba 100644 (file)
@@ -472,7 +472,7 @@ class Horde_ActiveSync_State_History extends Horde_ActiveSync_State_Base
                             $data->rwstatus,
                             $devId,
                             $data->user,
-                            (!empty($data->supported) ? $data->supported : ''));
+                            (!empty($data->supported) ? serialize($data->supported) : ''));
 
             $this->_devId = $devId;