A SyncML command is a protocol primitive. Each SyncML command specifies to a
recipient an individual operation that is to be performed.
The Horde_SyncMl_Command objects are hooked into the XML parser of the
Horde_SyncMl_ContentHandler class and are reponsible for parsing a single
command inside the SyncBody section of a SyncML message. All actions that
must be executed for a single SyncML command are handled by these objects,
by means of the handleCommand() method.
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.
/** * Callback public function called by WBXML parser. */ public function characters($str) { if (isset($this->_currentCommand)) { $this->_currentCommand->characters($str); } else { if (isset($this->_chars)) { $this->_chars = $this->_chars . $str; } else { $this->_chars = $str; } } }
/** * End element handler for the XML parser, delegated from * Horde_SyncMl_ContentHandler::endElement(). * * @param string $uri The namespace URI of the element. * @param string $element The element tag name. */ public function endElement($uri, $element) { switch (count($this->_stack)) { case 3: if ($element == 'LocURI') { if ($this->_stack[1] == 'Source') { $this->_sourceLocURI = trim($this->_chars); } elseif ($this->_stack[1] == 'Target') { $this->_targetLocURI = trim($this->_chars); } } break; case 4: if ($element == 'LocURI') { if ($this->_stack[2] == 'Source') { $this->_mapSources[] = trim($this->_chars); } elseif ($this->_stack[2] == 'Target') { $this->_mapTargets[] = trim($this->_chars); } } break; } parent::endElement($uri, $element); }
/** * End element handler for the XML parser, delegated from * Horde_SyncMl_ContentHandler::endElement(). * * @param string $uri The namespace URI of the element. * @param string $element The element tag name. */ public function endElement($uri, $element) { switch (count($this->_stack)) { case 2: switch ($element) { case 'CmdRef': case 'MsgRef': case 'Status': $this->{'_' . $element} = intval(trim($this->_chars)); break; case 'Cmd': case 'TargetRef': case 'SourceRef': $this->{'_' . $element} = trim($this->_chars); break; } break; case 1: $state = $GLOBALS['backend']->state; switch ($this->_Cmd) { case 'Replace': case 'Add': case 'Delete': $changes = $state->serverChanges[$this->_MsgRef]; /* Run through all stored changes and check if we find one * that matches this Status' message and command IDs. */ foreach ($changes as $db => $commands) { foreach ($commands as $cmdId => $ids) { if ($cmdId != $this->_CmdRef) { continue; } foreach ($ids as $key => $id) { /* If the Status has a SourceRef and/or TargetRef, * it's a response to a single Item only. */ if (isset($this->_SourceRef) && $this->_SourceRef != $id[0] || isset($this->_TargetRef) && $this->_TargetRef != $id[1]) { continue; } /* Match found, remove from stored changes. */ unset($state->serverChanges[$this->_MsgRef][$db][$this->_CmdRef][$key]); $sync =& $state->getSync($db); /* This was a Replace originally, but the object * wasn't found on the client. Try an Add * instead. */ if ($this->_Cmd == 'Replace' && $this->_Status == Horde_SyncMl::RESPONSE_NOT_FOUND) { $sync->setServerChange('add', $id[0], $id[1]); } if (isset($this->_SourceRef) || isset($this->_TargetRef)) { break 3; } } } } break; } break; } parent::endElement($uri, $element); }
/** * End element handler for the XML parser, delegated from * Horde_SyncMl_ContentHandler::endElement(). * * @param string $uri The namespace URI of the element. * @param string $element The element tag name. */ public function endElement($uri, $element) { switch ($element) { case 'VerDTD': case 'Man': case 'Mod': case 'OEM': case 'FwV': case 'SwV': case 'HwV': case 'DevID': case 'DevTyp': $this->_devinf->{$element} = trim($this->_chars); break; case 'UTC': case 'SupportLargeObjs': case 'SupportNumberOfChanges': $this->_devinf->{$element} = true; break; case 'DataStore': $this->_devinf->DataStores[] = $this->_currentDS; break; case 'CTCap': case 'Ext': // Automatically handled by subelements. break; case 'SourceRef': case 'DisplayName': case 'MaxGUIDSize': $this->_currentDS->{$element} = trim($this->_chars); break; case 'Rx-Pref': case 'Rx': case 'Tx-Pref': case 'Tx': $property = str_replace('-', '_', $element); $this->_currentDS->{$property}[$this->_currentCTType] = $this->_VerCT; break; case 'DSMem': // Currently ignored, to be done. break; case 'SyncCap': // Automatically handled by SyncType subelement. break; case 'CTType': $this->_currentCTType = trim($this->_chars); break; case 'PropName': $this->_currentPropName = trim($this->_chars); // Reset param state. unset($this->_currentParamName); $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName] = new Horde_SyncMl_Property(); break; case 'ParamName': $this->_currentParamName = trim($this->_chars); $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->Params[$this->_currentParamName] = new Horde_SyncMl_PropertyParameter(); break; case 'ValEnum': if (!empty($this->_currentParamName)) { // We're in parameter mode. $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->Params[$this->_currentParamName]->ValEnum[trim($this->_chars)] = true; } else { $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->ValEnum[trim($this->_chars)] = true; } break; case 'DataType': case 'Size': case 'DisplayName': if (!empty($this->_currentParamName)) { // We're in parameter mode. $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->Params[$this->_currentParamName]->{'_' . $element} = trim($this->_chars); } else { $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->{'_' . $element} = trim($this->_chars); } break; case 'XNam': $this->_currentXNam = trim($this->_chars); break; case 'XVal': $this->_devinf->Exts[$this->_currentXNam][] = trim($this->_chars); break; case 'VerCT': $this->_VerCT = trim($this->_chars); break; case 'SyncType': $this->_currentDS->SyncCap[trim($this->_chars)] = true; break; } parent::endElement($uri, $element); }
/** * End element handler for the XML parser, delegated from * Horde_SyncMl_ContentHandler::endElement(). * * @param string $uri The namespace URI of the element. * @param string $element The element tag name. */ public function endElement($uri, $element) { switch (count($this->_stack)) { case 2: if ($element == 'Data') { $this->_alert = intval(trim($this->_chars)); } break; case 4: if ($element == 'LocURI') { switch ($this->_stack[2]) { case 'Source': $this->_sourceLocURI = trim($this->_chars); break; case 'Target': $this->_targetLocURI = trim($this->_chars); break; } } break; case 5: switch ($element) { case 'Next': $this->_metaAnchorNext = trim($this->_chars); break; case 'Last': $this->_metaAnchorLast = trim($this->_chars); break; } break; } parent::endElement($uri, $element); }
/** * End element handler for the XML parser, delegated from * Horde_SyncMl_ContentHandler::endElement(). * * @param string $uri The namespace URI of the element. * @param string $element The element tag name. */ public function endElement($uri, $element) { switch (count($this->_stack)) { case 2: if ($element == 'VerProto') { // </VerProto></SyncHdr></SyncML> if (trim($this->_chars) == 'SyncML/1.1') { $this->_version = 1; } elseif (trim($this->_chars) == 'SyncML/1.2') { $this->_version = 2; } else { $this->_version = 0; } } elseif ($element == 'SessionID') { // </SessionID></SyncHdr></SyncML> $this->_sessionID = trim($this->_chars); } elseif ($element == 'MsgID') { // </MsgID></SyncHdr></SyncML> $this->_message = intval(trim($this->_chars)); } break; case 3: if ($element == 'LocURI') { if ($this->_stack[1] == 'Source') { // </LocURI></Source></SyncHdr></SyncML> $this->_sourceURI = trim($this->_chars); } elseif ($this->_stack[1] == 'Target') { // </LocURI></Target></SyncHdr></SyncML> $this->_targetURI = trim($this->_chars); } } elseif ($element == 'LocName') { if ($this->_stack[1] == 'Source') { // </LocName></Source></SyncHdr></SyncML> $this->user = trim($this->_chars); } } elseif ($element == 'Data') { // </Data></Cred></SyncHdr></SyncML> if ($this->_stack[1] == 'Cred') { $this->credData = trim($this->_chars); } } elseif ($element == 'MaxMsgSize') { // </MaxMsgSize></Meta></SyncHdr></SyncML> $this->_maxMsgSize = intval($this->_chars); } break; case 4: if ($this->_stack[1] == 'Cred') { if ($element == 'Format') { // </Format></Meta></Cred></SyncHdr></SyncML> $this->credFormat = trim($this->_chars); } elseif ($element == 'Type') { // </Type></Meta></Cred></SyncHdr></SyncML> $this->credType = trim($this->_chars); } } break; } parent::endElement($uri, $element); }
/** * End element handler for the XML parser, delegated from * Horde_SyncMl_ContentHandler::endElement(). * * @param string $uri The namespace URI of the element. * @param string $element The element tag name. */ public function endElement($uri, $element) { switch (count($this->_stack)) { case 3: switch ($element) { case 'LocURI': if (!isset($this->_currentSyncElement)) { if ($this->_stack[1] == 'Source') { $this->_sourceURI = trim($this->_chars); } elseif ($this->_stack[1] == 'Target') { $this->_targetURI = trim($this->_chars); } } break; case 'Item': if ($this->_itemMoreData) { // Store to continue in next session. $GLOBALS['backend']->state->curSyncItem = $this->_curItem; } else { // Finished. Store to syncElements[]. if (empty($this->_curItem->contentType)) { $this->_curItem->contentType = $this->_contentType; } if (empty($this->_curItem->contentFormat)) { $this->_curItem->contentFormat = $this->_contentFormat; } $this->_syncElements[] = $this->_curItem; // @todo: check if size matches strlen(content) when // size>0, esp. in case of <MoreData>. // Unset the saved state item if it was not unset in // endElement(). if (isset($GLOBALS['backend']->state->curSyncItem)) { unset($GLOBALS['backend']->state->curSyncItem); } unset($this->_curItem); } break; case 'CmdID': $this->_itemCmdID = trim($this->_chars); break; } break; case 4: switch ($element) { case 'Format': if ($this->_stack[2] == 'Meta') { $this->_contentFormat = trim($this->_chars); } break; case 'Type': if ($this->_stack[2] == 'Meta') { $this->_contentType = trim($this->_chars); } break; case 'Data': // Trim only if we had a MoreData tag before to not corrupt // pictures. if (isset($GLOBALS['backend']->state->curSyncItem)) { $this->_curItem->content .= ltrim($this->_chars); unset($GLOBALS['backend']->state->curSyncItem); } else { // Don't trim, because we have to check the raw content's // size. $this->_curItem->content .= $this->_chars; } break; case 'MoreData': $this->_itemMoreData = true; break; case 'Size': $this->_itemSize = $this->_chars; break; } break; case 5: switch ($element) { case 'LocURI': if ($this->_stack[3] == 'Source') { $this->_curItem->cuid = trim($this->_chars); } elseif ($this->_stack[3] == 'Target') { // Not used: we ignore "suid proposals" from client. } break; case 'Format': if ($this->_stack[3] == 'Meta') { $this->_curItem->contentFormat = trim($this->_chars); } break; case 'Type': $this->_curItem->contentType = trim($this->_chars); break; } break; case 6: if ($element == 'Type') { $this->_curItem->contentType = trim($this->_chars); } break; } parent::endElement($uri, $element); }