1<?php 2 3/** 4 * XML-parsing classes to wrap the domxml and DOM extensions for PHP 4 5 * and 5, respectively. 6 * 7 * @package OpenID 8 */ 9 10/** 11 * The base class for wrappers for available PHP XML-parsing 12 * extensions. To work with this Yadis library, subclasses of this 13 * class MUST implement the API as defined in the remarks for this 14 * class. Subclasses of Auth_Yadis_XMLParser are used to wrap 15 * particular PHP XML extensions such as 'domxml'. These are used 16 * internally by the library depending on the availability of 17 * supported PHP XML extensions. 18 * 19 * @package OpenID 20 */ 21class Auth_Yadis_XMLParser { 22 /** 23 * Initialize an instance of Auth_Yadis_XMLParser with some 24 * XML and namespaces. This SHOULD NOT be overridden by 25 * subclasses. 26 * 27 * @param string $xml_string A string of XML to be parsed. 28 * @param array $namespace_map An array of ($ns_name => $ns_uri) 29 * to be registered with the XML parser. May be empty. 30 * @return boolean $result True if the initialization and 31 * namespace registration(s) succeeded; false otherwise. 32 */ 33 function init($xml_string, $namespace_map) 34 { 35 if (!$this->setXML($xml_string)) { 36 return false; 37 } 38 39 foreach ($namespace_map as $prefix => $uri) { 40 if (!$this->registerNamespace($prefix, $uri)) { 41 return false; 42 } 43 } 44 45 return true; 46 } 47 48 /** 49 * Register a namespace with the XML parser. This should be 50 * overridden by subclasses. 51 * 52 * @param string $prefix The namespace prefix to appear in XML tag 53 * names. 54 * 55 * @param string $uri The namespace URI to be used to identify the 56 * namespace in the XML. 57 * 58 * @return boolean $result True if the registration succeeded; 59 * false otherwise. 60 */ 61 function registerNamespace($prefix, $uri) 62 { 63 // Not implemented. 64 } 65 66 /** 67 * Set this parser object's XML payload. This should be 68 * overridden by subclasses. 69 * 70 * @param string $xml_string The XML string to pass to this 71 * object's XML parser. 72 * 73 * @return boolean $result True if the initialization succeeded; 74 * false otherwise. 75 */ 76 function setXML($xml_string) 77 { 78 // Not implemented. 79 } 80 81 /** 82 * Evaluate an XPath expression and return the resulting node 83 * list. This should be overridden by subclasses. 84 * 85 * @param string $xpath The XPath expression to be evaluated. 86 * 87 * @param mixed $node A node object resulting from a previous 88 * evalXPath call. This node, if specified, provides the context 89 * for the evaluation of this xpath expression. 90 * 91 * @return array $node_list An array of matching opaque node 92 * objects to be used with other methods of this parser class. 93 */ 94 function &evalXPath($xpath, $node = null) 95 { 96 // Not implemented. 97 } 98 99 /** 100 * Return the textual content of a specified node. 101 * 102 * @param mixed $node A node object from a previous call to 103 * $this->evalXPath(). 104 * 105 * @return string $content The content of this node. 106 */ 107 function content($node) 108 { 109 // Not implemented. 110 } 111 112 /** 113 * Return the attributes of a specified node. 114 * 115 * @param mixed $node A node object from a previous call to 116 * $this->evalXPath(). 117 * 118 * @return array $attrs An array mapping attribute names to 119 * values. 120 */ 121 function attributes($node) 122 { 123 // Not implemented. 124 } 125} 126 127/** 128 * This concrete implementation of Auth_Yadis_XMLParser implements 129 * the appropriate API for the 'domxml' extension which is typically 130 * packaged with PHP 4. This class will be used whenever the 'domxml' 131 * extension is detected. See the Auth_Yadis_XMLParser class for 132 * details on this class's methods. 133 * 134 * @package OpenID 135 */ 136class Auth_Yadis_domxml extends Auth_Yadis_XMLParser { 137 function Auth_Yadis_domxml() 138 { 139 $this->xml = null; 140 $this->doc = null; 141 $this->xpath = null; 142 $this->errors = array(); 143 } 144 145 function setXML($xml_string) 146 { 147 $this->xml = $xml_string; 148 $this->doc = @domxml_open_mem($xml_string, DOMXML_LOAD_PARSING, 149 $this->errors); 150 151 if (!$this->doc) { 152 return false; 153 } 154 155 $this->xpath = $this->doc->xpath_new_context(); 156 157 return true; 158 } 159 160 function registerNamespace($prefix, $uri) 161 { 162 return xpath_register_ns($this->xpath, $prefix, $uri); 163 } 164 165 function &evalXPath($xpath, $node = null) 166 { 167 if ($node) { 168 $result = @$this->xpath->xpath_eval($xpath, $node); 169 } else { 170 $result = @$this->xpath->xpath_eval($xpath); 171 } 172 173 if (!$result) { 174 $n = array(); 175 return $n; 176 } 177 178 if (!$result->nodeset) { 179 $n = array(); 180 return $n; 181 } 182 183 return $result->nodeset; 184 } 185 186 function content($node) 187 { 188 if ($node) { 189 return $node->get_content(); 190 } 191 } 192 193 function attributes($node) 194 { 195 if ($node) { 196 $arr = $node->attributes(); 197 $result = array(); 198 199 if ($arr) { 200 foreach ($arr as $attrnode) { 201 $result[$attrnode->name] = $attrnode->value; 202 } 203 } 204 205 return $result; 206 } 207 } 208} 209 210/** 211 * This concrete implementation of Auth_Yadis_XMLParser implements 212 * the appropriate API for the 'dom' extension which is typically 213 * packaged with PHP 5. This class will be used whenever the 'dom' 214 * extension is detected. See the Auth_Yadis_XMLParser class for 215 * details on this class's methods. 216 * 217 * @package OpenID 218 */ 219class Auth_Yadis_dom extends Auth_Yadis_XMLParser { 220 function Auth_Yadis_dom() 221 { 222 $this->xml = null; 223 $this->doc = null; 224 $this->xpath = null; 225 $this->errors = array(); 226 } 227 228 function setXML($xml_string) 229 { 230 $this->xml = $xml_string; 231 $this->doc = new DOMDocument; 232 233 if (!$this->doc) { 234 return false; 235 } 236 237 if (!@$this->doc->loadXML($xml_string)) { 238 return false; 239 } 240 241 $this->xpath = new DOMXPath($this->doc); 242 243 if ($this->xpath) { 244 return true; 245 } else { 246 return false; 247 } 248 } 249 250 function registerNamespace($prefix, $uri) 251 { 252 return $this->xpath->registerNamespace($prefix, $uri); 253 } 254 255 function &evalXPath($xpath, $node = null) 256 { 257 if ($node) { 258 $result = @$this->xpath->query($xpath, $node); 259 } else { 260 $result = @$this->xpath->query($xpath); 261 } 262 263 $n = array(); 264 265 if (!$result) { 266 return $n; 267 } 268 269 for ($i = 0; $i < $result->length; $i++) { 270 $n[] = $result->item($i); 271 } 272 273 return $n; 274 } 275 276 function content($node) 277 { 278 if ($node) { 279 return $node->textContent; 280 } 281 } 282 283 function attributes($node) 284 { 285 if ($node) { 286 $arr = $node->attributes; 287 $result = array(); 288 289 if ($arr) { 290 for ($i = 0; $i < $arr->length; $i++) { 291 $node = $arr->item($i); 292 $result[$node->nodeName] = $node->nodeValue; 293 } 294 } 295 296 return $result; 297 } 298 } 299} 300 301global $__Auth_Yadis_defaultParser; 302$__Auth_Yadis_defaultParser = null; 303 304/** 305 * Set a default parser to override the extension-driven selection of 306 * available parser classes. This is helpful in a test environment or 307 * one in which multiple parsers can be used but one is more 308 * desirable. 309 * 310 * @param Auth_Yadis_XMLParser $parser An instance of a 311 * Auth_Yadis_XMLParser subclass. 312 */ 313function Auth_Yadis_setDefaultParser($parser) 314{ 315 global $__Auth_Yadis_defaultParser; 316 $__Auth_Yadis_defaultParser = $parser; 317} 318 319function Auth_Yadis_getSupportedExtensions() 320{ 321 return array('dom' => 'Auth_Yadis_dom', 322 'domxml' => 'Auth_Yadis_domxml'); 323} 324 325/** 326 * Returns an instance of a Auth_Yadis_XMLParser subclass based on 327 * the availability of PHP extensions for XML parsing. If 328 * Auth_Yadis_setDefaultParser has been called, the parser used in 329 * that call will be returned instead. 330 */ 331function Auth_Yadis_getXMLParser() 332{ 333 global $__Auth_Yadis_defaultParser; 334 335 if (isset($__Auth_Yadis_defaultParser)) { 336 return $__Auth_Yadis_defaultParser; 337 } 338 339 foreach(Auth_Yadis_getSupportedExtensions() as $extension => $classname) 340 { 341 if (extension_loaded($extension)) 342 { 343 $p = new $classname(); 344 Auth_Yadis_setDefaultParser($p); 345 return $p; 346 } 347 } 348 349 return false; 350} 351 352 353