Overview

Packages

  • None
  • SyncMl

Classes

  • Horde_SyncMl
  • Horde_SyncMl_Backend
  • Horde_SyncMl_Backend_Horde
  • Horde_SyncMl_Command
  • Horde_SyncMl_Command_Alert
  • Horde_SyncMl_Command_Final
  • Horde_SyncMl_Command_Get
  • Horde_SyncMl_Command_Map
  • Horde_SyncMl_Command_Put
  • Horde_SyncMl_Command_Replace
  • Horde_SyncMl_Command_Results
  • Horde_SyncMl_Command_Status
  • Horde_SyncMl_Command_Sync
  • Horde_SyncMl_Command_SyncHdr
  • Horde_SyncMl_ContentHandler
  • Horde_SyncMl_DataStore
  • Horde_SyncMl_Device
  • Horde_SyncMl_Device_Nokia
  • Horde_SyncMl_Device_P800
  • Horde_SyncMl_Device_sync4j
  • Horde_SyncMl_Device_Sync4JMozilla
  • Horde_SyncMl_Device_Synthesis
  • Horde_SyncMl_DeviceInfo
  • Horde_SyncMl_Property
  • Horde_SyncMl_PropertyParameter
  • Horde_SyncMl_State
  • Horde_SyncMl_Sync
  • Horde_SyncMl_SyncElement
  • Horde_SyncMl_Translation
  • Horde_SyncMl_XmlOutput
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The Horde_SyncMl_State class provides a SyncML state object.
  4:  *
  5:  * Copyright 2003-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * See the enclosed file COPYING for license information (LGPL). If you
  8:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  9:  *
 10:  * @author  Anthony Mills <amills@pyramid6.com>
 11:  * @author  Jan Schneider <jan@horde.org>
 12:  * @package SyncMl
 13:  */
 14: class Horde_SyncMl_State
 15: {
 16:     /**
 17:      * Id of this SyncML session.
 18:      *
 19:      * This is not to confuse with the PHP session id, though it is part of
 20:      * the generated PHP session id.
 21:      *
 22:      * @var string
 23:      */
 24:     public $sessionID;
 25: 
 26:     /**
 27:      * Id of the current message.
 28:      *
 29:      * @var integer
 30:      */
 31:     public $messageID;
 32: 
 33:     /**
 34:      * The target URI as sent by the client.
 35:      *
 36:      * This is normally the URL of the RPC server. However the client is
 37:      * free to send anything.
 38:      *
 39:      * @var string
 40:      */
 41:     public $targetURI;
 42: 
 43:     /**
 44:      * The source URI as sent by the client.
 45:      *
 46:      * Can be used to identify the client and is part of the PHP session id.
 47:      *
 48:      * @var string
 49:      */
 50:     public $sourceURI;
 51: 
 52:     /**
 53:      * SyncML protocol version.
 54:      *
 55:      * 0 for SyncML 1.0, 1 for SyncML 1.1, etc.
 56:      *
 57:      * @var integer
 58:      */
 59:     public $version;
 60: 
 61:     /**
 62:      * Username used to authenticate with the backend.
 63:      *
 64:      * @var string
 65:      */
 66:     public $user;
 67: 
 68:     /**
 69:      * Whether this session has authenticated successfully.
 70:      *
 71:      * @var boolean
 72:      */
 73:     public $authenticated = false;
 74: 
 75:     /**
 76:      * <SyncML> namespace uri.
 77:      *
 78:      * @var string
 79:      */
 80:     protected $_uri;
 81: 
 82:     /**
 83:      * <Meta> namespace uri.
 84:      *
 85:      * @var string
 86:      */
 87:     public $uriMeta;
 88: 
 89:     /**
 90:      * <DevInf> namespace uri.
 91:      *
 92:      * @var string
 93:      */
 94:     public $uriDevInf;
 95: 
 96:     /**
 97:      * Whether WBXML encoding is used.
 98:      *
 99:      * @var boolean
100:      */
101:     public $wbxml = false;
102: 
103:     /**
104:      * The maximum allowed message size in bytes.
105:      *
106:      * @todo Change to PHP_INT_MAX.
107:      *
108:      * @var integer
109:      */
110:     public $maxMsgSize = 1000000000;
111: 
112:     /**
113:      * Array of Horde_SyncMl_Sync objects.
114:      *
115:      * @var array
116:      */
117:     protected $_syncs = array();
118: 
119:     /**
120:      * The list of all server changes being sent to the client as a reference
121:      * for Status responses from the client.
122:      *
123:      * @var array
124:      */
125:     public $serverChanges = array();
126: 
127:     /**
128:      * Name of the appropriate device driver.
129:      *
130:      * @var string
131:      */
132:     protected $_deviceDriver;
133: 
134:     /**
135:      * Device info provided by the SyncML DevInf data.
136:      *
137:      * @var Horde_SyncMl_DeviceInfo
138:      */
139:     public $deviceInfo;
140: 
141:     /**
142:      * Current sync element sent from client.
143:      *
144:      * Stored in state if one element is split into multiple message packets.
145:      *
146:      * @var Horde_SyncMl_SyncElement
147:      */
148:     public $curSyncItem;
149: 
150:     /**
151:      * Flag that is set if the client sends a Final but we are not finished
152:      * with the current package and thus can't final this package yet.
153:      *
154:      * @var boolean
155:      */
156:     public $delayedFinal = false;
157: 
158:     /**
159:      * Constructor.
160:      */
161:     public function __construct($sourceURI, $user, $sessionID)
162:     {
163:         $this->sourceURI = $sourceURI;
164:         $this->user = $user;
165:         $this->sessionID = $sessionID;
166: 
167:         /* Create empty dummy device info. Will be replaced with real DevInf
168:          * information if provided by the client. */
169:         $this->deviceInfo = new Horde_SyncMl_DeviceInfo();
170:     }
171: 
172:     /**
173:      * Returns the <DevInf><VerDTD> content based on the protocol version.
174:      */
175:     public function getVerDTD()
176:     {
177:         switch ($this->version) {
178:             case 1:
179:                 return '1.1';
180:             case 2:
181:                 return '1.2';
182:             default:
183:                 return '1.0';
184:         }
185:     }
186: 
187:     /**
188:      * Returns the DevInf URI based on the protocol version.
189:      */
190:     public function getDevInfURI()
191:     {
192:         switch ($this->version) {
193:             case 1:
194:                 return './devinf11';
195:             case 2:
196:                 return './devinf12';
197:             default:
198:                 return './devinf10';
199:         }
200:     }
201: 
202:     /**
203:      * Returns the protocol name based on the protocol version.
204:      */
205:     public function getProtocolName()
206:     {
207:         switch ($this->version) {
208:             case 1:
209:                 return 'SyncML/1.1';
210:             case 2:
211:                 return 'SyncML/1.2';
212:             default:
213:                 return 'SyncML/1.0';
214:         }
215:     }
216: 
217:     /**
218:      * Sets the protocol version
219:      *
220:      * @param integer $version  The protocol version: 0 for SyncML 1.0, 1 for
221:      *                          SyncML 1.1 etc.
222:      */
223:     public function setVersion($version)
224:     {
225:         switch ($version) {
226:         case 1:
227:             $this->_uri = Horde_SyncMl::NAME_SPACE_URI_SYNCML_1_1;
228:             $this->uriMeta = Horde_SyncMl::NAME_SPACE_URI_METINF_1_1;
229:             $this->uriDevInf = Horde_SyncMl::NAME_SPACE_URI_DEVINF_1_1;
230:             break;
231:         case 2:
232:             $this->_uri = Horde_SyncMl::NAME_SPACE_URI_SYNCML_1_2;
233:             $this->uriMeta = Horde_SyncMl::NAME_SPACE_URI_METINF_1_2;
234:             $this->uriDevInf = Horde_SyncMl::NAME_SPACE_URI_DEVINF_1_2;
235:             break;
236:         default:
237:             $this->_uri = Horde_SyncMl::NAME_SPACE_URI_SYNCML;
238:             $this->uriMeta = Horde_SyncMl::NAME_SPACE_URI_METINF;
239:             $this->uriDevInf = Horde_SyncMl::NAME_SPACE_URI_DEVINF;
240:             break;
241:         }
242: 
243:         $this->version = $version;
244:     }
245: 
246:     /**
247:      * Returns the namespace URI for the <SyncML> element.
248:      *
249:      * @return string  The namespace URI to use, if any.
250:      */
251:     public function getURI()
252:     {
253:         /* The non WBXML devices (notably SonyEricsson and Funambol) seem to
254:          * get confused by a <SyncML xmlns="syncml:SYNCML1.1"> element. They
255:          * require just <SyncML>. So don't use a namespace for non-wbxml
256:          * devices. */
257:         if ($this->wbxml || $this->version > 0) {
258:             return $this->_uri;
259:         } else {
260:             return '';
261:         }
262:     }
263: 
264:     /**
265:      * Returns a Horde_SyncMl_Device instance for the device used in this session.
266:      *
267:      * @return Horde_SyncMl_Device  A Horde_SyncMl_Device instance.
268:      */
269:     public function getDevice()
270:     {
271:         if (empty($this->_deviceDriver)) {
272:             $si = $this->sourceURI;
273:             $di = $this->deviceInfo;
274: 
275:             if (stristr($si, 'sync4j') !== false ||
276:                 stristr($si, 'sc-pim') !== false ||
277:                 stristr($si, 'fol-') !== false ||
278:                 stristr($si, 'fwm-') !== false ||
279:                 stristr($si, 'fbb-') !== false) {
280:                 $this->_deviceDriver = 'Sync4j';
281:             } elseif (!empty($di->Man) &&
282:                       (stristr($di->Man, 'Sony Ericsson') !== false ||
283:                        stristr($di->Mod, 'A1000') !== false)) {
284:                 /* The Morola A1000 has a similar (UIQ) firmware as the
285:                  * P800: */
286:                 $this->_deviceDriver = 'P800';
287:             } elseif (!empty($di->Man) &&
288:                       stristr($di->Man, 'synthesis') !== false) {
289:                 $this->_deviceDriver = 'Synthesis';
290:             } elseif (!empty($di->Man) &&
291:                       stristr($di->Man, 'nokia') !== false) {
292:                 $this->_deviceDriver = 'Nokia';
293:             } elseif (stristr($si, 'fmz-') !== false) {
294:                 $this->_deviceDriver = 'Sync4JMozilla';
295:             } else {
296:                 $this->_deviceDriver = 'default';
297:             }
298:         }
299: 
300:         return Horde_SyncMl_Device::factory($this->_deviceDriver);
301:     }
302: 
303:     /**
304:      * @param string $target
305:      * @param Horde_SyncMl_Sync $sync
306:      */
307:     public function setSync($target, $sync)
308:     {
309:         $this->_syncs[$target] = $sync;
310:     }
311: 
312:     /**
313:      * @param string $target
314:      * @return Horde_SyncMl_Sync
315:      */
316:     public function getSync($target)
317:     {
318:         if (isset($this->_syncs[$target])) {
319:             return $this->_syncs[$target];
320:         } else {
321:             return false;
322:         }
323:     }
324: 
325:     /**
326:      * @return array
327:      */
328:     public function getSyncs()
329:     {
330:         return $this->_syncs;
331:     }
332: 
333:     /**
334:      * Returns whether there are any pending elements that have not been sent
335:      * to due to message size restrictions. These will be sent int the next
336:      * message.
337:      *
338:      * @return boolean  True if there are pending elements that have yet to be
339:      *                  sent.
340:      */
341:     public function hasPendingSyncs()
342:     {
343:         if (is_array($this->_syncs)) {
344:             foreach ($this->_syncs as $sync) {
345:                 if ($sync->hasPendingElements()) {
346:                     return true;
347:                 }
348:             }
349:         }
350:         return false;
351:     }
352: 
353:     /**
354:      * Returns all syncs which have pending elements left.
355:      *
356:      * @return array  Array of TargetLocURIs which can be used as a key in
357:      *                getSync() calls.
358:      */
359:     public function getPendingSyncs()
360:     {
361:         $pending = array();
362:         if (is_array($this->_syncs)) {
363:             foreach ($this->_syncs as $target => $sync) {
364:                 if ($sync->hasPendingElements()) {
365:                     $pending[] = $target;
366:                 }
367:             }
368:         }
369:         return $pending;
370:     }
371: 
372:     /**
373:      * Returns whether all syncs are in completed state or no syncs are
374:      * present.
375:      *
376:      * @return boolean  True if all syncs are in completed state.
377:      */
378:     public function isAllSyncsComplete()
379:     {
380:         if (is_array($this->_syncs)) {
381:             foreach ($this->_syncs as $target => $sync) {
382:                 if (!$sync->isComplete()) {
383:                     return false;
384:                 }
385:             }
386:         }
387:         return true;
388:     }
389: 
390:     /**
391:      * Propagates final tags here and then further to every sync.
392:      *
393:      * This allows the sync objects to determine if they are complete.
394:      */
395:     public function handleFinal(&$output, $debug = false)
396:     {
397:         if (is_array($this->_syncs)) {
398:             foreach (array_keys($this->_syncs) as $t) {
399:                 $this->_syncs[$t]->handleFinal($output, $debug);
400:             }
401:         }
402:     }
403: }
404: 
API documentation generated by ApiGen