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:  * This class creates the actual XML data and passes it on to a ContentHandler
  4:  * for optional WBXML encoding.
  5:  *
  6:  * Each member public function creates one type of SyncML artefact (like a
  7:  * Status response).  Currently some of the information is retrieved from
  8:  * state. Maybe remove these dependencies (by providing the data as parameter)
  9:  * for an even cleaner implementation.
 10:  *
 11:  * The Horde_SyncMl_XmlOutput class takes automatically care of creating a
 12:  * unique CmdID for each command created.
 13:  *
 14:  * Copyright 2006-2012 Horde LLC (http://www.horde.org/)
 15:  *
 16:  * See the enclosed file COPYING for license information (LGPL). If you
 17:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 18:  *
 19:  * @author  Karsten Fourmont <karsten@horde.org>
 20:  * @package SyncMl
 21:  */
 22: class Horde_SyncMl_XmlOutput
 23: {
 24:     /**
 25:      * The CmdID provides a unique ID for each command in a syncml packet.
 26:      */
 27:     protected $_msg_CmdID;
 28: 
 29:     /**
 30:      *  The outputhandler to whom the XML is passed: like
 31:      *  Horde_Xml_Wbxml_Encoder
 32:      */
 33:     public $output;
 34: 
 35:     protected $_uri;
 36: 
 37:     /**
 38:      * The final output as procuded by the _output Encoder. Either an
 39:      * XML string or a WBXML string.
 40:      */
 41:     public function getOutput()
 42:     {
 43:         return $this->output->getOutput();
 44:     }
 45: 
 46:     /**
 47:      * The length of the output as produced by the Encoder. To limit the
 48:      * size of individual messages.
 49:      */
 50:     public function getOutputSize()
 51:     {
 52:         return $this->output->getOutputSize();
 53:     }
 54: 
 55:     /**
 56:      * To we create wbxml or not?
 57:      */
 58:     public function isWBXML()
 59:     {
 60:         return is_a($this->output, 'Horde_Xml_Wbxml_Encoder');
 61:     }
 62: 
 63:     public function &singleton()
 64:     {
 65:         static $instance;
 66:         if (!isset($instance)) {
 67:             $instance = new Horde_SyncMl_XmlOutput();
 68:         }
 69:         return $instance;
 70:     }
 71: 
 72:     public function init(&$theoutputhandler)
 73:     {
 74:         $this->output = $theoutputhandler;
 75:         $this->_msg_CmdID = 1;
 76: 
 77:     }
 78: 
 79:     /**
 80:      * Creates a SyncHdr output.
 81:      *
 82:      * Required data is retrieved from state.
 83:      *
 84:      * @param string $respURI  The url of the server endpoint.
 85:      *
 86:      * @throws Horde_Xml_Wbxml_Exception
 87:      */
 88:     public function outputHeader($respURI)
 89:     {
 90:         $state = $GLOBALS['backend']->state;
 91: 
 92:         $this->_uriMeta = $state->uriMeta;
 93: 
 94:         $this->output->startElement($this->_uri, 'SyncHdr');
 95: 
 96:         $this->output->startElement($this->_uri, 'VerDTD');
 97:         $chars = $state->getVerDTD();
 98:         $this->output->characters($chars);
 99:         $this->output->endElement($this->_uri, 'VerDTD');
100: 
101:         $this->output->startElement($this->_uri, 'VerProto');
102:         $chars = $state->getProtocolName();
103:         $this->output->characters($chars);
104:         $this->output->endElement($this->_uri, 'VerProto');
105: 
106:         $this->output->startElement($this->_uri, 'SessionID');
107:         $this->output->characters($state->sessionID);
108:         $this->output->endElement($this->_uri, 'SessionID');
109: 
110:         $this->output->startElement($this->_uri, 'MsgID');
111:         $this->output->characters($state->messageID);
112:         $this->output->endElement($this->_uri, 'MsgID');
113: 
114:         $this->output->startElement($this->_uri, 'Target');
115:         $this->output->startElement($this->_uri, 'LocURI');
116:         // Source URI sent from client is Target for the server
117:         $this->output->characters($state->sourceURI);
118:         $this->output->endElement($this->_uri, 'LocURI');
119:         if ($state->user) {
120:             $this->output->startElement($this->_uri, 'LocName');
121:             $this->output->characters($state->user);
122:             $this->output->endElement($this->_uri, 'LocName');
123:         }
124:         $this->output->endElement($this->_uri, 'Target');
125: 
126:         $this->output->startElement($this->_uri, 'Source');
127:         $this->output->startElement($this->_uri, 'LocURI');
128:         // Target URI sent from client is Source for the server
129:         $this->output->characters($state->targetURI);
130:         $this->output->endElement($this->_uri, 'LocURI');
131:         $this->output->endElement($this->_uri, 'Source');
132: 
133:         if ($respURI) {
134:             $this->output->startElement($this->_uri, 'RespURI');
135:             $this->output->characters($respURI);
136:             $this->output->endElement($this->_uri, 'RespURI');
137:         }
138: 
139:         // @Todo: omit this in SyncML1.0?
140:         $this->output->startElement($this->_uri, 'Meta');
141: 
142:         // Dummy Max MsqSize, this is just put in to make the packet
143:         // work, it is not a real value.
144:         $this->output->startElement($this->_uriMeta, 'MaxMsgSize');
145:         $chars = Horde_SyncMl::SERVER_MAXMSGSIZE; // 1Meg
146:         $this->output->characters($chars);
147:         $this->output->endElement($this->_uriMeta, 'MaxMsgSize');
148: 
149: 
150:         // MaxObjSize, required by protocol for SyncML1.1 and higher.
151:         if ($state->version > 0) {
152:             $this->output->startElement($this->_uriMeta, 'MaxObjSize');
153:             $this->output->characters(Horde_SyncMl::SERVER_MAXOBJSIZE);
154:             $this->output->endElement($this->_uriMeta, 'MaxObjSize');
155:         }
156:         $this->output->endElement($this->_uri, 'Meta');
157: 
158:         $this->output->endElement($this->_uri, 'SyncHdr');
159:     }
160: 
161:     public function outputInit()
162:     {
163:         $this->_uri = $GLOBALS['backend']->state->getURI();
164: 
165:         $this->output->startElement($this->_uri, 'SyncML', array());
166:     }
167: 
168:     public function outputBodyStart()
169:     {
170:         $this->output->startElement($this->_uri, 'SyncBody', array());
171:     }
172: 
173:     public function outputFinal()
174:     {
175:         $this->output->startElement($this->_uri, 'Final', array());
176:         $this->output->endElement($this->_uri, 'Final');
177:     }
178: 
179:     public function outputEnd()
180:     {
181:         $this->output->endElement($this->_uri, 'SyncBody', array());
182:         $this->output->endElement($this->_uri, 'SyncML', array());
183:     }
184: 
185: 
186:     public function outputStatus($cmdRef, $cmd, $data,
187:                          $targetRef = '', $sourceRef = '',
188:                          $syncAnchorNext = '',
189:                          $syncAnchorLast = '')
190:     {
191:         $state = $GLOBALS['backend']->state;
192:         $uriMeta = $state->uriMeta;
193: 
194:         $this->output->startElement($this->_uri, 'Status');
195:         $this->_outputCmdID();
196: 
197:         $this->output->startElement($this->_uri, 'MsgRef');
198:         $chars = $state->messageID;
199:         $this->output->characters($chars);
200:         $this->output->endElement($this->_uri, 'MsgRef');
201: 
202:         $this->output->startElement($this->_uri, 'CmdRef');
203:         $chars = $cmdRef;
204:         $this->output->characters($chars);
205:         $this->output->endElement($this->_uri, 'CmdRef');
206: 
207:         $this->output->startElement($this->_uri, 'Cmd');
208:         $chars = $cmd;
209:         $this->output->characters($chars);
210:         $this->output->endElement($this->_uri, 'Cmd');
211: 
212:         if (!empty($targetRef)) {
213:             $this->output->startElement($this->_uri, 'TargetRef');
214:             $this->output->characters($targetRef);
215:             $this->output->endElement($this->_uri, 'TargetRef');
216:         }
217: 
218:         if (!empty($sourceRef)) {
219:             $this->output->startElement($this->_uri, 'SourceRef');
220:             $this->output->characters($sourceRef);
221:             $this->output->endElement($this->_uri, 'SourceRef');
222:         }
223: 
224:         // If we are responding to the SyncHdr and we are not
225:         // authenticated then request basic authorization.
226:         if ($cmd == 'SyncHdr' && !$state->authenticated) {
227:             // Keep Horde_SyncMl::RESPONSE_CREDENTIALS_MISSING, otherwise set to
228:             // Horde_SyncMl::RESPONSE_INVALID_CREDENTIALS.
229:             $data = $data == Horde_SyncMl::RESPONSE_CREDENTIALS_MISSING
230:                 ? Horde_SyncMl::RESPONSE_CREDENTIALS_MISSING
231:                 : Horde_SyncMl::RESPONSE_INVALID_CREDENTIALS;
232: 
233:             $this->output->startElement($this->_uri, 'Chal');
234:             $this->output->startElement($this->_uri, 'Meta');
235: 
236:             $this->output->startElement($uriMeta, 'Type');
237:             $this->output->characters('syncml:auth-basic');
238:             $this->output->endElement($uriMeta, 'Type');
239: 
240:             $this->output->startElement($uriMeta, 'Format');
241:             $this->output->characters('b64');
242:             $this->output->endElement($uriMeta, 'Format');
243: 
244:             $this->output->endElement($this->_uri, 'Meta');
245:             $this->output->endElement($this->_uri, 'Chal');
246: 
247:         }
248: 
249:         $this->output->startElement($this->_uri, 'Data');
250:         $this->output->characters($data);
251:         $this->output->endElement($this->_uri, 'Data');
252: 
253:         if (!empty($syncAnchorNext) || !empty($syncAnchorNLast)) {
254:             $this->output->startElement($this->_uri, 'Item');
255:             $this->output->startElement($this->_uri, 'Data');
256: 
257:             $this->output->startElement($uriMeta, 'Anchor');
258: 
259:             if (!empty($syncAnchorLast)) {
260:               $this->output->startElement($uriMeta, 'Last');
261:               $this->output->characters($syncAnchorLast);
262:               $this->output->endElement($uriMeta, 'Last');
263:             }
264: 
265:             if (!empty($syncAnchorNext)) {
266:               $this->output->startElement($uriMeta, 'Next');
267:               $this->output->characters($syncAnchorNext);
268:               $this->output->endElement($uriMeta, 'Next');
269:             }
270: 
271:             $this->output->endElement($uriMeta, 'Anchor');
272: 
273:             $this->output->endElement($this->_uri, 'Data');
274:             $this->output->endElement($this->_uri, 'Item');
275:         }
276: 
277:         $this->output->endElement($this->_uri, 'Status');
278: 
279:     }
280: 
281:     public function outputDevInf($cmdRef)
282:     {
283:         $state = $GLOBALS['backend']->state;
284:         $uriMeta = $state->uriMeta;
285:         $uriDevInf = $state->uriDevInf;
286: 
287:         $this->output->startElement($this->_uri, 'Results');
288:         $this->_outputCmdID();
289: 
290:         $this->output->startElement($this->_uri, 'MsgRef');
291:         $chars = $state->messageID;
292:         $this->output->characters($chars);
293:         $this->output->endElement($this->_uri, 'MsgRef');
294: 
295:         $this->output->startElement($this->_uri, 'CmdRef');
296:         $chars = $cmdRef;
297:         $this->output->characters($chars);
298:         $this->output->endElement($this->_uri, 'CmdRef');
299: 
300:         $this->output->startElement($this->_uri, 'Meta');
301:         $this->output->startElement($uriMeta, 'Type');
302:         if ($state->wbxml) {
303:             $this->output->characters(Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_WBXML);
304:         } else {
305:             $this->output->characters(Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_XML);
306:         }
307: 
308:         $this->output->endElement($uriMeta, 'Type');
309:         $this->output->endElement($this->_uri, 'Meta');
310: 
311:         $this->output->startElement($this->_uri, 'Item');
312:         $this->output->startElement($this->_uri, 'Source');
313:         $this->output->startElement($this->_uri, 'LocURI');
314:         $this->output->characters($state->getDevInfURI());
315:         $this->output->endElement($this->_uri, 'LocURI');
316:         $this->output->endElement($this->_uri, 'Source');
317: 
318:         $this->output->startElement($this->_uri, 'Data');
319: 
320:         /* DevInf data is stored in wbxml not as a seperate codepage but
321:          * rather as a complete wbxml stream as opaque data.  So we need a
322:          * new Handler. */
323:         $devinfoutput = $this->output->createSubHandler();
324: 
325:         $devinfoutput->startElement($uriDevInf , 'DevInf');
326:         $devinfoutput->startElement($uriDevInf , 'VerDTD');
327:         $devinfoutput->characters($state->getVerDTD());
328:         $devinfoutput->endElement($uriDevInf , 'VerDTD');
329:         $devinfoutput->startElement($uriDevInf , 'Man');
330:         $devinfoutput->characters('The Horde Project (http://www.horde.org/)');
331:         $devinfoutput->endElement($uriDevInf , 'Man');
332:         $devinfoutput->startElement($uriDevInf , 'DevID');
333:         $devinfoutput->characters(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost');
334:         $devinfoutput->endElement($uriDevInf , 'DevID');
335:         $devinfoutput->startElement($uriDevInf , 'DevTyp');
336:         $devinfoutput->characters('server');
337:         $devinfoutput->endElement($uriDevInf , 'DevTyp');
338: 
339:         if ($state->version > 0) {
340:             $devinfoutput->startElement($uriDevInf , 'SupportLargeObjs');
341:             $devinfoutput->endElement($uriDevInf , 'SupportLargeObjs');
342: 
343:             $devinfoutput->startElement($uriDevInf , 'SupportNumberOfChanges');
344:             $devinfoutput->endElement($uriDevInf , 'SupportNumberOfChanges');
345:         }
346:         $this->_writeDataStore('notes', 'text/plain', '1.0', $devinfoutput);
347:         $this->_writeDataStore('contacts', 'text/directory', '3.0',
348:                                $devinfoutput, array('text/x-vcard' => '2.1'));
349:         $this->_writeDataStore('tasks', 'text/calendar', '2.0', $devinfoutput,
350:                                array('text/x-vcalendar' => '1.0'));
351:         $this->_writeDataStore('calendar', 'text/calendar', '2.0',
352:                                $devinfoutput,
353:                                array('text/x-vcalendar' => '1.0'));
354:         $devinfoutput->endElement($uriDevInf , 'DevInf');
355: 
356:         $this->output->opaque($devinfoutput->getOutput());
357:         $this->output->endElement($this->_uri, 'Data');
358:         $this->output->endElement($this->_uri, 'Item');
359:         $this->output->endElement($this->_uri, 'Results');
360:     }
361: 
362:     /**
363:      * Writes DevInf data for one DataStore.
364:      *
365:      * @param string $sourceref                 Data for <SourceRef> element.
366:      * @param string $mimetype                  Data for <Rx-Pref><CTType> and
367:      *                                          <Tx-Pref><CTType>.
368:      * @param string $version                   Data for <Rx-Pref><VerCT> and
369:      *                                          <Tx-Pref><VerCT>.
370:      * @param Horde_Xml_Wbxml_ContentHandler $output  Content handler that will
371:      *                                          received the output.
372:      * @param array $additionaltypes            Array of additional types for
373:      *                                          <Tx> and <Rx>; format
374:      *                                          array('text/directory' => '3.0')
375:      */
376:     protected function _writeDataStore($sourceref, $mimetype, $version, &$output,
377:                              $additionaltypes = array())
378:     {
379:         $uriDevInf = $GLOBALS['backend']->state->uriDevInf;
380: 
381:         $output->startElement($uriDevInf , 'DataStore');
382:         $output->startElement($uriDevInf , 'SourceRef');
383:         $output->characters($sourceref);
384:         $output->endElement($uriDevInf , 'SourceRef');
385: 
386:         $output->startElement($uriDevInf , 'Rx-Pref');
387:         $output->startElement($uriDevInf , 'CTType');
388:         $output->characters($mimetype);
389:         $output->endElement($uriDevInf , 'CTType');
390:         $output->startElement($uriDevInf , 'VerCT');
391:         $output->characters($version);
392:         $output->endElement($uriDevInf , 'VerCT');
393:         $output->endElement($uriDevInf , 'Rx-Pref');
394: 
395:         foreach ($additionaltypes as $ct => $ctver){
396:             $output->startElement($uriDevInf , 'Rx');
397:             $output->startElement($uriDevInf , 'CTType');
398:             $output->characters($ct);
399:             $output->endElement($uriDevInf , 'CTType');
400:             $output->startElement($uriDevInf , 'VerCT');
401:             $output->characters($ctver);
402:             $output->endElement($uriDevInf , 'VerCT');
403:             $output->endElement($uriDevInf , 'Rx');
404:         }
405: 
406:         $output->startElement($uriDevInf , 'Tx-Pref');
407:         $output->startElement($uriDevInf , 'CTType');
408:         $output->characters($mimetype);
409:         $output->endElement($uriDevInf , 'CTType');
410:         $output->startElement($uriDevInf , 'VerCT');
411:         $output->characters($version);
412:         $output->endElement($uriDevInf , 'VerCT');
413:         $output->endElement($uriDevInf , 'Tx-Pref');
414: 
415:         foreach ($additionaltypes as $ct => $ctver){
416:             $output->startElement($uriDevInf , 'Tx');
417:             $output->startElement($uriDevInf , 'CTType');
418:             $output->characters($ct);
419:             $output->endElement($uriDevInf , 'CTType');
420:             $output->startElement($uriDevInf , 'VerCT');
421:             $output->characters($ctver);
422:             $output->endElement($uriDevInf , 'VerCT');
423:             $output->endElement($uriDevInf , 'Tx');
424:         }
425: 
426:         $output->startElement($uriDevInf , 'SyncCap');
427:         // We support all sync Types from 1-6: two way, slow, refresh|update
428:         // from client|server
429:         for ($i = 1; $i <= 6; ++$i) {
430:             $output->startElement($uriDevInf , 'SyncType');
431:             $output->characters($i);
432:             $output->endElement($uriDevInf , 'SyncType');
433:         }
434:         $output->endElement($uriDevInf , 'SyncCap');
435:         $output->endElement($uriDevInf , 'DataStore');
436:     }
437: 
438:     public function outputAlert($alertCode, $clientDB = '', $serverDB = '', $lastAnchor = '', $nextAnchor = '')
439:     {
440:         $uriMeta = $GLOBALS['backend']->state->uriMeta;
441: 
442:         $this->output->startElement($this->_uri, 'Alert');
443:         $this->_outputCmdID();
444: 
445:         $this->output->startElement($this->_uri, 'Data');
446:         $chars = $alertCode;
447:         $this->output->characters($chars);
448:         $this->output->endElement($this->_uri, 'Data');
449: 
450:         $this->output->startElement($this->_uri, 'Item');
451: 
452:         if (!empty($clientDB)) {
453:             $this->output->startElement($this->_uri, 'Target');
454:             $this->output->startElement($this->_uri, 'LocURI');
455:             $this->output->characters($clientDB);
456:             $this->output->endElement($this->_uri, 'LocURI');
457:             $this->output->endElement($this->_uri, 'Target');
458:         }
459: 
460:         if (!empty($serverDB)) {
461:             $this->output->startElement($this->_uri, 'Source');
462:             $this->output->startElement($this->_uri, 'LocURI');
463:             $this->output->characters($serverDB);
464:             $this->output->endElement($this->_uri, 'LocURI');
465:             $this->output->endElement($this->_uri, 'Source');
466:         }
467: 
468:         $this->output->startElement($this->_uri, 'Meta');
469: 
470:         $this->output->startElement($uriMeta, 'Anchor');
471: 
472:         $this->output->startElement($uriMeta, 'Last');
473:         $this->output->characters($lastAnchor);
474:         $this->output->endElement($uriMeta, 'Last');
475: 
476:         $this->output->startElement($uriMeta, 'Next');
477:         $this->output->characters($nextAnchor);
478:         $this->output->endElement($uriMeta, 'Next');
479: 
480:         $this->output->endElement($uriMeta, 'Anchor');
481: 
482: 
483:         // MaxObjSize, required by protocol for SyncML1.1 and higher.
484:         if ($GLOBALS['backend']->state->version > 0) {
485:             $this->output->startElement($uriMeta, 'MaxObjSize');
486:             $this->output->characters(Horde_SyncMl::SERVER_MAXOBJSIZE);
487:             $this->output->endElement($uriMeta, 'MaxObjSize');
488:         }
489:         $this->output->endElement($this->_uri, 'Meta');
490: 
491:                 $this->output->endElement($this->_uri, 'Item');
492:         $this->output->endElement($this->_uri, 'Alert');
493: 
494:     }
495: 
496: 
497:     public function outputGetDevInf()
498:     {
499:         $state = $GLOBALS['backend']->state;
500:         $uriMeta = $state->uriMeta;
501: 
502:         $this->output->startElement($this->_uri, 'Get');
503:         $this->_outputCmdID();
504: 
505:         $this->output->startElement($this->_uri, 'Meta');
506:         $this->output->startElement($uriMeta, 'Type');
507:         if ($state->wbxml) {
508:             $chars = Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_WBXML;
509:         } else {
510:             $chars = Horde_SyncMl::MIME_SYNCML_DEVICE_INFO_XML;
511:         }
512:         $this->output->characters($chars);
513:         $this->output->endElement($uriMeta, 'Type');
514:         $this->output->endElement($this->_uri, 'Meta');
515: 
516:         $this->output->startElement($this->_uri, 'Item');
517:         $this->output->startElement($this->_uri, 'Target');
518:         $this->output->startElement($this->_uri, 'LocURI');
519:         $this->output->characters($state->getDevInfURI());
520:         $this->output->endElement($this->_uri, 'LocURI');
521:         $this->output->endElement($this->_uri, 'Target');
522:         $this->output->endElement($this->_uri, 'Item');
523: 
524:         $this->output->endElement($this->_uri, 'Get');
525:     }
526: 
527:     /**
528:      * Creates a single Sync command
529:      *
530:      * @param string $command       The Sync command (Add, Delete, Replace).
531:      * @param string $content       The actual object content.
532:      * @param string $contentType   The content's MIME type.
533:      * @param string $encodingType  The content encoding of the object.
534:      * @param string $cuid          The client's object UID.
535:      * @param string $suid          The server's object UID.
536:      *
537:      * @return integer  The CmdID used for this command.
538:      */
539:     public function outputSyncCommand($command, $content = null, $contentType = null,
540:                                $encodingType = null, $cuid = null, $suid = null)
541:     {
542:         $uriMeta = $GLOBALS['backend']->state->uriMeta;
543: 
544:         $this->output->startElement($this->_uri, $command);
545:         $this->_outputCmdID();
546: 
547:         if (isset($contentType)) {
548:             $this->output->startElement($this->_uri, 'Meta');
549:             $this->output->startElement($uriMeta, 'Type');
550:             $this->output->characters($contentType);
551:             $this->output->endElement($uriMeta, 'Type');
552:             $this->output->endElement($this->_uri, 'Meta');
553:         }
554: 
555:         if (isset($content) || isset($cuid) || isset($suid)) {
556:             $this->output->startElement($this->_uri, 'Item');
557:             if ($suid != null) {
558:                 $this->output->startElement($this->_uri, 'Source');
559:                 $this->output->startElement($this->_uri, 'LocURI');
560:                 $this->output->characters($suid);
561:                 $this->output->endElement($this->_uri, 'LocURI');
562:                 $this->output->endElement($this->_uri, 'Source');
563:             }
564: 
565:             if ($cuid != null) {
566:                 $this->output->startElement($this->_uri, 'Target');
567:                 $this->output->startElement($this->_uri, 'LocURI');
568:                 $this->output->characters($cuid);
569:                 $this->output->endElement($this->_uri, 'LocURI');
570:                 $this->output->endElement($this->_uri, 'Target');
571:             }
572: 
573:             if (!empty($encodingType)) {
574:                 $this->output->startElement($this->_uri, 'Meta');
575:                 $this->output->startElement($uriMeta, 'Format');
576:                 $this->output->characters($encodingType);
577:                 $this->output->endElement($uriMeta, 'Format');
578:                 $this->output->endElement($this->_uri, 'Meta');
579:             }
580:             if (isset($content)) {
581:                 $this->output->startElement($this->_uri, 'Data');
582:                 if($this->isWBXML()) {
583:                     $this->output->characters($content);
584:                 } else {
585:                     $device = $GLOBALS['backend']->state->getDevice();
586:                     if ($device->useCdataTag()) {
587:                         /* Enclose data in CDATA if possible to avoid */
588:                         /* problems with &,< and >. */
589:                         $this->output->opaque('<![CDATA[' . $content . ']]>');
590:                     } else {
591:                         $this->output->characters($content);
592:                     }
593:                 }
594:                 $this->output->endElement($this->_uri, 'Data');
595:             }
596:             $this->output->endElement($this->_uri, 'Item');
597:         }
598: 
599:         $this->output->endElement($this->_uri, $command);
600: 
601:         return $this->_msg_CmdID - 1;
602:     }
603: 
604:     public function outputSyncStart($clientLocURI, $serverLocURI, $numberOfChanges = null)
605:     {
606:         $this->output->startElement($this->_uri, 'Sync');
607:         $this->_outputCmdID();
608: 
609:         $this->output->startElement($this->_uri, 'Target');
610:         $this->output->startElement($this->_uri, 'LocURI');
611:         $this->output->characters($clientLocURI);
612:         $this->output->endElement($this->_uri, 'LocURI');
613:         $this->output->endElement($this->_uri, 'Target');
614: 
615:         $this->output->startElement($this->_uri, 'Source');
616:         $this->output->startElement($this->_uri, 'LocURI');
617:         $this->output->characters($serverLocURI);
618:         $this->output->endElement($this->_uri, 'LocURI');
619:         $this->output->endElement($this->_uri, 'Source');
620: 
621:         if (is_int($numberOfChanges)) {
622:             $this->output->startElement($this->_uri, 'NumberOfChanges');
623:             $this->output->characters($numberOfChanges);
624:             $this->output->endElement($this->_uri, 'NumberOfChanges');
625:         }
626: 
627:     }
628: 
629:     public function outputSyncEnd()
630:     {
631:         $this->output->endElement($this->_uri, 'Sync');
632:     }
633: 
634: 
635:     //  internal helper functions:
636: 
637:     protected function _outputCmdID()
638:     {
639:         $this->output->startElement($this->_uri, 'CmdID');
640:         $this->output->characters($this->_msg_CmdID);
641:         $this->_msg_CmdID++;
642:         $this->output->endElement($this->_uri, 'CmdID');
643:     }
644: 
645:     /**
646:      * Output a single <ele>$str</ele> element.
647:      */
648:     protected function _singleEle($tag, $str, $uri = null)
649:     {
650:         if (empty($uri)) {
651:             $uri = $this->_uri;
652:         }
653:         $this->output->startElement($uri, $tag);
654:         $this->output->characters($str);
655:         $this->output->endElement($uri, $tag);
656:     }
657: }
658: 
API documentation generated by ApiGen