Completed
Push — master ( c7418d...8b4244 )
by stéphane
04:44
created

Dumper   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 85
dl 0
loc 171
rs 8.96
c 0
b 0
f 0
wmc 43

9 Methods

Rating   Name   Duplication   Size   Complexity  
A toString() 0 15 6
A add() 0 5 2
B dump() 0 15 11
A toFile() 0 3 1
B dumpObject() 0 21 7
A dumpSequence() 0 12 4
A dumpYamlObject() 0 8 3
A insertComments() 0 4 2
B dumpCompact() 0 24 7

How to fix   Complexity   

Complex Class

Complex classes like Dumper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Dumper, and based on these observations, apply Extract Interface, too.

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
    /** @var null|NodeList */
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
20
    private static $result;
0 ignored issues
show
Coding Style introduced by
Private member variable "result" must be prefixed with an underscore
Loading history...
21
    private static $options;
0 ignored issues
show
Coding Style introduced by
Private member variable "options" must be prefixed with an underscore
Loading history...
22
    //options
23
    public const EXPAND_SHORT = 00001;
24
    public const SERIALIZE_CUSTOM_OBJECTS = 00010;
25
26
    // public function __construct(int $options = null)
27
    // {
28
    //     if (is_int($options)) self::$options = $options;
29
    // }
30
31
    /**
32
     * Returns (as a string) the YAML representation of the $dataType provided
33
     *
34
     * @param mixed    $dataType The data type
35
     * @param int|null $options  The options
36
     *
37
     * @throws \Exception datatype cannot be null
38
     *
39
     * @return string The Yaml string content
40
     */
41
    public static function toString($dataType, int $options = null):string
42
    {
43
        if (is_null($dataType)) throw new \Exception(self::class.": No content to convert to Yaml", 1);
44
        self::$options = is_int($options) ? $options : self::OPTIONS;
45
        self::$result = new DLL;
46
        if ($dataType instanceof YamlObject) {
47
            self::dumpYamlObject($dataType);
48
        } elseif (is_array($dataType) && $dataType[0] instanceof YamlObject) {
49
            array_map([self::class, 'dumpYamlObject'], $dataType);
50
        } else {
51
            self::dump($dataType, 0);
52
        }
53
        $out = implode("\n", iterator_to_array(self::$result));
54
        self::$result = null;
55
        return $out;
56
    }
57
58
    /**
59
     * Calls and saves the result of Dumper::toString to the file $filePath provided
60
     *
61
     * @param string   $filePath The file path
62
     * @param mixed    $dataType The data type
63
     * @param int|null $options  The options
64
     *
65
     * @throws \Exception datatype cannot be null
66
     *
67
     * @return boolean  true = if the file has been correctly saved  (according to return from 'file_put_contents')
68
     */
69
    public static function toFile(string $filePath, $dataType, int $options = null):bool
70
    {
71
        return !is_bool(file_put_contents($filePath, self::toString($dataType, $options)));
72
    }
73
74
    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...
75
    {
76
        if (is_scalar($dataType)) {
77
            switch (gettype($dataType)) {
78
                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...
79
                case 'float': if (is_infinite($dataType)) return $dataType > 0 ? '.inf' : '-.inf';
80
                              return sprintf('%.2F', $dataType);
0 ignored issues
show
Coding Style introduced by
Case breaking statement indented incorrectly; expected 20 spaces, found 30
Loading history...
81
                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...
82
                default:
83
                    return $dataType;
84
            }
85
        } elseif (is_object($dataType)) {
86
            self::dumpObject($dataType, $indent);
87
        } elseif (is_array($dataType)) {
88
            self::dumpSequence($dataType, $indent);
89
        }
90
    }
91
92
    private static function dumpYamlObject(YamlObject $dataType)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
Coding Style introduced by
Private method name "Dumper::dumpYamlObject" must be prefixed with an underscore
Loading history...
93
    {
94
        if ($dataType->hasDocStart()) self::$result->push("---");
0 ignored issues
show
Bug introduced by
The method push() does not exist on null. ( Ignorable by Annotation )

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

94
        if ($dataType->hasDocStart()) self::$result->/** @scrutinizer ignore-call */ push("---");

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method hasDocStart() does not exist on Dallgoot\Yaml\YamlObject. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

94
        if ($dataType->/** @scrutinizer ignore-call */ hasDocStart()) self::$result->push("---");
Loading history...
95
        // self::dump($dataType, 0);
96
        if (count($dataType) > 0) {
97
            self::dumpSequence($dataType->getArrayCopy(), 0);
98
        } else {
99
            self::dumpObject($dataType, 0);
100
        }
101
        // self::insertComments($dataType->getComment());
102
        //TODO: $references = $dataType->getAllReferences();
103
    }
104
105
    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...
106
    {
107
        $newVal = str_repeat(" ", $indent).$value;
108
        foreach (str_split($newVal, self::WIDTH) as $chunks) {
109
            self::$result->push($chunks);
110
        }
111
    }
112
113
    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...
114
    {
115
        $refKeys = range(0, count($array));
116
        foreach ($array as $key => $item) {
117
            $lineStart = current($refKeys) === $key ? "- " : "- $key: ";
118
            if (is_scalar($item)) {
119
                self::add($lineStart.self::dump($item,0), $indent);
120
            } else {
121
                self::add($lineStart, $indent);
122
                self::dump($item, $indent + self::INDENT);
123
            }
124
            next($refKeys);
125
        }
126
    }
127
128
    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...
129
    {
130
        foreach ($commentsArray as $lineNb => $comment) {
131
            self::$result->add($lineNb, $comment);
132
        }
133
    }
134
135
    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...
136
    {
137
        if ($obj instanceof Tag) {
138
            if (is_scalar($obj->value)) {
139
                self::add("!".$obj->tagName.' '.$obj->value, $indent);
140
            } else {
141
                self::add("!".$obj->tagName, $indent);
142
                self::add(self::dump($obj->value, $indent + self::INDENT), $indent + self::INDENT);
143
            }
144
        }
145
        if ($obj instanceof Compact) return self::dumpCompact($obj, $indent);
146
        //TODO:  consider dumping datetime as date strings according to a format provided by user or default
147
        if ($obj instanceof \DateTime) return $obj->format('Y-m-d');
148
        // if ($obj instanceof \SplString) {var_dump('splstrin',$obj);return '"'.$obj.'"';}
149
        $propList = get_object_vars($obj);
150
        foreach ($propList as $property => $value) {
151
            if (is_scalar($value)) {
152
                self::add("$property: ".self::dump($value, $indent), $indent);
153
            } else {
154
                self::add("$property: ", $indent);
155
                self::add(self::dump($value, $indent + self::INDENT), $indent + self::INDENT);
156
            }
157
        }
158
    }
159
160
    public static function dumpCompact($subject, int $indent)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
161
    {
162
        $pairs = [];
163
        if (is_array($subject) || $subject instanceof \Countable) {
164
            $max = count($subject);
165
            $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

165
            $objectAsArray = is_array($subject) ? $subject : $subject->/** @scrutinizer ignore-call */ getArrayCopy();
Loading history...
166
            if(array_keys($objectAsArray) !== range(0, $max)) {
0 ignored issues
show
Coding Style introduced by
Expected "if (...) {\n"; found "if(...) {\n"
Loading history...
167
                $pairs = $objectAsArray;
168
            } else {
169
                $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...
170
                return '['.implode(', ', $valuesList).']';
171
            }
172
        } else {
173
            $pairs = get_object_vars($subject);
174
        }
175
        $content = [];
176
        foreach ($pairs as $key => $value) {
177
            if (is_scalar($value)) {
178
                $content[] = "$key: ".self::dump($value, $indent);
179
            } else {
180
                $content[] = "$key: ".self::dumpCompact($value, $indent);
181
            }
182
        }
183
        return '{'.implode(', ', $content).'}';
184
    }
185
}
186