670 lines
25 KiB
PHP
670 lines
25 KiB
PHP
<?php
|
|
/**
|
|
* This class creates the actual XML data and passes it on to a ContentHandler
|
|
* for optional WBXML encoding.
|
|
*
|
|
* Each member public function creates one type of SyncML artefact (like a
|
|
* Status response). Currently some of the information is retrieved from
|
|
* state. Maybe remove these dependencies (by providing the data as parameter)
|
|
* for an even cleaner implementation.
|
|
*
|
|
* The Horde_SyncMl_XmlOutput class takes automatically care of creating a
|
|
* unique CmdID for each command created.
|
|
*
|
|
* Copyright 2006-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 Karsten Fourmont <karsten@horde.org>
|
|
* @package SyncMl
|
|
*/
|
|
class Horde_SyncMl_XmlOutput
|
|
{
|
|
/**
|
|
* The CmdID provides a unique ID for each command in a syncml packet.
|
|
*/
|
|
protected $_msg_CmdID;
|
|
|
|
/**
|
|
* The outputhandler to whom the XML is passed: like
|
|
* Horde_Xml_Wbxml_Encoder
|
|
*/
|
|
public $output;
|
|
|
|
protected $_uri;
|
|
|
|
/**
|
|
* The final output as procuded by the _output Encoder. Either an
|
|
* XML string or a WBXML string.
|
|
*/
|
|
public function getOutput()
|
|
{
|
|
return $this->output->getOutput();
|
|
}
|
|
|
|
/**
|
|
* The length of the output as produced by the Encoder. To limit the
|
|
* size of individual messages.
|
|
*/
|
|
public function getOutputSize()
|
|
{
|
|
return $this->output->getOutputSize();
|
|
}
|
|
|
|
/**
|
|
* To we create wbxml or not?
|
|
*/
|
|
public function isWBXML()
|
|
{
|
|
return is_a($this->output, 'Horde_Xml_Wbxml_Encoder');
|
|
}
|
|
|
|
public function &singleton()
|
|
{
|
|
static $instance;
|
|
if (!isset($instance)) {
|
|
$instance = new Horde_SyncMl_XmlOutput();
|
|
}
|
|
return $instance;
|
|
}
|
|
|
|
public function init(&$theoutputhandler)
|
|
{
|
|
$this->output = $theoutputhandler;
|
|
$this->_msg_CmdID = 1;
|
|
|
|
}
|
|
|
|
/**
|
|
* Creates a SyncHdr output.
|
|
*
|
|
* Required data is retrieved from state.
|
|
*
|
|
* @param string $respURI The url of the server endpoint.
|
|
*
|
|
* @throws Horde_Xml_Wbxml_Exception
|
|
*/
|
|
public function outputHeader($respURI)
|
|
{
|
|
$state = $GLOBALS['backend']->state;
|
|
|
|
$this->_uriMeta = $state->uriMeta;
|
|
|
|
$this->output->startElement($this->_uri, 'SyncHdr');
|
|
|
|
$this->output->startElement($this->_uri, 'VerDTD');
|
|
$chars = $state->getVerDTD();
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'VerDTD');
|
|
|
|
$this->output->startElement($this->_uri, 'VerProto');
|
|
$chars = $state->getProtocolName();
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'VerProto');
|
|
|
|
$this->output->startElement($this->_uri, 'SessionID');
|
|
$this->output->characters($state->sessionID);
|
|
$this->output->endElement($this->_uri, 'SessionID');
|
|
|
|
$this->output->startElement($this->_uri, 'MsgID');
|
|
$this->output->characters($state->messageID);
|
|
$this->output->endElement($this->_uri, 'MsgID');
|
|
|
|
$this->output->startElement($this->_uri, 'Target');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
// Source URI sent from client is Target for the server
|
|
$this->output->characters($state->sourceURI);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
if ($state->user) {
|
|
$this->output->startElement($this->_uri, 'LocName');
|
|
$this->output->characters($state->user);
|
|
$this->output->endElement($this->_uri, 'LocName');
|
|
}
|
|
$this->output->endElement($this->_uri, 'Target');
|
|
|
|
$this->output->startElement($this->_uri, 'Source');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
// Target URI sent from client is Source for the server
|
|
$this->output->characters($state->targetURI);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Source');
|
|
|
|
if ($respURI) {
|
|
$this->output->startElement($this->_uri, 'RespURI');
|
|
$this->output->characters($respURI);
|
|
$this->output->endElement($this->_uri, 'RespURI');
|
|
}
|
|
|
|
// @Todo: omit this in SyncML1.0?
|
|
$this->output->startElement($this->_uri, 'Meta');
|
|
|
|
// Dummy Max MsqSize, this is just put in to make the packet
|
|
// work, it is not a real value.
|
|
$this->output->startElement($this->_uriMeta, 'MaxMsgSize');
|
|
$chars = Horde_SyncMl::SERVER_MAXMSGSIZE; // 1Meg
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uriMeta, 'MaxMsgSize');
|
|
|
|
|
|
// MaxObjSize, required by protocol for SyncML1.1 and higher.
|
|
if ($state->version > 0) {
|
|
$this->output->startElement($this->_uriMeta, 'MaxObjSize');
|
|
$this->output->characters(Horde_SyncMl::SERVER_MAXOBJSIZE);
|
|
$this->output->endElement($this->_uriMeta, 'MaxObjSize');
|
|
}
|
|
$this->output->endElement($this->_uri, 'Meta');
|
|
|
|
$this->output->endElement($this->_uri, 'SyncHdr');
|
|
}
|
|
|
|
public function outputInit()
|
|
{
|
|
$this->_uri = $GLOBALS['backend']->state->getURI();
|
|
|
|
$this->output->startElement($this->_uri, 'SyncML', array());
|
|
}
|
|
|
|
public function outputBodyStart()
|
|
{
|
|
$this->output->startElement($this->_uri, 'SyncBody', array());
|
|
}
|
|
|
|
public function outputFinal()
|
|
{
|
|
$this->output->startElement($this->_uri, 'Final', array());
|
|
$this->output->endElement($this->_uri, 'Final');
|
|
}
|
|
|
|
public function outputEnd()
|
|
{
|
|
$this->output->endElement($this->_uri, 'SyncBody', array());
|
|
$this->output->endElement($this->_uri, 'SyncML', array());
|
|
}
|
|
|
|
|
|
public function outputStatus($cmdRef, $cmd, $data,
|
|
$targetRef = '', $sourceRef = '',
|
|
$syncAnchorNext = '',
|
|
$syncAnchorLast = '')
|
|
{
|
|
$state = $GLOBALS['backend']->state;
|
|
$uriMeta = $state->uriMeta;
|
|
|
|
$this->output->startElement($this->_uri, 'Status');
|
|
$this->_outputCmdID();
|
|
|
|
$this->output->startElement($this->_uri, 'MsgRef');
|
|
$chars = $state->messageID;
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'MsgRef');
|
|
|
|
$this->output->startElement($this->_uri, 'CmdRef');
|
|
$chars = $cmdRef;
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'CmdRef');
|
|
|
|
$this->output->startElement($this->_uri, 'Cmd');
|
|
$chars = $cmd;
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'Cmd');
|
|
|
|
if (!empty($targetRef)) {
|
|
$this->output->startElement($this->_uri, 'TargetRef');
|
|
$this->output->characters($targetRef);
|
|
$this->output->endElement($this->_uri, 'TargetRef');
|
|
}
|
|
|
|
if (!empty($sourceRef)) {
|
|
$this->output->startElement($this->_uri, 'SourceRef');
|
|
$this->output->characters($sourceRef);
|
|
$this->output->endElement($this->_uri, 'SourceRef');
|
|
}
|
|
|
|
// If we are responding to the SyncHdr and we are not
|
|
// authenticated then request basic authorization.
|
|
if ($cmd == 'SyncHdr' && !$state->authenticated) {
|
|
// Keep Horde_SyncMl::RESPONSE_CREDENTIALS_MISSING, otherwise set to
|
|
// Horde_SyncMl::RESPONSE_INVALID_CREDENTIALS.
|
|
$data = $data == Horde_SyncMl::RESPONSE_CREDENTIALS_MISSING
|
|
? Horde_SyncMl::RESPONSE_CREDENTIALS_MISSING
|
|
: Horde_SyncMl::RESPONSE_INVALID_CREDENTIALS;
|
|
|
|
$this->output->startElement($this->_uri, 'Chal');
|
|
$this->output->startElement($this->_uri, 'Meta');
|
|
|
|
$this->output->startElement($uriMeta, 'Type');
|
|
$this->output->characters('syncml:auth-basic');
|
|
$this->output->endElement($uriMeta, 'Type');
|
|
|
|
$this->output->startElement($uriMeta, 'Format');
|
|
$this->output->characters('b64');
|
|
$this->output->endElement($uriMeta, 'Format');
|
|
|
|
$this->output->endElement($this->_uri, 'Meta');
|
|
$this->output->endElement($this->_uri, 'Chal');
|
|
|
|
}
|
|
|
|
$this->output->startElement($this->_uri, 'Data');
|
|
$this->output->characters($data);
|
|
$this->output->endElement($this->_uri, 'Data');
|
|
|
|
if (!empty($syncAnchorNext) || !empty($syncAnchorNLast)) {
|
|
$this->output->startElement($this->_uri, 'Item');
|
|
$this->output->startElement($this->_uri, 'Data');
|
|
|
|
$this->output->startElement($uriMeta, 'Anchor');
|
|
|
|
if (!empty($syncAnchorLast)) {
|
|
$this->output->startElement($uriMeta, 'Last');
|
|
$this->output->characters($syncAnchorLast);
|
|
$this->output->endElement($uriMeta, 'Last');
|
|
}
|
|
|
|
if (!empty($syncAnchorNext)) {
|
|
$this->output->startElement($uriMeta, 'Next');
|
|
$this->output->characters($syncAnchorNext);
|
|
$this->output->endElement($uriMeta, 'Next');
|
|
}
|
|
|
|
$this->output->endElement($uriMeta, 'Anchor');
|
|
|
|
$this->output->endElement($this->_uri, 'Data');
|
|
$this->output->endElement($this->_uri, 'Item');
|
|
}
|
|
|
|
$this->output->endElement($this->_uri, 'Status');
|
|
|
|
}
|
|
|
|
public function outputDevInf($cmdRef)
|
|
{
|
|
$state = $GLOBALS['backend']->state;
|
|
$uriMeta = $state->uriMeta;
|
|
$uriDevInf = $state->uriDevInf;
|
|
|
|
$this->output->startElement($this->_uri, 'Results');
|
|
$this->_outputCmdID();
|
|
|
|
$this->output->startElement($this->_uri, 'MsgRef');
|
|
$chars = $state->messageID;
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'MsgRef');
|
|
|
|
$this->output->startElement($this->_uri, 'CmdRef');
|
|
$chars = $cmdRef;
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'CmdRef');
|
|
|
|
$this->output->startElement($this->_uri, 'Meta');
|
|
$this->output->startElement($uriMeta, 'Type');
|
|
if ($state->wbxml) {
|
|
$this->output->characters(Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_WBXML);
|
|
} else {
|
|
$this->output->characters(Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_XML);
|
|
}
|
|
|
|
$this->output->endElement($uriMeta, 'Type');
|
|
$this->output->endElement($this->_uri, 'Meta');
|
|
|
|
$this->output->startElement($this->_uri, 'Item');
|
|
$this->output->startElement($this->_uri, 'Source');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($state->getDevInfURI());
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Source');
|
|
|
|
$this->output->startElement($this->_uri, 'Data');
|
|
|
|
/* DevInf data is stored in wbxml not as a seperate codepage but
|
|
* rather as a complete wbxml stream as opaque data. So we need a
|
|
* new Handler. */
|
|
$devinfoutput = $this->output->createSubHandler();
|
|
|
|
$devinfoutput->startElement($uriDevInf , 'DevInf');
|
|
$devinfoutput->startElement($uriDevInf , 'VerDTD');
|
|
$devinfoutput->characters($state->getVerDTD());
|
|
$devinfoutput->endElement($uriDevInf , 'VerDTD');
|
|
$devinfoutput->startElement($uriDevInf , 'Man');
|
|
$devinfoutput->characters('The Horde Project (http://www.horde.org/)');
|
|
$devinfoutput->endElement($uriDevInf , 'Man');
|
|
$devinfoutput->startElement($uriDevInf , 'DevID');
|
|
$devinfoutput->characters(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost');
|
|
$devinfoutput->endElement($uriDevInf , 'DevID');
|
|
$devinfoutput->startElement($uriDevInf , 'DevTyp');
|
|
$devinfoutput->characters('server');
|
|
$devinfoutput->endElement($uriDevInf , 'DevTyp');
|
|
|
|
if ($state->version > 0) {
|
|
$devinfoutput->startElement($uriDevInf , 'SupportLargeObjs');
|
|
$devinfoutput->endElement($uriDevInf , 'SupportLargeObjs');
|
|
|
|
$devinfoutput->startElement($uriDevInf , 'SupportNumberOfChanges');
|
|
$devinfoutput->endElement($uriDevInf , 'SupportNumberOfChanges');
|
|
}
|
|
$this->_writeDataStore('notes', 'text/plain', '1.0', $devinfoutput);
|
|
$this->_writeDataStore('contacts', 'text/directory', '3.0',
|
|
$devinfoutput, array('text/x-vcard' => '2.1'));
|
|
$this->_writeDataStore('tasks', 'text/calendar', '2.0', $devinfoutput,
|
|
array('text/x-vcalendar' => '1.0'));
|
|
$this->_writeDataStore('calendar', 'text/calendar', '2.0',
|
|
$devinfoutput,
|
|
array('text/x-vcalendar' => '1.0'));
|
|
$devinfoutput->endElement($uriDevInf , 'DevInf');
|
|
|
|
$this->output->opaque($devinfoutput->getOutput());
|
|
$this->output->endElement($this->_uri, 'Data');
|
|
$this->output->endElement($this->_uri, 'Item');
|
|
$this->output->endElement($this->_uri, 'Results');
|
|
}
|
|
|
|
/**
|
|
* Writes DevInf data for one DataStore.
|
|
*
|
|
* @param string $sourceref Data for <SourceRef> element.
|
|
* @param string $mimetype Data for <Rx-Pref><CTType> and
|
|
* <Tx-Pref><CTType>.
|
|
* @param string $version Data for <Rx-Pref><VerCT> and
|
|
* <Tx-Pref><VerCT>.
|
|
* @param Horde_Xml_Wbxml_ContentHandler $output Content handler that will
|
|
* received the output.
|
|
* @param array $additionaltypes Array of additional types for
|
|
* <Tx> and <Rx>; format
|
|
* array('text/directory' => '3.0')
|
|
*/
|
|
protected function _writeDataStore($sourceref, $mimetype, $version, &$output,
|
|
$additionaltypes = array())
|
|
{
|
|
$uriDevInf = $GLOBALS['backend']->state->uriDevInf;
|
|
|
|
$output->startElement($uriDevInf , 'DataStore');
|
|
$output->startElement($uriDevInf , 'SourceRef');
|
|
$output->characters($sourceref);
|
|
$output->endElement($uriDevInf , 'SourceRef');
|
|
|
|
$output->startElement($uriDevInf , 'Rx-Pref');
|
|
$output->startElement($uriDevInf , 'CTType');
|
|
$output->characters($mimetype);
|
|
$output->endElement($uriDevInf , 'CTType');
|
|
$output->startElement($uriDevInf , 'VerCT');
|
|
$output->characters($version);
|
|
$output->endElement($uriDevInf , 'VerCT');
|
|
$output->endElement($uriDevInf , 'Rx-Pref');
|
|
|
|
foreach ($additionaltypes as $ct => $ctver){
|
|
$output->startElement($uriDevInf , 'Rx');
|
|
$output->startElement($uriDevInf , 'CTType');
|
|
$output->characters($ct);
|
|
$output->endElement($uriDevInf , 'CTType');
|
|
$output->startElement($uriDevInf , 'VerCT');
|
|
$output->characters($ctver);
|
|
$output->endElement($uriDevInf , 'VerCT');
|
|
$output->endElement($uriDevInf , 'Rx');
|
|
}
|
|
|
|
$output->startElement($uriDevInf , 'Tx-Pref');
|
|
$output->startElement($uriDevInf , 'CTType');
|
|
$output->characters($mimetype);
|
|
$output->endElement($uriDevInf , 'CTType');
|
|
$output->startElement($uriDevInf , 'VerCT');
|
|
$output->characters($version);
|
|
$output->endElement($uriDevInf , 'VerCT');
|
|
$output->endElement($uriDevInf , 'Tx-Pref');
|
|
|
|
foreach ($additionaltypes as $ct => $ctver){
|
|
$output->startElement($uriDevInf , 'Tx');
|
|
$output->startElement($uriDevInf , 'CTType');
|
|
$output->characters($ct);
|
|
$output->endElement($uriDevInf , 'CTType');
|
|
$output->startElement($uriDevInf , 'VerCT');
|
|
$output->characters($ctver);
|
|
$output->endElement($uriDevInf , 'VerCT');
|
|
$output->endElement($uriDevInf , 'Tx');
|
|
}
|
|
|
|
$output->startElement($uriDevInf , 'SyncCap');
|
|
// We support all sync Types from 1-6: two way, slow, refresh|update
|
|
// from client|server
|
|
for ($i = 1; $i <= 6; ++$i) {
|
|
$output->startElement($uriDevInf , 'SyncType');
|
|
$output->characters($i);
|
|
$output->endElement($uriDevInf , 'SyncType');
|
|
}
|
|
$output->endElement($uriDevInf , 'SyncCap');
|
|
$output->endElement($uriDevInf , 'DataStore');
|
|
}
|
|
|
|
public function outputAlert($alertCode, $clientDB = '', $serverDB = '', $lastAnchor = '', $nextAnchor = '')
|
|
{
|
|
$uriMeta = $GLOBALS['backend']->state->uriMeta;
|
|
|
|
$this->output->startElement($this->_uri, 'Alert');
|
|
$this->_outputCmdID();
|
|
|
|
$this->output->startElement($this->_uri, 'Data');
|
|
$chars = $alertCode;
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($this->_uri, 'Data');
|
|
|
|
$this->output->startElement($this->_uri, 'Item');
|
|
|
|
if (!empty($clientDB)) {
|
|
$this->output->startElement($this->_uri, 'Target');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($clientDB);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Target');
|
|
}
|
|
|
|
if (!empty($serverDB)) {
|
|
$this->output->startElement($this->_uri, 'Source');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($serverDB);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Source');
|
|
}
|
|
|
|
$this->output->startElement($this->_uri, 'Meta');
|
|
|
|
$this->output->startElement($uriMeta, 'Anchor');
|
|
|
|
$this->output->startElement($uriMeta, 'Last');
|
|
$this->output->characters($lastAnchor);
|
|
$this->output->endElement($uriMeta, 'Last');
|
|
|
|
$this->output->startElement($uriMeta, 'Next');
|
|
$this->output->characters($nextAnchor);
|
|
$this->output->endElement($uriMeta, 'Next');
|
|
|
|
$this->output->endElement($uriMeta, 'Anchor');
|
|
|
|
|
|
// MaxObjSize, required by protocol for SyncML1.1 and higher.
|
|
if ($GLOBALS['backend']->state->version > 0) {
|
|
$this->output->startElement($uriMeta, 'MaxObjSize');
|
|
$this->output->characters(Horde_SyncMl::SERVER_MAXOBJSIZE);
|
|
$this->output->endElement($uriMeta, 'MaxObjSize');
|
|
}
|
|
$this->output->endElement($this->_uri, 'Meta');
|
|
|
|
$this->output->endElement($this->_uri, 'Item');
|
|
$this->output->endElement($this->_uri, 'Alert');
|
|
|
|
}
|
|
|
|
|
|
public function outputGetDevInf()
|
|
{
|
|
$state = $GLOBALS['backend']->state;
|
|
$uriMeta = $state->uriMeta;
|
|
|
|
$this->output->startElement($this->_uri, 'Get');
|
|
$this->_outputCmdID();
|
|
|
|
$this->output->startElement($this->_uri, 'Meta');
|
|
$this->output->startElement($uriMeta, 'Type');
|
|
if ($state->wbxml) {
|
|
$chars = Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_WBXML;
|
|
} else {
|
|
$chars = Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_XML;
|
|
}
|
|
$this->output->characters($chars);
|
|
$this->output->endElement($uriMeta, 'Type');
|
|
$this->output->endElement($this->_uri, 'Meta');
|
|
|
|
$this->output->startElement($this->_uri, 'Item');
|
|
$this->output->startElement($this->_uri, 'Target');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($state->getDevInfURI());
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Target');
|
|
$this->output->endElement($this->_uri, 'Item');
|
|
|
|
$this->output->endElement($this->_uri, 'Get');
|
|
}
|
|
|
|
/**
|
|
* Creates a single Sync command
|
|
*
|
|
* @param string $command The Sync command (Add, Delete, Replace).
|
|
* @param string $content The actual object content.
|
|
* @param string $contentType The content's MIME type.
|
|
* @param string $encodingType The content encoding of the object.
|
|
* @param string $cuid The client's object UID.
|
|
* @param string $suid The server's object UID.
|
|
* @param int $contentSize The total content size.
|
|
* @param bool $moreData Add MoreData tag when splitting messages.
|
|
*
|
|
* @return integer The CmdID used for this command.
|
|
*/
|
|
public function outputSyncCommand($command, $content = null, $contentType = null,
|
|
$encodingType = null, $cuid = null, $suid = null,
|
|
$contentSize = null, $moreData = false)
|
|
{
|
|
$uriMeta = $GLOBALS['backend']->state->uriMeta;
|
|
|
|
$this->output->startElement($this->_uri, $command);
|
|
$this->_outputCmdID();
|
|
|
|
if (isset($contentType)) {
|
|
$this->output->startElement($this->_uri, 'Meta');
|
|
$this->output->startElement($uriMeta, 'Type');
|
|
$this->output->characters($contentType);
|
|
$this->output->endElement($uriMeta, 'Type');
|
|
if (isset($content) && isset($contentSize)) {
|
|
$this->output->startElement($uriMeta, 'Size');
|
|
$this->output->characters($contentSize);
|
|
$this->output->endElement($uriMeta, 'Size');
|
|
}
|
|
$this->output->endElement($this->_uri, 'Meta');
|
|
}
|
|
|
|
if (isset($content) || isset($cuid) || isset($suid)) {
|
|
$this->output->startElement($this->_uri, 'Item');
|
|
if ($suid != null) {
|
|
$this->output->startElement($this->_uri, 'Source');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($suid);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Source');
|
|
}
|
|
|
|
if ($cuid != null) {
|
|
$this->output->startElement($this->_uri, 'Target');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($cuid);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Target');
|
|
}
|
|
|
|
if (!empty($encodingType)) {
|
|
$this->output->startElement($this->_uri, 'Meta');
|
|
$this->output->startElement($uriMeta, 'Format');
|
|
$this->output->characters($encodingType);
|
|
$this->output->endElement($uriMeta, 'Format');
|
|
$this->output->endElement($this->_uri, 'Meta');
|
|
}
|
|
if (isset($content)) {
|
|
$this->output->startElement($this->_uri, 'Data');
|
|
if($this->isWBXML()) {
|
|
$this->output->characters($content);
|
|
} else {
|
|
$device = $GLOBALS['backend']->state->getDevice();
|
|
if ($device->useCdataTag()) {
|
|
/* Enclose data in CDATA if possible to avoid */
|
|
/* problems with &,< and >. */
|
|
$this->output->opaque('<![CDATA[' . $content . ']]>');
|
|
} else {
|
|
$this->output->characters($content);
|
|
}
|
|
}
|
|
$this->output->endElement($this->_uri, 'Data');
|
|
if ($moreData) {
|
|
$this->output->startElement($this->_uri, 'MoreData');
|
|
$this->output->endElement($this->_uri, 'MoreData');
|
|
}
|
|
}
|
|
$this->output->endElement($this->_uri, 'Item');
|
|
}
|
|
|
|
$this->output->endElement($this->_uri, $command);
|
|
|
|
return $this->_msg_CmdID - 1;
|
|
}
|
|
|
|
public function outputSyncStart($clientLocURI, $serverLocURI, $numberOfChanges = null)
|
|
{
|
|
$this->output->startElement($this->_uri, 'Sync');
|
|
$this->_outputCmdID();
|
|
|
|
$this->output->startElement($this->_uri, 'Target');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($clientLocURI);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Target');
|
|
|
|
$this->output->startElement($this->_uri, 'Source');
|
|
$this->output->startElement($this->_uri, 'LocURI');
|
|
$this->output->characters($serverLocURI);
|
|
$this->output->endElement($this->_uri, 'LocURI');
|
|
$this->output->endElement($this->_uri, 'Source');
|
|
|
|
if (is_int($numberOfChanges)) {
|
|
$this->output->startElement($this->_uri, 'NumberOfChanges');
|
|
$this->output->characters($numberOfChanges);
|
|
$this->output->endElement($this->_uri, 'NumberOfChanges');
|
|
}
|
|
|
|
}
|
|
|
|
public function outputSyncEnd()
|
|
{
|
|
$this->output->endElement($this->_uri, 'Sync');
|
|
}
|
|
|
|
|
|
// internal helper functions:
|
|
|
|
protected function _outputCmdID()
|
|
{
|
|
$this->output->startElement($this->_uri, 'CmdID');
|
|
$this->output->characters($this->_msg_CmdID);
|
|
$this->_msg_CmdID++;
|
|
$this->output->endElement($this->_uri, 'CmdID');
|
|
}
|
|
|
|
/**
|
|
* Output a single <ele>$str</ele> element.
|
|
*/
|
|
protected function _singleEle($tag, $str, $uri = null)
|
|
{
|
|
if (empty($uri)) {
|
|
$uri = $this->_uri;
|
|
}
|
|
$this->output->startElement($uri, $tag);
|
|
$this->output->characters($str);
|
|
$this->output->endElement($uri, $tag);
|
|
}
|
|
}
|