[ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 3 require_once 'SyncML.php'; 4 require_once 'SyncML/State.php'; 5 require_once 'SyncML/Command/Status.php'; 6 7 /** 8 * The Horde_RPC_syncml class provides a SyncML implementation of the Horde 9 * RPC system. 10 * 11 * $Horde: framework/RPC/RPC/syncml.php,v 1.18.10.7 2006/05/01 12:05:13 jan Exp $ 12 * 13 * Copyright 2003-2006 Chuck Hagenbuch <chuck@horde.org> 14 * Copyright 2003-2006 Anthony Mills <amills@pyramid6.com> 15 * 16 * See the enclosed file COPYING for license information (LGPL). If you 17 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. 18 * 19 * @author Chuck Hagenbuch <chuck@horde.org> 20 * @author Anthony Mills <amills@pyramid6.com> 21 * @since Horde 3.0 22 * @package Horde_RPC 23 */ 24 class Horde_RPC_syncml extends Horde_RPC { 25 26 /** 27 * Output ContentHandler used to output XML events. 28 * 29 * @var object 30 */ 31 var $_output; 32 33 /** 34 * @var integer 35 */ 36 var $_xmlStack = 0; 37 38 /** 39 * Debug directory, if set will store copies of all packets. 40 * 41 * @var string 42 */ 43 var $_debugDir = '/tmp/sync'; 44 45 /** 46 * Default character set. Only supports UTF-8(ASCII?). 47 * 48 * @var string 49 */ 50 var $_charset = 'UTF-8'; 51 52 /** 53 * SyncML handles authentication internally, so bypass the RPC framework 54 * auth check by just returning true here. 55 */ 56 function authorize() 57 { 58 return true; 59 } 60 61 /** 62 * Sends an RPC request to the server and returns the result. 63 * 64 * @param string $request The raw request string. 65 * 66 * @return string The XML encoded response from the server. 67 */ 68 function getResponse($request) 69 { 70 /* Catch any errors/warnings/notices that may get thrown while 71 * processing. Don't want to let anything go to the client that's not 72 * part of the valid response. */ 73 ob_start(); 74 75 /* Very useful for debugging. Logs WBXML packets to 76 * $this->_debugDir. */ 77 if (!empty($this->_debugDir) && is_dir($this->_debugDir)) { 78 $packetNum = @intval(file_get_contents($this->_debugDir . '/syncml.packetnum')); 79 if (!isset($packetNum)) { 80 $packetNum = 0; 81 } 82 83 $f = @fopen($this->_debugDir . '/syncml_client_' . $packetNum . '.xml', 'wb'); 84 if ($f) { 85 fwrite($f, $request); 86 fclose($f); 87 } 88 } 89 90 require_once 'XML/WBXML/ContentHandler.php'; 91 $this->_output = &new XML_WBXML_ContentHandler(); 92 93 $this->_parse($request); 94 $response = $this->_output->getOutput(); 95 96 /* Very useful for debugging. */ 97 if (!empty($this->_debugDir) && is_dir($this->_debugDir)) { 98 $f = @fopen($this->_debugDir . '/syncml_server_' . $packetNum . '.xml', 'wb'); 99 if ($f) { 100 fwrite($f, $response); 101 fclose($f); 102 } 103 104 $fp = @fopen($this->_debugDir . '/syncml.packetnum', 'w'); 105 if ($fp) { 106 fwrite($fp, ++$packetNum); 107 fclose($fp); 108 } 109 } 110 111 /* Clear the output buffer that we started above, and log anything 112 * that came up for later debugging. */ 113 $errorLogging = ob_get_clean(); 114 if (!empty($errorLogging)) { 115 Horde::logMessage('SyncML: caught output=' . 116 str_replace("\n", ' ', $errorLogging), __FILE__, __LINE__, PEAR_LOG_DEBUG); 117 } 118 119 return $response; 120 } 121 122 function _parse($xml) 123 { 124 /* try to extract charset from XML text */ 125 if(preg_match('/^\s*<\?xml[^>]*encoding\s*=\s*"([^"]*)"/i', 126 $xml, $m)) { 127 $this->_charset = $m[1]; 128 } 129 NLS::setCharset($this->_charset); 130 String::setDefaultCharset($this->_charset); 131 132 /* Create the XML parser and set method references. */ 133 $this->_parser = xml_parser_create_ns($this->_charset); 134 xml_set_object($this->_parser, $this); 135 xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); 136 xml_set_element_handler($this->_parser, '_startElement', '_endElement'); 137 xml_set_character_data_handler($this->_parser, '_characters'); 138 xml_set_processing_instruction_handler($this->_parser, ''); 139 xml_set_external_entity_ref_handler($this->_parser, ''); 140 141 if (!xml_parse($this->_parser, $xml)) { 142 return $this->raiseError(sprintf('XML error: %s at line %d', 143 xml_error_string(xml_get_error_code($this->_parser)), 144 xml_get_current_line_number($this->_parser))); 145 } 146 147 xml_parser_free($this->_parser); 148 } 149 150 function _startElement($parser, $tag, $attributes) 151 { 152 list($uri, $name) = $this->_splitURI($tag); 153 154 $this->startElement($uri, $name, $attributes); 155 } 156 157 function _characters($parser, $chars) 158 { 159 $this->characters($chars); 160 } 161 162 function _endElement($parser, $tag) 163 { 164 list($uri, $name) = $this->_splitURI($tag); 165 166 $this->endElement($uri, $name); 167 } 168 169 function _splitURI($tag) 170 { 171 $parts = explode(':', $tag); 172 $name = array_pop($parts); 173 $uri = implode(':', $parts); 174 return array($uri, $name); 175 } 176 177 /** 178 * Returns the Content-Type of the response. 179 * 180 * @return string The MIME Content-Type of the RPC response. 181 */ 182 function getResponseContentType() 183 { 184 return 'application/vnd.syncml+xml'; 185 } 186 187 function startElement($uri, $element, $attrs) 188 { 189 $this->_xmlStack++; 190 191 switch ($this->_xmlStack) { 192 case 1: 193 // <SyncML> 194 // Defined in SyncML Representation Protocol, version 1.1 5.2.1 195 $this->_output->startElement($uri, $element, $attrs); 196 break; 197 198 case 2: 199 // Either <SyncML><SyncHdr> or <SyncML><SyncBody> 200 if (!isset($this->_contentHandler)) { 201 // If not defined then create SyncHdr. 202 $this->_contentHandler = &new SyncML_SyncmlHdr(); 203 $this->_contentHandler->setOutput($this->_output); 204 } 205 206 $this->_contentHandler->startElement($uri, $element, $attrs); 207 break; 208 209 default: 210 if (isset($this->_contentHandler)) { 211 $this->_contentHandler->startElement($uri, $element, $attrs); 212 } 213 break; 214 } 215 } 216 217 function endElement($uri, $element) 218 { 219 switch ($this->_xmlStack) { 220 case 1: 221 // </SyncML> 222 // Defined in SyncML Representation Protocol, version 1.1 5.2.1 223 $this->_output->endElement($uri, $element); 224 break; 225 226 case 2: 227 // Either </SyncHdr></SyncML> or </SyncBody></SyncML> 228 if ($element == 'SyncHdr') { 229 // Then we get the state from SyncMLHdr, and create a new 230 // SyncMLBody. 231 $this->_contentHandler->endElement($uri, $element); 232 233 unset($this->_contentHandler); 234 235 $this->_contentHandler = &new SyncML_SyncmlBody(); 236 $this->_contentHandler->setOutput($this->_output); 237 } else { 238 // No longer used. 239 $this->_contentHandler->endElement($uri, $element); 240 unset($this->_contentHandler); 241 } 242 break; 243 244 default: 245 // </*></SyncHdr></SyncML> or </*></SyncBody></SyncML> 246 if (isset($this->_contentHandler)) { 247 $this->_contentHandler->endElement($uri, $element); 248 } 249 break; 250 } 251 252 if (isset($this->_chars)) { 253 unset($this->_chars); 254 } 255 256 $this->_xmlStack--; 257 } 258 259 function characters($str) 260 { 261 if (isset($this->_contentHandler)) { 262 $this->_contentHandler->characters($str); 263 } 264 } 265 266 function raiseError($str) 267 { 268 return Horde::logMessage($str, __FILE__, __LINE__, PEAR_LOG_ERR); 269 } 270 271 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |