Passed
Push — master ( 7a981c...2773c2 )
by stéphane
04:34
created

Loader::parse()   C

Complexity

Conditions 16
Paths 94

Size

Total Lines 54
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 39
nc 94
nop 1
dl 0
loc 54
rs 5.5666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
4
namespace Dallgoot\Yaml;
5
6
use Dallgoot\Yaml as Y;
7
8
final class Loader
0 ignored issues
show
Coding Style introduced by
Missing class doc comment
Loading history...
9
{
10
    //public
11
    public $errors = [];
12
13
    public const EXCLUDE_DIRECTIVES = 1;//DONT include_directive
14
    public const IGNORE_COMMENTS    = 2;//DONT include_comments
15
    public const NO_PARSING_EXCEPTIONS = 4;//THROW Exception on parsing Errors
16
    public const NO_OBJECT_FOR_DATE = 8;//DONT import date strings as dateTime Object
17
    //privates
18
    private $content;/* @var null|string */
0 ignored issues
show
Coding Style introduced by
Private member variable "content" must be prefixed with an underscore
Loading history...
19
    private $filePath;/* @var null|string */
0 ignored issues
show
Coding Style introduced by
Private member variable "filePath" must be prefixed with an underscore
Loading history...
20
    private $debug = 0;//TODO: determine levels
0 ignored issues
show
Coding Style introduced by
Private member variable "debug" must be prefixed with an underscore
Loading history...
21
    private $options = 0;/* @var int */
0 ignored issues
show
Coding Style introduced by
Private member variable "options" must be prefixed with an underscore
Loading history...
22
    //Exceptions messages
23
    private const INVALID_VALUE        = self::class.": at line %d";
24
    private const EXCEPTION_NO_FILE    = self::class.": file '%s' does not exists (or path is incorrect?)";
25
    private const EXCEPTION_READ_ERROR = self::class.": file '%s' failed to be loaded (permission denied ?)";
26
    private const EXCEPTION_LINE_SPLIT = self::class.": content is not a string(maybe a file error?)";
27
28
    public function __construct($absolutePath = null, $options = null, $debug = 0)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
29
    {
30
        $this->debug   = is_int($debug)   ? min($debug, 3) : 1;
31
        $this->options = is_int($options) ? $options       : $this->options;
32
        if (is_string($absolutePath)) {
33
            $this->load($absolutePath);
34
        }
35
    }
36
37
    /**
38
     * load a file and save its content as $content
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
39
     *
40
     * @param      string       $absolutePath  The absolute path of a file
3 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 7 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 6
Loading history...
41
     *
42
     * @throws     \Exception   if file don't exist OR reading failed
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 5
Loading history...
43
     *
44
     * @return     self  ( returns the same Loader  )
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 5
Loading history...
45
     */
46
    public function load(string $absolutePath):Loader
47
    {
48
        $this->debug > 1 && var_dump($absolutePath);
1 ignored issue
show
Security Debugging Code introduced by
var_dump($absolutePath) looks like debug code. Are you sure you do not want to remove it?
Loading history...
49
        $this->filePath = $absolutePath;
50
        if (!file_exists($absolutePath)) {
51
            throw new \Exception(sprintf(self::EXCEPTION_NO_FILE, $absolutePath));
52
        }
53
        $adle = "auto_detect_line_endings";
54
        $prevADLE = ini_get($adle);
55
        !$prevADLE && ini_set($adle, "true");
56
        $content = file($absolutePath, FILE_IGNORE_NEW_LINES);
57
        !$prevADLE && ini_set($adle, "false");
58
        if (is_bool($content)) {
59
            throw new \Exception(sprintf(self::EXCEPTION_READ_ERROR, $absolutePath));
60
        }
61
        $this->content = $content;
62
        return $this;
63
    }
64
65
    /**
66
     * Parse Yaml lines into an hierarchy of Node
67
     *
68
     * @param      string       $strContent  The Yaml string or null to parse loaded content
3 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 7 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 6
Loading history...
69
     * @throws     \Exception    if content is not available as $strContent or as $this->content (from file)
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 5
Loading history...
70
     * @throws     \ParseError  if any error during parsing or building
1 ignored issue
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 5
Loading history...
71
     *
72
     * @return     array|YamlObject      the hierarchy built an array of YamlObject or just YamlObject
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 5
Loading history...
73
     */
74
    public function parse($strContent = null)
75
    {
76
        $source = $this->content;
77
        if (is_null($source)) $source = preg_split("/([^\n\r]+)/um", $strContent, 0, PREG_SPLIT_DELIM_CAPTURE);
1 ignored issue
show
Coding Style introduced by
Inline control structures are discouraged
Loading history...
78
        //TODO : be more permissive on $strContent values
79
        if (!is_array($source)) throw new \Exception(self::EXCEPTION_LINE_SPLIT);
1 ignored issue
show
Coding Style introduced by
Inline control structures are discouraged
Loading history...
80
        $previous = $root = new Node();
81
        $emptyLines = [];
82
        $specialTypes = Y\LITTERALS | Y\BLANK;
1 ignored issue
show
Bug introduced by
The constant Dallgoot\Yaml\Y\BLANK was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
83
        try {
84
            foreach ($source as $lineNb => $lineString) {
85
                $n = new Node($lineString, $lineNb + 1);//TODO: useful???-> $this->debug && var_dump($n);
86
                $deepest = $previous->getDeepestNode();
87
                if ($deepest->type & Y\PARTIAL) {
0 ignored issues
show
Bug introduced by
The constant Dallgoot\Yaml\Y\PARTIAL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
88
                    //TODO:verify this edge case
89
                    // if ($n->type === Y\KEY && $n->indent === $previous->indent) {
90
                    //     throw new \ParseError(sprintf(self::INVALID_VALUE, $lineNb), 1);
91
                    // }
92
                    $deepest->parse($deepest->value.' '.ltrim($lineString));
93
                } else {
94
                    if (($n->type & $specialTypes) && $this->onSpecialType($n, $previous, $emptyLines)) {
95
                        continue;
96
                    }
97
                    if ($n->type & Y\SCALAR) {
0 ignored issues
show
Bug introduced by
The constant Dallgoot\Yaml\Y\SCALAR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
98
                        foreach ($emptyLines as $blankNode) {
99
                            $blankNode->getParent()->add($blankNode);
100
                        }
101
                    }
102
                    $emptyLines = [];
103
                    switch ($n->indent <=> $previous->indent) {
104
                        case -1: $previous->getParent($n->indent)->add($n);break;
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
Coding Style introduced by
Closing brace must be on a line by itself
Loading history...
105
                        case  0: $previous->getParent()->add($n);break;
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
Coding Style introduced by
Closing brace must be on a line by itself
Loading history...
106
                        default:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
107
                            if ($this->onDeepestType($n, $previous, $lineString)) continue 2;
1 ignored issue
show
Coding Style introduced by
Inline control structures are discouraged
Loading history...
108
                            $previous->add($n);
109
                    }
110
                    $previous = $n;
111
                }
112
            }
113
            if ($this->debug === 2) {
0 ignored issues
show
introduced by
The condition $this->debug is always false. If $this->debug can have other possible types, add them to yaml/Loader.php:19
Loading history...
114
                var_dump("\033[33mParsed Structure\033[0m\n", $root);
0 ignored issues
show
Security Debugging Code introduced by
var_dump('Parsed Structure ', $root) looks like debug code. Are you sure you do not want to remove it?
Loading history...
115
                die("Debug of root structure requested (remove debug level to suppress these)");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
116
            }
117
            $out = Builder::buildContent($root, $this->debug);//var_dump($out);exit();
0 ignored issues
show
Bug introduced by
$this->debug of type null|string is incompatible with the type integer expected by parameter $_debug of Dallgoot\Yaml\Builder::buildContent(). ( Ignorable by Annotation )

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

117
            $out = Builder::buildContent($root, /** @scrutinizer ignore-type */ $this->debug);//var_dump($out);exit();
Loading history...
118
            return $out;
119
        } catch (\Error|\Exception|\ParseError $e) {
120
            $file = basename($this->filePath);
121
            $message = basename($e->getFile())."@".$e->getLine().":".$e->getMessage()." in '$file' @".($lineNb+1)."\n";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $lineNb seems to be defined by a foreach iteration on line 84. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
122
            if ($e instanceof \ParseError && ($this->options & self::NO_PARSING_EXCEPTIONS)) {
123
                trigger_error($message, E_USER_WARNING);
124
                $this->errors[] = $message;
125
                var_dump($root);
126
            }
127
            throw new \Exception($message, 3);
128
        }
129
    }
130
131
    private function onSpecialType(&$n, &$previous, &$emptyLines):bool
0 ignored issues
show
Coding Style introduced by
Private method name "Loader::onSpecialType" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
132
    {
133
        $deepest = $previous->getDeepestNode();
134
        if ($n->type & Y\LITTERALS) {
135
            if ($deepest->type & Y\KEY && is_null($deepest->value)) {
1 ignored issue
show
Bug introduced by
The constant Dallgoot\Yaml\Y\KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
136
                $deepest->add($n);
137
                $previous = $n;
138
                return true;
139
            }
140
        }
141
        if ($n->type & Y\BLANK) {
1 ignored issue
show
Bug introduced by
The constant Dallgoot\Yaml\Y\BLANK was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
142
            if ($previous->type & Y\SCALAR) $emptyLines[] = $n->setParent($previous->getParent());
1 ignored issue
show
Bug introduced by
The constant Dallgoot\Yaml\Y\SCALAR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Coding Style introduced by
Inline control structures are discouraged
Loading history...
143
            if ($deepest->type & Y\LITTERALS) $emptyLines[] = $n->setParent($deepest);
1 ignored issue
show
Coding Style introduced by
Inline control structures are discouraged
Loading history...
144
            return true;
145
        }
146
        return false;
147
    }
148
149
    private function onDeepestType(&$n, &$previous, $lineString):bool
0 ignored issues
show
Unused Code introduced by
The parameter $n is not used and could be removed. ( Ignorable by Annotation )

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

149
    private function onDeepestType(/** @scrutinizer ignore-unused */ &$n, &$previous, $lineString):bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $lineString is not used and could be removed. ( Ignorable by Annotation )

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

149
    private function onDeepestType(&$n, &$previous, /** @scrutinizer ignore-unused */ $lineString):bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
Private method name "Loader::onDeepestType" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
150
    {
151
        $deepest = $previous->getDeepestNode();
152
        // if ($deepest->type & Y\LITTERALS) {
153
        //     $n->value = trim($lineString);//fall through
154
        // }
155
        // if ($deepest->type & (Y\LITTERALS | Y\REF_DEF | Y\SET_VALUE | Y\TAG) && is_null($deepest->value)) {
156
        //     $parent = $deepest;
157
        // }
158
        // // if ($previous->type & Y\ITEM && $n->type & Y\KEY) {
159
        // //     $previous
160
        // // }
161
        if ($deepest->type & (Y\BLANK | Y\SCALAR) ) {//|| ($previous->type & (Y\ITEM | Y\SET_KEY))) {
1 ignored issue
show
Bug introduced by
The constant Dallgoot\Yaml\Y\SCALAR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant Dallgoot\Yaml\Y\BLANK was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
162
                $previous = $deepest->getParent();
163
        //     // if ($n->type === Y\SCALAR && ($deepest->getParent()->type & Y\LITTERALS)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
164
        //     //     // $deepest->type = Y\SCALAR;
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
165
        //     //     // $deepest->value .= "\n".$n->value;
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
166
        //     //     // ->add($n);
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
167
        //     //     // return true;
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
168
        //     // } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
169
        //     //     if ($previous->type & (Y\ITEM | Y\SET_KEY)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
170
        //     //         $parent = $deepest->getParent();
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
171
        //     //     }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
172
        //     // }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 12 spaces, found 8
Loading history...
173
        }
174
        return false;
175
    }
176
}
177