[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/yaml/Symfony/Component/Yaml/ -> Parser.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\Yaml;
  13  
  14  use Symfony\Component\Yaml\Exception\ParseException;
  15  
  16  /**
  17   * Parser parses YAML strings to convert them to PHP arrays.
  18   *
  19   * @author Fabien Potencier <fabien@symfony.com>
  20   */
  21  class Parser
  22  {
  23      const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
  24      // BC - wrongly named
  25      const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN;
  26  
  27      private $offset = 0;
  28      private $totalNumberOfLines;
  29      private $lines = array();
  30      private $currentLineNb = -1;
  31      private $currentLine = '';
  32      private $refs = array();
  33  
  34      /**
  35       * Constructor.
  36       *
  37       * @param int      $offset             The offset of YAML document (used for line numbers in error messages)
  38       * @param int|null $totalNumberOfLines The overall number of lines being parsed
  39       */
  40      public function __construct($offset = 0, $totalNumberOfLines = null)
  41      {
  42          $this->offset = $offset;
  43          $this->totalNumberOfLines = $totalNumberOfLines;
  44      }
  45  
  46      /**
  47       * Parses a YAML string to a PHP value.
  48       *
  49       * @param string $value                  A YAML string
  50       * @param bool   $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  51       * @param bool   $objectSupport          true if object support is enabled, false otherwise
  52       *
  53       * @return mixed A PHP value
  54       *
  55       * @throws ParseException If the YAML is not valid
  56       */
  57      public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false)
  58      {
  59          if (!preg_match('//u', $value)) {
  60              throw new ParseException('The YAML value does not appear to be valid UTF-8.');
  61          }
  62          $this->currentLineNb = -1;
  63          $this->currentLine = '';
  64          $value = $this->cleanup($value);
  65          $this->lines = explode("\n", $value);
  66  
  67          if (null === $this->totalNumberOfLines) {
  68              $this->totalNumberOfLines = count($this->lines);
  69          }
  70  
  71          if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
  72              $mbEncoding = mb_internal_encoding();
  73              mb_internal_encoding('UTF-8');
  74          }
  75  
  76          $data = array();
  77          $context = null;
  78          while ($this->moveToNextLine()) {
  79              if ($this->isCurrentLineEmpty()) {
  80                  continue;
  81              }
  82  
  83              // tab?
  84              if ("\t" === $this->currentLine[0]) {
  85                  throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  86              }
  87  
  88              $isRef = $isInPlace = $isProcessed = false;
  89              if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
  90                  if ($context && 'mapping' == $context) {
  91                      throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  92                  }
  93                  $context = 'sequence';
  94  
  95                  if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
  96                      $isRef = $matches['ref'];
  97                      $values['value'] = $matches['value'];
  98                  }
  99  
 100                  // array
 101                  if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
 102                      $c = $this->getRealCurrentLineNb() + 1;
 103                      $parser = new self($c, $this->totalNumberOfLines);
 104                      $parser->refs = &$this->refs;
 105                      $data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport);
 106                  } else {
 107                      if (isset($values['leadspaces'])
 108                          && preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
 109                      ) {
 110                          // this is a compact notation element, add to next block and parse
 111                          $c = $this->getRealCurrentLineNb();
 112                          $parser = new self($c, $this->totalNumberOfLines);
 113                          $parser->refs = &$this->refs;
 114  
 115                          $block = $values['value'];
 116                          if ($this->isNextLineIndented()) {
 117                              $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
 118                          }
 119  
 120                          $data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport);
 121                      } else {
 122                          $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
 123                      }
 124                  }
 125                  if ($isRef) {
 126                      $this->refs[$isRef] = end($data);
 127                  }
 128              } elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
 129                  if ($context && 'sequence' == $context) {
 130                      throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine);
 131                  }
 132                  $context = 'mapping';
 133  
 134                  // force correct settings
 135                  Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $this->refs);
 136                  try {
 137                      $key = Inline::parseScalar($values['key']);
 138                  } catch (ParseException $e) {
 139                      $e->setParsedLine($this->getRealCurrentLineNb() + 1);
 140                      $e->setSnippet($this->currentLine);
 141  
 142                      throw $e;
 143                  }
 144  
 145                  // Convert float keys to strings, to avoid being converted to integers by PHP
 146                  if (is_float($key)) {
 147                      $key = (string) $key;
 148                  }
 149  
 150                  if ('<<' === $key) {
 151                      if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
 152                          $isInPlace = substr($values['value'], 1);
 153                          if (!array_key_exists($isInPlace, $this->refs)) {
 154                              throw new ParseException(sprintf('Reference "%s" does not exist.', $isInPlace), $this->getRealCurrentLineNb() + 1, $this->currentLine);
 155                          }
 156                      } else {
 157                          if (isset($values['value']) && $values['value'] !== '') {
 158                              $value = $values['value'];
 159                          } else {
 160                              $value = $this->getNextEmbedBlock();
 161                          }
 162                          $c = $this->getRealCurrentLineNb() + 1;
 163                          $parser = new self($c, $this->totalNumberOfLines);
 164                          $parser->refs = &$this->refs;
 165                          $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport);
 166  
 167                          $merged = array();
 168                          if (!is_array($parsed)) {
 169                              throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
 170                          } elseif (isset($parsed[0])) {
 171                              // Numeric array, merge individual elements
 172                              foreach (array_reverse($parsed) as $parsedItem) {
 173                                  if (!is_array($parsedItem)) {
 174                                      throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
 175                                  }
 176                                  $merged = array_merge($parsedItem, $merged);
 177                              }
 178                          } else {
 179                              // Associative array, merge
 180                              $merged = array_merge($merged, $parsed);
 181                          }
 182  
 183                          $isProcessed = $merged;
 184                      }
 185                  } elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
 186                      $isRef = $matches['ref'];
 187                      $values['value'] = $matches['value'];
 188                  }
 189  
 190                  if ($isProcessed) {
 191                      // Merge keys
 192                      $data = $isProcessed;
 193                  // hash
 194                  } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
 195                      // if next line is less indented or equal, then it means that the current value is null
 196                      if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
 197                          $data[$key] = null;
 198                      } else {
 199                          $c = $this->getRealCurrentLineNb() + 1;
 200                          $parser = new self($c, $this->totalNumberOfLines);
 201                          $parser->refs = &$this->refs;
 202                          $data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
 203                      }
 204                  } else {
 205                      if ($isInPlace) {
 206                          $data = $this->refs[$isInPlace];
 207                      } else {
 208                          $data[$key] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
 209                      }
 210                  }
 211                  if ($isRef) {
 212                      $this->refs[$isRef] = $data[$key];
 213                  }
 214              } else {
 215                  // multiple documents are not supported
 216                  if ('---' === $this->currentLine) {
 217                      throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine);
 218                  }
 219  
 220                  // 1-liner optionally followed by newline(s)
 221                  if ($this->lines[0] === trim($value)) {
 222                      try {
 223                          $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $this->refs);
 224                      } catch (ParseException $e) {
 225                          $e->setParsedLine($this->getRealCurrentLineNb() + 1);
 226                          $e->setSnippet($this->currentLine);
 227  
 228                          throw $e;
 229                      }
 230  
 231                      if (is_array($value)) {
 232                          $first = reset($value);
 233                          if (is_string($first) && 0 === strpos($first, '*')) {
 234                              $data = array();
 235                              foreach ($value as $alias) {
 236                                  $data[] = $this->refs[substr($alias, 1)];
 237                              }
 238                              $value = $data;
 239                          }
 240                      }
 241  
 242                      if (isset($mbEncoding)) {
 243                          mb_internal_encoding($mbEncoding);
 244                      }
 245  
 246                      return $value;
 247                  }
 248  
 249                  switch (preg_last_error()) {
 250                      case PREG_INTERNAL_ERROR:
 251                          $error = 'Internal PCRE error.';
 252                          break;
 253                      case PREG_BACKTRACK_LIMIT_ERROR:
 254                          $error = 'pcre.backtrack_limit reached.';
 255                          break;
 256                      case PREG_RECURSION_LIMIT_ERROR:
 257                          $error = 'pcre.recursion_limit reached.';
 258                          break;
 259                      case PREG_BAD_UTF8_ERROR:
 260                          $error = 'Malformed UTF-8 data.';
 261                          break;
 262                      case PREG_BAD_UTF8_OFFSET_ERROR:
 263                          $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
 264                          break;
 265                      default:
 266                          $error = 'Unable to parse.';
 267                  }
 268  
 269                  throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
 270              }
 271          }
 272  
 273          if (isset($mbEncoding)) {
 274              mb_internal_encoding($mbEncoding);
 275          }
 276  
 277          return empty($data) ? null : $data;
 278      }
 279  
 280      /**
 281       * Returns the current line number (takes the offset into account).
 282       *
 283       * @return int The current line number
 284       */
 285      private function getRealCurrentLineNb()
 286      {
 287          return $this->currentLineNb + $this->offset;
 288      }
 289  
 290      /**
 291       * Returns the current line indentation.
 292       *
 293       * @return int The current line indentation
 294       */
 295      private function getCurrentLineIndentation()
 296      {
 297          return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
 298      }
 299  
 300      /**
 301       * Returns the next embed block of YAML.
 302       *
 303       * @param int  $indentation The indent level at which the block is to be read, or null for default
 304       * @param bool $inSequence  True if the enclosing data structure is a sequence
 305       *
 306       * @return string A YAML string
 307       *
 308       * @throws ParseException When indentation problem are detected
 309       */
 310      private function getNextEmbedBlock($indentation = null, $inSequence = false)
 311      {
 312          $oldLineIndentation = $this->getCurrentLineIndentation();
 313          $blockScalarIndentations = array();
 314  
 315          if ($this->isBlockScalarHeader()) {
 316              $blockScalarIndentations[] = $this->getCurrentLineIndentation();
 317          }
 318  
 319          if (!$this->moveToNextLine()) {
 320              return;
 321          }
 322  
 323          if (null === $indentation) {
 324              $newIndent = $this->getCurrentLineIndentation();
 325  
 326              $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem();
 327  
 328              if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
 329                  throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
 330              }
 331          } else {
 332              $newIndent = $indentation;
 333          }
 334  
 335          $data = array();
 336          if ($this->getCurrentLineIndentation() >= $newIndent) {
 337              $data[] = substr($this->currentLine, $newIndent);
 338          } else {
 339              $this->moveToPreviousLine();
 340  
 341              return;
 342          }
 343  
 344          if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) {
 345              // the previous line contained a dash but no item content, this line is a sequence item with the same indentation
 346              // and therefore no nested list or mapping
 347              $this->moveToPreviousLine();
 348  
 349              return;
 350          }
 351  
 352          $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
 353  
 354          if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) {
 355              $blockScalarIndentations[] = $this->getCurrentLineIndentation();
 356          }
 357  
 358          $previousLineIndentation = $this->getCurrentLineIndentation();
 359  
 360          while ($this->moveToNextLine()) {
 361              $indent = $this->getCurrentLineIndentation();
 362  
 363              // terminate all block scalars that are more indented than the current line
 364              if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') {
 365                  foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
 366                      if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) {
 367                          unset($blockScalarIndentations[$key]);
 368                      }
 369                  }
 370              }
 371  
 372              if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) {
 373                  $blockScalarIndentations[] = $this->getCurrentLineIndentation();
 374              }
 375  
 376              $previousLineIndentation = $indent;
 377  
 378              if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
 379                  $this->moveToPreviousLine();
 380                  break;
 381              }
 382  
 383              if ($this->isCurrentLineBlank()) {
 384                  $data[] = substr($this->currentLine, $newIndent);
 385                  continue;
 386              }
 387  
 388              // we ignore "comment" lines only when we are not inside a scalar block
 389              if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) {
 390                  continue;
 391              }
 392  
 393              if ($indent >= $newIndent) {
 394                  $data[] = substr($this->currentLine, $newIndent);
 395              } elseif (0 == $indent) {
 396                  $this->moveToPreviousLine();
 397  
 398                  break;
 399              } else {
 400                  throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
 401              }
 402          }
 403  
 404          return implode("\n", $data);
 405      }
 406  
 407      /**
 408       * Moves the parser to the next line.
 409       *
 410       * @return bool
 411       */
 412      private function moveToNextLine()
 413      {
 414          if ($this->currentLineNb >= count($this->lines) - 1) {
 415              return false;
 416          }
 417  
 418          $this->currentLine = $this->lines[++$this->currentLineNb];
 419  
 420          return true;
 421      }
 422  
 423      /**
 424       * Moves the parser to the previous line.
 425       */
 426      private function moveToPreviousLine()
 427      {
 428          $this->currentLine = $this->lines[--$this->currentLineNb];
 429      }
 430  
 431      /**
 432       * Parses a YAML value.
 433       *
 434       * @param string $value                  A YAML value
 435       * @param bool   $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
 436       * @param bool   $objectSupport          True if object support is enabled, false otherwise
 437       *
 438       * @return mixed A PHP value
 439       *
 440       * @throws ParseException When reference does not exist
 441       */
 442      private function parseValue($value, $exceptionOnInvalidType, $objectSupport)
 443      {
 444          if (0 === strpos($value, '*')) {
 445              if (false !== $pos = strpos($value, '#')) {
 446                  $value = substr($value, 1, $pos - 2);
 447              } else {
 448                  $value = substr($value, 1);
 449              }
 450  
 451              if (!array_key_exists($value, $this->refs)) {
 452                  throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine);
 453              }
 454  
 455              return $this->refs[$value];
 456          }
 457  
 458          if (preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
 459              $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
 460  
 461              return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
 462          }
 463  
 464          try {
 465              return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $this->refs);
 466          } catch (ParseException $e) {
 467              $e->setParsedLine($this->getRealCurrentLineNb() + 1);
 468              $e->setSnippet($this->currentLine);
 469  
 470              throw $e;
 471          }
 472      }
 473  
 474      /**
 475       * Parses a block scalar.
 476       *
 477       * @param string $style       The style indicator that was used to begin this block scalar (| or >)
 478       * @param string $chomping    The chomping indicator that was used to begin this block scalar (+ or -)
 479       * @param int    $indentation The indentation indicator that was used to begin this block scalar
 480       *
 481       * @return string The text value
 482       */
 483      private function parseBlockScalar($style, $chomping = '', $indentation = 0)
 484      {
 485          $notEOF = $this->moveToNextLine();
 486          if (!$notEOF) {
 487              return '';
 488          }
 489  
 490          $isCurrentLineBlank = $this->isCurrentLineBlank();
 491          $blockLines = array();
 492  
 493          // leading blank lines are consumed before determining indentation
 494          while ($notEOF && $isCurrentLineBlank) {
 495              // newline only if not EOF
 496              if ($notEOF = $this->moveToNextLine()) {
 497                  $blockLines[] = '';
 498                  $isCurrentLineBlank = $this->isCurrentLineBlank();
 499              }
 500          }
 501  
 502          // determine indentation if not specified
 503          if (0 === $indentation) {
 504              if (preg_match('/^ +/', $this->currentLine, $matches)) {
 505                  $indentation = strlen($matches[0]);
 506              }
 507          }
 508  
 509          if ($indentation > 0) {
 510              $pattern = sprintf('/^ {%d}(.*)$/', $indentation);
 511  
 512              while (
 513                  $notEOF && (
 514                      $isCurrentLineBlank ||
 515                      preg_match($pattern, $this->currentLine, $matches)
 516                  )
 517              ) {
 518                  if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) {
 519                      $blockLines[] = substr($this->currentLine, $indentation);
 520                  } elseif ($isCurrentLineBlank) {
 521                      $blockLines[] = '';
 522                  } else {
 523                      $blockLines[] = $matches[1];
 524                  }
 525  
 526                  // newline only if not EOF
 527                  if ($notEOF = $this->moveToNextLine()) {
 528                      $isCurrentLineBlank = $this->isCurrentLineBlank();
 529                  }
 530              }
 531          } elseif ($notEOF) {
 532              $blockLines[] = '';
 533          }
 534  
 535          if ($notEOF) {
 536              $blockLines[] = '';
 537              $this->moveToPreviousLine();
 538          } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
 539              $blockLines[] = '';
 540          }
 541  
 542          // folded style
 543          if ('>' === $style) {
 544              $text = '';
 545              $previousLineIndented = false;
 546              $previousLineBlank = false;
 547  
 548              for ($i = 0; $i < count($blockLines); ++$i) {
 549                  if ('' === $blockLines[$i]) {
 550                      $text .= "\n";
 551                      $previousLineIndented = false;
 552                      $previousLineBlank = true;
 553                  } elseif (' ' === $blockLines[$i][0]) {
 554                      $text .= "\n".$blockLines[$i];
 555                      $previousLineIndented = true;
 556                      $previousLineBlank = false;
 557                  } elseif ($previousLineIndented) {
 558                      $text .= "\n".$blockLines[$i];
 559                      $previousLineIndented = false;
 560                      $previousLineBlank = false;
 561                  } elseif ($previousLineBlank || 0 === $i) {
 562                      $text .= $blockLines[$i];
 563                      $previousLineIndented = false;
 564                      $previousLineBlank = false;
 565                  } else {
 566                      $text .= ' '.$blockLines[$i];
 567                      $previousLineIndented = false;
 568                      $previousLineBlank = false;
 569                  }
 570              }
 571          } else {
 572              $text = implode("\n", $blockLines);
 573          }
 574  
 575          // deal with trailing newlines
 576          if ('' === $chomping) {
 577              $text = preg_replace('/\n+$/', "\n", $text);
 578          } elseif ('-' === $chomping) {
 579              $text = preg_replace('/\n+$/', '', $text);
 580          }
 581  
 582          return $text;
 583      }
 584  
 585      /**
 586       * Returns true if the next line is indented.
 587       *
 588       * @return bool Returns true if the next line is indented, false otherwise
 589       */
 590      private function isNextLineIndented()
 591      {
 592          $currentIndentation = $this->getCurrentLineIndentation();
 593          $EOF = !$this->moveToNextLine();
 594  
 595          while (!$EOF && $this->isCurrentLineEmpty()) {
 596              $EOF = !$this->moveToNextLine();
 597          }
 598  
 599          if ($EOF) {
 600              return false;
 601          }
 602  
 603          $ret = false;
 604          if ($this->getCurrentLineIndentation() > $currentIndentation) {
 605              $ret = true;
 606          }
 607  
 608          $this->moveToPreviousLine();
 609  
 610          return $ret;
 611      }
 612  
 613      /**
 614       * Returns true if the current line is blank or if it is a comment line.
 615       *
 616       * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
 617       */
 618      private function isCurrentLineEmpty()
 619      {
 620          return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
 621      }
 622  
 623      /**
 624       * Returns true if the current line is blank.
 625       *
 626       * @return bool Returns true if the current line is blank, false otherwise
 627       */
 628      private function isCurrentLineBlank()
 629      {
 630          return '' == trim($this->currentLine, ' ');
 631      }
 632  
 633      /**
 634       * Returns true if the current line is a comment line.
 635       *
 636       * @return bool Returns true if the current line is a comment line, false otherwise
 637       */
 638      private function isCurrentLineComment()
 639      {
 640          //checking explicitly the first char of the trim is faster than loops or strpos
 641          $ltrimmedLine = ltrim($this->currentLine, ' ');
 642  
 643          return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
 644      }
 645  
 646      private function isCurrentLineLastLineInDocument()
 647      {
 648          return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
 649      }
 650  
 651      /**
 652       * Cleanups a YAML string to be parsed.
 653       *
 654       * @param string $value The input YAML string
 655       *
 656       * @return string A cleaned up YAML string
 657       */
 658      private function cleanup($value)
 659      {
 660          $value = str_replace(array("\r\n", "\r"), "\n", $value);
 661  
 662          // strip YAML header
 663          $count = 0;
 664          $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
 665          $this->offset += $count;
 666  
 667          // remove leading comments
 668          $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
 669          if ($count == 1) {
 670              // items have been removed, update the offset
 671              $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
 672              $value = $trimmedValue;
 673          }
 674  
 675          // remove start of the document marker (---)
 676          $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
 677          if ($count == 1) {
 678              // items have been removed, update the offset
 679              $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
 680              $value = $trimmedValue;
 681  
 682              // remove end of the document marker (...)
 683              $value = preg_replace('#\.\.\.\s*$#', '', $value);
 684          }
 685  
 686          return $value;
 687      }
 688  
 689      /**
 690       * Returns true if the next line starts unindented collection.
 691       *
 692       * @return bool Returns true if the next line starts unindented collection, false otherwise
 693       */
 694      private function isNextLineUnIndentedCollection()
 695      {
 696          $currentIndentation = $this->getCurrentLineIndentation();
 697          $notEOF = $this->moveToNextLine();
 698  
 699          while ($notEOF && $this->isCurrentLineEmpty()) {
 700              $notEOF = $this->moveToNextLine();
 701          }
 702  
 703          if (false === $notEOF) {
 704              return false;
 705          }
 706  
 707          $ret = false;
 708          if (
 709              $this->getCurrentLineIndentation() == $currentIndentation
 710              &&
 711              $this->isStringUnIndentedCollectionItem()
 712          ) {
 713              $ret = true;
 714          }
 715  
 716          $this->moveToPreviousLine();
 717  
 718          return $ret;
 719      }
 720  
 721      /**
 722       * Returns true if the string is un-indented collection item.
 723       *
 724       * @return bool Returns true if the string is un-indented collection item, false otherwise
 725       */
 726      private function isStringUnIndentedCollectionItem()
 727      {
 728          return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
 729      }
 730  
 731      /**
 732       * Tests whether or not the current line is the header of a block scalar.
 733       *
 734       * @return bool
 735       */
 736      private function isBlockScalarHeader()
 737      {
 738          return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
 739      }
 740  }


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