1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeau/* 4*04fd306cSNickeau * This file is part of the Symfony package. 5*04fd306cSNickeau * 6*04fd306cSNickeau * (c) Fabien Potencier <fabien@symfony.com> 7*04fd306cSNickeau * 8*04fd306cSNickeau * For the full copyright and license information, please view the LICENSE 9*04fd306cSNickeau * file that was distributed with this source code. 10*04fd306cSNickeau */ 11*04fd306cSNickeau 12*04fd306cSNickeaunamespace Symfony\Component\Yaml; 13*04fd306cSNickeau 14*04fd306cSNickeauuse Symfony\Component\Yaml\Tag\TaggedValue; 15*04fd306cSNickeau 16*04fd306cSNickeau/** 17*04fd306cSNickeau * Dumper dumps PHP variables to YAML strings. 18*04fd306cSNickeau * 19*04fd306cSNickeau * @author Fabien Potencier <fabien@symfony.com> 20*04fd306cSNickeau * 21*04fd306cSNickeau * @final 22*04fd306cSNickeau */ 23*04fd306cSNickeauclass Dumper 24*04fd306cSNickeau{ 25*04fd306cSNickeau /** 26*04fd306cSNickeau * The amount of spaces to use for indentation of nested nodes. 27*04fd306cSNickeau * 28*04fd306cSNickeau * @var int 29*04fd306cSNickeau */ 30*04fd306cSNickeau protected $indentation; 31*04fd306cSNickeau 32*04fd306cSNickeau public function __construct(int $indentation = 4) 33*04fd306cSNickeau { 34*04fd306cSNickeau if ($indentation < 1) { 35*04fd306cSNickeau throw new \InvalidArgumentException('The indentation must be greater than zero.'); 36*04fd306cSNickeau } 37*04fd306cSNickeau 38*04fd306cSNickeau $this->indentation = $indentation; 39*04fd306cSNickeau } 40*04fd306cSNickeau 41*04fd306cSNickeau /** 42*04fd306cSNickeau * Dumps a PHP value to YAML. 43*04fd306cSNickeau * 44*04fd306cSNickeau * @param mixed $input The PHP value 45*04fd306cSNickeau * @param int $inline The level where you switch to inline YAML 46*04fd306cSNickeau * @param int $indent The level of indentation (used internally) 47*04fd306cSNickeau * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string 48*04fd306cSNickeau */ 49*04fd306cSNickeau public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): string 50*04fd306cSNickeau { 51*04fd306cSNickeau $output = ''; 52*04fd306cSNickeau $prefix = $indent ? str_repeat(' ', $indent) : ''; 53*04fd306cSNickeau $dumpObjectAsInlineMap = true; 54*04fd306cSNickeau 55*04fd306cSNickeau if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) { 56*04fd306cSNickeau $dumpObjectAsInlineMap = empty((array) $input); 57*04fd306cSNickeau } 58*04fd306cSNickeau 59*04fd306cSNickeau if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) { 60*04fd306cSNickeau $output .= $prefix.Inline::dump($input, $flags); 61*04fd306cSNickeau } elseif ($input instanceof TaggedValue) { 62*04fd306cSNickeau $output .= $this->dumpTaggedValue($input, $inline, $indent, $flags, $prefix); 63*04fd306cSNickeau } else { 64*04fd306cSNickeau $dumpAsMap = Inline::isHash($input); 65*04fd306cSNickeau 66*04fd306cSNickeau foreach ($input as $key => $value) { 67*04fd306cSNickeau if ('' !== $output && "\n" !== $output[-1]) { 68*04fd306cSNickeau $output .= "\n"; 69*04fd306cSNickeau } 70*04fd306cSNickeau 71*04fd306cSNickeau if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { 72*04fd306cSNickeau // If the first line starts with a space character, the spec requires a blockIndicationIndicator 73*04fd306cSNickeau // http://www.yaml.org/spec/1.2/spec.html#id2793979 74*04fd306cSNickeau $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : ''; 75*04fd306cSNickeau 76*04fd306cSNickeau if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) { 77*04fd306cSNickeau $blockChompingIndicator = '+'; 78*04fd306cSNickeau } elseif ("\n" === $value[-1]) { 79*04fd306cSNickeau $blockChompingIndicator = ''; 80*04fd306cSNickeau } else { 81*04fd306cSNickeau $blockChompingIndicator = '-'; 82*04fd306cSNickeau } 83*04fd306cSNickeau 84*04fd306cSNickeau $output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator); 85*04fd306cSNickeau 86*04fd306cSNickeau foreach (explode("\n", $value) as $row) { 87*04fd306cSNickeau if ('' === $row) { 88*04fd306cSNickeau $output .= "\n"; 89*04fd306cSNickeau } else { 90*04fd306cSNickeau $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); 91*04fd306cSNickeau } 92*04fd306cSNickeau } 93*04fd306cSNickeau 94*04fd306cSNickeau continue; 95*04fd306cSNickeau } 96*04fd306cSNickeau 97*04fd306cSNickeau if ($value instanceof TaggedValue) { 98*04fd306cSNickeau $output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag()); 99*04fd306cSNickeau 100*04fd306cSNickeau if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { 101*04fd306cSNickeau // If the first line starts with a space character, the spec requires a blockIndicationIndicator 102*04fd306cSNickeau // http://www.yaml.org/spec/1.2/spec.html#id2793979 103*04fd306cSNickeau $blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : ''; 104*04fd306cSNickeau $output .= sprintf(' |%s', $blockIndentationIndicator); 105*04fd306cSNickeau 106*04fd306cSNickeau foreach (explode("\n", $value->getValue()) as $row) { 107*04fd306cSNickeau $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); 108*04fd306cSNickeau } 109*04fd306cSNickeau 110*04fd306cSNickeau continue; 111*04fd306cSNickeau } 112*04fd306cSNickeau 113*04fd306cSNickeau if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) { 114*04fd306cSNickeau $output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n"; 115*04fd306cSNickeau } else { 116*04fd306cSNickeau $output .= "\n"; 117*04fd306cSNickeau $output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags); 118*04fd306cSNickeau } 119*04fd306cSNickeau 120*04fd306cSNickeau continue; 121*04fd306cSNickeau } 122*04fd306cSNickeau 123*04fd306cSNickeau $dumpObjectAsInlineMap = true; 124*04fd306cSNickeau 125*04fd306cSNickeau if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { 126*04fd306cSNickeau $dumpObjectAsInlineMap = empty((array) $value); 127*04fd306cSNickeau } 128*04fd306cSNickeau 129*04fd306cSNickeau $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); 130*04fd306cSNickeau 131*04fd306cSNickeau $output .= sprintf('%s%s%s%s', 132*04fd306cSNickeau $prefix, 133*04fd306cSNickeau $dumpAsMap ? Inline::dump($key, $flags).':' : '-', 134*04fd306cSNickeau $willBeInlined ? ' ' : "\n", 135*04fd306cSNickeau $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) 136*04fd306cSNickeau ).($willBeInlined ? "\n" : ''); 137*04fd306cSNickeau } 138*04fd306cSNickeau } 139*04fd306cSNickeau 140*04fd306cSNickeau return $output; 141*04fd306cSNickeau } 142*04fd306cSNickeau 143*04fd306cSNickeau private function dumpTaggedValue(TaggedValue $value, int $inline, int $indent, int $flags, string $prefix): string 144*04fd306cSNickeau { 145*04fd306cSNickeau $output = sprintf('%s!%s', $prefix ? $prefix.' ' : '', $value->getTag()); 146*04fd306cSNickeau 147*04fd306cSNickeau if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { 148*04fd306cSNickeau // If the first line starts with a space character, the spec requires a blockIndicationIndicator 149*04fd306cSNickeau // http://www.yaml.org/spec/1.2/spec.html#id2793979 150*04fd306cSNickeau $blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : ''; 151*04fd306cSNickeau $output .= sprintf(' |%s', $blockIndentationIndicator); 152*04fd306cSNickeau 153*04fd306cSNickeau foreach (explode("\n", $value->getValue()) as $row) { 154*04fd306cSNickeau $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); 155*04fd306cSNickeau } 156*04fd306cSNickeau 157*04fd306cSNickeau return $output; 158*04fd306cSNickeau } 159*04fd306cSNickeau 160*04fd306cSNickeau if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) { 161*04fd306cSNickeau return $output.' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n"; 162*04fd306cSNickeau } 163*04fd306cSNickeau 164*04fd306cSNickeau return $output."\n".$this->dump($value->getValue(), $inline - 1, $indent, $flags); 165*04fd306cSNickeau } 166*04fd306cSNickeau} 167