parameters1, 'name2' => parameters1, ... ) * * name1, name2 ... - Имена модулей * parameters1, parameters1 - Массивы с параметрами модуля * Имя необходимо чтобы потом легко было удалить ненужные ветки дерева */ class Settings { public $data = []; protected $file; protected $format = 'php'; protected $is_read = false; public function __construct ($file = null, $format = false) { $fileFormat = ['theme' => 'json']; $extname = pathinfo($file, PATHINFO_EXTENSION); $this->format = $format ? $format : Arr::get($fileFormat, $extname, $extname); $this->file = $file; } /** * Чтение настроек из файла * @return Boolean */ public function read() { if (!file_exists ($this->file)) { $this->is_read = true; return false; } // Не include_once т.к читать настройки можно несколько раз $settings = array(); if ($this->format == 'json') { $settings = json_decode(File::getContents($this->file), true); } else { $settings = include ($this->file); } if (!is_array($settings)) { throw new Exception('no data in ' . $this->file); } $this->is_read = true; $this->data = $settings; return true; } /** * Запись ключа в реестр (Реестр это многомерный массив) */ public function writeKey(array $key, $value) { // assert(count($key) >= 1); $data = &$this->data; while (count($key) > 1) { $name = array_shift($key); $data = &$data[$name]; } // assert(count($key) == 1); $name = array_shift($key); if (is_array($value)) { if (!isset($data[$name])) { $data[$name] = array(); } $this->merge($data[$name], $value); } else { $data[$name] = $value; } } /** * Обновляет массив в соответствии со значением */ protected function merge(array &$data, $value) { foreach ($value as $key => $subvalue) { if (is_array($subvalue)) { if (! isset($data[$key])) $data[$key] = array(); $this->merge($data[$key], $subvalue); } else { $data[$key] = $subvalue; } } } /** * Чтение ключа из реестра * @param mixed $args Путь к значению ключа */ public function readKey(array $key) { return $this->readKeyData($key, $this->data); } protected function readKeyData(array $key, $data) { // assert(count($key) >= 1); while (count($key) > 1) { $name = array_shift($key); if (isset($data[$name])) { $data = $data[$name]; } else { return null; } } // assert(count($key) == 1); $name = array_shift($key); if (isset($data[$name])) { return $data[$name]; } else { return null; } } /** * Чтение ключа из реестра (Собирает все ключи с определенным значением во всех модулях) * @param mixed $key Путь к значению ключа внутри модуля */ public function readKeyList($_rest) { $key = func_get_args(); $result = array(); foreach ($this->data as $name => $value) { $output = $this->readKeyData($key, $value); if ($output) { $result[$name] = $output; } } return $result; } public function removeKey($name) { unset($this->data[$name]); } public function removeNode(array $key) { $data = &$this->data; while (count($key) > 1) { $name = array_shift($key); $data = &$data[$name]; } $name = array_shift($key); unset($data[$name]); } /** * Запись настроек в файл (Может переименовать в store) * * @param File $file * @return void */ public function write($file = null) { if (!$this->is_read) { throw new Exception('read settings before write'); } if ($this->format == 'json') { $result = json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); } else { $result = var_export($this->data, true); $result = ""; } file_put_contents (($file) ? $file : $this->file, $result); } public function set($key, $value) { $this->data[$key] = $value; } public function get($key, $default = null) { return isset($this->data[$key]) && $this->data[$key] != '' ? $this->data[$key] : $default; } function export() { return $this->data; } function import($data) { $this->data = $data; } /** * Список модулей/ключей */ public function getKeys() { return array_keys($this->data); } /** * Проверка наличия ключа */ public function hasKey($name) { return isset($this->data[$name]); } }