added database driven system configurations with admin screen (#647)

This commit is contained in:
Kevin Papst
2019-03-22 20:58:38 +01:00
committed by GitHub
parent e990ae4800
commit 13d9f8f3f7
142 changed files with 2262 additions and 64727 deletions

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Configuration;
use App\Entity\Configuration;
interface ConfigLoaderInterface
{
/**
* @param null|string $prefix
* @return Configuration[]
*/
public function getConfiguration(?string $prefix = null): array;
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Configuration;
class FormConfiguration implements SystemBundleConfiguration
{
use StringAccessibleConfigTrait;
public function getPrefix(): string
{
return 'defaults';
}
public function getCustomerDefaultTimezone(): string
{
return $this->find('customer.timezone');
}
public function getCustomerDefaultCurrency(): string
{
return $this->find('customer.currency');
}
public function getCustomerDefaultCountry(): string
{
return $this->find('customer.country');
}
}

View File

@@ -0,0 +1,123 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Configuration;
use App\Entity\Configuration;
trait StringAccessibleConfigTrait
{
/**
* @var array
*/
protected $settings;
/**
* @var ConfigLoaderInterface
*/
protected $repository;
/**
* @var bool
*/
protected $initialized = false;
/**
* @param array $settings
*/
public function __construct(ConfigLoaderInterface $repository, array $settings)
{
$this->repository = $repository;
$this->settings = $settings;
}
/**
* @param ConfigLoaderInterface $repository
* @return Configuration[]
*/
protected function getConfigurations(ConfigLoaderInterface $repository): array
{
return $repository->getConfiguration($this->getPrefix() . '.');
}
protected function prepare()
{
if ($this->initialized) {
return;
}
// this foreach should be replaced by a better piece of code,
// especially the pointers could be a problem in the future
foreach ($this->getConfigurations($this->repository) as $configuration) {
$temp = explode('.', $configuration->getName());
$array = &$this->settings;
if ($temp[0] === $this->getPrefix()) {
$temp = array_slice($temp, 1);
}
foreach ($temp as $key2) {
if (!isset($array[$key2])) {
// unknown values will silently be skipped
continue 2;
}
if (is_array($array[$key2])) {
$array = &$array[$key2];
} elseif (is_bool($array[$key2])) {
$array[$key2] = (bool) $configuration->getValue();
} elseif (is_int($array[$key2])) {
$array[$key2] = (int) $configuration->getValue();
} else {
$array[$key2] = $configuration->getValue();
}
}
}
$this->initialized = true;
}
/**
* @return string
*/
abstract protected function getPrefix(): string;
/**
* @param string $key
* @return mixed
*/
public function find(string $key)
{
$this->prepare();
$prefix = $this->getPrefix() . '.';
$length = strlen($prefix);
if (substr($key, 0, $length) === $prefix) {
$key = substr($key, $length);
}
return $this->get($key, $this->settings);
}
/**
* @param string $key
* @param array $config
* @return mixed
*/
private function get(string $key, array $config)
{
$keys = explode('.', $key);
$search = array_shift($keys);
if (!isset($config[$search])) {
throw new \InvalidArgumentException('Unknown config: ' . $key);
}
if (is_array($config[$search]) && !empty($keys)) {
return $this->get(implode('.', $keys), $config[$search]);
}
return $config[$search];
}
}

View File

@@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Configuration;
interface SystemBundleConfiguration
{
/**
* @return string
*/
public function getPrefix(): string;
/**
* @param string $key
* @return mixed
*/
public function find(string $key);
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Configuration;
class SystemConfiguration implements SystemBundleConfiguration
{
use StringAccessibleConfigTrait;
public function getPrefix(): string
{
return 'kimai';
}
protected function getConfigurations(ConfigLoaderInterface $repository): array
{
return $repository->getConfiguration();
}
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Configuration;
class TimesheetConfiguration implements SystemBundleConfiguration
{
use StringAccessibleConfigTrait;
public function getPrefix(): string
{
return 'timesheet';
}
public function isAllowFutureTimes(): bool
{
return (bool) $this->find('rules.allow_future_times');
}
public function isDurationOnly(): bool
{
return (bool) $this->find('duration_only');
}
public function isMarkdownEnabled(): bool
{
return (bool) $this->find('markdown_content');
}
public function getActiveEntriesHardLimit(): int
{
return (int) $this->find('active_entries.hard_limit');
}
public function getActiveEntriesSoftLimit(): int
{
return (int) $this->find('active_entries.soft_limit');
}
}