mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-10-16 16:37:12 +00:00
[Web] Update Bootstrap to 5.3.8, add theme support
This commit is contained in:
18 files changed
+4120
-3095
No files matched your search
@@ -233,6 +233,38 @@ function customize($_action, $_item, $_data = null) {
|
||||
'msg' => 'custom_login_modified'
|
||||
);
|
||||
break;
|
||||
case 'ui_theme':
|
||||
$ui_theme = is_array($_data['ui_theme']) ? (string)reset($_data['ui_theme']) : (string)$_data['ui_theme'];
|
||||
if ($ui_theme !== '' && !array_key_exists($ui_theme, customize('get', 'ui_themes'))) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_item, $_data),
|
||||
'msg' => 'ui_theme_invalid'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if ($ui_theme === '') {
|
||||
$redis->del('UI_THEME');
|
||||
}
|
||||
else {
|
||||
$redis->set('UI_THEME', $ui_theme);
|
||||
}
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_item, $_data),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_item, $_data),
|
||||
'msg' => 'ui_theme_modified'
|
||||
);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'delete':
|
||||
@@ -402,6 +434,42 @@ function customize($_action, $_item, $_data = null) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'ui_themes':
|
||||
// theme folders in css/themes/<name>/ with a theme.css
|
||||
$themes = array();
|
||||
foreach (glob('/web/css/themes/*/theme.css') as $theme_css) {
|
||||
$theme_dir = dirname($theme_css);
|
||||
$theme = basename($theme_dir);
|
||||
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $theme)) {
|
||||
continue;
|
||||
}
|
||||
$meta = json_decode(@file_get_contents($theme_dir . '/theme.json'), true);
|
||||
$themes[$theme] = array(
|
||||
'name' => (!empty($meta['name'])) ? $meta['name'] : $theme,
|
||||
'description' => (!empty($meta['description'])) ? $meta['description'] : '',
|
||||
'dark' => file_exists($theme_dir . '/dark.css')
|
||||
);
|
||||
}
|
||||
ksort($themes);
|
||||
return $themes;
|
||||
break;
|
||||
case 'ui_theme':
|
||||
try {
|
||||
$ui_theme = $redis->get('UI_THEME');
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_item, $_data),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (empty($ui_theme) || !preg_match('/^[a-zA-Z0-9_-]+$/', $ui_theme) || !file_exists('/web/css/themes/' . $ui_theme . '/theme.css')) {
|
||||
return '';
|
||||
}
|
||||
return $ui_theme;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ if (preg_match("/debug/i", $_SERVER['REQUEST_URI'])) {
|
||||
if ($_SERVER['REQUEST_URI'] == '/') {
|
||||
$css_minifier->add('/web/css/site/index.css');
|
||||
}
|
||||
if (file_exists('/web/css/themes/'.$UI_THEME.'/theme.css')) {
|
||||
$css_minifier->add('/web/css/themes/'.$UI_THEME.'/theme.css');
|
||||
}
|
||||
|
||||
$hash = $css_minifier->getDataHash();
|
||||
$CSSPath = '/tmp/' . $hash . '.css';
|
||||
@@ -30,6 +33,17 @@ if(!file_exists($CSSPath)) {
|
||||
cleanupCSS($hash);
|
||||
}
|
||||
|
||||
// dark mode bundle, core dark mode + theme dark.css
|
||||
$dark_minifier = new CSSminifierExtended('/web/css/themes/mailcow-darkmode.css');
|
||||
if (file_exists('/web/css/themes/'.$UI_THEME.'/dark.css')) {
|
||||
$dark_minifier->add('/web/css/themes/'.$UI_THEME.'/dark.css');
|
||||
}
|
||||
$DarkCSSPath = '/tmp/' . $hash . '-' . $dark_minifier->getDataHash() . '.css';
|
||||
if(!file_exists($DarkCSSPath)) {
|
||||
$dark_minifier->minify($DarkCSSPath);
|
||||
}
|
||||
$dark_css_path = '/cache/' . basename($DarkCSSPath);
|
||||
|
||||
$mailcow_apps_processed = $MAILCOW_APPS;
|
||||
$app_links = customize('get', 'app_links');
|
||||
$app_links_processed = $app_links;
|
||||
@@ -77,6 +91,7 @@ $globalVariables = [
|
||||
'dual_login' => @$_SESSION['dual-login'],
|
||||
'ui_texts' => $UI_TEXTS,
|
||||
'css_path' => '/cache/'.basename($CSSPath),
|
||||
'dark_css_path' => $dark_css_path,
|
||||
'logo' => customize('get', 'main_logo'),
|
||||
'logo_dark' => customize('get', 'main_logo_dark'),
|
||||
'available_languages' => $AVAILABLE_LANGUAGES,
|
||||
|
||||
@@ -319,10 +319,16 @@ $css_minifier = new CSSminifierExtended();
|
||||
$css_dir = array_diff(scandir('/web/css/build'), array('..', '.'));
|
||||
// get customized ui data
|
||||
$UI_TEXTS = customize('get', 'ui_texts');
|
||||
// theme selected in admin UI overrides $UI_THEME
|
||||
if ($ui_theme_selected = customize('get', 'ui_theme')) {
|
||||
$UI_THEME = $ui_theme_selected;
|
||||
}
|
||||
|
||||
|
||||
// minify bootstrap theme
|
||||
if (file_exists('/web/css/themes/'.$UI_THEME.'-bootstrap.css'))
|
||||
if (file_exists('/web/css/themes/'.$UI_THEME.'/bootstrap.css'))
|
||||
$css_minifier->add('/web/css/themes/'.$UI_THEME.'/bootstrap.css');
|
||||
elseif (file_exists('/web/css/themes/'.$UI_THEME.'-bootstrap.css'))
|
||||
$css_minifier->add('/web/css/themes/'.$UI_THEME.'-bootstrap.css');
|
||||
else
|
||||
$css_minifier->add('/web/css/themes/lumen-bootstrap.css');
|
||||
|
||||
@@ -121,6 +121,8 @@ $AVAILABLE_LANGUAGES = array(
|
||||
// default theme is lumen
|
||||
// additional themes can be found here: https://bootswatch.com/
|
||||
// copy them to data/web/css/themes/{THEME-NAME}-bootstrap.css
|
||||
// or use a theme folder data/web/css/themes/{THEME-NAME}/ (theme.css, optional dark.css, bootstrap.css, theme.json)
|
||||
// theme folders can be selected in System > Configuration > Customize, which overrides $UI_THEME
|
||||
$UI_THEME = "lumen";
|
||||
|
||||
// Show DKIM private keys - false by default
|
||||
|
||||
Reference in new issue
Block a user