[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/config/Symfony/Component/Config/Util/ -> XmlUtils.php (source)

   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  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1