phplibrary/src/Settings.php

234 lines
6.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace ctiso;
use ctiso\File,
Exception;
/**
* Класс реестра
* Реестр организован как ассоциативный многомерный массив
* array( 'name1' => parameters1, 'name2' => parameters1, ... )
*
* name1, name2 ... - Имена модулей
* parameters1, parameters1 - Массивы с параметрами модуля
* Имя необходимо чтобы потом легко было удалить ненужные ветки дерева
*/
class Settings
{
/** @var array */
public $data = [];
/** @var string */
protected $file;
/** @var string */
protected $format = 'php';
/** @var bool */
protected $is_read = false;
/**
* Конструктор
* @param string $file Путь к файлу
* @param 'php'|'json'|false $format Формат файла
*/
public function __construct ($file = null, $format = false)
{
$fileFormat = ['theme' => 'json'];
$extname = pathinfo($file, PATHINFO_EXTENSION);
$this->format = $format ?: Arr::get($fileFormat, $extname, $extname);
$this->file = $file;
}
/**
* Чтение настроек из файла
* @return Boolean
*/
public function read(): bool
{
if (!file_exists ($this->file)) {
$this->is_read = true;
return false;
}
// Не include_once т.к читать настройки можно несколько раз
$settings = [];
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] = [];
}
$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] = [];
$this->merge($data[$key], $subvalue);
} else {
$data[$key] = $subvalue;
}
}
}
/**
* Чтение ключа из реестра
* @param array $key Путь к значению ключа
* @return mixed
*/
public function readKey(array $key)
{
return $this->readKeyData($key, $this->data);
}
/**
* Чтение ключа из реестра
* @param array $key Путь к значению ключа
* @return mixed
*/
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(...$key)
{
$result = [];
foreach ($this->data as $name => $value) {
$output = $this->readKeyData($key, $value);
if ($output) {
$result[$name] = $output;
}
}
return $result;
}
/**
* Удаление ключа из реестра
* @param string $name Имя ключа
*/
public function removeKey($name): void
{
unset($this->data[$name]);
}
public function removeNode(array $key): void
{
$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 = "<?php\nreturn ".$result.";\n?>";
}
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]);
}
}