Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)

This commit is contained in:
Kevin Papst
2022-12-31 21:19:55 +01:00
committed by GitHub
parent 95e06746bd
commit 90a0fd8a22
2164 changed files with 83700 additions and 86426 deletions

View File

@@ -1,92 +0,0 @@
<?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;
/**
* @deprecated since 1.11 - use SystemConfiguration instead
*/
class CalendarConfiguration implements SystemBundleConfiguration
{
private $configuration;
public function __construct(SystemConfiguration $configuration)
{
$this->configuration = $configuration;
}
public function find(string $key)
{
if (strpos($key, $this->getPrefix() . '.') === false) {
$key = $this->getPrefix() . '.' . $key;
}
return $this->configuration->find($key);
}
public function getPrefix(): string
{
return 'calendar';
}
public function getBusinessDays(): array
{
return $this->configuration->getCalendarBusinessDays();
}
public function getBusinessTimeBegin(): string
{
return $this->configuration->getCalendarBusinessTimeBegin();
}
public function getBusinessTimeEnd(): string
{
return $this->configuration->getCalendarBusinessTimeEnd();
}
public function getTimeframeBegin(): string
{
return $this->configuration->getCalendarTimeframeBegin();
}
public function getTimeframeEnd(): string
{
return $this->configuration->getCalendarTimeframeEnd();
}
public function getDayLimit(): int
{
return $this->configuration->getCalendarDayLimit();
}
public function isShowWeekNumbers(): bool
{
return $this->configuration->isCalendarShowWeekNumbers();
}
public function isShowWeekends(): bool
{
return $this->configuration->isCalendarShowWeekends();
}
public function getGoogleApiKey(): ?string
{
return $this->configuration->getCalendarGoogleApiKey();
}
public function getGoogleSources(): ?array
{
return $this->configuration->getCalendarGoogleSources();
}
public function getSlotDuration(): string
{
return $this->configuration->getCalendarSlotDuration();
}
}

View File

@@ -14,8 +14,13 @@ use App\Entity\Configuration;
interface ConfigLoaderInterface
{
/**
* @param null|string $prefix
* @param string $name
* @return ?Configuration
*/
public function getConfiguration(string $name): ?Configuration;
/**
* @return Configuration[]
*/
public function getConfiguration(?string $prefix = null): array;
public function getConfigurations(): array;
}

View File

@@ -1,72 +0,0 @@
<?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;
/**
* @deprecated will be removed with 2.0, use SystemConfiguration instead
*/
class FormConfiguration implements SystemBundleConfiguration
{
private $configuration;
public function __construct(SystemConfiguration $configuration)
{
$this->configuration = $configuration;
}
public function find(string $key)
{
if (strpos($key, $this->getPrefix() . '.') === false) {
$key = $this->getPrefix() . '.' . $key;
}
return $this->configuration->find($key);
}
public function getPrefix(): string
{
return 'defaults';
}
public function getCustomerDefaultTimezone(): ?string
{
return $this->configuration->getCustomerDefaultTimezone();
}
public function getCustomerDefaultCurrency(): string
{
return $this->configuration->getCustomerDefaultCurrency();
}
public function getCustomerDefaultCountry(): string
{
return $this->configuration->getCustomerDefaultCountry();
}
public function getUserDefaultTimezone(): ?string
{
return $this->configuration->getUserDefaultTimezone();
}
public function getUserDefaultTheme(): ?string
{
return $this->configuration->getUserDefaultTheme();
}
public function getUserDefaultLanguage(): string
{
return $this->configuration->getUserDefaultLanguage();
}
public function getUserDefaultCurrency(): string
{
return $this->configuration->getUserDefaultCurrency();
}
}

View File

@@ -11,11 +11,8 @@ namespace App\Configuration;
final class LdapConfiguration
{
private $configuration;
public function __construct(SystemConfiguration $configuration)
public function __construct(private SystemConfiguration $configuration)
{
$this->configuration = $configuration;
}
public function isActivated(): bool
@@ -25,16 +22,16 @@ final class LdapConfiguration
public function getRoleParameters(): array
{
return $this->configuration->getLdapRoleParameters();
return $this->configuration->findArray('ldap.role');
}
public function getUserParameters(): array
{
return $this->configuration->getLdapUserParameters();
return $this->configuration->findArray('ldap.user');
}
public function getConnectionParameters(): array
{
return $this->configuration->getLdapConnectionParameters();
return $this->configuration->findArray('ldap.connection');
}
}

View File

@@ -9,23 +9,12 @@
namespace App\Configuration;
use App\Utils\MomentFormatConverter;
use App\Constants;
final class LanguageFormattings
final class LocaleService
{
/**
* @var array
*/
private $settings;
/**
* @var MomentFormatConverter
*/
private $momentFormatter;
public function __construct(array $languageSettings)
public function __construct(private array $languageSettings)
{
$this->settings = $languageSettings;
$this->momentFormatter = new MomentFormatConverter();
}
/**
@@ -33,31 +22,19 @@ final class LanguageFormattings
*
* @return string[]
*/
public function getAvailableLanguages(): array
public function getAllLocales(): array
{
return array_keys($this->settings);
return array_keys($this->languageSettings);
}
/**
* Returns the format which is used by the form component to handle date values.
*
* @param string $locale
* @return string
*/
public function getDateTypeFormat(string $locale): string
public function isKnownLocale(string $language): bool
{
return $this->getConfig('date_type', $locale);
return \in_array($language, $this->getAllLocales());
}
/**
* Returns the format which is used by the Javascript component to handle date values.
*
* @param string $locale
* @return string
*/
public function getDatePickerFormat(string $locale): string
public function getDefaultLocale(): string
{
return $this->momentFormatter->convert($this->getDateTypeFormat($locale));
return Constants::DEFAULT_LOCALE;
}
/**
@@ -90,7 +67,7 @@ final class LanguageFormattings
*/
public function getDateTimeFormat(string $locale): string
{
return $this->getConfig('date_time', $locale);
return $this->getDateFormat($locale) . ' ' . $this->getTimeFormat($locale);
}
/**
@@ -101,24 +78,31 @@ final class LanguageFormattings
*/
public function getDurationFormat(string $locale): string
{
return $this->getConfig('duration', $locale);
return '%h:%m';
}
/**
* @param string $key
* @param string $locale
* @return string
*/
private function getConfig(string $key, string $locale): string
public function isRightToLeft(string $locale): bool
{
if (!isset($this->settings[$locale])) {
return $this->getConfig('rtl', $locale);
}
public function is24Hour(string $locale): bool
{
$format = $this->getTimeFormat($locale);
return stripos($format, 'a') === false;
}
private function getConfig(string $key, string $locale): string|bool
{
if (!isset($this->languageSettings[$locale])) {
throw new \InvalidArgumentException(sprintf('Unknown locale given: %s', $locale));
}
if (!isset($this->settings[$locale][$key])) {
if (!isset($this->languageSettings[$locale][$key])) {
throw new \InvalidArgumentException(sprintf('Unknown setting for locale %s: %s', $locale, $key));
}
return $this->settings[$locale][$key];
return $this->languageSettings[$locale][$key];
}
}

View File

@@ -11,14 +11,8 @@ namespace App\Configuration;
final class MailConfiguration
{
/**
* @var string
*/
private $mailFrom;
public function __construct(string $mailFrom)
public function __construct(private string $mailFrom)
{
$this->mailFrom = $mailFrom;
}
public function getFromAddress(): ?string

View File

@@ -14,11 +14,8 @@ namespace App\Configuration;
*/
final class SamlConfiguration implements SamlConfigurationInterface
{
private $configuration;
public function __construct(SystemConfiguration $configuration)
public function __construct(private SystemConfiguration $configuration)
{
$this->configuration = $configuration;
}
public function isActivated(): bool
@@ -31,19 +28,29 @@ final class SamlConfiguration implements SamlConfigurationInterface
return $this->configuration->getSamlTitle();
}
public function getProvider(): string
{
return $this->configuration->getSamlProvider();
}
public function getAttributeMapping(): array
{
return $this->configuration->getSamlAttributeMapping();
return $this->configuration->findArray('saml.mapping');
}
public function getRolesAttribute(): ?string
{
return $this->configuration->getSamlRolesAttribute();
$attr = $this->configuration->find('saml.roles.attribute');
if (empty($attr)) {
return null;
}
return (string) $attr;
}
public function getRolesMapping(): array
{
return $this->configuration->getSamlRolesMapping();
return $this->configuration->findArray('saml.roles.mapping');
}
public function isRolesResetOnLogin(): bool
@@ -53,6 +60,6 @@ final class SamlConfiguration implements SamlConfigurationInterface
public function getConnection(): array
{
return $this->configuration->getSamlConnection();
return $this->configuration->findArray('saml.connection');
}
}

View File

@@ -15,6 +15,8 @@ interface SamlConfigurationInterface
public function getTitle(): string;
public function getProvider(): string;
public function getAttributeMapping(): array;
public function getRolesAttribute(): ?string;

View File

@@ -1,212 +0,0 @@
<?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;
/**
* @internal do NOT use this trait, but access your configs via SystemConfiguration
*/
trait StringAccessibleConfigTrait
{
/**
* @var array
*/
protected $settings;
/**
* @var array
*/
protected $original;
/**
* @var ConfigLoaderInterface
*/
protected $repository;
/**
* @var bool
*/
protected $initialized = false;
public function __construct(ConfigLoaderInterface $repository, array $settings)
{
$this->repository = $repository;
$this->original = $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;
}
foreach ($this->getConfigurations($this->repository) as $configuration) {
$this->set($configuration->getName(), $configuration->getValue());
}
$this->initialized = true;
}
/**
* @return string
*/
abstract protected function getPrefix(): string;
/**
* @param string $key
* @return mixed
*/
public function default(string $key)
{
$key = $this->prepareSearchKey($key);
return $this->get($key, $this->original);
}
/**
* @param string $key
* @return string|int|bool|float|null|array
*/
public function find(string $key)
{
$this->prepare();
$key = $this->prepareSearchKey($key);
return $this->get($key, $this->settings);
}
private function prepareSearchKey(string $key): string
{
$prefix = $this->getPrefix() . '.';
$length = \strlen($prefix);
if (substr($key, 0, $length) === $prefix) {
$key = substr($key, $length);
}
return $key;
}
/**
* @param string $key
* @param array $config
* @return mixed
*/
private function get(string $key, array $config)
{
$keys = explode('.', $key);
$search = array_shift($keys);
if (!\array_key_exists($search, $config)) {
return null;
}
if (\is_array($config[$search]) && !empty($keys)) {
return $this->get(implode('.', $keys), $config[$search]);
}
return $config[$search];
}
public function has(string $key): bool
{
$this->prepare();
$key = $this->prepareSearchKey($key);
$keys = explode('.', $key);
$search = array_shift($keys);
if (!\array_key_exists($search, $this->settings)) {
return false;
}
return true;
}
public function offsetExists($offset): bool
{
return $this->has($offset);
}
/**
* @param $offset
* @return array|bool|float|int|string|null
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->find($offset);
}
/**
* @param mixed $offset
* @param mixed $value
* @throws \BadMethodCallException
*/
public function offsetSet($offset, $value)
{
$this->set($offset, $value);
}
/**
* @param mixed $offset
* @throws \BadMethodCallException
*/
public function offsetUnset($offset)
{
throw new \BadMethodCallException('SystemBundleConfiguration does not support offsetUnset()');
}
/**
* Set an array item to a given value using "dot" notation.
*
* If no key is given to the method, the entire array will be replaced.
*
* @see https://github.com/divineomega/array_undot
* @param string $key
* @param mixed $value
*
* @return array
*/
private function set(string $key, $value): array
{
$array = &$this->settings;
$keys = explode('.', $key);
while (\count($keys) > 1) {
$key = array_shift($keys);
if (!isset($array[$key]) || !\is_array($array[$key])) {
$array[$key] = [];
}
$array = &$array[$key];
}
$k = array_shift($keys);
if (\array_key_exists($k, $array)) {
if (\is_bool($array[$k])) {
$value = (bool) $value;
} elseif (\is_int($array[$k])) {
$value = (int) $value;
}
}
$array[$k] = $value;
return $array;
}
}

View File

@@ -1,24 +0,0 @@
<?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

@@ -9,21 +9,152 @@
namespace App\Configuration;
class SystemConfiguration implements SystemBundleConfiguration
final class SystemConfiguration
{
use StringAccessibleConfigTrait;
private bool $initialized = false;
public function getPrefix(): string
public function __construct(private ConfigLoaderInterface $repository, private ?array $settings)
{
return 'kimai';
}
protected function getConfigurations(ConfigLoaderInterface $repository): array
private function prepare(): void
{
return $repository->getConfiguration();
if ($this->initialized) {
return;
}
foreach ($this->repository->getConfigurations() as $configuration) {
$this->set($configuration->getName(), $configuration->getValue());
}
$this->initialized = true;
}
// ========== Login form ==========
/**
* Set an array item to a given value using "dot" notation.
*
* If no key is given to the method, the entire array will be replaced.
*
* @see https://github.com/divineomega/array_undot
* @param string $key
* @param mixed $value
* @return void
*/
private function set(string $key, $value): void
{
if (\array_key_exists($key, $this->settings)) {
if (\is_bool($this->settings[$key])) {
$value = (bool) $value;
} elseif (\is_int($this->settings[$key])) {
$value = (int) $value;
}
}
$this->settings[$key] = $value;
}
/**
* @param string $key
* @return string|int|bool|float|null
*/
public function find(string $key): string|int|bool|float|null
{
$this->prepare();
if (\array_key_exists($key, $this->settings)) {
return $this->settings[$key];
}
return null;
}
/**
* This method should be avoided if possible, use plain keys instead.
*
* @param string $key
* @return array
*/
public function findArray(string $key): array
{
$this->prepare();
$result = array_filter($this->settings, function ($settingName) use ($key): bool {
return str_starts_with($settingName, $key);
}, ARRAY_FILTER_USE_KEY);
$replaced = [];
foreach ($result as $settingName => $value) {
if (\is_bool($this->settings[$settingName])) {
$value = (bool) $value;
} elseif (\is_int($this->settings[$settingName])) {
$value = (int) $value;
}
$baseName = str_replace($key . '.', '', $settingName);
$keys = explode('.', $baseName);
$array = &$replaced;
while (\count($keys) > 1) {
$search = array_shift($keys);
/* @phpstan-ignore-next-line */
if (!\array_key_exists($search, $array) || !\is_array($array[$search])) {
$array[$search] = [];
}
$array = &$array[$search];
}
$array[array_shift($keys)] = $value;
}
return $replaced;
}
public function has(string $key): bool
{
$this->prepare();
if (\array_key_exists($key, $this->settings)) {
return true;
}
$result = array_filter($this->settings, function ($settingName) use ($key): bool {
return str_starts_with($settingName, $key);
}, ARRAY_FILTER_USE_KEY);
return \count($result) > 0;
}
// ========== Array access methods ==========
public function offsetExists($offset): bool
{
return $this->has($offset);
}
public function offsetGet($offset): mixed
{
return $this->find($offset);
}
/**
* @param mixed $offset
* @param mixed $value
* @throws \BadMethodCallException
*/
public function offsetSet($offset, $value)
{
$this->set($offset, $value);
}
/**
* @param mixed $offset
* @throws \BadMethodCallException
*/
public function offsetUnset($offset)
{
throw new \BadMethodCallException('SystemBundleConfiguration does not support offsetUnset()');
}
// ========== Authentication configurations ==========
public function isLoginFormActive(): bool
{
@@ -41,6 +172,10 @@ class SystemConfiguration implements SystemBundleConfiguration
public function isSelfRegistrationActive(): bool
{
if (!$this->isLoginFormActive()) {
return false;
}
return (bool) $this->find('user.registration');
}
@@ -56,11 +191,13 @@ class SystemConfiguration implements SystemBundleConfiguration
public function isPasswordResetActive(): bool
{
if (!$this->isLoginFormActive()) {
return false;
}
return (bool) $this->find('user.password_reset');
}
// ========== SAML configurations ==========
public function isSamlActive(): bool
{
return (bool) $this->find('saml.activate');
@@ -71,19 +208,9 @@ class SystemConfiguration implements SystemBundleConfiguration
return (string) $this->find('saml.title');
}
public function getSamlAttributeMapping(): array
public function getSamlProvider(): ?string
{
return (array) $this->find('saml.mapping');
}
public function getSamlRolesAttribute(): ?string
{
return (string) $this->find('saml.roles.attribute');
}
public function getSamlRolesMapping(): array
{
return (array) $this->find('saml.roles.mapping');
return $this->find('saml.provider');
}
public function isSamlRolesResetOnLogin(): bool
@@ -91,40 +218,13 @@ class SystemConfiguration implements SystemBundleConfiguration
return (bool) $this->find('saml.roles.resetOnLogin');
}
public function getSamlConnection(): array
{
return (array) $this->find('saml.connection');
}
// ========== LDAP configurations ==========
public function isLdapActive(): bool
{
return (bool) $this->find('ldap.activate');
}
public function getLdapRoleParameters(): array
{
return (array) $this->find('ldap.role');
}
public function getLdapUserParameters(): array
{
return (array) $this->find('ldap.user');
}
public function getLdapConnectionParameters(): array
{
return (array) $this->find('ldap.connection');
}
// ========== Calendar configurations ==========
public function getCalendarBusinessDays(): array
{
return (array) $this->find('calendar.businessHours.days');
}
public function getCalendarBusinessTimeBegin(): string
{
return (string) $this->find('calendar.businessHours.begin');
@@ -165,9 +265,9 @@ class SystemConfiguration implements SystemBundleConfiguration
return $this->find('calendar.google.api_key');
}
public function getCalendarGoogleSources(): ?array
public function getCalendarGoogleSources(): array
{
return $this->find('calendar.google.sources');
return $this->findArray('calendar.google.sources');
}
public function getCalendarSlotDuration(): string
@@ -272,18 +372,16 @@ class SystemConfiguration implements SystemBundleConfiguration
return (bool) $this->find('timesheet.markdown_content');
}
public function isTimesheetRequiresActivity(): bool
{
return (bool) $this->find('timesheet.rules.require_activity');
}
public function getTimesheetActiveEntriesHardLimit(): int
{
return (int) $this->find('timesheet.active_entries.hard_limit');
}
public function getTimesheetActiveEntriesSoftLimit(): int
{
@trigger_error('The configuration timesheet.active_entries.soft_limit is deprecated since 1.15', E_USER_DEPRECATED);
return $this->getTimesheetActiveEntriesHardLimit();
}
public function getTimesheetDefaultRoundingDays(): string
{
return (string) $this->find('timesheet.rounding.default.days');
@@ -309,32 +407,7 @@ class SystemConfiguration implements SystemBundleConfiguration
return (int) $this->find('timesheet.rounding.default.duration');
}
public function getTimesheetLockdownPeriodStart(): string
{
return (string) $this->find('timesheet.rules.lockdown_period_start');
}
public function getTimesheetLockdownPeriodEnd(): string
{
return (string) $this->find('timesheet.rules.lockdown_period_end');
}
public function getTimesheetLockdownGracePeriod(): string
{
return (string) $this->find('timesheet.rules.lockdown_grace_period');
}
public function getTimesheetLockdownTimeZone(): ?string
{
return $this->find('timesheet.rules.lockdown_period_timezone');
}
public function isTimesheetLockdownActive(): bool
{
return !empty($this->find('timesheet.rules.lockdown_period_start')) && !empty($this->find('timesheet.rules.lockdown_period_end'));
}
private function getIncrement(string $key, int $fallback, int $min = 1): ?int
private function getIncrement(string $key, int $fallback, int $min = 1): int
{
$config = $this->find($key);
@@ -344,27 +417,22 @@ class SystemConfiguration implements SystemBundleConfiguration
$config = (int) $config;
return $config < $min ? null : $config;
return max($config, $min);
}
public function getTimesheetIncrementDuration(): ?int
public function getTimesheetIncrementDuration(): int
{
return $this->getIncrement('timesheet.duration_increment', $this->getTimesheetDefaultRoundingDuration(), 1);
return $this->getIncrement('timesheet.duration_increment', $this->getTimesheetDefaultRoundingDuration(), 0);
}
public function getTimesheetIncrementBegin(): ?int
public function getTimesheetIncrementMinutes(): int
{
return $this->getIncrement('timesheet.time_increment', $this->getTimesheetDefaultRoundingBegin(), 0);
}
public function getTimesheetIncrementEnd(): ?int
{
return $this->getIncrement('timesheet.time_increment', $this->getTimesheetDefaultRoundingEnd(), 0);
return $this->getIncrement('timesheet.time_increment', $this->getTimesheetDefaultRoundingDuration(), 0);
}
public function getQuickEntriesRecentAmount(): int
{
return $this->getIncrement('quick_entry.recent_activities', 5, 0) ?? 5;
return $this->getIncrement('quick_entry.recent_activities', 5, 5);
}
// ========== Company configurations ==========
@@ -382,14 +450,9 @@ class SystemConfiguration implements SystemBundleConfiguration
// ========== Theme configurations ==========
public function isThemeColorsLimited(): bool
public function isShowAbout(): bool
{
return (bool) $this->find('theme.colors_limited');
}
public function isThemeRandomColors(): bool
{
return (bool) $this->find('theme.random_colors');
return (bool) $this->find('theme.show_about');
}
public function isThemeAllowAvatarUrls(): bool
@@ -397,11 +460,6 @@ class SystemConfiguration implements SystemBundleConfiguration
return (bool) $this->find('theme.avatar_url');
}
public function getThemeAutocompleteCharacters(): int
{
return (int) $this->find('theme.autocomplete_chars');
}
public function getThemeColorChoices(): ?string
{
$config = $this->find('theme.color_choices');
@@ -409,19 +467,7 @@ class SystemConfiguration implements SystemBundleConfiguration
return $config;
}
return $this->default('theme.color_choices');
}
// ========== Branding configurations ==========
public function getBrandingTitle(): ?string
{
return $this->find('theme.branding.title');
}
public function isAllowTagCreation(): bool
{
return (bool) $this->find('theme.tags_create');
return 'Silver|#c0c0c0';
}
// ========== Projects ==========

View File

@@ -1,77 +0,0 @@
<?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;
/**
* @internal might be deprecated in the future, use SystemConfiguration instead
*/
final class ThemeConfiguration implements \ArrayAccess
{
private $systemConfiguration;
public function __construct(SystemConfiguration $systemConfiguration)
{
$this->systemConfiguration = $systemConfiguration;
}
public function offsetExists($offset): bool
{
return $this->systemConfiguration->has('theme.' . $offset);
}
/**
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->systemConfiguration->find('theme.' . $offset);
}
/**
* @param mixed $offset
* @param mixed $value
* @throws \BadMethodCallException
*/
public function offsetSet($offset, $value): void
{
throw new \BadMethodCallException('ThemeConfiguration does not support offsetSet()');
}
/**
* @param mixed $offset
* @throws \BadMethodCallException
*/
public function offsetUnset($offset): void
{
throw new \BadMethodCallException('ThemeConfiguration does not support offsetUnset()');
}
/**
* @deprecated since 1.15
*/
public function isAllowTagCreation(): bool
{
return (bool) $this->offsetGet('tags_create');
}
/**
* @deprecated since 1.15
*/
public function getTitle(): ?string
{
$title = $this->offsetGet('branding.title');
if (null === $title) {
return null;
}
return (string) $title;
}
}

View File

@@ -1,117 +0,0 @@
<?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;
/**
* @deprecated since 1.13, use SystemConfiguration instead
*/
class TimesheetConfiguration implements SystemBundleConfiguration
{
private $configuration;
public function __construct(SystemConfiguration $configuration)
{
$this->configuration = $configuration;
}
public function find(string $key)
{
if (strpos($key, $this->getPrefix() . '.') === false) {
$key = $this->getPrefix() . '.' . $key;
}
return $this->configuration->find($key);
}
public function getPrefix(): string
{
return 'timesheet';
}
public function isAllowFutureTimes(): bool
{
return $this->configuration->isTimesheetAllowFutureTimes();
}
public function isAllowOverlappingRecords(): bool
{
return $this->configuration->isTimesheetAllowOverlappingRecords();
}
public function getTrackingMode(): string
{
return $this->configuration->getTimesheetTrackingMode();
}
public function getDefaultBeginTime(): string
{
return $this->configuration->getTimesheetDefaultBeginTime();
}
public function isMarkdownEnabled(): bool
{
return $this->configuration->isTimesheetMarkdownEnabled();
}
public function getActiveEntriesHardLimit(): int
{
return $this->configuration->getTimesheetActiveEntriesHardLimit();
}
public function getActiveEntriesSoftLimit(): int
{
return $this->configuration->getTimesheetActiveEntriesSoftLimit();
}
public function getDefaultRoundingDays(): string
{
return $this->configuration->getTimesheetDefaultRoundingDays();
}
public function getDefaultRoundingMode(): string
{
return $this->configuration->getTimesheetDefaultRoundingMode();
}
public function getDefaultRoundingBegin(): int
{
return $this->configuration->getTimesheetDefaultRoundingBegin();
}
public function getDefaultRoundingEnd(): int
{
return $this->configuration->getTimesheetDefaultRoundingEnd();
}
public function getDefaultRoundingDuration(): int
{
return $this->configuration->getTimesheetDefaultRoundingDuration();
}
public function getLockdownPeriodStart(): string
{
return $this->configuration->getTimesheetLockdownPeriodStart();
}
public function getLockdownPeriodEnd(): string
{
return $this->configuration->getTimesheetLockdownPeriodEnd();
}
public function getLockdownGracePeriod(): string
{
return $this->configuration->getTimesheetLockdownGracePeriod();
}
public function isLockdownActive(): bool
{
return $this->configuration->isTimesheetLockdownActive();
}
}