243 lines
6.9 KiB
PHP
243 lines
6.9 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* dmarc-srg - A php parser, viewer and summary report generator for incoming DMARC reports.
|
||
|
* Copyright (C) 2020 Aleksey Andreev (liuch)
|
||
|
*
|
||
|
* Available at:
|
||
|
* https://github.com/liuch/dmarc-srg
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by the Free
|
||
|
* Software Foundation, either version 3 of the License.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||
|
* more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License along with
|
||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*
|
||
|
* =========================
|
||
|
*
|
||
|
* This file contains implementation of the class Setting
|
||
|
*
|
||
|
* @category API
|
||
|
* @package DmarcSrg
|
||
|
* @author Aleksey Andreev (liuch)
|
||
|
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU/GPLv3
|
||
|
*/
|
||
|
|
||
|
namespace Liuch\DmarcSrg\Settings;
|
||
|
|
||
|
use Liuch\DmarcSrg\Core;
|
||
|
use Liuch\DmarcSrg\Exception\SoftException;
|
||
|
use Liuch\DmarcSrg\Exception\DatabaseNotFoundException;
|
||
|
|
||
|
/**
|
||
|
* It's a class for accessing to settings item data
|
||
|
*
|
||
|
* This class is designed for storing and manipulating one item of settings data.
|
||
|
* All queries to the datatabase are made in lazy mode.
|
||
|
*/
|
||
|
abstract class Setting
|
||
|
{
|
||
|
public const TYPE_STRING = 1;
|
||
|
public const TYPE_INTEGER = 2;
|
||
|
public const TYPE_STRING_SELECT = 3;
|
||
|
|
||
|
protected $db = null;
|
||
|
protected $name = null;
|
||
|
protected $value = null;
|
||
|
protected $wignore = false;
|
||
|
|
||
|
/**
|
||
|
* Returns the type of the setting
|
||
|
*
|
||
|
* @return int Type of the setting
|
||
|
*/
|
||
|
abstract public function type(): int;
|
||
|
|
||
|
/**
|
||
|
* Checks if the value is correct
|
||
|
*
|
||
|
* @return bool True if the value is correct or false otherwise
|
||
|
*/
|
||
|
abstract protected function checkValue(): bool;
|
||
|
|
||
|
/**
|
||
|
* Converts a string to the value
|
||
|
*
|
||
|
* @param string $s String for conversion
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
abstract protected function stringToValue(string $s): void;
|
||
|
|
||
|
/**
|
||
|
* Returns a string representation of the value
|
||
|
*
|
||
|
* @return string The string value
|
||
|
*/
|
||
|
abstract protected function valueToString(): string;
|
||
|
|
||
|
/**
|
||
|
* It's a constructor of the class
|
||
|
*
|
||
|
* Some examples of using:
|
||
|
* (new Setting('some.setting'))->value(); - will return the value of the setting 'some.setting'.
|
||
|
* (new Setting([ 'name' => 'some.setting', 'value' => 'some string value' ])->save(); - will add
|
||
|
* this setting to the database if it does not exist in it or update the value of the setting.
|
||
|
*
|
||
|
* @param string|array $data Some setting data to identify it
|
||
|
* string value is treated as a name
|
||
|
* array has these fields: `name`, `value`
|
||
|
* and usually uses for creating a new setting item.
|
||
|
* @param boolean $wignore If true the wrong value is reset to the default
|
||
|
* or it throws an exception otherwise.
|
||
|
* @param DatabaseController $db The database controller
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function __construct($data, bool $wignore = false, $db = null)
|
||
|
{
|
||
|
$this->wignore = $wignore;
|
||
|
$this->db = $db ?? Core::instance()->database();
|
||
|
switch (gettype($data)) {
|
||
|
case 'string':
|
||
|
$this->name = $data;
|
||
|
SettingsList::checkName($this->name);
|
||
|
return;
|
||
|
case 'array':
|
||
|
if (!isset($data['name']) || gettype($data['name']) !== 'string') {
|
||
|
break;
|
||
|
}
|
||
|
$this->name = $data['name'];
|
||
|
SettingsList::checkName($this->name);
|
||
|
if (isset($data['value'])) {
|
||
|
$this->value = $data['value'];
|
||
|
if (!$this->checkValue()) {
|
||
|
if (!$wignore) {
|
||
|
break;
|
||
|
}
|
||
|
$this->resetToDefault();
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
throw new SoftException('Wrong setting data');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the name of the setting
|
||
|
*
|
||
|
* @return string The name of the setting
|
||
|
*/
|
||
|
public function name(): string
|
||
|
{
|
||
|
return $this->name;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the value of the setting
|
||
|
*
|
||
|
* @return mixed The value of the setting
|
||
|
*/
|
||
|
public function value()
|
||
|
{
|
||
|
if (is_null($this->value)) {
|
||
|
$this->fetchData();
|
||
|
}
|
||
|
return $this->value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Assigns the passed value to the setting
|
||
|
*
|
||
|
* @param mixed Value to assign
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function setValue($value): void
|
||
|
{
|
||
|
$this->value = $value;
|
||
|
if (!$this->checkValue()) {
|
||
|
if (!$this->wignore) {
|
||
|
throw new SoftException('Wrong setting value');
|
||
|
}
|
||
|
$this->resetToDefault();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an array with setting data
|
||
|
*
|
||
|
* @return array Setting data
|
||
|
*/
|
||
|
public function toArray(): array
|
||
|
{
|
||
|
if (is_null($this->value)) {
|
||
|
$this->fetchData();
|
||
|
}
|
||
|
switch ($this->type()) {
|
||
|
case self::TYPE_STRING:
|
||
|
$type = 'string';
|
||
|
break;
|
||
|
case self::TYPE_INTEGER:
|
||
|
$type = 'integer';
|
||
|
break;
|
||
|
case self::TYPE_STRING_SELECT:
|
||
|
$type = 'select';
|
||
|
break;
|
||
|
}
|
||
|
return [
|
||
|
'type' => $type,
|
||
|
'name' => $this->name,
|
||
|
'value' => $this->value,
|
||
|
'default' => SettingsList::$schema[$this->name]['default']
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Saves the setting to the database
|
||
|
*
|
||
|
* Updates the value of the setting in the database if the setting exists there or insert a new record otherwise.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function save(): void
|
||
|
{
|
||
|
$this->db->getMapper('setting')->save($this->name, $this->valueToString());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Fetches the setting data from the database by its name
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
private function fetchData(): void
|
||
|
{
|
||
|
try {
|
||
|
$res = $this->db->getMapper('setting')->value($this->name);
|
||
|
} catch (DatabaseNotFoundException $e) {
|
||
|
$this->resetToDefault();
|
||
|
return;
|
||
|
}
|
||
|
$this->stringToValue($res);
|
||
|
if (!$this->checkValue()) {
|
||
|
$this->resetToDefault();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Resets the setting value to its default value
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
private function resetToDefault(): void
|
||
|
{
|
||
|
$this->value = SettingsList::$schema[$this->name]['default'];
|
||
|
}
|
||
|
}
|