'Light', 'dark' => 'Dark', ]; } $themes = include $file; if (!is_array($themes)) { return [ 'light' => 'Light', 'dark' => 'Dark', ]; } $clean = []; foreach ($themes as $key => $label) { $key = strtolower(trim((string) $key)); $label = trim((string) $label); if ($key !== '' && $label !== '') { $clean[$key] = $label; } } return $clean ?: [ 'light' => 'Light', 'dark' => 'Dark', ]; } function appDefaultLocale(): ?string { $locale = appSetting('app_locale'); if ($locale === null) { return null; } $available = defined('APP_LOCALES') ? APP_LOCALES : []; if ($available && !in_array($locale, $available, true)) { return null; } return $locale; } function appDefaultTheme(): string { $themes = appThemes(); $setting = appSetting('app_theme'); if ($setting !== null && isset($themes[$setting])) { return $setting; } $envTheme = getenv('APP_THEME') ?: 'light'; $envTheme = strtolower(trim((string) $envTheme)); return isset($themes[$envTheme]) ? $envTheme : 'light'; } function currentTheme(): string { $themes = appThemes(); $theme = appDefaultTheme(); if (!allowUserTheme()) { return $theme; } $user = $_SESSION['user'] ?? []; $userTheme = strtolower(trim((string) ($user['theme'] ?? ''))); if ($userTheme !== '' && isset($themes[$userTheme])) { return $userTheme; } return $theme; } function allowUserTheme(): bool { $value = appSetting('app_theme_user'); if ($value === null || $value === '') { return true; } return in_array(strtolower($value), ['1', 'true', 'yes', 'on'], true); } function allowRegistration(): bool { $value = appSetting('app_registration'); if ($value === null || $value === '') { return true; } return in_array(strtolower($value), ['1', 'true', 'yes', 'on'], true); } function appPrimaryColor(): ?string { $tenantColor = $_SESSION['current_tenant']['primary_color'] ?? null; if ($tenantColor !== null) { $tenantColor = strtolower(trim((string) $tenantColor)); if (preg_match('/^#([0-9a-f]{3}|[0-9a-f]{6})$/i', $tenantColor)) { return $tenantColor; } } $value = appSetting('app_primary_color'); if ($value === null) { return null; } $value = strtolower(trim($value)); if (!preg_match('/^#([0-9a-f]{3}|[0-9a-f]{6})$/i', $value)) { return null; } return $value; } function appPrimaryCssVars(): string { $hex = appPrimaryColor(); if ($hex === null) { return ''; } $hex = ltrim($hex, '#'); if (strlen($hex) === 3) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } $r = hexdec(substr($hex, 0, 2)) / 255; $g = hexdec(substr($hex, 2, 2)) / 255; $b = hexdec(substr($hex, 4, 2)) / 255; $monoThreshold = 0.000001; if (abs($r - $g) < $monoThreshold && abs($g - $b) < $monoThreshold) { $l = round($r * 100, 2) . '%'; return "--app-primary-h-base: 0; --app-primary-s-base: 0%; --app-primary-l-base: {$l}; --app-primary-h-light: 0; --app-primary-s-light: 0%; --app-primary-l-light: {$l};"; } $max = max($r, $g, $b); $min = min($r, $g, $b); $delta = $max - $min; if ($delta == 0.0) { $l = round((($max + $min) / 2) * 100, 2) . '%'; return "--app-primary-h-base: 0; --app-primary-s-base: 0%; --app-primary-l-base: {$l}; --app-primary-h-light: 0; --app-primary-s-light: 0%; --app-primary-l-light: {$l};"; } $h = 0.0; if ($max === $r) { $h = 60 * fmod((($g - $b) / $delta), 6); } elseif ($max === $g) { $h = 60 * ((($b - $r) / $delta) + 2); } else { $h = 60 * ((($r - $g) / $delta) + 4); } if ($h < 0) { $h += 360; } $l = ($max + $min) / 2; $denominator = 1 - abs(2 * $l - 1); if ($delta === 0.0 || $denominator == 0.0) { $s = 0.0; } else { $s = $delta / $denominator; } $h = round($h, 2); $s = round($s * 100, 2) . '%'; $l = round($l * 100, 2) . '%'; return "--app-primary-h-base: {$h}; --app-primary-s-base: {$s}; --app-primary-l-base: {$l}; --app-primary-h-light: {$h}; --app-primary-s-light: {$s}; --app-primary-l-light: {$l};"; } function appLogoUrl(?int $size = null): string { if (class_exists('MintyPHP\\Service\\Branding\\BrandingLogoService') && \MintyPHP\Service\Branding\BrandingLogoService::hasLogo()) { $query = $size ? '?size=' . (int) $size : ''; return lurl('branding/logo' . $query); } return asset('brand/logo.svg'); } function appFaviconUrl(string $file): string { $tenantUuid = $_SESSION['current_tenant']['uuid'] ?? ''; if ($tenantUuid !== '' && class_exists('MintyPHP\\Service\\Tenant\\TenantFaviconService')) { if (\MintyPHP\Service\Tenant\TenantFaviconService::hasFavicon($tenantUuid)) { return asset('favicon/tenants/' . $tenantUuid . '/favicon/' . ltrim($file, '/')); } } return asset('favicon/' . ltrim($file, '/')); } function d() { return call_user_func_array('MintyPHP\\Debugger::debug', func_get_args()); } function sortByDescription(array &$items): void { usort($items, static fn($a, $b) => strcasecmp((string) ($a['description'] ?? ''), (string) ($b['description'] ?? '')) ); }