PhpTreeSerializer   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 71.43%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 33
lcom 0
cbo 2
dl 0
loc 121
ccs 10
cts 14
cp 0.7143
rs 9.3999
c 2
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getContentType() 0 4 1
A getFileExtension() 0 4 1
A serialize() 0 4 1
F syntaxCheck() 0 70 26
A deserialize() 0 18 4
1
<?php
2
3
namespace ConfigToken\TreeSerializer\Types;
4
5
6
use ConfigToken\TreeSerializer\Exception\TreeSerializerSyntaxException;
7
8
class PhpTreeSerializer extends AbstractTreeSerializer
9
{
10
    /**
11
     * @codeCoverageIgnore
12
     * @return string
13
     */
14
    public static function getContentType()
15
    {
16
        return 'application/x-php';
17
    }
18
19
    /**
20
     * @codeCoverageIgnore
21
     * @return string
22
     */
23
    public static function getFileExtension()
24
    {
25
        return 'php';
26
    }
27
28 1
    public static function serialize($data)
29
    {
30 1
        return "<?php\n\n\$data = " . var_export($data, true) . ';';
31
    }
32
33
    /**
34
     * Check syntax of the given PHP code string.
35
     * @param string $code The PHP code for which to perform syntax checking.
36
     * @return array|boolean Array of syntax errors or true/false to indicate success/unknown failure.
37
     * @codeCoverageIgnore
38
     */
39
    protected static function syntaxCheck($code){
40
        error_reporting(E_ALL);
41
        $braces=0;
42
        $inString=0;
43
        foreach (token_get_all('<?php ' . $code) as $token) {
44
            if (is_array($token)) {
45
                switch ($token[0]) {
46
                    case T_CURLY_OPEN:
47
                    case T_DOLLAR_OPEN_CURLY_BRACES:
48
                    case T_START_HEREDOC: ++$inString; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
49
                    case T_END_HEREDOC:   --$inString; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
50
                }
51
            } else if ($inString & 1) {
52
                switch ($token) {
53
                    case '`': case '\'':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
54
                    case '"': --$inString; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
55
                }
56
            } else {
57
                switch ($token) {
58
                    case '`': case '\'':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
59
                    case '"': ++$inString; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
60
                    case '{': ++$braces; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
61
                    case '}':
62
                        if ($inString) {
63
                            --$inString;
64
                        } else {
65
                            --$braces;
66
                            if ($braces < 0) break 2;
67
                        }
68
                        break;
69
                }
70
            }
71
        }
72
        $inString = @ini_set('log_errors', false);
73
        $token = @ini_set('display_errors', true);
74
        ob_start();
75
        $braces || $code = "if(0){" . $code . "\n}";
76
        if (class_exists('ParseError')) { // PHP 7
77
            try {
78
                $evalResult = eval($code);
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
79
            } /** @noinspection PhpUndefinedClassInspection */ catch(\ParseError $e) {
0 ignored issues
show
Unused Code introduced by
/** @noinspection PhpUnd...ge(), $e->getCode()); } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
Bug introduced by
The class ParseError does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
80
                return array($e->getMessage(), $e->getCode());
81
            }
82
        } else {
83
            $evalResult = eval($code);
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
84
        }
85
		if ($evalResult === false) {
86
            if ($braces) {
87
                $braces = PHP_INT_MAX;
88
            } else {
89
                false !== strpos($code,"\r") && $code = strtr(str_replace("\r\n", "\n", $code), "\r", "\n");
90
                $braces = substr_count($code,"\n");
91
            }
92
            $code = ob_get_clean();
93
            $code = strip_tags($code);
94
            // todo: fix regex
95
            if (@preg_match("'syntax error, (.+) in .+ on line (.+)$'s", $code, $code)) {
96
                $code[2] = (int) $code[2];
97
                $code = $code[2] <= $braces
98
                    ? array($code[1], $code[2])
99
                    : array('unexpected $end' . substr($code[1], 14), $braces);
100
            } else $code = array('syntax error', 0);
101
        } else {
102
            ob_end_clean();
103
            $code = false;
104
        }
105
		@ini_set('display_errors', $token);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
106
		@ini_set('log_errors', $inString);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
107
		return $code;
108
	}
109
110 3
    public static function deserialize($string)
111
    {
112 3
        $data = array();
113 3
        $code = static::syntaxCheck(str_replace('<?php', '', $string));
114 3
        if ($code !== false) {
115 2
            throw new TreeSerializerSyntaxException(sprintf('Unable to deserialize PHP tree: %s', implode(', ', $code)));
116
        }
117 1
        if (class_exists('ParseError')) { // PHP 7
118
            try {
119
                eval(str_replace('<?php', '', $string));
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
120
            } /** @noinspection PhpUndefinedClassInspection */ catch(\ParseError $e) {
0 ignored issues
show
Bug introduced by
The class ParseError does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
121
                throw new TreeSerializerSyntaxException($e->getMessage());
122
            }
123
        } else {
124 1
            eval(str_replace('<?php', '', $string));
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
125
        }
126 1
        return $data;
127
    }
128
}