1<?php 2 3namespace 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 <chris@jalakai.co.uk> 12 */ 13class ConfigParser 14{ 15 /** @var string variable to parse from the file */ 16 protected $varname = 'conf'; 17 /** @var string the key to mark sub arrays */ 18 protected $keymarker = Configuration::KEYMARKER; 19 20 /** 21 * Parse the given PHP file into an array 22 * 23 * When the given files does not exist, this returns an empty array 24 * 25 * @param string $file 26 * @return array 27 */ 28 public function parse($file) { 29 if(!file_exists($file)) return []; 30 31 $config = []; 32 $contents = @php_strip_whitespace($file); 33 34 // fallback to simply including the file #3271 35 if($contents === null) { 36 $conf = []; 37 include $file; 38 return $conf; 39 } 40 41 $pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s'; 42 $matches = []; 43 preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER); 44 $counter = count($matches); 45 46 for($i = 0; $i < $counter; $i++) { 47 $value = $matches[$i][2]; 48 49 // merge multi-dimensional array indices using the keymarker 50 $key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]); 51 52 // handle arrays 53 if(preg_match('/^array ?\((.*)\)/', $value, $match)) { 54 $arr = explode(',', $match[1]); 55 56 // remove quotes from quoted strings & unescape escaped data 57 $len = count($arr); 58 for($j = 0; $j < $len; $j++) { 59 $arr[$j] = trim($arr[$j]); 60 $arr[$j] = $this->readValue($arr[$j]); 61 } 62 63 $value = $arr; 64 } else { 65 $value = $this->readValue($value); 66 } 67 68 $config[$key] = $value; 69 } 70 71 return $config; 72 } 73 74 /** 75 * Convert php string into value 76 * 77 * @param string $value 78 * @return bool|string 79 */ 80 protected function readValue($value) { 81 $removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s'; 82 $unescape_pairs = [ 83 '\\\\' => '\\', 84 '\\\'' => '\'', 85 '\\"' => '"' 86 ]; 87 88 if($value == 'true') { 89 $value = true; 90 } elseif($value == 'false') { 91 $value = false; 92 } else { 93 // remove quotes from quoted strings & unescape escaped data 94 $value = preg_replace($removequotes_pattern, '$2', $value); 95 $value = strtr($value, $unescape_pairs); 96 } 97 return $value; 98 } 99} 100