1e063babfSAndreas Gohr<?php 2e063babfSAndreas Gohr 3e063babfSAndreas Gohrnamespace dokuwiki\plugin\config\core; 4e063babfSAndreas Gohr 5e063babfSAndreas Gohr/** 6e063babfSAndreas Gohr * A naive PHP file parser 7e063babfSAndreas Gohr * 8e063babfSAndreas Gohr * This parses our very simple config file in PHP format. We use this instead of simply including 9e063babfSAndreas Gohr * the file, because we want to keep expressions such as 24*60*60 as is. 10e063babfSAndreas Gohr * 11e063babfSAndreas Gohr * @author Chris Smith <chris@jalakai.co.uk> 12e063babfSAndreas Gohr */ 138c7c53b0SAndreas Gohrclass ConfigParser 148c7c53b0SAndreas Gohr{ 15e063babfSAndreas Gohr /** @var string variable to parse from the file */ 1613b5250aSAndreas Gohr protected $varname = 'conf'; 17e063babfSAndreas Gohr /** @var string the key to mark sub arrays */ 1813b5250aSAndreas Gohr protected $keymarker = Configuration::KEYMARKER; 19e063babfSAndreas Gohr 20e063babfSAndreas Gohr /** 21e063babfSAndreas Gohr * Parse the given PHP file into an array 22e063babfSAndreas Gohr * 23e063babfSAndreas Gohr * When the given files does not exist, this returns an empty array 24e063babfSAndreas Gohr * 25e063babfSAndreas Gohr * @param string $file 26e063babfSAndreas Gohr * @return array 27e063babfSAndreas Gohr */ 28*d868eb89SAndreas Gohr public function parse($file) 29*d868eb89SAndreas Gohr { 30467c1427SAndreas Gohr if (!file_exists($file)) return []; 31e063babfSAndreas Gohr 32467c1427SAndreas Gohr $config = []; 33e063babfSAndreas Gohr $contents = @php_strip_whitespace($file); 34571a8adbSAndreas Gohr 35571a8adbSAndreas Gohr // fallback to simply including the file #3271 36571a8adbSAndreas Gohr if ($contents === null) { 37571a8adbSAndreas Gohr $conf = []; 38571a8adbSAndreas Gohr include $file; 39571a8adbSAndreas Gohr return $conf; 40571a8adbSAndreas Gohr } 41571a8adbSAndreas Gohr 42e063babfSAndreas Gohr $pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s'; 43467c1427SAndreas Gohr $matches = []; 44e063babfSAndreas Gohr preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER); 45467c1427SAndreas Gohr $counter = count($matches); 46e063babfSAndreas Gohr 47467c1427SAndreas Gohr for ($i = 0; $i < $counter; $i++) { 48e063babfSAndreas Gohr $value = $matches[$i][2]; 49e063babfSAndreas Gohr 50e063babfSAndreas Gohr // merge multi-dimensional array indices using the keymarker 51e063babfSAndreas Gohr $key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]); 52e063babfSAndreas Gohr 53e063babfSAndreas Gohr // handle arrays 54e063babfSAndreas Gohr if (preg_match('/^array ?\((.*)\)/', $value, $match)) { 55e063babfSAndreas Gohr $arr = explode(',', $match[1]); 56e063babfSAndreas Gohr 57e063babfSAndreas Gohr // remove quotes from quoted strings & unescape escaped data 58e063babfSAndreas Gohr $len = count($arr); 59e063babfSAndreas Gohr for ($j = 0; $j < $len; $j++) { 60e063babfSAndreas Gohr $arr[$j] = trim($arr[$j]); 61e063babfSAndreas Gohr $arr[$j] = $this->readValue($arr[$j]); 62e063babfSAndreas Gohr } 63e063babfSAndreas Gohr 64e063babfSAndreas Gohr $value = $arr; 65e063babfSAndreas Gohr } else { 66e063babfSAndreas Gohr $value = $this->readValue($value); 67e063babfSAndreas Gohr } 68e063babfSAndreas Gohr 69e063babfSAndreas Gohr $config[$key] = $value; 70e063babfSAndreas Gohr } 71e063babfSAndreas Gohr 72e063babfSAndreas Gohr return $config; 73e063babfSAndreas Gohr } 74e063babfSAndreas Gohr 75e063babfSAndreas Gohr /** 76e063babfSAndreas Gohr * Convert php string into value 77e063babfSAndreas Gohr * 78e063babfSAndreas Gohr * @param string $value 79e063babfSAndreas Gohr * @return bool|string 80e063babfSAndreas Gohr */ 81*d868eb89SAndreas Gohr protected function readValue($value) 82*d868eb89SAndreas Gohr { 83e063babfSAndreas Gohr $removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s'; 84467c1427SAndreas Gohr $unescape_pairs = [ 85e063babfSAndreas Gohr '\\\\' => '\\', 86e063babfSAndreas Gohr '\\\'' => '\'', 87e063babfSAndreas Gohr '\\"' => '"' 88467c1427SAndreas Gohr ]; 89e063babfSAndreas Gohr 90e063babfSAndreas Gohr if ($value == 'true') { 91e063babfSAndreas Gohr $value = true; 92e063babfSAndreas Gohr } elseif ($value == 'false') { 93e063babfSAndreas Gohr $value = false; 94e063babfSAndreas Gohr } else { 95e063babfSAndreas Gohr // remove quotes from quoted strings & unescape escaped data 96e063babfSAndreas Gohr $value = preg_replace($removequotes_pattern, '$2', $value); 97e063babfSAndreas Gohr $value = strtr($value, $unescape_pairs); 98e063babfSAndreas Gohr } 99e063babfSAndreas Gohr return $value; 100e063babfSAndreas Gohr } 101e063babfSAndreas Gohr} 102