<?php
namespace Moto\System; use Moto; class ConfigFile { protected $_file = '@websiteSettings'; protected $_settingsContent = null; protected $_settingsHash = null; protected $_debug = false; public function debug($debug = false) { $this->_debug = (boolean) $debug; } public function getAbsolutePath() { return Moto\System::getAbsolutePath($this->_file); } public function getSettingsContent() { if ($this->_settingsContent !== null) { return $this->_settingsContent; } $filePath = $this->getAbsolutePath(); $content = file_get_contents($filePath); $settings = null; if (preg_match('/(\/\* USER_SETTINGS:START \*\/)(.*)(\/\* USER_SETTINGS:END \*\/)/uis', $content, $match)) { $settings = trim($match[2]); } if ($settings === null) { throw new \Exception('CONFIG_FILE:CANT_FIND_SETTINGS'); } $this->_settingsContent = $settings; $this->_settingsHash = md5($settings); return $settings; } public function parseSettingsContent($settings = null) { $debug = $this->_debug; if ($settings === null) { $settings = $this->getSettingsContent(); } $config = []; $lines = preg_split('/;[\s\n\r]/', $settings); if (!is_array($lines)) { return false; } if (count($lines) < 2) { return false; } foreach ($lines as $index => $line) { if ($debug) { echo "\n--------------------\n$line\n========>\n"; } $line = trim($line, " \n\r;"); if (!preg_match('/\$config([^=]*)[\s]*=[\s]*(.*)[\s]*$/uis', $line, $match)) { if ($debug) { echo "BAD STRING\n"; } continue; } $name = $this->parseName($match[1]); if (!$name) { if ($debug) { echo "BAD NAME\n"; } continue; } if ($debug) { echo "NAME : " . var_export($name, true) . "\n"; } $value = $this->parseValue($match[2]); if ($debug) { echo "VALUE : " . var_export($value, true) . "\n"; } Moto\Util::setToArrayDeep($config, $name, $value); } if ($debug) { print_r($config); } return $config; } public function parseName($str) { if (!is_string($str)) { return false; } $str = trim($str); $str = preg_replace('/([\'\"]\]\[[\'\"])/', '.', $str); $str = preg_replace('/([\'\"]\]|\[[\'\"])/', '', $str); $str = trim($str); if (!preg_match('/^[a-z0-9\_\-\.\s]+$/i', $str)) { return null; } return $str; } public function parseValue($str) { if (!is_string($str)) { return false; } $result = [ 'value' => '', 'type' => 'string', ]; $str = trim($str); if ($str === '') { return $result; } if (strlen($str) <= 5) { $_value = strtolower($str); if ($_value === 'null') { return [ 'value' => null, 'type' => 'null' ]; } if ($_value === 'true' || $_value === 'false') { return [ 'value' => ($_value === 'true'), 'type' => 'boolean' ]; } } if (strpos($str, 'base64_decode') !== false) { $result['base64'] = true; $result['decoded'] = false; $result['raw'] = $str; if (preg_match('/base64_decode\([\'\"](.*)[\'\"]\)$/', $str, $match)) { $result['value'] = base64_decode($match[1]); $result['decoded'] = true; } return $result; } if ($str[0] === '\'' || $str[0] === '"') { $str = substr($str, 1); $str = substr($str, 0, -1); $result['value'] = $str; return $result; } elseif (preg_match('/\d+\.\d+/', $str)) { $result['value'] = $str * 1; $result['type'] = 'float'; return $result; } elseif (preg_match('/\d+/', $str)) { $result['value'] = $str * 1; $result['type'] = 'int'; return $result; } return null; } public function updateSettingsContent($path, $rawValue) { $debug = $this->_debug; if ($debug) { echo "\n" . __FUNCTION__ . "()\n"; } if (!is_string($path) || !preg_match('/^[a-z][a-z0-9\_\.]+$/i', $path)) { if ($debug) { echo "ERROR : Invalid path settings\n\n"; } return false; } $pattern = str_replace('.', '[\\\'\"]\]\[[\\\'\"]', $path); $pattern = '\$config\[[\\\'\"]' . $pattern . '[\\\'\"]\]'; if ($debug) { echo "PATH : $path\n"; echo "PATTERN : $pattern\n"; } if (is_numeric($rawValue)) { $value = $rawValue; } elseif (!is_string($rawValue)) { if ($debug) { echo "ERROR : Invalid value : must be a string or numeric\n\n"; } return false; } else { $value = 'base64_decode(\'' . base64_encode($rawValue) . '\')'; } $patch = '$config[\'' . str_replace('.', '\'][\'', $path) . '\'] = ' . $value . ';'; $settings = $this->getSettingsContent(); $lines = explode("\n", $settings); $settings = ''; foreach ($lines as $index => $line) { if (preg_match('/' . $pattern . '/', $line)) { continue; } $settings .= $line . "\n"; } $settings .= $patch . "\n"; $settings = preg_replace('/[\r\n]+/', "\n", $settings); $this->_settingsContent = $settings; } public function saveSettingsContent() { $settings = $this->getSettingsContent(); $settings = trim($settings); $hash = md5($settings); if ($hash === $this->_settingsHash) { return true; } $filePath = $this->getAbsolutePath(); $content = file_get_contents($filePath); $content = preg_replace('/(\/\* USER_SETTINGS:START \*\/)(.*)(\/\* USER_SETTINGS:END \*\/)/uis', "$1\n$settings\n$3", $content); Moto\Util::filePutContents($filePath, $content); return true; } } 