[ Index ] |
PHP Cross Reference of phpBB-3.1.12-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 $schemaOrCallable An XSD schema file path or callable 36 * 37 * @return \DOMDocument 38 * 39 * @throws \InvalidArgumentException When loading of XML file returns error 40 */ 41 public static function loadFile($file, $schemaOrCallable = null) 42 { 43 $content = @file_get_contents($file); 44 if ('' === trim($content)) { 45 throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file)); 46 } 47 48 $internalErrors = libxml_use_internal_errors(true); 49 $disableEntities = libxml_disable_entity_loader(true); 50 libxml_clear_errors(); 51 52 $dom = new \DOMDocument(); 53 $dom->validateOnParse = true; 54 if (!$dom->loadXML($content, LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { 55 libxml_disable_entity_loader($disableEntities); 56 57 throw new \InvalidArgumentException(implode("\n", static::getXmlErrors($internalErrors))); 58 } 59 60 $dom->normalizeDocument(); 61 62 libxml_use_internal_errors($internalErrors); 63 libxml_disable_entity_loader($disableEntities); 64 65 foreach ($dom->childNodes as $child) { 66 if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { 67 throw new \InvalidArgumentException('Document types are not allowed.'); 68 } 69 } 70 71 if (null !== $schemaOrCallable) { 72 $internalErrors = libxml_use_internal_errors(true); 73 libxml_clear_errors(); 74 75 $e = null; 76 if (is_callable($schemaOrCallable)) { 77 try { 78 $valid = call_user_func($schemaOrCallable, $dom, $internalErrors); 79 } catch (\Exception $e) { 80 $valid = false; 81 } 82 } elseif (!is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) { 83 $schemaSource = file_get_contents((string) $schemaOrCallable); 84 $valid = @$dom->schemaValidateSource($schemaSource); 85 } else { 86 libxml_use_internal_errors($internalErrors); 87 88 throw new \InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.'); 89 } 90 91 if (!$valid) { 92 $messages = static::getXmlErrors($internalErrors); 93 if (empty($messages)) { 94 $messages = array(sprintf('The XML file "%s" is not valid.', $file)); 95 } 96 throw new \InvalidArgumentException(implode("\n", $messages), 0, $e); 97 } 98 } 99 100 libxml_clear_errors(); 101 libxml_use_internal_errors($internalErrors); 102 103 return $dom; 104 } 105 106 /** 107 * Converts a \DomElement object to a PHP array. 108 * 109 * The following rules applies during the conversion: 110 * 111 * * Each tag is converted to a key value or an array 112 * if there is more than one "value" 113 * 114 * * The content of a tag is set under a "value" key (<foo>bar</foo>) 115 * if the tag also has some nested tags 116 * 117 * * The attributes are converted to keys (<foo foo="bar"/>) 118 * 119 * * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>) 120 * 121 * @param \DomElement $element A \DomElement instance 122 * @param bool $checkPrefix Check prefix in an element or an attribute name 123 * 124 * @return array A PHP array 125 */ 126 public static function convertDomElementToArray(\DomElement $element, $checkPrefix = true) 127 { 128 $prefix = (string) $element->prefix; 129 $empty = true; 130 $config = array(); 131 foreach ($element->attributes as $name => $node) { 132 if ($checkPrefix && !in_array((string) $node->prefix, array('', $prefix), true)) { 133 continue; 134 } 135 $config[$name] = static::phpize($node->value); 136 $empty = false; 137 } 138 139 $nodeValue = false; 140 foreach ($element->childNodes as $node) { 141 if ($node instanceof \DOMText) { 142 if ('' !== trim($node->nodeValue)) { 143 $nodeValue = trim($node->nodeValue); 144 $empty = false; 145 } 146 } elseif ($checkPrefix && $prefix != (string) $node->prefix) { 147 continue; 148 } elseif (!$node instanceof \DOMComment) { 149 $value = static::convertDomElementToArray($node, $checkPrefix); 150 151 $key = $node->localName; 152 if (isset($config[$key])) { 153 if (!is_array($config[$key]) || !is_int(key($config[$key]))) { 154 $config[$key] = array($config[$key]); 155 } 156 $config[$key][] = $value; 157 } else { 158 $config[$key] = $value; 159 } 160 161 $empty = false; 162 } 163 } 164 165 if (false !== $nodeValue) { 166 $value = static::phpize($nodeValue); 167 if (count($config)) { 168 $config['value'] = $value; 169 } else { 170 $config = $value; 171 } 172 } 173 174 return !$empty ? $config : null; 175 } 176 177 /** 178 * Converts an xml value to a PHP type. 179 * 180 * @param mixed $value 181 * 182 * @return mixed 183 */ 184 public static function phpize($value) 185 { 186 $value = (string) $value; 187 $lowercaseValue = strtolower($value); 188 189 switch (true) { 190 case 'null' === $lowercaseValue: 191 return; 192 case ctype_digit($value): 193 $raw = $value; 194 $cast = (int) $value; 195 196 return '0' == $value[0] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw); 197 case 'true' === $lowercaseValue: 198 return true; 199 case 'false' === $lowercaseValue: 200 return false; 201 case is_numeric($value): 202 return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value; 203 case preg_match('/^0x[0-9a-f]++$/i', $value): 204 return hexdec($value); 205 case preg_match('/^(-|\+)?[0-9]+(\.[0-9]+)?$/', $value): 206 return (float) $value; 207 default: 208 return $value; 209 } 210 } 211 212 protected static function getXmlErrors($internalErrors) 213 { 214 $errors = array(); 215 foreach (libxml_get_errors() as $error) { 216 $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', 217 LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', 218 $error->code, 219 trim($error->message), 220 $error->file ?: 'n/a', 221 $error->line, 222 $error->column 223 ); 224 } 225 226 libxml_clear_errors(); 227 libxml_use_internal_errors($internalErrors); 228 229 return $errors; 230 } 231 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |