Overview

Packages

  • ActiveSync
  • None

Classes

  • Horde_ActiveSync
  • Horde_ActiveSync_Connector_Exporter
  • Horde_ActiveSync_Connector_Importer
  • Horde_ActiveSync_Driver_Base
  • Horde_ActiveSync_Exception
  • Horde_ActiveSync_Exception_InvalidRequest
  • Horde_ActiveSync_Exception_StateGone
  • Horde_ActiveSync_Message_Base
  • Horde_ActiveSync_Request_Base
  • Horde_ActiveSync_Request_FolderCreate
  • Horde_ActiveSync_Request_FolderSync
  • Horde_ActiveSync_Request_GetHierarchy
  • Horde_ActiveSync_Request_GetItemEstimate
  • Horde_ActiveSync_Request_MeetingResponse
  • Horde_ActiveSync_Request_MoveItems
  • Horde_ActiveSync_Request_Notify
  • Horde_ActiveSync_Request_Ping
  • Horde_ActiveSync_Request_Provision
  • Horde_ActiveSync_Request_Search
  • Horde_ActiveSync_Request_SendMail
  • Horde_ActiveSync_Request_SmartForward
  • Horde_ActiveSync_Request_SmartReply
  • Horde_ActiveSync_Request_Sync
  • Horde_ActiveSync_State_File
  • Horde_ActiveSync_Sync
  • Horde_ActiveSync_Wbxml
  • Horde_ActiveSync_Wbxml_Decoder
  • Horde_ActiveSync_Wbxml_Encoder
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Syncronizer object. Responsible for performing syncronization of the PIM
  4:  * state with the server state. Sends each change to the exporter and updates
  5:  * state accordingly.
  6:  *
  7:  * Some code adapted from the Z-Push project. Original file header below.
  8:  *
  9:  * Copyright 2010-2012 Horde LLC (http://www.horde.org/)
 10:  *
 11:  * @author Michael J. Rubinsky <mrubinsk@horde.org>
 12:  * @package ActiveSync
 13:  */
 14: 
 15: /***********************************************
 16: * File      :   diffbackend.php
 17: * Project   :   Z-Push
 18: * Descr     :   We do a standard differential
 19: *               change detection by sorting both
 20: *               lists of items by their unique id,
 21: *               and then traversing both arrays
 22: *               of items at once. Changes can be
 23: *               detected by comparing items at
 24: *               the same position in both arrays.
 25: *
 26: * Created   :   01.10.2007
 27: *
 28: * © Zarafa Deutschland GmbH, www.zarafaserver.de
 29: * This file is distributed under GPL-2.0.
 30: * Consult COPYING file for details
 31: ************************************************/
 32: class Horde_ActiveSync_Sync
 33: {
 34:     /**
 35:      * Local copy of changes to push to PIM
 36:      *
 37:      * @var array
 38:      */
 39:     protected $_changes;
 40: 
 41:     /**
 42:      * Tracks the number of changes that have been sent.
 43:      *
 44:      * @var int
 45:      */
 46:     protected $_step = 0;
 47: 
 48:     /**
 49:      * Server specific folder id
 50:      *
 51:      * @var string
 52:      */
 53:     protected $_folderId;
 54: 
 55:     /**
 56:      * The collection type for this folder
 57:      *
 58:      * @var string
 59:      */
 60:     protected $_collection;
 61: 
 62:     /**
 63:      * The backend driver
 64:      *
 65:      * @var Horde_ActiveSync_Driver_Base
 66:      */
 67:     protected $_backend;
 68: 
 69:     /**
 70:      * Any flags
 71:      * ???
 72:      * @var <type>
 73:      */
 74:     protected $_flags;
 75: 
 76:     /**
 77:      * The statemachine
 78:      *
 79:      * @var Horde_ActiveSynce_StateMachine_Base
 80:      */
 81:     protected $_state;
 82: 
 83:     /**
 84:      * The change streamer
 85:      *
 86:      * @var Horde_ActiveSync_Connector_Exporter
 87:      */
 88:     protected $_exporter;
 89: 
 90:     /**
 91:      * Logger
 92:      *
 93:      * @var Horde_Log_Logger
 94:      */
 95:     protected $_logger;
 96: 
 97:     /**
 98:      * Const'r
 99:      *
100:      * @param Horde_ActiveSync_Driver_Base $backend  The backend driver
101:      */
102:     public function __construct(Horde_ActiveSync_Driver_Base $backend)
103:     {
104:         $this->_backend = $backend;
105:     }
106: 
107:     /**
108:      * Initialize the sync
109:      *
110:      * @param Horde_ActiveSync_State_Base $stateMachine      The state machine
111:      * @param Horde_ActiveSync_Connector_Exporter $exporter  The exporter object
112:      * @param array $collection                              Collection data
113:      *
114:      * @return void
115:      */
116:     public function init(Horde_ActiveSync_State_Base &$stateMachine,
117:                          Horde_ActiveSync_Connector_Exporter $exporter = null,
118:                          array $collection = array())
119:     {
120:         $this->_stateMachine = &$stateMachine;
121: 
122:         // We might not need an exporter, like e.g., when we are handling a PING
123:         // request the changes are never exported.
124:         $this->_exporter = $exporter;
125:         $this->_folderId = !empty($collection['id']) ? $collection['id'] : false;
126:         $this->_changes = $stateMachine->getChanges();
127:         $this->_truncation = !empty($collection['truncation']) ? $collection['truncation'] : 0;
128:     }
129: 
130:     public function setLogger($logger)
131:     {
132:         $this->_logger = $logger;
133:     }
134: 
135:     /**
136:      * Sends the next change in the set and updates the stateMachine if
137:      * successful
138:      *
139:      * @param integer $flags  A Horde_ActiveSync:: flag constant
140:      *
141:      * @return mixed  A progress array or false if no more changes
142:      */
143:     public function syncronize($flags = 0)
144:     {
145:         $progress = array();
146: 
147:         if ($this->_folderId == false) {
148:             if ($this->_step < count($this->_changes)) {
149:                 $change = $this->_changes[$this->_step];
150:                 switch($change['type']) {
151:                 case 'change':
152:                     $folder = $this->_backend->getFolder($change['id']);
153:                     $stat = $this->_backend->statFolder($change['id']);
154:                     if (!$folder) {
155:                         return;
156:                     }
157:                     if ($flags & Horde_ActiveSync::BACKEND_DISCARD_DATA ||
158:                         $this->_exporter->folderChange($folder)) {
159: 
160:                         $this->_stateMachine->updateState('foldersync', $stat);
161:                     }
162:                     break;
163:                 case 'delete':
164:                     if ($flags & Horde_ActiveSync::BACKEND_DISCARD_DATA ||
165:                         $this->_exporter->folderDeletion($change['id'])) {
166: 
167:                         $this->_stateMachine->updateState('foldersync', $change);
168:                     }
169:                     break;
170:                 }
171:                 $this->_step++;
172:                 $progress = array();
173:                 $progress['steps'] = count($this->_changes);
174:                 $progress['progress'] = $this->_step;
175:                 return $progress;
176:             } else {
177:                 return false;
178:             }
179:         } else {
180:             if ($this->_step < count($this->_changes)) {
181:                 $change = $this->_changes[$this->_step];
182: 
183:                 // Prevent corrupt server entries from causing infinite sync
184:                 // attempts.
185:                 while (empty($change['id']) && $this->_step < count($this->_changes) - 1) {
186:                     $this->_logger->err('Missing UID value for an entry in: ' . $this->_folderId);
187:                     $this->_step++;
188:                     $change = $this->_changes[$this->_step];
189:                 }
190: 
191:                 switch($change['type']) {
192:                 case 'change':
193:                     $truncsize = self::_getTruncSize($this->_truncation);
194:                     if (!$message = $this->_backend->getMessage($this->_folderId, $change['id'], $truncsize)) {
195:                         return false;
196:                     }
197: 
198:                     // copy the flag to the message
199:                     $message->flags = (isset($change['flags'])) ? $change['flags'] : 0;
200:                     if ($flags & Horde_ActiveSync::BACKEND_DISCARD_DATA || $this->_exporter->messageChange($change['id'], $message) == true) {
201:                         $this->_stateMachine->updateState('change', $change);
202:                     }
203:                     break;
204: 
205:                 case 'delete':
206:                     if ($flags & Horde_ActiveSync::BACKEND_DISCARD_DATA || $this->_exporter->messageDeletion($change['id']) == true) {
207:                         $this->_stateMachine->updateState('delete', $change);
208:                     }
209:                     break;
210: 
211:                 case 'flags':
212:                     if ($flags & Horde_ActiveSync::BACKEND_DISCARD_DATA || $this->_exporter->messageReadFlag($change['id'], $change['flags']) == true) {
213:                         $this->_stateMachine->updateState('flags', $change);
214:                     }
215:                     break;
216: 
217:                 case 'move':
218:                     if ($flags & Horde_ActiveSync::BACKEND_DISCARD_DATA || $this->_exporter->messageMove($change['id'], $change['parent']) == true) {
219:                         $this->_stateMachine->updateState('move', $change);
220:                     }
221:                     break;
222:                 }
223: 
224:                 $this->_step++;
225: 
226:                 $progress = array();
227:                 $progress['steps'] = count($this->_changes);
228:                 $progress['progress'] = $this->_step;
229: 
230:                 return $progress;
231:             } else {
232:                 return false;
233:             }
234:         }
235:     }
236: 
237:     public function getChangeCount()
238:     {
239:         return count($this->_changes);
240:     }
241: 
242:     /**
243:      *
244:      * @param $truncation
245:      * @return unknown_type
246:      */
247:     private static function _getTruncSize($truncation)
248:     {
249:         switch($truncation) {
250:         case Horde_ActiveSync::TRUNCATION_HEADERS:
251:             return 0;
252:         case Horde_ActiveSync::TRUNCATION_512B:
253:             return 512;
254:         case Horde_ActiveSync::TRUNCATION_1K:
255:             return 1024;
256:         case Horde_ActiveSync::TRUNCATION_5K:
257:             return 5 * 1024;
258:         case Horde_ActiveSync::TRUNCATION_SEVEN:
259:         case Horde_ActiveSync::TRUNCATION_ALL:
260:             return 1024 * 1024; // We'll limit to 1MB anyway
261:         default:
262:             return 1024; // Default to 1Kb
263:         }
264:     }
265: 
266: }
267: 
API documentation generated by ApiGen