Edit file File name : SystemConfiguration.php Content :<?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(); } // ========== Login form ========== public function isLoginFormActive(): bool { if ($this->isLdapActive()) { return true; } // if SAML is active, the login form can be deactivated if (!$this->isSamlActive()) { return true; } return (bool) $this->find('user.login'); } public function isSelfRegistrationActive(): bool { return (bool) $this->find('user.registration'); } public function getPasswordResetTokenLifetime(): int { return (int) $this->find('user.password_reset_token_ttl'); } public function getPasswordResetRetryLifetime(): int { return (int) $this->find('user.password_reset_retry_ttl'); } public function isPasswordResetActive(): bool { return (bool) $this->find('user.password_reset'); } // ========== SAML configurations ========== public function isSamlActive(): bool { return (bool) $this->find('saml.activate'); } public function getSamlTitle(): string { return (string) $this->find('saml.title'); } public function getSamlAttributeMapping(): array { 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'); } 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'); } public function getCalendarBusinessTimeEnd(): string { return (string) $this->find('calendar.businessHours.end'); } public function getCalendarTimeframeBegin(): string { return (string) $this->find('calendar.visibleHours.begin'); } public function getCalendarTimeframeEnd(): string { return (string) $this->find('calendar.visibleHours.end'); } public function getCalendarDayLimit(): int { return (int) $this->find('calendar.day_limit'); } public function isCalendarShowWeekNumbers(): bool { return (bool) $this->find('calendar.week_numbers'); } public function isCalendarShowWeekends(): bool { return (bool) $this->find('calendar.weekends'); } public function getCalendarGoogleApiKey(): ?string { return $this->find('calendar.google.api_key'); } public function getCalendarGoogleSources(): ?array { return $this->find('calendar.google.sources'); } public function getCalendarSlotDuration(): string { return (string) $this->find('calendar.slot_duration'); } public function getCalendarDragAndDropMaxEntries(): int { return (int) $this->find('calendar.dragdrop_amount'); } // ========== Customer configurations ========== public function getCustomerDefaultTimezone(): ?string { return $this->find('defaults.customer.timezone'); } public function getCustomerDefaultCurrency(): string { return $this->find('defaults.customer.currency'); } public function getCustomerDefaultCountry(): string { return $this->find('defaults.customer.country'); } // ========== User configurations ========== public function getUserDefaultTimezone(): ?string { return $this->find('defaults.user.timezone'); } public function getUserDefaultTheme(): ?string { return $this->find('defaults.user.theme'); } public function getUserDefaultLanguage(): string { return $this->find('defaults.user.language'); } // TODO this is only used to display the hourly rate in the user profile public function getUserDefaultCurrency(): string { return $this->find('defaults.user.currency'); } // ========== Timesheet configurations ========== /* public function getTimesheetBreakWarningDuration(): int { return (int) $this->find('timesheet.rules.break_warning_duration'); } */ public function getTimesheetLongRunningDuration(): int { return (int) $this->find('timesheet.rules.long_running_duration'); } public function getTimesheetDefaultBeginTime(): string { return (string) $this->find('timesheet.default_begin'); } public function isTimesheetAllowFutureTimes(): bool { return (bool) $this->find('timesheet.rules.allow_future_times'); } public function isTimesheetAllowOverbookingBudget(): bool { return (bool) $this->find('timesheet.rules.allow_overbooking_budget'); } public function isTimesheetAllowOverlappingRecords(): bool { return (bool) $this->find('timesheet.rules.allow_overlapping_records'); } public function getTimesheetTrackingMode(): string { return (string) $this->find('timesheet.mode'); } public function isTimesheetMarkdownEnabled(): bool { return (bool) $this->find('timesheet.markdown_content'); } 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'); } public function getTimesheetDefaultRoundingMode(): string { return (string) $this->find('timesheet.rounding.default.mode'); } public function getTimesheetDefaultRoundingBegin(): int { return (int) $this->find('timesheet.rounding.default.begin'); } public function getTimesheetDefaultRoundingEnd(): int { return (int) $this->find('timesheet.rounding.default.end'); } public function getTimesheetDefaultRoundingDuration(): int { 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 { $config = $this->find($key); if ($config === null || trim($config) === '') { return $fallback; } $config = (int) $config; return $config < $min ? null : $config; } public function getTimesheetIncrementDuration(): ?int { return $this->getIncrement('timesheet.duration_increment', $this->getTimesheetDefaultRoundingDuration(), 1); } public function getTimesheetIncrementBegin(): ?int { return $this->getIncrement('timesheet.time_increment', $this->getTimesheetDefaultRoundingBegin(), 0); } public function getTimesheetIncrementEnd(): ?int { return $this->getIncrement('timesheet.time_increment', $this->getTimesheetDefaultRoundingEnd(), 0); } public function getQuickEntriesRecentAmount(): int { return $this->getIncrement('quick_entry.recent_activities', 5, 0) ?? 5; } // ========== Company configurations ========== public function getFinancialYearStart(): ?string { $start = $this->find('company.financial_year'); if (empty($start)) { return null; } return (string) $start; } // ========== Theme configurations ========== public function isThemeColorsLimited(): bool { return (bool) $this->find('theme.colors_limited'); } public function isThemeRandomColors(): bool { return (bool) $this->find('theme.random_colors'); } public function isThemeAllowAvatarUrls(): bool { 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'); if (!empty($config)) { 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'); } } Save