Files
server/usr/share/psa-pear/pear/php/Horde/SyncMl/State.php
2026-01-07 20:52:11 +01:00

410 lines
10 KiB
PHP

<?php
/**
* The Horde_SyncMl_State class provides a SyncML state object.
*
* Copyright 2003-2016 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Anthony Mills <amills@pyramid6.com>
* @author Jan Schneider <jan@horde.org>
* @package SyncMl
*/
class Horde_SyncMl_State
{
/**
* Id of this SyncML session.
*
* This is not to confuse with the PHP session id, though it is part of
* the generated PHP session id.
*
* @var string
*/
public $sessionID;
/**
* Id of the current message.
*
* @var integer
*/
public $messageID;
/**
* The target URI as sent by the client.
*
* This is normally the URL of the RPC server. However the client is
* free to send anything.
*
* @var string
*/
public $targetURI;
/**
* The source URI as sent by the client.
*
* Can be used to identify the client and is part of the PHP session id.
*
* @var string
*/
public $sourceURI;
/**
* SyncML protocol version.
*
* 0 for SyncML 1.0, 1 for SyncML 1.1, etc.
*
* @var integer
*/
public $version;
/**
* Username used to authenticate with the backend.
*
* @var string
*/
public $user;
/**
* Whether this session has authenticated successfully.
*
* @var boolean
*/
public $authenticated = false;
/**
* <SyncML> namespace uri.
*
* @var string
*/
protected $_uri;
/**
* <Meta> namespace uri.
*
* @var string
*/
public $uriMeta;
/**
* <DevInf> namespace uri.
*
* @var string
*/
public $uriDevInf;
/**
* Whether WBXML encoding is used.
*
* @var boolean
*/
public $wbxml = false;
/**
* The maximum allowed message size in bytes.
*
* @todo Change to PHP_INT_MAX.
*
* @var integer
*/
public $maxMsgSize = 1000000000;
/**
* The maximum allowed object size in bytes.
*
* @todo Change to PHP_INT_MAX.
*
* @var integer
*/
public $maxObjSize = 1000000000;
/**
* Array of Horde_SyncMl_Sync objects.
*
* @var array
*/
protected $_syncs = array();
/**
* The list of all server changes being sent to the client as a reference
* for Status responses from the client.
*
* @var array
*/
public $serverChanges = array();
/**
* Name of the appropriate device driver.
*
* @var string
*/
protected $_deviceDriver;
/**
* Device info provided by the SyncML DevInf data.
*
* @var Horde_SyncMl_DeviceInfo
*/
public $deviceInfo;
/**
* Current sync element sent from client.
*
* Stored in state if one element is split into multiple message packets.
*
* @var Horde_SyncMl_SyncElement
*/
public $curSyncItem;
/**
* Flag that is set if the client sends a Final but we are not finished
* with the current package and thus can't final this package yet.
*
* @var boolean
*/
public $delayedFinal = false;
/**
* Constructor.
*/
public function __construct($sourceURI, $user, $sessionID)
{
$this->sourceURI = $sourceURI;
$this->user = $user;
$this->sessionID = $sessionID;
/* Create empty dummy device info. Will be replaced with real DevInf
* information if provided by the client. */
$this->deviceInfo = new Horde_SyncMl_DeviceInfo();
}
/**
* Returns the <DevInf><VerDTD> content based on the protocol version.
*/
public function getVerDTD()
{
switch ($this->version) {
case 1:
return '1.1';
case 2:
return '1.2';
default:
return '1.0';
}
}
/**
* Returns the DevInf URI based on the protocol version.
*/
public function getDevInfURI()
{
switch ($this->version) {
case 1:
return './devinf11';
case 2:
return './devinf12';
default:
return './devinf10';
}
}
/**
* Returns the protocol name based on the protocol version.
*/
public function getProtocolName()
{
switch ($this->version) {
case 1:
return 'SyncML/1.1';
case 2:
return 'SyncML/1.2';
default:
return 'SyncML/1.0';
}
}
/**
* Sets the protocol version
*
* @param integer $version The protocol version: 0 for SyncML 1.0, 1 for
* SyncML 1.1 etc.
*/
public function setVersion($version)
{
switch ($version) {
case 1:
$this->_uri = Horde_SyncMl::NAME_SPACE_URI_SYNCML_1_1;
$this->uriMeta = Horde_SyncMl::NAME_SPACE_URI_METINF_1_1;
$this->uriDevInf = Horde_SyncMl::NAME_SPACE_URI_DEVINF_1_1;
break;
case 2:
$this->_uri = Horde_SyncMl::NAME_SPACE_URI_SYNCML_1_2;
$this->uriMeta = Horde_SyncMl::NAME_SPACE_URI_METINF_1_2;
$this->uriDevInf = Horde_SyncMl::NAME_SPACE_URI_DEVINF_1_2;
break;
default:
$this->_uri = Horde_SyncMl::NAME_SPACE_URI_SYNCML;
$this->uriMeta = Horde_SyncMl::NAME_SPACE_URI_METINF;
$this->uriDevInf = Horde_SyncMl::NAME_SPACE_URI_DEVINF;
break;
}
$this->version = $version;
}
/**
* Returns the namespace URI for the <SyncML> element.
*
* @return string The namespace URI to use, if any.
*/
public function getURI()
{
/* The non WBXML devices (notably SonyEricsson and Funambol) seem to
* get confused by a <SyncML xmlns="syncml:SYNCML1.1"> element. They
* require just <SyncML>. So don't use a namespace for non-wbxml
* devices. */
if ($this->wbxml || $this->version > 0) {
return $this->_uri;
} else {
return '';
}
}
/**
* Returns a Horde_SyncMl_Device instance for the device used in this session.
*
* @return Horde_SyncMl_Device A Horde_SyncMl_Device instance.
*/
public function getDevice()
{
if (empty($this->_deviceDriver)) {
$si = $this->sourceURI;
$di = $this->deviceInfo;
if (stristr($si, 'sync4j') !== false ||
stristr($si, 'sc-pim') !== false ||
stristr($si, 'fol-') !== false ||
stristr($si, 'fwm-') !== false ||
stristr($si, 'fbb-') !== false) {
$this->_deviceDriver = 'Sync4j';
} elseif (!empty($di->Man) &&
(stristr($di->Man, 'Sony Ericsson') !== false ||
stristr($di->Mod, 'A1000') !== false)) {
/* The Morola A1000 has a similar (UIQ) firmware as the
* P800: */
$this->_deviceDriver = 'P800';
} elseif (!empty($di->Man) &&
stristr($di->Man, 'nokia') !== false) {
$this->_deviceDriver = 'Nokia';
} elseif (stristr($si, 'fmz-') !== false) {
$this->_deviceDriver = 'Sync4JMozilla';
} else {
$this->_deviceDriver = 'default';
}
}
return Horde_SyncMl_Device::factory($this->_deviceDriver);
}
/**
* @param string $target
* @param Horde_SyncMl_Sync $sync
*/
public function setSync($target, $sync)
{
$this->_syncs[$target] = $sync;
}
/**
* @param string $target
* @return Horde_SyncMl_Sync
*/
public function getSync($target)
{
if (isset($this->_syncs[$target])) {
return $this->_syncs[$target];
} else {
return false;
}
}
/**
* @return array
*/
public function getSyncs()
{
return $this->_syncs;
}
/**
* Returns whether there are any pending elements that have not been sent
* to due to message size restrictions. These will be sent int the next
* message.
*
* @return boolean True if there are pending elements that have yet to be
* sent.
*/
public function hasPendingSyncs()
{
if (is_array($this->_syncs)) {
foreach ($this->_syncs as $sync) {
if ($sync->hasPendingElements()) {
return true;
}
}
}
return false;
}
/**
* Returns all syncs which have pending elements left.
*
* @return array Array of TargetLocURIs which can be used as a key in
* getSync() calls.
*/
public function getPendingSyncs()
{
$pending = array();
if (is_array($this->_syncs)) {
foreach ($this->_syncs as $target => $sync) {
if ($sync->hasPendingElements()) {
$pending[] = $target;
}
}
}
return $pending;
}
/**
* Returns whether all syncs are in completed state or no syncs are
* present.
*
* @return boolean True if all syncs are in completed state.
*/
public function isAllSyncsComplete()
{
if (is_array($this->_syncs)) {
foreach ($this->_syncs as $target => $sync) {
if (!$sync->isComplete()) {
return false;
}
}
}
return true;
}
/**
* Propagates final tags here and then further to every sync.
*
* This allows the sync objects to determine if they are complete.
*/
public function handleFinal(&$output, $debug = false)
{
if (is_array($this->_syncs)) {
foreach (array_keys($this->_syncs) as $t) {
$this->_syncs[$t]->handleFinal($output, $debug);
}
}
}
}