Completed
Push — bug3271 ( 571a8a )
by Andreas
05:36 queued 02:59
created

ConfigParser::parse()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 5
nop 1
dl 0
loc 44
rs 8.5937
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki\plugin\config\core;
4
5
/**
6
 * A naive PHP file parser
7
 *
8
 * This parses our very simple config file in PHP format. We use this instead of simply including
9
 * the file, because we want to keep expressions such as 24*60*60 as is.
10
 *
11
 * @author  Chris Smith <[email protected]>
12
 */
13
class ConfigParser {
14
    /** @var string variable to parse from the file */
15
    protected $varname = 'conf';
16
    /** @var string the key to mark sub arrays */
17
    protected $keymarker = Configuration::KEYMARKER;
18
19
    /**
20
     * Parse the given PHP file into an array
21
     *
22
     * When the given files does not exist, this returns an empty array
23
     *
24
     * @param string $file
25
     * @return array
26
     */
27
    public function parse($file) {
28
        if(!file_exists($file)) return array();
29
30
        $config = array();
31
        $contents = @php_strip_whitespace($file);
32
33
        // fallback to simply including the file #3271
34
        if($contents === null) {
35
            $conf = [];
36
            include $file;
37
            return $conf;
38
        }
39
40
        $pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s';
41
        $matches = array();
42
        preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER);
43
44
        for($i = 0; $i < count($matches); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
45
            $value = $matches[$i][2];
46
47
            // merge multi-dimensional array indices using the keymarker
48
            $key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]);
49
50
            // handle arrays
51
            if(preg_match('/^array ?\((.*)\)/', $value, $match)) {
52
                $arr = explode(',', $match[1]);
53
54
                // remove quotes from quoted strings & unescape escaped data
55
                $len = count($arr);
56
                for($j = 0; $j < $len; $j++) {
57
                    $arr[$j] = trim($arr[$j]);
58
                    $arr[$j] = $this->readValue($arr[$j]);
59
                }
60
61
                $value = $arr;
62
            } else {
63
                $value = $this->readValue($value);
64
            }
65
66
            $config[$key] = $value;
67
        }
68
69
        return $config;
70
    }
71
72
    /**
73
     * Convert php string into value
74
     *
75
     * @param string $value
76
     * @return bool|string
77
     */
78
    protected function readValue($value) {
79
        $removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s';
80
        $unescape_pairs = array(
81
            '\\\\' => '\\',
82
            '\\\'' => '\'',
83
            '\\"' => '"'
84
        );
85
86
        if($value == 'true') {
87
            $value = true;
88
        } elseif($value == 'false') {
89
            $value = false;
90
        } else {
91
            // remove quotes from quoted strings & unescape escaped data
92
            $value = preg_replace($removequotes_pattern, '$2', $value);
93
            $value = strtr($value, $unescape_pairs);
94
        }
95
        return $value;
96
    }
97
98
}
99