[ Index ]
 

Code source de Horde 3.1.3

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/ -> SyncML.php (source)

   1  <?php
   2  
   3  include_once  'SyncML/Command.php';
   4  include_once  'SyncML/Command/Status.php';
   5  include_once  'SyncML/Command/Alert.php';
   6  include_once  'SyncML/Command/Sync.php';
   7  include_once  'SyncML/Command/Final.php';
   8  include_once  'SyncML/Sync.php';
   9  include_once  'SyncML/Backend.php';
  10  
  11  /**
  12   * The SyncML_SyncHdr and SyncML_SyncBody classes provides
  13   * a SyncHdr and SyncBody in SyncML Representation Protocol, version
  14   * 1.1 5.2.2 and 5.2.3.  Most of the work is passed on to
  15   * SyncML_Command_Alert and SyncML_Command_Sync.
  16   *
  17   * There are two global objects that are used by SyncML:
  18   * 1) $_SESSION['SyncML.state']:
  19   *    session object used to maintain the state between the individual
  20   *    SyncML messages.
  21   *
  22   * 2) $GLOBALS['backend']
  23   *    Backend to handle the communication with the datastore. Currently the
  24   *    horde backend is the only backend provided.
  25   *
  26   * $Horde: framework/SyncML/SyncML.php,v 1.21.10.10 2006/01/01 21:28:35 jan Exp $
  27   *
  28   * Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
  29   *
  30   * See the enclosed file COPYING for license information (LGPL). If you
  31   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  32   *
  33   * @author  Anthony Mills <amills@pyramid6.com>
  34   * @author  Karsten Fourmont <fourmont@gmx.de>
  35   * @since   Horde 3.0
  36   * @package SyncML
  37   */
  38  class SyncML_ContentHandler {
  39  
  40      /**
  41       * Output ContentHandler used to output XML events.
  42       *
  43       * @var object
  44       */
  45      var $_output;
  46  
  47      /**
  48       * Stack for holding the xml elements during creation of the object from
  49       * the xml event flow.
  50       *
  51       * @var array
  52       */
  53      var $_Stack = array();
  54  
  55      /**
  56       * @var string
  57       */
  58      var $_chars;
  59  
  60      function setOutput(&$output)
  61      {
  62          $this->_output = &$output;
  63      }
  64  
  65      function startElement($uri, $element, $attrs)
  66      {
  67          $this->_Stack[] = $element;
  68      }
  69  
  70      function endElement($uri, $element)
  71      {
  72          if (isset($this->_chars)) {
  73              unset($this->_chars);
  74          }
  75  
  76          array_pop($this->_Stack);
  77      }
  78  
  79      function characters($str)
  80      {
  81          if (isset($this->_chars)) {
  82              $this->_chars = $this->_chars . $str;
  83          } else {
  84              $this->_chars = $str;
  85          }
  86      }
  87  
  88  }
  89  
  90  
  91  /**
  92   * Defined in SyncML Representation Protocol, version 1.1 5.2.2
  93   *
  94   * @package SyncML
  95   */
  96  class SyncML_SyncMLHdr extends SyncML_ContentHandler {
  97  
  98      /**
  99       * Defined in SyncML Representation Protocol, version 1.1 5.1.9. User name.
 100       *
 101       * @var string
 102       */
 103      var $_locName;
 104  
 105      /**
 106       * Defined in SyncML Representation Protocol, version 1.1 5.1.18
 107       *
 108       * @var string
 109       */
 110      var $_sessionID;
 111  
 112      /**
 113       * Defined in SyncML Representation Protocol, version 1.1.  Must be 1.0 (0)
 114       * or 1.1 (1).
 115       *
 116       * @var string
 117       */
 118      var $_version;
 119  
 120      /**
 121       * Defined in SyncML Representation Protocol, version 1.1 5.1.12
 122       *
 123       * @var string
 124       */
 125      var $_msgID;
 126  
 127      /**
 128       * Defined in SyncML Representation Protocol, version 1.1 5.1.10
 129       *
 130       * @var string
 131       */
 132      var $_targetURI;
 133  
 134      /**
 135       * Defined in SyncML Representation Protocol, version 1.1 5.1.10, 5.1.20
 136       *
 137       * @var string
 138       */
 139      var $_sourceURI;
 140  
 141      var $_credData;
 142  
 143      var $_credFormat;
 144  
 145      var $_credType;
 146  
 147      var $_maxMsgSize;
 148  
 149      function getStateFromSession($sourceURI, $locName, $sessionID)
 150      {
 151          $GLOBALS['backend'] = &new SyncML_Backend_Horde();
 152  
 153          // Reload the Horde SessionHandler if necessary.
 154          Horde::setupSessionHandler();
 155  
 156          // SyncML protocol does not require the client to send the
 157          // username on any messages but the first.  So unfortunately
 158          // we can't use it to make a unique session id.
 159          session_id('syncml' . preg_replace('/[^a-zA-Z0-9]/',
 160                                             '', $sourceURI . $sessionID));
 161          session_start();
 162  
 163          // It would seem multisync does not send the user name once it
 164          // has been authorized. Make sure we have a valid session id.
 165          session_id('syncml' . preg_replace('/[^a-zA-Z0-9]/', '', $sourceURI . $sessionID));
 166          @session_start();
 167  
 168          if (!isset($_SESSION['SyncML.state'])) {
 169              // Create a new state if one does not already exist.
 170              $GLOBALS['backend']->logMessage('New session created: '
 171                                . session_id(),
 172                                __FILE__, __LINE__, PEAR_LOG_DEBUG);
 173  
 174              $_SESSION['SyncML.state'] = &new SyncML_State($sourceURI,
 175                                                            $locName,
 176                                                            $sessionID);
 177          } else {
 178              $GLOBALS['backend']->logMessage('Existing session continued: '
 179                                . session_id(),
 180                                __FILE__, __LINE__, PEAR_LOG_DEBUG);
 181          }
 182  
 183          return $_SESSION['SyncML.state'];
 184      }
 185  
 186      function startElement($uri, $element, $attrs)
 187      {
 188          parent::startElement($uri, $element, $attrs);
 189      }
 190  
 191      function endElement($uri, $element)
 192      {
 193          switch (count($this->_Stack)) {
 194          case 1:
 195              // </SyncHdr></SyncML>
 196              // Find the state.
 197              $state = $this->getStateFromSession($this->_sourceURI, $this->_locName, $this->_sessionID);
 198  
 199              $state->setVersion($this->_version);
 200              $state->setMsgID($this->_msgID);
 201              $state->setTargetURI($this->_targetURI);
 202              $state->setPassword($this->_credData);
 203              $state->setWBXML(is_a($this->_output, 'XML_WBXML_Encoder'));
 204  
 205              // Store login name in state if not already set
 206              if (empty($state->_locName) && !empty($this->_locName)) {
 207                  $state->setLocName($this->_locName);
 208              }
 209              if (!empty($this->_maxMsgSize)) {
 210                  $state->setMaxMsgSize($this->_maxMsgSize);
 211              }
 212  
 213              $str = 'authorized=' . $state->isAuthorized() .
 214                  ' version=' . $state->getVersion() .
 215                  ' msgid=' . $state->getMsgID() .
 216                  ' source=' . $state->getSourceURI() .
 217                  ' target=' . $state->getTargetURI() .
 218                  ' user=' . $state->getLocName() .
 219                  ' charset=' . NLS::getCharset() .
 220                  ' wbxml=' . $state->isWBXML()
 221  
 222                  ;
 223  
 224              $_SESSION['SyncML.state'] = $state;
 225  
 226              $GLOBALS['backend']->logMessage($str, __FILE__, __LINE__, PEAR_LOG_DEBUG);
 227  
 228              // Got the state; now write our SyncHdr header.
 229              $this->outputSyncHdr($this->_output);
 230              break;
 231  
 232          case 2:
 233              if ($element == 'VerProto') {
 234                  // </VerProto></SyncHdr></SyncML>
 235                  if (trim($this->_chars) == 'SyncML/1.1') {
 236                      $this->_version = 1;
 237                  } else {
 238                      $this->_version = 0;
 239                  }
 240              } elseif ($element == 'SessionID') {
 241                  // </SessionID></SyncHdr></SyncML>
 242                  $this->_sessionID = trim($this->_chars);
 243              } elseif ($element == 'MsgID') {
 244                  // </MsgID></SyncHdr></SyncML>
 245                  $this->_msgID = intval(trim($this->_chars));
 246              } elseif ($element == 'Cred') {
 247                  // </Cred></SyncHdr></SyncML>
 248                  $this->_credData = base64_decode($this->_credData);
 249  
 250                  $tmp = explode(':', $this->_credData);
 251                  $this->_locName = $tmp[0];
 252                  $this->_credData = $tmp[1];
 253                  Horde::logMessage('SyncML: received credentials for user='
 254                                                  . $this->_locName , 'cred='
 255                                                  . $this->_credData,
 256                                                  __FILE__, __LINE__, PEAR_LOG_DEBUG);
 257  
 258              }
 259              break;
 260  
 261          case 3:
 262              if ($element == 'LocURI') {
 263                  if ($this->_Stack[1] == 'Source') {
 264                      // </LocURI></Source></SyncHdr></SyncML>
 265                      $this->_sourceURI = trim($this->_chars);
 266                  } elseif ($this->_Stack[1] == 'Target') {
 267                      // </LocURI></Target></SyncHdr></SyncML>
 268                      $this->_targetURI = trim($this->_chars);
 269                  }
 270              } elseif ($element == 'LocName') {
 271                  if ($this->_Stack[1] == 'Source') {
 272                      // </LocName></Source></SyncHdr></SyncML>
 273                      $this->_locName = trim($this->_chars);
 274                  }
 275              } elseif ($element == 'Data') {
 276                      // </Data></Cred></SyncHdr></SyncML>
 277                  if ($this->_Stack[1] == 'Cred') {
 278                      $this->_credData = trim($this->_chars);
 279                  }
 280              } elseif ($element == 'MaxMsgSize') {
 281                  // </MaxMsgSize></Meta></SyncHdr></SyncML>
 282                  $this->_maxMsgSize = intval($this->_chars);
 283              }
 284              break;
 285  
 286          case 4:
 287              if ($this->_Stack[1] == 'Cred') {
 288                  if ($element == 'Format') {
 289                      // </Format></Meta></Cred></SyncHdr></SyncML>
 290                      $this->_credFormat = trim($this->_chars);
 291                  } elseif ($element == 'Type') {
 292                      // </Type></Meta></Cred></SyncHdr></SyncML>
 293                      $this->_credType = trim($this->_chars);
 294                  }
 295              }
 296              break;
 297          }
 298  
 299          parent::endElement($uri, $element);
 300      }
 301  
 302      function outputSyncHdr(&$output)
 303      {
 304          $attrs = array();
 305  
 306          $state = &$_SESSION['SyncML.state'];
 307  
 308          $uri = $state->getURI();
 309          $uriMeta = $state->getURIMeta();
 310  
 311          $output->startElement($uri, 'SyncHdr', $attrs);
 312  
 313          $output->startElement($uri, 'VerDTD', $attrs);
 314          $chars = ($this->_version == 1) ? '1.1' : '1.0';
 315          $output->characters($chars);
 316          $output->endElement($uri, 'VerDTD');
 317  
 318          $output->startElement($uri, 'VerProto', $attrs);
 319          $chars = ($this->_version == 1) ? 'SyncML/1.1' : 'SyncML/1.0';
 320          $output->characters($chars);
 321          $output->endElement($uri, 'VerProto');
 322  
 323          $output->startElement($uri, 'SessionID', $attrs);
 324          $output->characters($this->_sessionID);
 325          $output->endElement($uri, 'SessionID');
 326  
 327          $output->startElement($uri, 'MsgID', $attrs);
 328          $output->characters($this->_msgID);
 329          $output->endElement($uri, 'MsgID');
 330  
 331          $output->startElement($uri, 'Target', $attrs);
 332          $output->startElement($uri, 'LocURI', $attrs);
 333          $output->characters($this->_sourceURI);
 334          $output->endElement($uri, 'LocURI');
 335          $output->startElement($uri, 'LocName', $attrs);
 336          $output->characters($state->getLocName());
 337          $output->endElement($uri, 'LocName');
 338          $output->endElement($uri, 'Target');
 339  
 340          $output->startElement($uri, 'Source', $attrs);
 341          $output->startElement($uri, 'LocURI', $attrs);
 342          $output->characters($this->_targetURI);
 343          $output->endElement($uri, 'LocURI');
 344          $output->endElement($uri, 'Source');
 345  
 346          /*
 347          Do not send RespURI Element. It's optional and may be misleading:
 348          $this->_targetURI is data from the client and not guaranteed to be
 349          the correct URL for access. Let the client just stay with the same
 350          URL it has used for the previous request(s).
 351          */
 352          //$output->startElement($uri, 'RespURI', $attrs);
 353          //$output->characters($this->_targetURI);
 354          //$output->endElement($uri, 'RespURI');
 355  
 356          /*
 357          $output->startElement($uri, 'Meta', $attrs);
 358  
 359          // Dummy Max MsqSize, this is just put in to make the packet
 360          // work, it is not a real value.
 361          $output->startElement($uriMeta, 'MaxMsgSize', $attrs);
 362          $chars = '50000';
 363          $output->characters($chars);
 364          $output->endElement($uriMeta, 'MaxMsgSize');
 365  
 366          // Dummy MaxObjSize, this is just put in to make the packet
 367          // work, it is not a real value.
 368          $output->startElement($uriMeta, 'MaxObjSize', $attrs);
 369          $chars = '4000000';
 370          $output->characters($chars);
 371          $output->endElement($uriMeta, 'MaxObjSize');
 372  
 373          $output->endElement($uri, 'Meta');
 374          */
 375  
 376          $output->endElement($uri, 'SyncHdr');
 377      }
 378  
 379      function getSourceURI()
 380      {
 381          return $this->_sourceURI;
 382      }
 383  
 384      function getLocName()
 385      {
 386          return $this->_locName;
 387      }
 388  
 389      function getSessionID()
 390      {
 391          return $this->_sessionID;
 392      }
 393  
 394      function getVersion()
 395      {
 396          return $this->_version;
 397      }
 398  
 399      function getMsgID()
 400      {
 401          return $this->_msgID;
 402      }
 403  
 404      function getTargetURI()
 405      {
 406          return $this->_targetURI;
 407      }
 408  
 409      function opaque($o)
 410      {
 411      }
 412  
 413  }
 414  
 415  /**
 416   * Defined in SyncML Representation Protocol, version 1.1 5.2.3
 417   *
 418   * @package SyncML
 419   */
 420  class SyncML_SyncMLBody extends SyncML_ContentHandler {
 421  
 422      var $_currentCmdID = 1;
 423  
 424      var $_currentCommand;
 425  
 426      var $_actionCommands = false;
 427  
 428      function startElement($uri, $element, $attrs)
 429      {
 430          parent::startElement($uri, $element, $attrs);
 431  
 432          switch (count($this->_Stack)) {
 433          case 1:
 434              $state = &$_SESSION['SyncML.state'];
 435  
 436              $this->_actionCommands = false; // so far, we have not seen commands that require action from our side
 437  
 438              // <SyncML><SyncBody>
 439              $uri = $state->getURI();
 440              $this->_output->startElement($uri, $element, $attrs);
 441  
 442              // Right our status about the header.
 443              $status = &new SyncML_Command_Status(($state->isAuthorized()) ?
 444                                                   RESPONSE_AUTHENTICATION_ACCEPTED : RESPONSE_INVALID_CREDENTIALS, 'SyncHdr');
 445              $status->setSourceRef($state->getSourceURI());
 446              $status->setTargetRef($state->getTargetURI());
 447              $status->setCmdRef(0);
 448  
 449              $this->_currentCmdID = $status->output($this->_currentCmdID, $this->_output);
 450              break;
 451  
 452          case 2:
 453              // <SyncML><SyncBody><[Command]>
 454              $this->_currentCommand = SyncML_Command::factory($element);
 455              $this->_currentCommand->startElement($uri, $element, $attrs);
 456  
 457              if ($element != 'Status' && $element != 'Map' && $element != 'Final') {
 458                  // We've got to do something! This can't be the last
 459                  // packet.
 460                  $this->_actionCommands = true;
 461              }
 462              break;
 463  
 464          default:
 465              // <SyncML><SyncBody><Command><...>
 466              $this->_currentCommand->startElement($uri, $element, $attrs);
 467              break;
 468          }
 469      }
 470  
 471      function endElement($uri, $element)
 472      {
 473          switch (count($this->_Stack)) {
 474          case 1:
 475              // </SyncBody></SyncML>
 476              $state = &$_SESSION['SyncML.state'];
 477  
 478              if ($state->hasPendingElements()) {
 479                  /* still something to do: don't close session */
 480                  $this->_actionCommands = true;
 481              }
 482              $this->_currentCmdID = SyncML_Command_Final::outputFinal(
 483                                          $this->_currentCmdID,
 484                                          $this->_output);
 485              $this->_output->endElement($uri, $element);
 486  
 487              if (!$this->_actionCommands) {
 488                  // This packet did not contain any real actions, just
 489                  // status and map. This means we're done. The session
 490                  // can be closed and the anchors saved for the next
 491                  // sync.
 492                  $GLOBALS['backend']->logMessage('sync' . session_id() .
 493                                                  ' completed successfully!' .
 494                                                  ' Storing Client-TS ' .
 495                                                  $state->_clientAnchorNext,
 496                                                  __FILE__, __LINE__, PEAR_LOG_INFO);
 497                  $GLOBALS['backend']->writeSyncSummary(
 498                      $state->getSyncIdentifier(),
 499                      $state->_clientAnchorNext,
 500                      $state->_serverAnchorNext);
 501                  $log = $state->getLog();
 502                  $s = '';
 503                  foreach ($log as $k => $v) {
 504                      $s .= " $k=$v";
 505                  }
 506                  $GLOBALS['backend']->logMessage('Summary:' . $s, __FILE__, __LINE__, PEAR_LOG_INFO);
 507  
 508                  // Session can be closed here.
 509                  session_unset();
 510                  session_destroy();
 511              } else {
 512                  $GLOBALS['backend']->logMessage('SyncML: return message completed',
 513                                                  __FILE__, __LINE__, PEAR_LOG_DEBUG);
 514              }
 515              break;
 516  
 517          case 2:
 518              // </[Command]></SyncBody></SyncML>
 519              $this->_currentCommand->endElement($uri, $element);
 520  
 521              $this->_currentCmdID = $this->_currentCommand->output($this->_currentCmdID, $this->_output);
 522  
 523              unset($this->_currentCommand);
 524              break;
 525  
 526          default:
 527              // </...></[Command]></SyncBody></SyncML>
 528              $this->_currentCommand->endElement($uri, $element);
 529              break;
 530          }
 531  
 532          parent::endElement($uri, $element);
 533      }
 534  
 535      function characters($str)
 536      {
 537          if (isset($this->_currentCommand)) {
 538              $this->_currentCommand->characters($str);
 539          }
 540      }
 541  
 542  }


Généré le : Sun Feb 25 18:01:28 2007 par Balluche grâce à PHPXref 0.7