PageRenderTime 51ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/SyncML/State.php

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