[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\Config\Util; 13 14 /** 15 * XMLUtils is a bunch of utility methods to XML operations. 16 * 17 * This class contains static methods only and is not meant to be instantiated. 18 * 19 * @author Fabien Potencier <fabien@symfony.com> 20 * @author Martin HasoĊ <martin.hason@gmail.com> 21 */ 22 class XmlUtils 23 { 24 /** 25 * This class should not be instantiated. 26 */ 27 private function __construct() 28 { 29 } 30 31 /** 32 * Loads an XML file. 33 * 34 * @param string $file An XML file path 35 * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation 36 * 37 * @return \DOMDocument 38 * 39 * @throws \InvalidArgumentException When loading of XML file returns error 40 * @throws \RuntimeException When DOM extension is missing 41 */ 42 public static function loadFile($file, $schemaOrCallable = null) 43 { 44 if (!\extension_loaded('dom')) { 45 throw new \RuntimeException('Extension DOM is required.'); 46 } 47 48 $content = @file_get_contents($file); 49 if ('' === trim($content)) { 50 throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file)); 51 } 52 53 $internalErrors = libxml_use_internal_errors(true); 54 $disableEntities = libxml_disable_entity_loader(true); 55 libxml_clear_errors(); 56 57 $dom = new \DOMDocument(); 58 $dom->validateOnParse = true; 59 if (!$dom->loadXML($content, LIBXML_NONET | (\defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { 60 libxml_disable_entity_loader($disableEntities); 61 62 throw new \InvalidArgumentException(implode("\n", static::getXmlErrors($internalErrors))); 63 } 64 65 $dom->normalizeDocument(); 66 67 libxml_use_internal_errors($internalErrors); 68 libxml_disable_entity_loader($disableEntities); 69 70 foreach ($dom->childNodes as $child) { 71 if (XML_DOCUMENT_TYPE_NODE === $child->nodeType) { 72 throw new \InvalidArgumentException('Document types are not allowed.'); 73 } 74 } 75 76 if (null !== $schemaOrCallable) { 77 $internalErrors = libxml_use_internal_errors(true); 78 libxml_clear_errors(); 79 80 $e = null; 81 if (\is_callable($schemaOrCallable)) { 82 try { 83 $valid = \call_user_func($schemaOrCallable, $dom, $internalErrors); 84 } catch (\Exception $e) { 85 $valid = false; 86 } 87 } elseif (!\is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) { 88 $schemaSource = file_get_contents((string) $schemaOrCallable); 89 $valid = @$dom->schemaValidateSource($schemaSource); 90 } else { 91 libxml_use_internal_errors($internalErrors); 92 93 throw new \InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.'); 94 } 95 96 if (!$valid) { 97 $messages = static::getXmlErrors($internalErrors); 98 if (empty($messages)) { 99 $messages = array(sprintf('The XML file "%s" is not valid.', $file)); 100 } 101 throw new \InvalidArgumentException(implode("\n", $messages), 0, $e); 102 } 103 } 104 105 libxml_clear_errors(); 106 libxml_use_internal_errors($internalErrors); 107 108 return $dom; 109 } 110 111 /** 112 * Converts a \DOMElement object to a PHP array. 113 * 114 * The following rules applies during the conversion: 115 * 116 * * Each tag is converted to a key value or an array 117 * if there is more than one "value" 118 * 119 * * The content of a tag is set under a "value" key (<foo>bar</foo>) 120 * if the tag also has some nested tags 121 * 122 * * The attributes are converted to keys (<foo foo="bar"/>) 123 * 124 * * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>) 125 * 126 * @param \DOMElement $element A \DOMElement instance 127 * @param bool $checkPrefix Check prefix in an element or an attribute name 128 * 129 * @return array A PHP array 130 */ 131 public static function convertDomElementToArray(\DOMElement $element, $checkPrefix = true) 132 { 133 $prefix = (string) $element->prefix; 134 $empty = true; 135 $config = array(); 136 foreach ($element->attributes as $name => $node) { 137 if ($checkPrefix && !\in_array((string) $node->prefix, array('', $prefix), true)) { 138 continue; 139 } 140 $config[$name] = static::phpize($node->value); 141 $empty = false; 142 } 143 144 $nodeValue = false; 145 foreach ($element->childNodes as $node) { 146 if ($node instanceof \DOMText) { 147 if ('' !== trim($node->nodeValue)) { 148 $nodeValue = trim($node->nodeValue); 149 $empty = false; 150 } 151 } elseif ($checkPrefix && $prefix != (string) $node->prefix) { 152 continue; 153 } elseif (!$node instanceof \DOMComment) { 154 $value = static::convertDomElementToArray($node, $checkPrefix); 155 156 $key = $node->localName; 157 if (isset($config[$key])) { 158 if (!\is_array($config[$key]) || !\is_int(key($config[$key]))) { 159 $config[$key] = array($config[$key]); 160 } 161 $config[$key][] = $value; 162 } else { 163 $config[$key] = $value; 164 } 165 166 $empty = false; 167 } 168 } 169 170 if (false !== $nodeValue) { 171 $value = static::phpize($nodeValue); 172 if (\count($config)) { 173 $config['value'] = $value; 174 } else { 175 $config = $value; 176 } 177 } 178 179 return !$empty ? $config : null; 180 } 181 182 /** 183 * Converts an xml value to a PHP type. 184 * 185 * @param mixed $value 186 * 187 * @return mixed 188 */ 189 public static function phpize($value) 190 { 191 $value = (string) $value; 192 $lowercaseValue = strtolower($value); 193 194 switch (true) { 195 case 'null' === $lowercaseValue: 196 return; 197 case ctype_digit($value): 198 $raw = $value; 199 $cast = (int) $value; 200 201 return '0' == $value[0] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw); 202 case isset($value[1]) && '-' === $value[0] && ctype_digit(substr($value, 1)): 203 $raw = $value; 204 $cast = (int) $value; 205 206 return '0' == $value[1] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw); 207 case 'true' === $lowercaseValue: 208 return true; 209 case 'false' === $lowercaseValue: 210 return false; 211 case isset($value[1]) && '0b' == $value[0].$value[1]: 212 return bindec($value); 213 case is_numeric($value): 214 return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value; 215 case preg_match('/^0x[0-9a-f]++$/i', $value): 216 return hexdec($value); 217 case preg_match('/^(-|\+)?[0-9]+(\.[0-9]+)?$/', $value): 218 return (float) $value; 219 default: 220 return $value; 221 } 222 } 223 224 protected static function getXmlErrors($internalErrors) 225 { 226 $errors = array(); 227 foreach (libxml_get_errors() as $error) { 228 $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', 229 LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', 230 $error->code, 231 trim($error->message), 232 $error->file ?: 'n/a', 233 $error->line, 234 $error->column 235 ); 236 } 237 238 libxml_clear_errors(); 239 libxml_use_internal_errors($internalErrors); 240 241 return $errors; 242 } 243 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |