DumperHandlers::dumpObject()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1.125

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 7
ccs 3
cts 6
cp 0.5
rs 10
cc 1
nc 1
nop 4
crap 1.125
1
<?php
2
3
namespace Dallgoot\Yaml;
4
5
use Dallgoot\Yaml\Dumper;
6
use Dallgoot\Yaml\Types\YamlObject;
7
use Dallgoot\Yaml\Types\Compact;
8
use Dallgoot\Yaml\Types\Tagged;
9
10
/**
11
 *  Convert PHP datatypes to a YAML string syntax
12
 *
13
 * @author  Stéphane Rebai <[email protected]>
14
 * @license Apache 2.0
15
 * @link    https://github.com/dallgoot/yaml
16
 */
17
class DumperHandlers
18
{
19
    private $dumper;
20
21 6
    public function __construct(Dumper $dumper)
22
    {
23 6
        $this->dumper = $dumper;
24
    }
25
26
27 3
    public function dumpScalar($dataType): string
28
    {
29 3
        if ($dataType === \INF) return '.inf';
30 3
        if ($dataType === -\INF) return '-.inf';
31 3
        $precision = "%." . $this->dumper->floatPrecision . "F";
32 3
        switch (gettype($dataType)) {
33 3
            case 'boolean':
34 1
                return $dataType ? 'true' : 'false';
35 3
            case 'float': //fall through
36 3
            case 'double':
37 1
                return is_nan((float) $dataType) ? '.nan' : sprintf($precision, $dataType);
38
        }
39 2
        return $this->dumpString($dataType);
40
    }
41
42
43
    // public function dumpCompound($compound, int $indent, bool $compact=false): string
44
    // {
45
    //     if ($compact) {
46
    //         return $this->dumpCompact($compound, $indent);
47
    //     } else {
48
    //         if (is_array($compound)) {
49
    //             if (isset($compound[0]) && $compound[0] instanceof YamlObject) {
50
    //                 return $this->dumper->dumpMultiDoc($compound);
51
    //             }
52
    //             $keyMask = '-';
53
    //             $refKeys = range(0, count($compound) - 1);
54
    //             if (array_keys($compound) !== $refKeys) {
55
    //                 $keyMask = '%s:';
56
    //             }
57
    //             return $this->dumper->iteratorToString($compound, $keyMask, "\n", $indent);
58
    //         } elseif (is_object($compound) && !is_callable($compound)) {
59
    //             return $this->dumpObject($compound, $indent);
60
    //         }
61
    //     }
62
    //     throw new \Exception("Dumping Callable|Resource is not currently supported", 1);
63
    // }
64
65 1
    public function dumpObject(object $object, int $indent, bool $isCompact = false, bool $isRoot = false): string
66
    {
67 1
        return match ($object::class) {
68
            Compact::class => $this->dumpCompact($object, $indent),
69
            Tagged::class => $this->dumpTagged($object, $indent),
70
            \DateTime::class => $this->dumpDateTime($object),
71 1
            default => $this->_object($object, $indent, $isCompact, $isRoot),
72 1
        };
73
    }
74
75
76 1
    public function dumpCompact(Compact $compact, int $indent, bool $isRoot = false)
77
    {
78 1
        $arr = $compact->getArrayCopy();
79 1
        if (count(get_object_vars($compact)) === 0) {
80 1
            return $this->dumpArray($arr, $indent, true);
81
        }
82
        return $this->_objectCompact($compact, $indent, $isRoot);
83
    }
84
85
86 1
    public function _object(object $o, int $indent, bool $isCompact = false, $isRoot = false): string
87
    {
88 1
        return $isCompact ? $this->_objectCompact($o, $indent, $isRoot)
89 1
                          : $this->_objectStd($o, $indent, false, $isRoot);
90
    }
91
92
93
    public function _objectStd(object $o, int $indent, bool $isCompact = false, bool $isRoot = false)
94
    {
95
        $pairs = [''];
96
        $realIndent = $indent + Dumper::INDENT;
97
        if($isRoot) {
98
            $pairs = [];
99
            $realIndent = 0;
100
        }
101
        foreach (get_object_vars($o) as $key => $value) {
102
            $dumpedValue = $this->dumper->dump($value, $realIndent, $value instanceof Compact, false);
103
            $pairs[] = sprintf("%s%s: %s", str_repeat(' ', $realIndent), $key, $dumpedValue);
104
        }
105
        return implode(PHP_EOL, $pairs);
106
    }
107
108
109 1
    public function _objectCompact(object $o, int $indent, bool $isRoot = false)
110
    {
111 1
        $pairs = [];
112 1
        foreach ($o as $key => $value) {
113 1
            $pairs[] = "$key: " . $this->dumper->dump($value, 0, true, false);
114
        }
115 1
        return '{'. implode(', ', $pairs) . '}';
116
    }
117
118
119 2
    public function dumpArray(array $a, int $indent, bool $isCompact = false, $isRoot = false): string
120
    {
121 2
        if(isset($a[0]) && $a[0] instanceof YamlObject) {
122
            return $this->dumper->dumpMultiDoc($a);
123
        }
124 2
        if (array_keys($a) !== range(0, count($a) - 1)) {
125 1
            return $this->_object((object) $a, $indent, $isCompact, $isRoot);
126
        }
127 2
        return $isCompact ? $this->_dumpCompactArray($a, $indent)
128 2
                          : $this->_dumpNativeArray($a, $indent, $isRoot);
129
    }
130
131
132 1
    public function _dumpNativeArray(array $a, int $indent, $isRoot = false): string
133
    {
134 1
        $pairs = [''];
135 1
        $realIndent = $indent + Dumper::INDENT;
136 1
        if($isRoot) {
137
            $pairs = [];
138
            $realIndent = 0;
139
        }
140 1
        foreach ($a as $value) {
141 1
            $dumpedValue = $this->dumper->dump($value, 0, $value instanceof Compact, false);
0 ignored issues
show
Unused Code introduced by
The assignment to $dumpedValue is dead and can be removed.
Loading history...
142
            // TODO : seems ok but make tests to double check : fixed by PR from Delkano
143 1
            $dumpedValue = $this->dumper->dump($value, $realIndent, $value instanceof Compact, false);
144 1
            $pairs[] = sprintf("%s- %s", str_repeat(' ', $realIndent), $dumpedValue);
145
        }
146 1
        return implode(PHP_EOL, $pairs);
147
    }
148
149
150 1
    public function _dumpCompactArray(array $a, int $indent): string
151
    {
152 1
        $pairs = [];
153 1
        foreach ($a as $value) {
154 1
            $pairs[] = $this->dumper->dump($value, $indent, true);
155
        }
156 1
        return '[' . implode(', ', $pairs) . ']';
157
    }
158
159
160
    public function dumpDateTime(\DateTime $datetime): string
161
    {
162
        return $datetime->format($this->dumper::DATE_FORMAT);
163
    }
164
165
    
166
    /**
167
     * Dumps a string. Protects it if needed
168
     *
169
     * @param      string  $str    The string
170
     *
171
     * @return     string  ( description_of_the_return_value )
172
     * @todo   implements checking and protection function
173
     */
174 3
    public function dumpString(string $str): string
175
    {
176
        //those characters must be escaped : - : ? { } [ ] # , & * ! > | ' " %
177
        // The “@” (#x40, at) and “`” (#x60, grave accent) are reserved for future use.
178
        // 5.4. Line Break Characters
179
        // Example 5.13. Escaped Characters
180
181 3
        $str = json_encode(ltrim($str));
182 3
        return strspn(substr($str, 1, -1), "-:?{}[]#,&*!>|'\"%") > 0 ? $str : trim($str, '"');
183
    }
184
185
    //TODO : handle 'php/object'
186 1
    public function dumpTagged(Tagged $obj, int $indent): string
187
    {
188 1
        $separator = "\n";
189 1
        $isCompact = $obj->value instanceof Compact;
190 1
        if (is_scalar($obj->value) || $isCompact) {
191 1
            $separator   = ' ';
192
        }
193 1
        return ($obj->tagName) . $separator . $this->dumper->dump($obj->value, $indent, $isCompact);
194
    }
195
196
197
}
198