Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Inline.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 20.79 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\Yaml;
 013   
 014  use Symfony\Component\Yaml\Exception\ParseException;
 015  use Symfony\Component\Yaml\Exception\DumpException;
 016   
 017  /**
 018   * Inline implements a YAML parser/dumper for the YAML inline syntax.
 019   *
 020   * @author Fabien Potencier <fabien@symfony.com>
 021   */
 022  class Inline
 023  {
 024      const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
 025   
 026      private static $exceptionOnInvalidType = false;
 027      private static $objectSupport = false;
 028      private static $objectForMap = false;
 029   
 030      /**
 031       * Converts a YAML string to a PHP value.
 032       *
 033       * @param string $value                  A YAML string
 034       * @param bool   $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
 035       * @param bool   $objectSupport          true if object support is enabled, false otherwise
 036       * @param bool   $objectForMap           true if maps should return a stdClass instead of array()
 037       * @param array  $references             Mapping of variable names to values
 038       *
 039       * @return mixed A PHP value
 040       *
 041       * @throws ParseException
 042       */
 043      public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
 044      {
 045          self::$exceptionOnInvalidType = $exceptionOnInvalidType;
 046          self::$objectSupport = $objectSupport;
 047          self::$objectForMap = $objectForMap;
 048   
 049          $value = trim($value);
 050   
 051          if ('' === $value) {
 052              return '';
 053          }
 054   
 055          if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
 056              $mbEncoding = mb_internal_encoding();
 057              mb_internal_encoding('ASCII');
 058          }
 059   
 060          $i = 0;
 061          switch ($value[0]) {
 062              case '[':
 063                  $result = self::parseSequence($value, $i, $references);
 064                  ++$i;
 065                  break;
 066              case '{':
 067                  $result = self::parseMapping($value, $i, $references);
 068                  ++$i;
 069                  break;
 070              default:
 071                  $result = self::parseScalar($value, null, array('"', "'"), $i, true, $references);
 072          }
 073   
 074          // some comments are allowed at the end
 075          if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
 076              throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
 077          }
 078   
 079          if (isset($mbEncoding)) {
 080              mb_internal_encoding($mbEncoding);
 081          }
 082   
 083          return $result;
 084      }
 085   
 086      /**
 087       * Dumps a given PHP variable to a YAML string.
 088       *
 089       * @param mixed $value                  The PHP variable to convert
 090       * @param bool  $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
 091       * @param bool  $objectSupport          true if object support is enabled, false otherwise
 092       *
 093       * @return string The YAML string representing the PHP value
 094       *
 095       * @throws DumpException When trying to dump PHP resource
 096       */
 097      public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false)
 098      {
 099          switch (true) {
 100              case is_resource($value):
 101                  if ($exceptionOnInvalidType) {
 102                      throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
 103                  }
 104   
 105                  return 'null';
 106              case is_object($value):
 107                  if ($objectSupport) {
 108                      return '!php/object:'.serialize($value);
 109                  }
 110   
 111                  if ($exceptionOnInvalidType) {
 112                      throw new DumpException('Object support when dumping a YAML file has been disabled.');
 113                  }
 114   
 115                  return 'null';
 116              case is_array($value):
 117                  return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport);
 118              case null === $value:
 119                  return 'null';
 120              case true === $value:
 121                  return 'true';
 122              case false === $value:
 123                  return 'false';
 124              case ctype_digit($value):
 125                  return is_string($value) ? "'$value'" : (int) $value;
 126              case is_numeric($value):
 127                  $locale = setlocale(LC_NUMERIC, 0);
 128                  if (false !== $locale) {
 129                      setlocale(LC_NUMERIC, 'C');
 130                  }
 131                  if (is_float($value)) {
 132                      $repr = (string) $value;
 133                      if (is_infinite($value)) {
 134                          $repr = str_ireplace('INF', '.Inf', $repr);
 135                      } elseif (floor($value) == $value && $repr == $value) {
 136                          // Preserve float data type since storing a whole number will result in integer value.
 137                          $repr = '!!float '.$repr;
 138                      }
 139                  } else {
 140                      $repr = is_string($value) ? "'$value'" : (string) $value;
 141                  }
 142                  if (false !== $locale) {
 143                      setlocale(LC_NUMERIC, $locale);
 144                  }
 145   
 146                  return $repr;
 147              case '' == $value:
 148                  return "''";
 149              case Escaper::requiresDoubleQuoting($value):
 150                  return Escaper::escapeWithDoubleQuotes($value);
 151              case Escaper::requiresSingleQuoting($value):
 152              case preg_match(self::getHexRegex(), $value):
 153              case preg_match(self::getTimestampRegex(), $value):
 154                  return Escaper::escapeWithSingleQuotes($value);
 155              default:
 156                  return $value;
 157          }
 158      }
 159   
 160      /**
 161       * Check if given array is hash or just normal indexed array.
 162       *
 163       * @internal
 164       *
 165       * @param array $value The PHP array to check
 166       *
 167       * @return bool true if value is hash array, false otherwise
 168       */
 169      public static function isHash(array $value)
 170      {
 171          $expectedKey = 0;
 172   
 173          foreach ($value as $key => $val) {
 174              if ($key !== $expectedKey++) {
 175                  return true;
 176              }
 177          }
 178   
 179          return false;
 180      }
 181   
 182      /**
 183       * Dumps a PHP array to a YAML string.
 184       *
 185       * @param array $value                  The PHP array to dump
 186       * @param bool  $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
 187       * @param bool  $objectSupport          true if object support is enabled, false otherwise
 188       *
 189       * @return string The YAML string representing the PHP array
 190       */
 191      private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
 192      {
 193          // array
 194          if ($value && !self::isHash($value)) {
 195              $output = array();
 196              foreach ($value as $val) {
 197                  $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
 198              }
 199   
 200              return sprintf('[%s]', implode(', ', $output));
 201          }
 202   
 203          // hash
 204          $output = array();
 205          foreach ($value as $key => $val) {
 206              $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
 207          }
 208   
 209          return sprintf('{ %s }', implode(', ', $output));
 210      }
 211   
 212      /**
 213       * Parses a YAML scalar.
 214       *
 215       * @param string $scalar
 216       * @param string $delimiters
 217       * @param array  $stringDelimiters
 218       * @param int    &$i
 219       * @param bool   $evaluate
 220       * @param array  $references
 221       *
 222       * @return string
 223       *
 224       * @throws ParseException When malformed inline YAML string is parsed
 225       *
 226       * @internal
 227       */
 228      public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array())
 229      {
 230          if (in_array($scalar[$i], $stringDelimiters)) {
 231              // quoted scalar
 232              $output = self::parseQuotedScalar($scalar, $i);
 233   
 234              if (null !== $delimiters) {
 235                  $tmp = ltrim(substr($scalar, $i), ' ');
 236                  if (!in_array($tmp[0], $delimiters)) {
 237                      throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)));
 238                  }
 239              }
 240          } else {
 241              // "normal" string
 242              if (!$delimiters) {
 243                  $output = substr($scalar, $i);
 244                  $i += strlen($output);
 245   
 246                  // remove comments
 247                  if (preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) {
 248                      $output = substr($output, 0, $match[0][1]);
 249                  }
 250              } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
 251                  $output = $match[1];
 252                  $i += strlen($output);
 253              } else {
 254                  throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar));
 255              }
 256   
 257              // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
 258              if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) {
 259                  @trigger_error(sprintf('Not quoting the scalar "%s" starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output, $output[0]), E_USER_DEPRECATED);
 260   
 261                  // to be thrown in 3.0
 262                  // throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]));
 263              }
 264   
 265              if ($evaluate) {
 266                  $output = self::evaluateScalar($output, $references);
 267              }
 268          }
 269   
 270          return $output;
 271      }
 272   
 273      /**
 274       * Parses a YAML quoted scalar.
 275       *
 276       * @param string $scalar
 277       * @param int    &$i
 278       *
 279       * @return string
 280       *
 281       * @throws ParseException When malformed inline YAML string is parsed
 282       */
 283      private static function parseQuotedScalar($scalar, &$i)
 284      {
 285          if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
 286              throw new ParseException(sprintf('Malformed inline YAML string: %s.', substr($scalar, $i)));
 287          }
 288   
 289          $output = substr($match[0], 1, strlen($match[0]) - 2);
 290   
 291          $unescaper = new Unescaper();
 292          if ('"' == $scalar[$i]) {
 293              $output = $unescaper->unescapeDoubleQuotedString($output);
 294          } else {
 295              $output = $unescaper->unescapeSingleQuotedString($output);
 296          }
 297   
 298          $i += strlen($match[0]);
 299   
 300          return $output;
 301      }
 302   
 303      /**
 304       * Parses a YAML sequence.
 305       *
 306       * @param string $sequence
 307       * @param int    &$i
 308       * @param array  $references
 309       *
 310       * @return array
 311       *
 312       * @throws ParseException When malformed inline YAML string is parsed
 313       */
 314      private static function parseSequence($sequence, &$i = 0, $references = array())
 315      {
 316          $output = array();
 317          $len = strlen($sequence);
 318          ++$i;
 319   
 320          // [foo, bar, ...]
 321          while ($i < $len) {
 322              switch ($sequence[$i]) {
 323                  case '[':
 324                      // nested sequence
 325                      $output[] = self::parseSequence($sequence, $i, $references);
 326                      break;
 327                  case '{':
 328                      // nested mapping
 329                      $output[] = self::parseMapping($sequence, $i, $references);
 330                      break;
 331                  case ']':
 332                      return $output;
 333                  case ',':
 334                  case ' ':
 335                      break;
 336                  default:
 337                      $isQuoted = in_array($sequence[$i], array('"', "'"));
 338                      $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references);
 339   
 340                      // the value can be an array if a reference has been resolved to an array var
 341                      if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) {
 342                          // embedded mapping?
 343                          try {
 344                              $pos = 0;
 345                              $value = self::parseMapping('{'.$value.'}', $pos, $references);
 346                          } catch (\InvalidArgumentException $e) {
 347                              // no, it's not
 348                          }
 349                      }
 350   
 351                      $output[] = $value;
 352   
 353                      --$i;
 354              }
 355   
 356              ++$i;
 357          }
 358   
 359          throw new ParseException(sprintf('Malformed inline YAML string: %s.', $sequence));
 360      }
 361   
 362      /**
 363       * Parses a YAML mapping.
 364       *
 365       * @param string $mapping
 366       * @param int    &$i
 367       * @param array  $references
 368       *
 369       * @return array|\stdClass
 370       *
 371       * @throws ParseException When malformed inline YAML string is parsed
 372       */
 373      private static function parseMapping($mapping, &$i = 0, $references = array())
 374      {
 375          $output = array();
 376          $len = strlen($mapping);
 377          ++$i;
 378   
 379          // {foo: bar, bar:foo, ...}
 380          while ($i < $len) {
 381              switch ($mapping[$i]) {
 382                  case ' ':
 383                  case ',':
 384                      ++$i;
 385                      continue 2;
 386                  case '}':
 387                      if (self::$objectForMap) {
 388                          return (object) $output;
 389                      }
 390   
 391                      return $output;
 392              }
 393   
 394              // key
 395              $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
 396   
 397              // value
 398              $done = false;
 399   
 400              while ($i < $len) {
 401                  switch ($mapping[$i]) {
 402                      case '[':
 403                          // nested sequence
 404                          $value = self::parseSequence($mapping, $i, $references);
 405                          // Spec: Keys MUST be unique; first one wins.
 406                          // Parser cannot abort this mapping earlier, since lines
 407                          // are processed sequentially.
 408                          if (!isset($output[$key])) {
 409                              $output[$key] = $value;
 410                          }
 411                          $done = true;
 412                          break;
 413                      case '{':
 414                          // nested mapping
 415                          $value = self::parseMapping($mapping, $i, $references);
 416                          // Spec: Keys MUST be unique; first one wins.
 417                          // Parser cannot abort this mapping earlier, since lines
 418                          // are processed sequentially.
 419                          if (!isset($output[$key])) {
 420                              $output[$key] = $value;
 421                          }
 422                          $done = true;
 423                          break;
 424                      case ':':
 425                      case ' ':
 426                          break;
 427                      default:
 428                          $value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references);
 429                          // Spec: Keys MUST be unique; first one wins.
 430                          // Parser cannot abort this mapping earlier, since lines
 431                          // are processed sequentially.
 432                          if (!isset($output[$key])) {
 433                              $output[$key] = $value;
 434                          }
 435                          $done = true;
 436                          --$i;
 437                  }
 438   
 439                  ++$i;
 440   
 441                  if ($done) {
 442                      continue 2;
 443                  }
 444              }
 445          }
 446   
 447          throw new ParseException(sprintf('Malformed inline YAML string: %s.', $mapping));
 448      }
 449   
 450      /**
 451       * Evaluates scalars and replaces magic values.
 452       *
 453       * @param string $scalar
 454       * @param array  $references
 455       *
 456       * @return string A YAML string
 457       *
 458       * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
 459       */
 460      private static function evaluateScalar($scalar, $references = array())
 461      {
 462          $scalar = trim($scalar);
 463          $scalarLower = strtolower($scalar);
 464   
 465          if (0 === strpos($scalar, '*')) {
 466              if (false !== $pos = strpos($scalar, '#')) {
 467                  $value = substr($scalar, 1, $pos - 2);
 468              } else {
 469                  $value = substr($scalar, 1);
 470              }
 471   
 472              // an unquoted *
 473              if (false === $value || '' === $value) {
 474                  throw new ParseException('A reference must contain at least one character.');
 475              }
 476   
 477              if (!array_key_exists($value, $references)) {
 478                  throw new ParseException(sprintf('Reference "%s" does not exist.', $value));
 479              }
 480   
 481              return $references[$value];
 482          }
 483   
 484          switch (true) {
 485              case 'null' === $scalarLower:
 486              case '' === $scalar:
 487              case '~' === $scalar:
 488                  return;
 489              case 'true' === $scalarLower:
 490                  return true;
 491              case 'false' === $scalarLower:
 492                  return false;
 493              // Optimise for returning strings.
 494              case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
 495                  switch (true) {
 496                      case 0 === strpos($scalar, '!str'):
 497                          return (string) substr($scalar, 5);
 498                      case 0 === strpos($scalar, '! '):
 499                          return (int) self::parseScalar(substr($scalar, 2));
 500                      case 0 === strpos($scalar, '!php/object:'):
 501                          if (self::$objectSupport) {
 502                              return unserialize(substr($scalar, 12));
 503                          }
 504   
 505                          if (self::$exceptionOnInvalidType) {
 506                              throw new ParseException('Object support when parsing a YAML file has been disabled.');
 507                          }
 508   
 509                          return;
 510                      case 0 === strpos($scalar, '!!php/object:'):
 511                          if (self::$objectSupport) {
 512                              return unserialize(substr($scalar, 13));
 513                          }
 514   
 515                          if (self::$exceptionOnInvalidType) {
 516                              throw new ParseException('Object support when parsing a YAML file has been disabled.');
 517                          }
 518   
 519                          return;
 520                      case 0 === strpos($scalar, '!!float '):
 521                          return (float) substr($scalar, 8);
 522                      case ctype_digit($scalar):
 523                          $raw = $scalar;
 524                          $cast = (int) $scalar;
 525   
 526                          return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
 527                      case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
 528                          $raw = $scalar;
 529                          $cast = (int) $scalar;
 530   
 531                          return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
 532                      case is_numeric($scalar):
 533                      case preg_match(self::getHexRegex(), $scalar):
 534                          return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
 535                      case '.inf' === $scalarLower:
 536                      case '.nan' === $scalarLower:
 537                          return -log(0);
 538                      case '-.inf' === $scalarLower:
 539                          return log(0);
 540                      case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
 541                          return (float) str_replace(',', '', $scalar);
 542                      case preg_match(self::getTimestampRegex(), $scalar):
 543                          $timeZone = date_default_timezone_get();
 544                          date_default_timezone_set('UTC');
 545                          $time = strtotime($scalar);
 546                          date_default_timezone_set($timeZone);
 547   
 548                          return $time;
 549                  }
 550              default:
 551                  return (string) $scalar;
 552          }
 553      }
 554   
 555      /**
 556       * Gets a regex that matches a YAML date.
 557       *
 558       * @return string The regular expression
 559       *
 560       * @see http://www.yaml.org/spec/1.2/spec.html#id2761573
 561       */
 562      private static function getTimestampRegex()
 563      {
 564          return <<<EOF
 565          ~^
 566          (?P<year>[0-9][0-9][0-9][0-9])
 567          -(?P<month>[0-9][0-9]?)
 568          -(?P<day>[0-9][0-9]?)
 569          (?:(?:[Tt]|[ \t]+)
 570          (?P<hour>[0-9][0-9]?)
 571          :(?P<minute>[0-9][0-9])
 572          :(?P<second>[0-9][0-9])
 573          (?:\.(?P<fraction>[0-9]*))?
 574          (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
 575          (?::(?P<tz_minute>[0-9][0-9]))?))?)?
 576          $~x
 577  EOF;
 578   
 579      }
 580   
 581      /**
 582       * Gets a regex that matches a YAML number in hexadecimal notation.
 583       *
 584       * @return string
 585       */
 586      private static function getHexRegex()
 587      {
 588          return '~^0x[0-9a-f]++$~i';
 589      }
 590  }
 591