[ 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\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 }
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 |