Completed
Push — master ( 602f00...8ac133 )
by stéphane
07:27
created

Dumper::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Dallgoot\Yaml;
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
4
use Dallgoot\Yaml as Y;
5
use \SplDoublyLinkedList as DLL;
6
7
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
8
 *
9
 * @author  Stéphane Rebai <[email protected]>
10
 * @license Apache 2.0
11
 * @link    TODO : url to specific online doc
12
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
13
class Dumper //extends AnotherClass
14
{
15
    private const INDENT = 2;
16
    private const WIDTH = 120;
17
    private const OPTIONS = 00000;
18
19
    private static $result;
0 ignored issues
show
Coding Style introduced by
Private member variable "result" must be prefixed with an underscore
Loading history...
20
    private static $options;
0 ignored issues
show
Coding Style introduced by
Private member variable "options" must be prefixed with an underscore
Loading history...
21
    //options
22
    public const EXPAND_SHORT = 00001;
23
    public const SERIALIZE_CUSTOM_OBJECTS = 00010;
24
25
    // public function __construct(int $options = null)
26
    // {
27
    //     if (is_int($options)) self::$options = $options;
28
    // }
29
30
    /**
31
     * Returns the YAML representation as a string of the $dataType provided
32
     *
33
     * @param mixed    $dataType The data type
34
     * @param int|null $options  The options
35
     *
36
     * @throws \Exception datatype cannot be null
37
     *
38
     * @return string The Yaml string content
39
     */
40
    public static function toString($dataType, int $options = null):string
41
    {
42
        if (is_null($dataType)) throw new \Exception(self::class.": No content to convert to Yaml", 1);
43
        self::$options = is_int($options) ? $options : self::OPTIONS;
44
        self::$result = new DLL;
45
        if ($dataType instanceof YamlObject) {
46
            self::dumpYamlObject($dataType);
47
        } elseif (is_array($dataType) && $dataType[0] instanceof YamlObject) {
48
            array_map([self::class, 'dumpYamlObject'], $dataType);
49
        } else {
50
            self::dump($dataType, 0);
51
        }
52
        $out = implode("\n", iterator_to_array(self::$result));
53
        self::$result = null;
54
        return $out;
55
    }
56
57
    /**
58
     * Calls and saves the result of Dumper::toString to the file $filePath provided
59
     *
60
     * @param string   $filePath The file path
61
     * @param mixed    $dataType The data type
62
     * @param int|null $options  The options
63
     *
64
     * @return boolean  true = if the file has been correctly saved  (according to return from 'file_put_contents')
65
     */
66
    public static function toFile(string $filePath, $dataType, int $options = null):bool
67
    {
68
        return !is_bool(file_put_contents($filePath, self::toString($dataType, $options)));
69
    }
70
71
    private static function dump($dataType, int $indent)
0 ignored issues
show
Coding Style introduced by
Private method name "Dumper::dump" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
72
    {
73
        if (is_scalar($dataType)) {
74
            switch (gettype($dataType)) {
75
                case 'boolean': return $dataType ? 'true' : 'false';
0 ignored issues
show
Coding Style introduced by
Closing brace must be on a line by itself
Loading history...
76
                case 'float': if (is_infinite($dataType)) return $dataType > 0 ? '.inf' : '-.inf';
77
                              return sprintf('%.2F', $dataType);
0 ignored issues
show
Coding Style introduced by
Case breaking statement indented incorrectly; expected 20 spaces, found 30
Loading history...
78
                case 'double': if (is_nan((float) $dataType)) return '.nan';
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
79
                default:
80
                    return $dataType;
81
            }
82
        } elseif (is_object($dataType)) {
83
            self::dumpObject($dataType, $indent);
84
        } elseif (is_array($dataType)) {
85
            self::dumpSequence($dataType, $indent);
86
        }
87
    }
88
89
    private static function dumpYamlObject(YamlObject $dataType)
0 ignored issues
show
Coding Style introduced by
Private method name "Dumper::dumpYamlObject" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
90
    {
91
        self::$result->push("---");
92
        // self::dump($dataType, 0);
93
        if (count($dataType) > 0) {
94
            self::dumpSequence($dataType->getArrayCopy(), 0);
95
        } else {
96
            self::dumpObject($dataType, 0);
97
        }
98
        // self::insertComments($dataType->getComment());
99
        //TODO: $references = $dataType->getAllReferences();
100
    }
101
102
    private static function add($value, $indent)
0 ignored issues
show
Coding Style introduced by
Private method name "Dumper::add" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
103
    {
104
        $newVal = str_repeat(" ", $indent).$value;
105
        foreach (str_split($newVal, self::WIDTH) as $chunks) {
106
            self::$result->push($chunks);
107
        }
108
    }
109
110
    private static function dumpSequence(array $array, int $indent)
0 ignored issues
show
Coding Style introduced by
Private method name "Dumper::dumpSequence" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
111
    {
112
        $refKeys = range(0, count($array));
113
        foreach ($array as $key => $item) {
114
            $lineStart = current($refKeys) === $key ? "- " : "- $key: ";
115
            if (is_scalar($item)) {
116
                self::add($lineStart.$item, $indent);
117
            } else {
118
                self::add($lineStart, $indent);
119
                self::dump($item, $indent + self::INDENT);
120
            }
121
            next($refKeys);
122
        }
123
    }
124
125
    private static function insertComments(array $commentsArray)
0 ignored issues
show
Unused Code introduced by
The method insertComments() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
Coding Style introduced by
Private method name "Dumper::insertComments" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
126
    {
127
        foreach ($commentsArray as $lineNb => $comment) {
128
            self::$result->add($lineNb, $comment);
129
        }
130
    }
131
132
    private static function dumpObject(object $obj, int $indent)
0 ignored issues
show
Coding Style introduced by
Private method name "Dumper::dumpObject" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
133
    {
134
        if ($obj instanceof Tag) {
135
            if (is_scalar($obj->value)) {
136
                self::add("!".$obj->tagName.' '.$obj->value);
0 ignored issues
show
Bug introduced by
The call to Dallgoot\Yaml\Dumper::add() has too few arguments starting with indent. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

136
                self::/** @scrutinizer ignore-call */ 
137
                      add("!".$obj->tagName.' '.$obj->value);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
137
            } else {
138
                self::add("!".$obj->tagName);
139
                self::add(self::dump($obj->value, $indent + self::INDENT), $indent + self::INDENT);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::dump($obj->value, $indent + self::INDENT) targeting Dallgoot\Yaml\Dumper::dump() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
140
            }
141
        }
142
        if ($obj instanceof Compact) return self::dumpCompact($obj, $indent);
143
        //TODO:  consider dumping datetime as date strings according to a format provided by user or default
144
        if ($obj instanceof \DateTime) return $obj->format('Y-m-d');
145
        $propList = get_object_vars($obj);
146
        foreach ($propList as $property => $value) {
147
            if (is_scalar($value)) {
148
                self::add("$property: ".self::dump($value, $indent), $indent);
149
            } else {
150
                self::add("$property: ", $indent);
151
                self::add(self::dump($value, $indent + self::INDENT), $indent + self::INDENT);
152
            }
153
        }
154
    }
155
156
    public static function dumpCompact($subject, int $indent)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
157
    {
158
        $pairs = [];
159
        if (is_array($subject) || $subject instanceof \Countable) {
160
            $max = count($subject);
161
            $objectAsArray = is_array($subject) ? $subject : $subject->getArrayCopy();
0 ignored issues
show
Bug introduced by
The method getArrayCopy() does not exist on Countable. It seems like you code against a sub-type of Countable such as Nette\Utils\Finder or Nette\Utils\Html or Latte\Runtime\CachingIterator or Nette\Iterators\CachingIterator or Nette\Utils\ArrayList or ArrayObject or ArrayIterator or Symfony\Component\HttpKe...equestDataCollectorTest or Latte\Runtime\CachingIterator or Nette\Iterators\CachingIterator. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

161
            $objectAsArray = is_array($subject) ? $subject : $subject->/** @scrutinizer ignore-call */ getArrayCopy();
Loading history...
162
            if(array_keys($objectAsArray) !== range(0, $max)) {
0 ignored issues
show
Coding Style introduced by
Expected "if (...) {\n"; found "if(...) {\n"
Loading history...
163
                $pairs = $objectAsArray;
164
            } else {
165
                $valuesList = array_map([self, 'dump'], $objectAsArray, array_fill( 0 , $max , $indent ));
0 ignored issues
show
Bug introduced by
The constant self was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Coding Style introduced by
Space after opening parenthesis of function call prohibited
Loading history...
Coding Style introduced by
Expected 0 spaces before closing bracket; 1 found
Loading history...
Coding Style introduced by
Space found before comma in function call
Loading history...
166
                return '['.implode(', ', $valuesList).']';
167
            }
168
        } else {
169
            $pairs = get_object_vars($subject);
170
        }
171
        $content = [];
172
        foreach ($pairs as $key => $value) {
173
            if (is_scalar($value)) {
174
                $content[] = "$key: ".self::dump($value, $indent);
175
            } else {
176
                $content[] = "$key: ".self::dumpCompact($value, $indent);
177
            }
178
        }
179
        return '{'.implode(', ', $content).'}';
180
    }
181
}
182