Merge branch '0.11-dev' of github.com:Froxlor/Froxlor into 0.11-dev
This commit is contained in:
@@ -47,7 +47,7 @@ return array(
|
||||
'type' => 'select',
|
||||
'default' => 'Froxlor',
|
||||
'option_options_method' => array(
|
||||
'\\Froxlor\\UI\\Template',
|
||||
'\\Froxlor\\UI\\Panel\\UI',
|
||||
'getThemes'
|
||||
),
|
||||
'save_method' => 'storeSettingDefaultTheme'
|
||||
@@ -74,7 +74,8 @@ return array(
|
||||
'varname' => 'natsorting',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_paging' => array(
|
||||
'label' => $lng['serversettings']['paging'],
|
||||
@@ -121,7 +122,8 @@ return array(
|
||||
'type' => 'email',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_decimal_places' => array(
|
||||
'label' => $lng['serversettings']['decimal_places'],
|
||||
@@ -131,7 +133,8 @@ return array(
|
||||
'min' => 0,
|
||||
'max' => 15,
|
||||
'default' => 4,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_phpmyadmin_url' => array(
|
||||
'label' => $lng['serversettings']['phpmyadmin_url'],
|
||||
@@ -166,7 +169,8 @@ return array(
|
||||
'varname' => 'show_version_login',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'admin_show_version_footer' => array(
|
||||
'label' => $lng['admin']['show_version_footer'],
|
||||
@@ -207,7 +211,8 @@ return array(
|
||||
'varname' => 'allow_domain_change_admin',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_allow_domain_change_customer' => array(
|
||||
'label' => $lng['serversettings']['panel_allow_domain_change_customer'],
|
||||
@@ -215,7 +220,8 @@ return array(
|
||||
'varname' => 'allow_domain_change_customer',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_phpconfigs_hidestdsubdomain' => array(
|
||||
'label' => $lng['serversettings']['panel_phpconfigs_hidestdsubdomain'],
|
||||
@@ -223,7 +229,8 @@ return array(
|
||||
'varname' => 'phpconfigs_hidestdsubdomain',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_customer_hide_options' => array(
|
||||
'label' => $lng['serversettings']['panel_customer_hide_options'],
|
||||
@@ -248,7 +255,8 @@ return array(
|
||||
'traffic.ftp' => $lng['menue']['traffic']['traffic'] . " / FTP",
|
||||
'traffic.mail' => $lng['menue']['traffic']['traffic'] . " / Mail"
|
||||
],
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_imprint_url' => array(
|
||||
'label' => $lng['serversettings']['imprint_url'],
|
||||
|
||||
@@ -128,7 +128,8 @@ return array(
|
||||
'varname' => 'password_regex',
|
||||
'type' => 'text',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'customer_accountprefix' => array(
|
||||
'label' => $lng['serversettings']['accountprefix'],
|
||||
|
||||
@@ -144,7 +144,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_regexp' => '/^[a-zA-Z0-9]{1,6}$/',
|
||||
'default' => 'html',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_store_index_file_subs' => array(
|
||||
'label' => $lng['serversettings']['system_store_index_file_subs'],
|
||||
@@ -195,7 +196,6 @@ return array(
|
||||
'default' => 90,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
|
||||
'system_mail_use_smtp' => array(
|
||||
'label' => $lng['serversettings']['mail_use_smtp'],
|
||||
'settinggroup' => 'system',
|
||||
@@ -260,7 +260,8 @@ return array(
|
||||
'varname' => 'apply_specialsettings_default',
|
||||
'type' => 'checkbox',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_apply_phpconfigs_default' => array(
|
||||
'label' => $lng['serversettings']['apply_phpconfigs_default'],
|
||||
@@ -268,7 +269,8 @@ return array(
|
||||
'varname' => 'apply_phpconfigs_default',
|
||||
'type' => 'checkbox',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_domaindefaultalias' => array(
|
||||
'label' => $lng['admin']['domaindefaultalias'],
|
||||
@@ -281,15 +283,17 @@ return array(
|
||||
'1' => $lng['domains']['serveraliasoption_www'],
|
||||
'2' => $lng['domains']['serveraliasoption_none']
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'hide_incompatible_settings' => array(
|
||||
'label' => $lng['serversettings']['hide_incompatible_settings'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'hide_incompatible_settings',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -39,7 +39,8 @@ return array(
|
||||
'string_regexp' => '/^(([a-z0-9\-\._]+, ?)*[a-z0-9\-\._]+)?$/i',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
/**
|
||||
* SSL / Let's Encrypt
|
||||
@@ -75,12 +76,13 @@ return array(
|
||||
'type' => 'number',
|
||||
'min' => 0,
|
||||
'max' => 94608000, // 3-years
|
||||
'default' => 0,
|
||||
'default' => 10368000,
|
||||
'save_method' => 'storeSettingField',
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array(
|
||||
'\Froxlor\Settings\FroxlorVhostSettings',
|
||||
'hasVhostContainerEnabled'
|
||||
), true)
|
||||
), true),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_hsts_incsub' => array(
|
||||
'label' => $lng['admin']['domain_hsts_incsub'],
|
||||
@@ -92,7 +94,8 @@ return array(
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array(
|
||||
'\Froxlor\Settings\FroxlorVhostSettings',
|
||||
'hasVhostContainerEnabled'
|
||||
), true)
|
||||
), true),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_hsts_preload' => array(
|
||||
'label' => $lng['admin']['domain_hsts_preload'],
|
||||
@@ -104,7 +107,8 @@ return array(
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array(
|
||||
'\Froxlor\Settings\FroxlorVhostSettings',
|
||||
'hasVhostContainerEnabled'
|
||||
), true)
|
||||
), true),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_honorcipherorder' => array(
|
||||
'label' => $lng['admin']['domain_honorcipherorder'],
|
||||
@@ -116,7 +120,8 @@ return array(
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array(
|
||||
'\Froxlor\Settings\FroxlorVhostSettings',
|
||||
'hasVhostContainerEnabled'
|
||||
), true)
|
||||
), true),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_sessiontickets' => array(
|
||||
'label' => $lng['admin']['domain_sessiontickets'],
|
||||
@@ -128,7 +133,8 @@ return array(
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array(
|
||||
'\Froxlor\Settings\FroxlorVhostSettings',
|
||||
'hasVhostContainerEnabled'
|
||||
), true)
|
||||
), true),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
/**
|
||||
* FCGID
|
||||
|
||||
@@ -19,6 +19,7 @@ return array(
|
||||
'crond' => array(
|
||||
'title' => $lng['admin']['cronsettings'],
|
||||
'icon' => 'fa-solid fa-clock-rotate-left',
|
||||
'advanced_mode' => true,
|
||||
'fields' => array(
|
||||
'system_cronconfig' => array(
|
||||
'label' => $lng['serversettings']['system_cronconfig'],
|
||||
|
||||
@@ -60,7 +60,8 @@ return array(
|
||||
'visible' => (\Froxlor\Settings::Get('system.mod_fcgid') == 0 && \Froxlor\Settings::Get('phpfpm.enabled') == 0),
|
||||
'websrv_avail' => array(
|
||||
'apache2'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_http2_support' => array(
|
||||
'label' => $lng['serversettings']['http2_support'],
|
||||
@@ -84,7 +85,8 @@ return array(
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl')
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl'),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_httpuser' => array(
|
||||
'label' => $lng['admin']['webserver_user'],
|
||||
@@ -147,7 +149,8 @@ return array(
|
||||
'save_method' => 'storeSettingField',
|
||||
'websrv_avail' => array(
|
||||
'apache2'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_logfiles_piped' => array(
|
||||
'label' => $lng['serversettings']['logfiles_piped'],
|
||||
@@ -158,7 +161,8 @@ return array(
|
||||
'save_method' => 'storeSettingField',
|
||||
'websrv_avail' => array(
|
||||
'apache2'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_logfiles_format' => array(
|
||||
'label' => $lng['serversettings']['logfiles_format'],
|
||||
@@ -172,7 +176,8 @@ return array(
|
||||
'apache2',
|
||||
'nginx'
|
||||
),
|
||||
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
|
||||
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1,
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_logfiles_type' => array(
|
||||
'label' => $lng['serversettings']['logfiles_type'],
|
||||
@@ -227,7 +232,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_deactivateddocroot' => array(
|
||||
'label' => $lng['serversettings']['deactivateddocroot'],
|
||||
@@ -245,7 +251,8 @@ return array(
|
||||
'varname' => 'default_vhostconf',
|
||||
'type' => 'textarea',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_default_sslvhostconf' => array(
|
||||
'label' => $lng['serversettings']['default_sslvhostconf'],
|
||||
@@ -254,7 +261,8 @@ return array(
|
||||
'type' => 'textarea',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') == 1
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') == 1,
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_include_default_vhostconf' => array(
|
||||
'label' => $lng['serversettings']['includedefault_sslvhostconf'],
|
||||
@@ -262,7 +270,8 @@ return array(
|
||||
'varname' => 'include_default_vhostconf',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_apache_globaldiropt' => array(
|
||||
'label' => $lng['serversettings']['apache_globaldiropt'],
|
||||
@@ -274,7 +283,8 @@ return array(
|
||||
'visible' => (\Froxlor\Settings::Get('system.mod_fcgid') == 0 && \Froxlor\Settings::Get('phpfpm.enabled') == 0),
|
||||
'websrv_avail' => array(
|
||||
'apache2'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_apachereload_command' => array(
|
||||
'label' => $lng['serversettings']['apachereload_command'],
|
||||
@@ -324,7 +334,8 @@ return array(
|
||||
'varname' => 'enabled',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'defaultwebsrverrhandler_err401' => array(
|
||||
'label' => $lng['serversettings']['defaultwebsrverrhandler_err401'],
|
||||
@@ -336,7 +347,8 @@ return array(
|
||||
'websrv_avail' => array(
|
||||
'apache2',
|
||||
'nginx'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'defaultwebsrverrhandler_err403' => array(
|
||||
'label' => $lng['serversettings']['defaultwebsrverrhandler_err403'],
|
||||
@@ -348,7 +360,8 @@ return array(
|
||||
'websrv_avail' => array(
|
||||
'apache2',
|
||||
'nginx'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'defaultwebsrverrhandler_err404' => array(
|
||||
'label' => $lng['serversettings']['defaultwebsrverrhandler_err404'],
|
||||
@@ -356,7 +369,8 @@ return array(
|
||||
'varname' => 'err404',
|
||||
'type' => 'text',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'defaultwebsrverrhandler_err500' => array(
|
||||
'label' => $lng['serversettings']['defaultwebsrverrhandler_err500'],
|
||||
@@ -368,7 +382,8 @@ return array(
|
||||
'websrv_avail' => array(
|
||||
'apache2',
|
||||
'nginx'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'customredirect_enabled' => array(
|
||||
'label' => $lng['serversettings']['customredirect_enabled'],
|
||||
|
||||
@@ -53,7 +53,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_emptyallowed' => false,
|
||||
'default' => 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_tlsv13_cipher_list' => array(
|
||||
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list'],
|
||||
@@ -63,7 +64,8 @@ return array(
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_ssl_cert_file' => array(
|
||||
'label' => $lng['serversettings']['ssl']['ssl_cert_file'],
|
||||
@@ -113,7 +115,8 @@ return array(
|
||||
'string_emptyallowed' => false,
|
||||
'default' => 'shmcb:/var/run/apache2/ocsp-stapling.cache(131072)',
|
||||
'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_sessionticketsenabled' => array(
|
||||
'label' => $lng['admin']['domain_sessionticketsenabled'],
|
||||
@@ -122,7 +125,8 @@ return array(
|
||||
'type' => 'checkbox',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField',
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') && (\Froxlor\Settings::Get('system.webserver') == "nginx" || (\Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1))
|
||||
'visible' => \Froxlor\Settings::Get('system.use_ssl') && (\Froxlor\Settings::Get('system.webserver') == "nginx" || (\Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1)),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_leenabled' => array(
|
||||
'label' => $lng['serversettings']['leenabled'],
|
||||
@@ -140,7 +144,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_type' => 'file',
|
||||
'default' => '/root/.acme.sh/acme.sh',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_letsencryptacmeconf' => array(
|
||||
'label' => $lng['serversettings']['letsencryptacmeconf'],
|
||||
@@ -188,7 +193,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_emptyallowed' => false,
|
||||
'default' => \Froxlor\Froxlor::getInstallDir(),
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_letsencryptkeysize' => array(
|
||||
'label' => $lng['serversettings']['letsencryptkeysize'],
|
||||
@@ -215,7 +221,8 @@ return array(
|
||||
'256' => 'ec-256',
|
||||
'384' => 'ec-384'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_letsencryptreuseold' => array(
|
||||
'label' => $lng['serversettings']['letsencryptreuseold'],
|
||||
@@ -223,7 +230,8 @@ return array(
|
||||
'varname' => 'letsencryptreuseold',
|
||||
'type' => 'checkbox',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_disable_le_selfcheck' => array(
|
||||
'label' => $lng['serversettings']['le_domain_dnscheck'],
|
||||
|
||||
@@ -68,7 +68,8 @@ return array(
|
||||
'string_delimiter' => ':',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '/usr/share/php/:/usr/share/php5/',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mod_fcgid_wrapper' => array(
|
||||
'label' => $lng['serversettings']['mod_fcgid']['wrapper'],
|
||||
@@ -83,7 +84,8 @@ return array(
|
||||
'save_method' => 'storeSettingField',
|
||||
'websrv_avail' => array(
|
||||
'apache2'
|
||||
)
|
||||
),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mod_fcgid_starter' => array(
|
||||
'label' => $lng['serversettings']['mod_fcgid']['starter'],
|
||||
@@ -92,7 +94,8 @@ return array(
|
||||
'type' => 'number',
|
||||
'min' => 0,
|
||||
'default' => 0,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mod_fcgid_maxrequests' => array(
|
||||
'label' => $lng['serversettings']['mod_fcgid']['maxrequests'],
|
||||
@@ -100,7 +103,8 @@ return array(
|
||||
'varname' => 'mod_fcgid_maxrequests',
|
||||
'type' => 'number',
|
||||
'default' => 250,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mod_fcgid_defaultini' => array(
|
||||
'label' => $lng['serversettings']['mod_fcgid']['defaultini'],
|
||||
@@ -119,7 +123,8 @@ return array(
|
||||
'varname' => 'mod_fcgid_idle_timeout',
|
||||
'type' => 'number',
|
||||
'default' => 30,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -52,7 +52,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_type' => 'confdir',
|
||||
'default' => '/var/www/php-fpm/',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_phpfpm_tmpdir' => array(
|
||||
'label' => $lng['serversettings']['mod_fcgid']['tmpdir'],
|
||||
@@ -72,7 +73,8 @@ return array(
|
||||
'string_delimiter' => ':',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '/usr/share/php/:/usr/share/php5/',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_phpfpm_envpath' => array(
|
||||
'label' => $lng['serversettings']['phpfpm_settings']['envpath'],
|
||||
@@ -83,7 +85,8 @@ return array(
|
||||
'string_delimiter' => ':',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '/usr/local/bin:/usr/bin:/bin',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_phpfpm_fastcgi_ipcdir' => array(
|
||||
'label' => $lng['serversettings']['phpfpm_settings']['ipcdir'],
|
||||
@@ -92,7 +95,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_type' => 'dir',
|
||||
'default' => '/var/lib/apache2/fastcgi/',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_phpfpm_use_mod_proxy' => array(
|
||||
'label' => $lng['phpfpm']['use_mod_proxy'],
|
||||
@@ -109,7 +113,8 @@ return array(
|
||||
'varname' => 'ini_flags',
|
||||
'type' => 'textarea',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_phpfpm_ini_values' => array(
|
||||
'label' => $lng['phpfpm']['ini_values'],
|
||||
@@ -117,7 +122,8 @@ return array(
|
||||
'varname' => 'ini_values',
|
||||
'type' => 'textarea',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_phpfpm_ini_admin_flags' => array(
|
||||
'label' => $lng['phpfpm']['ini_admin_flags'],
|
||||
@@ -125,7 +131,8 @@ return array(
|
||||
'varname' => 'ini_admin_flags',
|
||||
'type' => 'textarea',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_phpfpm_ini_admin_values' => array(
|
||||
'label' => $lng['phpfpm']['ini_admin_values'],
|
||||
@@ -133,7 +140,8 @@ return array(
|
||||
'varname' => 'ini_admin_values',
|
||||
'type' => 'textarea',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -91,7 +91,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'default' => '1',
|
||||
'save_method' => 'storeSettingField',
|
||||
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
|
||||
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1,
|
||||
'advanced_mode' => true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -30,7 +30,8 @@ return array(
|
||||
'default' => 2000,
|
||||
'min' => 2,
|
||||
'max' => 65535,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_vmail_gid' => array(
|
||||
'label' => $lng['serversettings']['vmail_gid'],
|
||||
@@ -40,7 +41,8 @@ return array(
|
||||
'default' => 2000,
|
||||
'min' => 2,
|
||||
'max' => 65535,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_vmail_homedir' => array(
|
||||
'label' => $lng['serversettings']['vmail_homedir'],
|
||||
@@ -59,7 +61,8 @@ return array(
|
||||
'string_type' => 'dir',
|
||||
'default' => 'Maildir',
|
||||
'string_emptyallowed' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'panel_sendalternativemail' => array(
|
||||
'label' => $lng['serversettings']['sendalternativemail'],
|
||||
@@ -99,7 +102,8 @@ return array(
|
||||
'varname' => 'mailtraffic_enabled',
|
||||
'type' => 'checkbox',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mdaserver' => array(
|
||||
'label' => $lng['serversettings']['mdaserver'],
|
||||
@@ -111,7 +115,8 @@ return array(
|
||||
'courier' => 'Courier',
|
||||
'dovecot' => 'Dovecot'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mdalog' => array(
|
||||
'label' => $lng['serversettings']['mdalog'],
|
||||
@@ -121,7 +126,8 @@ return array(
|
||||
'string_type' => 'file',
|
||||
'default' => '/var/log/mail.log',
|
||||
'string_emptyallowed' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mtaserver' => array(
|
||||
'label' => $lng['serversettings']['mtaserver'],
|
||||
@@ -133,7 +139,8 @@ return array(
|
||||
'exim4' => 'Exim4',
|
||||
'postfix' => 'Postfix'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_mtalog' => array(
|
||||
'label' => $lng['serversettings']['mtalog'],
|
||||
@@ -143,7 +150,8 @@ return array(
|
||||
'string_type' => 'file',
|
||||
'default' => '/var/log/mail.log',
|
||||
'string_emptyallowed' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -109,7 +109,8 @@ return array(
|
||||
'Native' => 'Native',
|
||||
'Master' => 'Master'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_dns_createmailentry' => array(
|
||||
'label' => $lng['serversettings']['mail_also_with_mxservers'],
|
||||
@@ -125,7 +126,8 @@ return array(
|
||||
'varname' => 'dns_createcaaentry',
|
||||
'type' => 'checkbox',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'caa_caa_entry' => array(
|
||||
'label' => $lng['serversettings']['caa_entry_custom'],
|
||||
@@ -133,7 +135,8 @@ return array(
|
||||
'varname' => 'caa_entry',
|
||||
'type' => 'textarea',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_defaultttl' => array(
|
||||
'label' => $lng['serversettings']['defaultttl'],
|
||||
|
||||
@@ -47,7 +47,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_regexp' => '/^[a-z0-9\._]+$/i',
|
||||
'default' => '.priv',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'dkim_domains' => array(
|
||||
'label' => $lng['dkim']['dkim_domains'],
|
||||
@@ -79,7 +80,8 @@ return array(
|
||||
'sha1' => 'SHA1',
|
||||
'sha256' => 'SHA256'
|
||||
),
|
||||
'save_method' => 'storeSettingFieldInsertBindTask'
|
||||
'save_method' => 'storeSettingFieldInsertBindTask',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'dkim_servicetype' => array(
|
||||
'label' => $lng['dkim']['dkim_servicetype'],
|
||||
@@ -91,7 +93,8 @@ return array(
|
||||
'0' => 'All',
|
||||
'1' => 'E-Mail'
|
||||
),
|
||||
'save_method' => 'storeSettingFieldInsertBindTask'
|
||||
'save_method' => 'storeSettingFieldInsertBindTask',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'dkim_keylength' => array(
|
||||
'label' => array(
|
||||
@@ -115,7 +118,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_regexp' => '/^[a-z0-9\._]+$/i',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingFieldInsertBindTask'
|
||||
'save_method' => 'storeSettingFieldInsertBindTask',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'dkimrestart_command' => array(
|
||||
'label' => $lng['dkim']['dkimrestart_command'],
|
||||
|
||||
@@ -36,7 +36,8 @@ return array(
|
||||
'varname' => 'mailpwcleartext',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_passwordcryptfunc' => array(
|
||||
'label' => $lng['serversettings']['passwordcryptfunc'],
|
||||
@@ -48,7 +49,8 @@ return array(
|
||||
'\\Froxlor\\System\\Crypt',
|
||||
'getAvailablePasswordHashes'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_allow_error_report_admin' => array(
|
||||
'label' => $lng['serversettings']['allow_error_report_admin'],
|
||||
@@ -72,7 +74,8 @@ return array(
|
||||
'varname' => 'allow_customer_shell',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_available_shells' => array(
|
||||
'label' => $lng['serversettings']['available_shells'],
|
||||
@@ -81,7 +84,8 @@ return array(
|
||||
'type' => 'text',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
),
|
||||
'system_froxlorusergroup' => array(
|
||||
'label' => $lng['serversettings']['froxlorusergroup'],
|
||||
@@ -94,7 +98,8 @@ return array(
|
||||
'\\Froxlor\\Validate\\Check',
|
||||
'checkLocalGroup'
|
||||
),
|
||||
'visible' => \Froxlor\Settings::Get('system.nssextrausers')
|
||||
'visible' => \Froxlor\Settings::Get('system.nssextrausers'),
|
||||
'advanced_mode' => true
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -18,6 +18,7 @@ return array(
|
||||
'diskquota' => array(
|
||||
'title' => $lng['diskquota'],
|
||||
'icon' => 'fa-solid fa-sliders',
|
||||
'advanced_mode' => true,
|
||||
'fields' => array(
|
||||
'diskquota_enabled' => array(
|
||||
'label' => $lng['serversettings']['diskquota_enabled'],
|
||||
|
||||
@@ -396,4 +396,10 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
|
||||
'type' => $note_type,
|
||||
'alert_msg' => $note_msg
|
||||
]);
|
||||
} elseif ($page == 'toggleSettingsMode') {
|
||||
if ($userinfo['change_serversettings'] == '1') {
|
||||
$cmode = Settings::Get('panel.settings_mode');
|
||||
Settings::Set('panel.settings_mode', (int)(!(bool)$cmode));
|
||||
}
|
||||
\Froxlor\UI\Response::redirectTo($filename);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ use Froxlor\UI\Request;
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_API_KEYS . "` WHERE id = :id");
|
||||
$success_message = "";
|
||||
$id = (int) Request::get('id');
|
||||
$area = AREA;
|
||||
|
||||
// do the delete and then just show a success-message and the apikeys list again
|
||||
if ($action == 'delete') {
|
||||
|
||||
19
bin/froxlor-cli
Executable file
19
bin/froxlor-cli
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
use Froxlor\Cli\ConfigServices;
|
||||
use Froxlor\Cli\PhpSessionclean;
|
||||
use Froxlor\Cli\SwitchServerIp;
|
||||
use Froxlor\Froxlor;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
require dirname(__DIR__) . '/lib/tables.inc.php';
|
||||
|
||||
$application = new Application('froxlor-cli', Froxlor::getFullVersion());
|
||||
$application->add(new ConfigServices());
|
||||
$application->add(new PhpSessionclean());
|
||||
$application->add(new SwitchServerIp());
|
||||
$application->run();
|
||||
@@ -51,7 +51,8 @@
|
||||
"froxlor/idna-convert-legacy": "^2.1",
|
||||
"voku/anti-xss": "^4.1",
|
||||
"twig/twig": "^3.3",
|
||||
"erusev/parsedown": "^1.7"
|
||||
"erusev/parsedown": "^1.7",
|
||||
"symfony/console": "^5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9",
|
||||
|
||||
1192
composer.lock
generated
1192
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -653,7 +653,7 @@ opcache.validate_timestamps'),
|
||||
('system', 'mail_smtp_auth', '1'),
|
||||
('system', 'mail_smtp_user', ''),
|
||||
('system', 'mail_smtp_passwd', ''),
|
||||
('system', 'hsts_maxage', '0'),
|
||||
('system', 'hsts_maxage', '10368000'),
|
||||
('system', 'hsts_incsub', '0'),
|
||||
('system', 'hsts_preload', '0'),
|
||||
('system', 'leregistered', '0'),
|
||||
@@ -675,7 +675,7 @@ opcache.validate_timestamps'),
|
||||
('system', 'froxloraliases', ''),
|
||||
('system', 'apply_specialsettings_default', '1'),
|
||||
('system', 'apply_phpconfigs_default', '1'),
|
||||
('system', 'hide_incompatible_settings', '0'),
|
||||
('system', 'hide_incompatible_settings', '1'),
|
||||
('system', 'include_default_vhostconf', '0'),
|
||||
('system', 'soaemail', ''),
|
||||
('system', 'domaindefaultalias', '0'),
|
||||
@@ -723,6 +723,7 @@ opcache.validate_timestamps'),
|
||||
('panel', 'logo_image_login', ''),
|
||||
('panel', 'logo_overridetheme', '0'),
|
||||
('panel', 'logo_overridecustom', '0'),
|
||||
('panel', 'settings_mode', '0'),
|
||||
('panel', 'version', '0.11.0-dev1'),
|
||||
('panel', 'db_version', '202112310');
|
||||
|
||||
@@ -863,7 +864,7 @@ CREATE TABLE `panel_fpmdaemons` (
|
||||
|
||||
|
||||
INSERT INTO `panel_fpmdaemons` (`id`, `description`, `reload_cmd`, `config_dir`) VALUES
|
||||
(1, 'System default', 'service php7.3-fpm restart', '/etc/php/7.3/fpm/pool.d/');
|
||||
(1, 'System default', 'service php7.4-fpm restart', '/etc/php/7.4/fpm/pool.d/');
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
// Check if we're in the CLI
|
||||
if (@php_sapi_name() !== 'cli') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
require dirname(dirname(__DIR__)) . '/vendor/autoload.php';
|
||||
|
||||
// give control to command line handler
|
||||
try {
|
||||
\Froxlor\Cli\ConfigServicesCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\Cli\ConfigServicesCmd::printerr($e->getMessage());
|
||||
exit(1);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2016-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
// Check if we're in the CLI
|
||||
if (@php_sapi_name() !== 'cli') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
require dirname(dirname(__DIR__)) . '/vendor/autoload.php';
|
||||
|
||||
// give control to command line handler
|
||||
try {
|
||||
\Froxlor\Cli\SwitchServerIpCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\Cli\SwitchServerIpCmd::printerr($e->getMessage());
|
||||
exit(1);
|
||||
}
|
||||
@@ -56,9 +56,10 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.99')) {
|
||||
showUpdateStep("Cleaning up old files");
|
||||
$to_clean = array(
|
||||
"templates/Sparkle",
|
||||
"lib/version.inc.php"
|
||||
);
|
||||
$disabled = explode(',', ini_get('disable_functions'));
|
||||
$exec_allowed = ! in_array('exec', $disabled);
|
||||
$exec_allowed = !in_array('exec', $disabled);
|
||||
$del_list = "";
|
||||
foreach ($to_clean as $filedir) {
|
||||
$complete_filedir = \Froxlor\Froxlor::getInstallDir() . $filedir;
|
||||
@@ -81,6 +82,11 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.99')) {
|
||||
}
|
||||
}
|
||||
|
||||
showUpdateStep("Adding new settings");
|
||||
$panel_settings_mode = isset($_POST['panel_settings_mode']) ? (int) $_POST['panel_settings_mode'] : 0;
|
||||
Settings::AddNew("panel.settings_mode", $panel_settings_mode);
|
||||
lastStepStatus(0);
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.99')) {
|
||||
showUpdateStep("Updating from 0.10.99 to 0.11.0-dev1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.11.0-dev1');
|
||||
|
||||
@@ -35,14 +35,21 @@ function getPreConfig($current_version, $current_db_version): array
|
||||
'title' => '0.9.x updates',
|
||||
'fields' => []
|
||||
];
|
||||
parseAndOutputPreconfig($has_preconfig, $return['section_09']['fields'], $current_version, $current_db_version);
|
||||
parseAndOutputPreconfig09($has_preconfig, $return['section_09']['fields'], $current_version, $current_db_version);
|
||||
|
||||
include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.10/preconfig_0.10.inc.php');
|
||||
$return['section_010'] = [
|
||||
'title' => '0.10.x updates',
|
||||
'fields' => []
|
||||
];
|
||||
parseAndOutputPreconfig2($has_preconfig, $return['section_010']['fields'], $current_version, $current_db_version);
|
||||
parseAndOutputPreconfig010($has_preconfig, $return['section_010']['fields'], $current_version, $current_db_version);
|
||||
|
||||
include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.11/preconfig_0.11.inc.php');
|
||||
$return['section_011'] = [
|
||||
'title' => '0.11.x updates',
|
||||
'fields' => []
|
||||
];
|
||||
parseAndOutputPreconfig011($has_preconfig, $return['section_011']['fields'], $current_version, $current_db_version);
|
||||
|
||||
if (empty($return['section_09']['fields'])) {
|
||||
unset($return['section_09']);
|
||||
@@ -50,6 +57,9 @@ function getPreConfig($current_version, $current_db_version): array
|
||||
if (empty($return['section_010']['fields'])) {
|
||||
unset($return['section_010']);
|
||||
}
|
||||
if (empty($return['section_011']['fields'])) {
|
||||
unset($return['section_011']);
|
||||
}
|
||||
|
||||
if (!empty($return)) {
|
||||
$has_preconfig = true;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function parseAndOutputPreconfig2(&$has_preconfig, &$return, $current_version, $current_db_version)
|
||||
function parseAndOutputPreconfig010(&$has_preconfig, &$return, $current_version, $current_db_version)
|
||||
{
|
||||
global $lng;
|
||||
|
||||
|
||||
49
install/updates/preconfig/0.11/preconfig_0.11.inc.php
Normal file
49
install/updates/preconfig/0.11/preconfig_0.11.inc.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Updater
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* checks if the new-version has some updating to do
|
||||
*
|
||||
* @param boolean $has_preconfig
|
||||
* pointer to check if any preconfig has to be output
|
||||
* @param string $return
|
||||
* pointer to output string
|
||||
* @param string $current_version
|
||||
* current froxlor version
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function parseAndOutputPreconfig011(&$has_preconfig, &$return, $current_version, $current_db_version)
|
||||
{
|
||||
global $lng;
|
||||
|
||||
if (versionInUpdate($current_version, '0.10.99')) {
|
||||
$has_preconfig = true;
|
||||
$description = 'We have rearranged the settings and split them into basic and advanced categories. This makes it easier for users who do not need all the detailed or very specific settings and options and gives a better overview of the basic/mostly used settings.';
|
||||
$return['panel_settings_mode_note'] = ['type' => 'infotext', 'value' => $description];
|
||||
$question = '<strong>Chose settings mode (you can change that at any time)</strong>';
|
||||
$return['panel_settings_mode'] = [
|
||||
'type' => 'select',
|
||||
'select_var' => [
|
||||
0 => 'Basic',
|
||||
1 => 'Advanced'
|
||||
],
|
||||
'selected' => 1,
|
||||
'label' => $question
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use PHPMailer\PHPMailer;
|
||||
use Froxlor\UI\Panel\UI;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
|
||||
/**
|
||||
* checks if the new-version has some updating to do
|
||||
@@ -32,7 +32,7 @@ use Froxlor\UI\Panel\UI;
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $current_db_version)
|
||||
function parseAndOutputPreconfig09(&$has_preconfig, &$return, $current_version, $current_db_version)
|
||||
{
|
||||
global $lng;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Froxlor\Ajax;
|
||||
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\UI\Collection;
|
||||
|
||||
/**
|
||||
@@ -50,9 +51,15 @@ class GlobalSearch
|
||||
$pk = explode(".", $pathkey);
|
||||
if (count($pk) > 4) {
|
||||
$settingkey = $pk[0] . '.' . $pk[1] . '.' . $pk[2] . '.' . $pk[3];
|
||||
if (isset($settings_data[$pk[0]][$pk[1]]['advanced_mode']) && $settings_data[$pk[0]][$pk[1]]['advanced_mode'] && (int) Settings::Get('panel.settings_mode') == 0) {
|
||||
continue;
|
||||
}
|
||||
if (is_array($processed['settings']) && !array_key_exists($settingkey, $processed['settings'])) {
|
||||
$processed['settings'][$settingkey] = true;
|
||||
$sresult = $settings_data[$pk[0]][$pk[1]][$pk[2]][$pk[3]];
|
||||
if (isset($sresult['advanced_mode']) && $sresult['advanced_mode'] && (int) Settings::Get('panel.settings_mode') == 0) {
|
||||
continue;
|
||||
}
|
||||
if ($sresult['type'] != 'hidden') {
|
||||
if (!isset($result['settings'])) {
|
||||
$result['settings'] = [];
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
abstract class Action
|
||||
{
|
||||
|
||||
protected function __construct($args)
|
||||
{
|
||||
$this->_args = $args;
|
||||
}
|
||||
|
||||
public function getActionName()
|
||||
{
|
||||
return get_called_class();
|
||||
}
|
||||
|
||||
abstract public function run();
|
||||
}
|
||||
@@ -1,456 +0,0 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli\Action;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\SImExporter;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cli\ConfigServicesCmd;
|
||||
|
||||
class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
{
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function validate()
|
||||
{
|
||||
global $lng;
|
||||
|
||||
$this->checkConfigParam(true);
|
||||
$this->parseConfig();
|
||||
|
||||
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
|
||||
|
||||
include_once FROXLOR_INSTALL_DIR . '/lng/english.lng.php';
|
||||
include_once FROXLOR_INSTALL_DIR . '/lng/lng_references.php';
|
||||
|
||||
if (array_key_exists("import-settings", $this->_args)) {
|
||||
$this->importSettings();
|
||||
}
|
||||
|
||||
if (array_key_exists("create", $this->_args)) {
|
||||
$this->createConfig();
|
||||
} elseif (array_key_exists("apply", $this->_args)) {
|
||||
$this->applyConfig();
|
||||
} elseif (array_key_exists("list-daemons", $this->_args) || array_key_exists("daemon", $this->_args)) {
|
||||
ConfigServicesCmd::printwarn("--list-daemons and --daemon only work together with --apply");
|
||||
}
|
||||
}
|
||||
|
||||
private function importSettings()
|
||||
{
|
||||
if (strtoupper(substr($this->_args["import-settings"], 0, 4)) == 'HTTP') {
|
||||
echo "Settings file seems to be an URL, trying to download" . PHP_EOL;
|
||||
$target = "/tmp/froxlor-import-settings-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($this->_args["import-settings"], $target);
|
||||
$this->_args["import-settings"] = $target;
|
||||
}
|
||||
if (! is_file($this->_args["import-settings"])) {
|
||||
throw new \Exception("Given settings file is not a file");
|
||||
} elseif (! file_exists($this->_args["import-settings"])) {
|
||||
throw new \Exception("Given settings file cannot be found ('" . $this->_args["import-settings"] . "')");
|
||||
} elseif (! is_readable($this->_args["import-settings"])) {
|
||||
throw new \Exception("Given settings file cannot be read ('" . $this->_args["import-settings"] . "')");
|
||||
}
|
||||
$imp_content = file_get_contents($this->_args["import-settings"]);
|
||||
SImExporter::import($imp_content);
|
||||
ConfigServicesCmd::printsucc("Successfully imported settings from '" . $this->_args["import-settings"] . "'");
|
||||
}
|
||||
|
||||
private function createConfig()
|
||||
{
|
||||
$_daemons_config = array(
|
||||
'distro' => ""
|
||||
);
|
||||
|
||||
$config_dir = FROXLOR_INSTALL_DIR . '/lib/configfiles/';
|
||||
// show list of available distro's
|
||||
$distros = glob($config_dir . '*.xml');
|
||||
// tmp array
|
||||
$distributions_select_data = array();
|
||||
|
||||
//set default os.
|
||||
$os_dist = array('ID' => 'bullseye');
|
||||
$os_version = array('0' => '11');
|
||||
$os_default = $os_dist['ID'];
|
||||
|
||||
//read os-release
|
||||
if(file_exists('/etc/os-release')) {
|
||||
$os_dist = parse_ini_file('/etc/os-release', false);
|
||||
if(is_array($os_dist) && array_key_exists('ID', $os_dist) && array_key_exists('VERSION_ID', $os_dist)) {
|
||||
$os_version = explode('.',$os_dist['VERSION_ID'])[0];
|
||||
}
|
||||
}
|
||||
|
||||
// read in all the distros
|
||||
foreach ($distros as $_distribution) {
|
||||
// get configparser object
|
||||
$dist = new \Froxlor\Config\ConfigParser($_distribution);
|
||||
// get distro-info
|
||||
$dist_display = $this->getCompleteDistroName($dist);
|
||||
// store in tmp array
|
||||
$distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
|
||||
//guess if this is the current distro.
|
||||
$ver = explode('.', $dist->distributionVersion)[0];
|
||||
if (strtolower($os_dist['ID']) == strtolower($dist->distributionName) && $os_version == $ver) {
|
||||
$os_default = str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
}
|
||||
}
|
||||
|
||||
// sort by distribution name
|
||||
ksort($distributions_select_data);
|
||||
|
||||
// list all distributions
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'dist', 'name');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
foreach ($distributions_select_data as $name => $filename) {
|
||||
printf($mask, $filename, $name);
|
||||
}
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
|
||||
while (! in_array($_daemons_config['distro'], $distributions_select_data)) {
|
||||
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", $os_default);
|
||||
}
|
||||
|
||||
// go through all services and let user check whether to include it or not
|
||||
$configfiles = new \Froxlor\Config\ConfigParser($config_dir . '/' . $_daemons_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
echo PHP_EOL . "--- " . strtoupper($si) . " ---" . PHP_EOL . PHP_EOL;
|
||||
$_daemons_config[$si] = "";
|
||||
|
||||
$daemons = $service->getDaemons();
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'value', 'name');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
$default_daemon = "";
|
||||
foreach ($daemons as $di => $dd) {
|
||||
$title = $dd->title;
|
||||
if ($dd->default) {
|
||||
$default_daemon = $di;
|
||||
$title = $title . " (default)";
|
||||
}
|
||||
printf($mask, $di, $title);
|
||||
}
|
||||
printf($mask, "x", "No " . $si);
|
||||
$daemons['x'] = 'x';
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
if ($si == 'system') {
|
||||
$_daemons_config[$si] = array();
|
||||
// for the system/other services we need a multiple choice possibility
|
||||
ConfigServicesCmd::println("Select every service you need. Enter empty value when done");
|
||||
$sysservice = "";
|
||||
do {
|
||||
$sysservice = ConfigServicesCmd::getInput("choose service");
|
||||
if (! empty($sysservice)) {
|
||||
$_daemons_config[$si][] = $sysservice;
|
||||
}
|
||||
} while (! empty($sysservice));
|
||||
// add 'cron' as fixed part (doesn't hurt if it exists)
|
||||
if (! in_array('cron', $_daemons_config[$si])) {
|
||||
$_daemons_config[$si][] = 'cron';
|
||||
}
|
||||
} else {
|
||||
// for all others -> only one value
|
||||
while (! array_key_exists($_daemons_config[$si], $daemons)) {
|
||||
$_daemons_config[$si] = ConfigServicesCmd::getInput("choose service", $default_daemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo PHP_EOL . PHP_EOL;
|
||||
$daemons_config = json_encode($_daemons_config);
|
||||
$output = ConfigServicesCmd::getInput("choose output-filename", "/tmp/froxlor-config-" . date('Ymd') . ".json");
|
||||
file_put_contents($output, $daemons_config);
|
||||
ConfigServicesCmd::printsucc("Successfully generated service-configfile '" . $output . "'");
|
||||
echo PHP_EOL;
|
||||
ConfigServicesCmd::printsucc("You can now apply this config running:" . PHP_EOL . "php " . FROXLOR_INSTALL_DIR . "install/scripts/config-services.php --apply=" . $output);
|
||||
echo PHP_EOL;
|
||||
$proceed = ConfigServicesCmd::getYesNo("Do you want to apply the config now? [y/N]", 0);
|
||||
if ($proceed) {
|
||||
passthru("php " . FROXLOR_INSTALL_DIR . "install/scripts/config-services.php --apply=" . $output);
|
||||
}
|
||||
}
|
||||
|
||||
private function getCompleteDistroName($cparser)
|
||||
{
|
||||
// get distro-info
|
||||
$dist_display = $cparser->distributionName;
|
||||
if ($cparser->distributionCodename != '') {
|
||||
$dist_display .= " " . $cparser->distributionCodename;
|
||||
}
|
||||
if ($cparser->distributionVersion != '') {
|
||||
$dist_display .= " (" . $cparser->distributionVersion . ")";
|
||||
}
|
||||
if ($cparser->deprecated) {
|
||||
$dist_display .= " [deprecated]";
|
||||
}
|
||||
return $dist_display;
|
||||
}
|
||||
|
||||
private function applyConfig()
|
||||
{
|
||||
if (strtoupper(substr($this->_args["apply"], 0, 4)) == 'HTTP') {
|
||||
echo "Config file seems to be an URL, trying to download" . PHP_EOL;
|
||||
$target = "/tmp/froxlor-config-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($this->_args["apply"], $target);
|
||||
$this->_args["apply"] = $target;
|
||||
}
|
||||
if (! is_file($this->_args["apply"])) {
|
||||
throw new \Exception("Given config file is not a file");
|
||||
} elseif (! file_exists($this->_args["apply"])) {
|
||||
throw new \Exception("Given config file cannot be found ('" . $this->_args["apply"] . "')");
|
||||
} elseif (! is_readable($this->_args["apply"])) {
|
||||
throw new \Exception("Given config file cannot be read ('" . $this->_args["apply"] . "')");
|
||||
}
|
||||
|
||||
$config = file_get_contents($this->_args["apply"]);
|
||||
$decoded_config = json_decode($config, true);
|
||||
|
||||
if (array_key_exists("list-daemons", $this->_args)) {
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'service', 'daemon');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
foreach ($decoded_config as $service => $daemon) {
|
||||
if (is_array($daemon) && count($daemon) > 0) {
|
||||
foreach ($daemon as $sysdaemon) {
|
||||
printf($mask, $service, $sysdaemon);
|
||||
}
|
||||
} else {
|
||||
if ($daemon == 'x') {
|
||||
$daemon = '--- skipped ---';
|
||||
}
|
||||
printf($mask, $service, $daemon);
|
||||
}
|
||||
}
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
exit();
|
||||
}
|
||||
|
||||
$only_daemon = null;
|
||||
if (array_key_exists("daemon", $this->_args)) {
|
||||
$only_daemon = $this->_args['daemon'];
|
||||
}
|
||||
|
||||
if (! empty($decoded_config)) {
|
||||
$config_dir = FROXLOR_INSTALL_DIR . '/lib/configfiles/';
|
||||
$configfiles = new \Froxlor\Config\ConfigParser($config_dir . '/' . $decoded_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
$replace_arr = $this->getReplacerArray();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
echo PHP_EOL . "--- Configuring: " . strtoupper($si) . " ---" . PHP_EOL . PHP_EOL;
|
||||
if (! isset($decoded_config[$si]) || $decoded_config[$si] == 'x') {
|
||||
ConfigServicesCmd::printwarn("Skipping " . strtoupper($si) . " configuration as desired");
|
||||
continue;
|
||||
}
|
||||
$daemons = $service->getDaemons();
|
||||
foreach ($daemons as $di => $dd) {
|
||||
// check for desired service
|
||||
if (($si != 'system' && $decoded_config[$si] != $di) || (is_array($decoded_config[$si]) && ! in_array($di, $decoded_config[$si]))) {
|
||||
continue;
|
||||
}
|
||||
ConfigServicesCmd::println("Configuring '" . $di . "'");
|
||||
|
||||
if (! empty($only_daemon) && $only_daemon != $di) {
|
||||
ConfigServicesCmd::printwarn("Skipping " . $di . " configuration as desired");
|
||||
continue;
|
||||
}
|
||||
// run all cmds
|
||||
$confarr = $dd->getConfig();
|
||||
foreach ($confarr as $action) {
|
||||
switch ($action['type']) {
|
||||
case "install":
|
||||
ConfigServicesCmd::println("Installing required packages");
|
||||
$result = null;
|
||||
passthru(strtr($action['content'], $replace_arr), $result);
|
||||
if (strlen($result) > 1) {
|
||||
echo $result;
|
||||
}
|
||||
break;
|
||||
case "command":
|
||||
exec(strtr($action['content'], $replace_arr));
|
||||
break;
|
||||
case "file":
|
||||
if (array_key_exists('content', $action)) {
|
||||
ConfigServicesCmd::printwarn("Creating file '" . $action['name'] . "'");
|
||||
file_put_contents($action['name'], trim(strtr($action['content'], $replace_arr)));
|
||||
} elseif (array_key_exists('subcommands', $action)) {
|
||||
foreach ($action['subcommands'] as $fileaction) {
|
||||
if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "post") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif ($fileaction['type'] == 'file') {
|
||||
ConfigServicesCmd::printwarn("Creating file '" . $fileaction['name'] . "'");
|
||||
file_put_contents($fileaction['name'], trim(strtr($fileaction['content'], $replace_arr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// set is_configured flag
|
||||
Settings::Set('panel.is_configured', '1', true);
|
||||
// run cronjob at the end to ensure configs are all up to date
|
||||
exec('php ' . FROXLOR_INSTALL_DIR . '/scripts/froxlor_master_cronjob.php --force');
|
||||
// and done
|
||||
ConfigServicesCmd::printsucc("All services have been configured");
|
||||
} else {
|
||||
ConfigServicesCmd::printerr("Unable to decode given JSON file");
|
||||
}
|
||||
}
|
||||
|
||||
private function getReplacerArray()
|
||||
{
|
||||
$customer_tmpdir = '/tmp/';
|
||||
if (Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('system.mod_fcgid_tmpdir');
|
||||
} elseif (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('phpfpm.tmpdir');
|
||||
}
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
$known_ns_ips = [];
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, - 1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (! is_array($nameserver_ips)) {
|
||||
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver
|
||||
);
|
||||
} else {
|
||||
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
|
||||
}
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
|
||||
// AXFR server
|
||||
if (Settings::Get('system.axfrservers') != '') {
|
||||
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
|
||||
foreach ($axfrservers as $axfrserver) {
|
||||
if (!in_array(trim($axfrserver), $known_ns_ips)) {
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= trim($axfrserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Database::needSqlData();
|
||||
$sql = Database::getSqlData();
|
||||
|
||||
$replace_arr = array(
|
||||
'<SQL_UNPRIVILEGED_USER>' => $sql['user'],
|
||||
'<SQL_UNPRIVILEGED_PASSWORD>' => $sql['passwd'],
|
||||
'<SQL_DB>' => $sql['db'],
|
||||
'<SQL_HOST>' => $sql['host'],
|
||||
'<SQL_SOCKET>' => isset($sql['socket']) ? $sql['socket'] : null,
|
||||
'<SERVERNAME>' => Settings::Get('system.hostname'),
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
'<SSLPROTOCOLS>' => (Settings::Get('system.use_ssl') == '1') ? 'imaps pop3s' : '',
|
||||
'<CUSTOMER_TMP>' => \Froxlor\FileDir::makeCorrectDir($customer_tmpdir),
|
||||
'<BASE_PATH>' => \Froxlor\FileDir::makeCorrectDir(FROXLOR_INSTALL_DIR),
|
||||
'<BIND_CONFIG_PATH>' => \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory')),
|
||||
'<WEBSERVER_RELOAD_CMD>' => Settings::Get('system.apachereload_command'),
|
||||
'<CUSTOMER_LOGS>' => \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.logfiles_directory')),
|
||||
'<FPM_IPCDIR>' => \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir')),
|
||||
'<WEBSERVER_GROUP>' => Settings::Get('system.httpgroup')
|
||||
);
|
||||
return $replace_arr;
|
||||
}
|
||||
|
||||
private function parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (! class_exists('\\Froxlor\\Database\\Database')) {
|
||||
throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
}
|
||||
|
||||
private function checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (! isset($this->_args["froxlor-dir"])) {
|
||||
$this->_args["froxlor-dir"] = \Froxlor\Froxlor::getInstallDir();
|
||||
} elseif (! is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function downloadFile($src, $dest)
|
||||
{
|
||||
set_time_limit(0);
|
||||
// This is the file where we save the information
|
||||
$fp = fopen($dest, 'w+');
|
||||
// Here is the file we are downloading, replace spaces with %20
|
||||
$ch = curl_init(str_replace(" ", "%20", $src));
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
// write curl response to file
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
// get curl response
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli\Action;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class PhpSessioncleanAction extends \Froxlor\Cli\Action
|
||||
{
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (isset($this->_args["max-lifetime"]) && is_numeric($this->_args["max-lifetime"]) && $this->_args["max-lifetime"] > 0) {
|
||||
$this->cleanSessionfiles((int)$this->_args["max-lifetime"]);
|
||||
} else {
|
||||
// use default max-lifetime value
|
||||
$this->cleanSessionfiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function validate()
|
||||
{
|
||||
global $lng;
|
||||
|
||||
$this->checkConfigParam(true);
|
||||
$this->parseConfig();
|
||||
|
||||
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
|
||||
}
|
||||
|
||||
private function cleanSessionfiles(int $maxlifetime = 1440)
|
||||
{
|
||||
// store paths to clean up
|
||||
$paths_to_clean = [];
|
||||
// get all pool-config directories configured
|
||||
$sel_stmt = Database::prepare("SELECT DISTINCT `config_dir` FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($sel_stmt);
|
||||
while ($fpmd = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$poolfiles = glob(\Froxlor\FileDir::makeCorrectFile($fpmd['config_dir'] . '/*.conf'));
|
||||
foreach ($poolfiles as $cf) {
|
||||
$contents = file_get_contents($cf);
|
||||
$pattern = preg_quote('session.save_path', '/');
|
||||
$pattern = "/" . $pattern . ".+?\=(.*)/";
|
||||
if (preg_match_all($pattern, $contents, $matches)) {
|
||||
$paths_to_clean[] = \Froxlor\FileDir::makeCorrectDir(trim($matches[1][0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// every path is just needed once
|
||||
$paths_to_clean = array_unique($paths_to_clean);
|
||||
|
||||
if (count($paths_to_clean) > 0) {
|
||||
foreach ($paths_to_clean as $ptc) {
|
||||
// find all files older then maxlifetime and delete them
|
||||
\Froxlor\FileDir::safe_exec("find -O3 \"" . $ptc . "\" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin \"+" . $maxlifetime . "\" -delete");
|
||||
}
|
||||
}
|
||||
}
|
||||
private function parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (!class_exists('\\Froxlor\\Database\\Database')) {
|
||||
throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (!file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
}
|
||||
|
||||
private function checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (!isset($this->_args["froxlor-dir"])) {
|
||||
$this->_args["froxlor-dir"] = \Froxlor\Froxlor::getInstallDir();
|
||||
} elseif (!is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (!file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (!is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli\Action;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Cli\SwitchServerIpCmd;
|
||||
|
||||
class SwitchServerIpAction extends \Froxlor\Cli\Action
|
||||
{
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function validate()
|
||||
{
|
||||
$need_config = false;
|
||||
if (array_key_exists("list", $this->_args) || array_key_exists("switch", $this->_args)) {
|
||||
$need_config = true;
|
||||
}
|
||||
|
||||
$this->checkConfigParam($need_config);
|
||||
|
||||
$this->parseConfig();
|
||||
|
||||
if (array_key_exists("list", $this->_args)) {
|
||||
$this->listIPs();
|
||||
}
|
||||
if (array_key_exists("switch", $this->_args)) {
|
||||
$this->switchIPs();
|
||||
}
|
||||
}
|
||||
|
||||
private function listIPs()
|
||||
{
|
||||
$sel_stmt = Database::prepare("SELECT * FROM panel_ipsandports ORDER BY ip ASC, port ASC");
|
||||
Database::pexecute($sel_stmt);
|
||||
$ips = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$mask = "|%-10.10s |%-50.50s | %10.10s |\n";
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
printf($mask, 'id', 'IP address', 'port');
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
foreach ($ips as $ipdata) {
|
||||
printf($mask, $ipdata['id'], $ipdata['ip'], $ipdata['port']);
|
||||
}
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
echo PHP_EOL . PHP_EOL;
|
||||
}
|
||||
|
||||
private function switchIPs()
|
||||
{
|
||||
$ip_list = $this->_args['switch'];
|
||||
|
||||
if (empty($ip_list) || is_bool($ip_list)) {
|
||||
throw new \Exception("No parameters given for --switch action.");
|
||||
}
|
||||
|
||||
$ips_to_switch = array();
|
||||
$ip_list = explode(" ", $ip_list);
|
||||
foreach ($ip_list as $ips_combo) {
|
||||
$ip_pair = explode(",", $ips_combo);
|
||||
if (count($ip_pair) != 2) {
|
||||
throw new \Exception("Invalid parameter given for --switch");
|
||||
} else {
|
||||
if (filter_var($ip_pair[0], FILTER_VALIDATE_IP) == false) {
|
||||
throw new \Exception("Invalid source ip address: " . $ip_pair[0]);
|
||||
}
|
||||
if (filter_var($ip_pair[1], FILTER_VALIDATE_IP) == false) {
|
||||
throw new \Exception("Invalid target ip address: " . $ip_pair[1]);
|
||||
}
|
||||
if ($ip_pair[0] == $ip_pair[1]) {
|
||||
throw new \Exception("Source and target ip address are equal");
|
||||
}
|
||||
}
|
||||
$ips_to_switch[] = $ip_pair;
|
||||
}
|
||||
|
||||
if (count($ips_to_switch) > 0) {
|
||||
$check_stmt = Database::prepare("SELECT `id` FROM panel_ipsandports WHERE `ip` = :newip");
|
||||
$upd_stmt = Database::prepare("UPDATE panel_ipsandports SET `ip` = :newip WHERE `ip` = :oldip");
|
||||
|
||||
// system.ipaddress
|
||||
$check_sysip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
$check_sysip = Database::pexecute_first($check_sysip_stmt);
|
||||
|
||||
// system.mysql_access_host
|
||||
$check_mysqlip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
$check_mysqlip = Database::pexecute_first($check_mysqlip_stmt);
|
||||
|
||||
// system.axfrservers
|
||||
$check_axfrip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
$check_axfrip = Database::pexecute_first($check_axfrip_stmt);
|
||||
|
||||
foreach ($ips_to_switch as $ip_pair) {
|
||||
echo "Switching IP \033[1m" . $ip_pair[0] . "\033[0m to IP \033[1m" . $ip_pair[1] . "\033[0m" . PHP_EOL;
|
||||
|
||||
$ip_check = Database::pexecute_first($check_stmt, array(
|
||||
'newip' => $ip_pair[1]
|
||||
));
|
||||
if ($ip_check) {
|
||||
SwitchServerIpCmd::printwarn("Note: " . $ip_pair[0] . " not updated to " . $ip_pair[1] . " - IP already exists in froxlor's database");
|
||||
continue;
|
||||
}
|
||||
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'newip' => $ip_pair[1],
|
||||
'oldip' => $ip_pair[0]
|
||||
));
|
||||
$rows_updated = $upd_stmt->rowCount();
|
||||
|
||||
if ($rows_updated == 0) {
|
||||
SwitchServerIpCmd::printwarn("Note: " . $ip_pair[0] . " not updated to " . $ip_pair[1] . " (possibly no entry found in froxlor database. Use --list to see what IP addresses are added in froxlor");
|
||||
}
|
||||
|
||||
// check whether the system.ipaddress needs updating
|
||||
if ($check_sysip['value'] == $ip_pair[0]) {
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newip WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newip' => $ip_pair[1]
|
||||
));
|
||||
SwitchServerIpCmd::printsucc("Updated system-ipaddress from '" . $ip_pair[0] . "' to '" . $ip_pair[1] . "'");
|
||||
}
|
||||
|
||||
// check whether the system.mysql_access_host needs updating
|
||||
if (strstr($check_mysqlip['value'], $ip_pair[0]) !== false) {
|
||||
$new_mysqlip = str_replace($ip_pair[0], $ip_pair[1], $check_mysqlip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newmysql WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newmysql' => $new_mysqlip
|
||||
));
|
||||
SwitchServerIpCmd::printsucc("Updated mysql_access_host from '" . $check_mysqlip['value'] . "' to '" . $new_mysqlip . "'");
|
||||
}
|
||||
|
||||
// check whether the system.axfrservers needs updating
|
||||
if (strstr($check_axfrip['value'], $ip_pair[0]) !== false) {
|
||||
$new_axfrip = str_replace($ip_pair[0], $ip_pair[1], $check_axfrip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newaxfr WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newaxfr' => $new_axfrip
|
||||
));
|
||||
SwitchServerIpCmd::printsucc("Updated axfrservers from '" . $check_axfrip['value'] . "' to '" . $new_axfrip . "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
SwitchServerIpCmd::printwarn("*** ATTENTION *** Remember to replace IP addresses in configuration files if used anywhere.");
|
||||
SwitchServerIpCmd::printsucc("IP addresses updated");
|
||||
}
|
||||
|
||||
private function parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (! class_exists('\\Froxlor\\Database\\Database')) {
|
||||
throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
}
|
||||
|
||||
private function checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (! isset($this->_args["froxlor-dir"])) {
|
||||
$this->_args["froxlor-dir"] = \Froxlor\Froxlor::getInstallDir();
|
||||
} elseif (! is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
abstract class CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* internal variable for passed arguments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $args = null;
|
||||
|
||||
/**
|
||||
* Action object read from commandline/config
|
||||
*
|
||||
* @var \Froxlor\Cli\Action
|
||||
*/
|
||||
private $action = null;
|
||||
|
||||
/**
|
||||
* Returns a CmdLineHandler object with given
|
||||
* arguments from command line
|
||||
*
|
||||
* @param int $argc
|
||||
* @param array $argv
|
||||
*
|
||||
* @return CmdLineHandler
|
||||
*/
|
||||
public static function processParameters($argc, $argv)
|
||||
{
|
||||
$me = get_called_class();
|
||||
return new $me($argc, $argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* class constructor, validates the command line parameters
|
||||
* and sets the Action-object if valid
|
||||
*
|
||||
* @param int $argc
|
||||
* @param string[] $argv
|
||||
*
|
||||
* @return null
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function __construct($argc, $argv)
|
||||
{
|
||||
self::$args = $this->parseArgs($argv);
|
||||
$this->action = $this->createAction();
|
||||
$this->action->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the arguments given via the command line;
|
||||
* three types are supported:
|
||||
* 1.
|
||||
* --parm1 or --parm2=value
|
||||
* 2. -xyz (multiple switches in one) or -a=value
|
||||
* 3. parm1 parm2
|
||||
*
|
||||
* The 1. will be mapped as
|
||||
* ["parm1"] => true, ["parm2"] => "value"
|
||||
* The 2. as
|
||||
* ["x"] => true, ["y"] => true, ["z"] => true, ["a"] => "value"
|
||||
* And the 3. as
|
||||
* [0] => "parm1", [1] => "parm2"
|
||||
*
|
||||
* @param array $argv
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseArgs($argv)
|
||||
{
|
||||
array_shift($argv);
|
||||
$o = array();
|
||||
foreach ($argv as $a) {
|
||||
if (substr($a, 0, 2) == '--') {
|
||||
$eq = strpos($a, '=');
|
||||
if ($eq !== false) {
|
||||
$o[substr($a, 2, $eq - 2)] = substr($a, $eq + 1);
|
||||
} else {
|
||||
$k = substr($a, 2);
|
||||
if (! isset($o[$k])) {
|
||||
$o[$k] = true;
|
||||
}
|
||||
}
|
||||
} elseif (substr($a, 0, 1) == '-') {
|
||||
if (substr($a, 2, 1) == '=') {
|
||||
$o[substr($a, 1, 1)] = substr($a, 3);
|
||||
} else {
|
||||
foreach (str_split(substr($a, 1)) as $k) {
|
||||
if (! isset($o[$k])) {
|
||||
$o[$k] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$o[] = $a;
|
||||
}
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Action-Object for the Action-Handler
|
||||
*
|
||||
* @return \Froxlor\Cli\Action
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function createAction()
|
||||
{
|
||||
|
||||
// Test for help-switch
|
||||
if (empty(self::$args) || array_key_exists("help", self::$args) || array_key_exists("h", self::$args)) {
|
||||
static::printHelp();
|
||||
// end of execution
|
||||
}
|
||||
// check if no unknown parameters are present
|
||||
foreach (self::$args as $arg => $value) {
|
||||
|
||||
if (is_numeric($arg)) {
|
||||
throw new \Exception("Unknown parameter '" . $value . "' in argument list");
|
||||
} elseif (! in_array($arg, static::$params) && ! in_array($arg, static::$switches)) {
|
||||
throw new \Exception("Unknown parameter '" . $arg . "' in argument list");
|
||||
}
|
||||
}
|
||||
|
||||
// set debugger switch
|
||||
if (isset(self::$args["d"]) && self::$args["d"] == true) {
|
||||
// Debugger::getInstance()->setEnabled(true);
|
||||
// Debugger::getInstance()->debug("debug output enabled");
|
||||
}
|
||||
|
||||
return new static::$action_class(self::$args);
|
||||
}
|
||||
|
||||
public static function getInput($prompt = "#", $default = "")
|
||||
{
|
||||
if (! empty($default)) {
|
||||
$prompt .= " [" . $default . "]";
|
||||
}
|
||||
$result = readline($prompt . ":");
|
||||
if (empty($result) && ! empty($default)) {
|
||||
$result = $default;
|
||||
}
|
||||
return mb_strtolower($result);
|
||||
}
|
||||
|
||||
public static function getYesNo($prompt = "#", $default = null)
|
||||
{
|
||||
$value = null;
|
||||
$_v = null;
|
||||
|
||||
while (true) {
|
||||
$_v = self::getInput($prompt);
|
||||
|
||||
if (strtolower($_v) == 'y' || strtolower($_v) == 'yes') {
|
||||
$value = 1;
|
||||
break;
|
||||
} elseif (strtolower($_v) == 'n' || strtolower($_v) == 'no') {
|
||||
$value = 0;
|
||||
break;
|
||||
} else {
|
||||
if ($_v == '' && $default != null) {
|
||||
$value = $default;
|
||||
break;
|
||||
} else {
|
||||
echo "Sorry, response " . $_v . " not understood. Please enter 'yes' or 'no'\n";
|
||||
$value = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function println($msg = "")
|
||||
{
|
||||
print $msg . PHP_EOL;
|
||||
}
|
||||
|
||||
private static function printcolor($msg = "", $color = "0")
|
||||
{
|
||||
print "\033[" . $color . "m" . $msg . "\033[0m" . PHP_EOL;
|
||||
}
|
||||
|
||||
public static function printerr($msg = "")
|
||||
{
|
||||
self::printcolor($msg, "31");
|
||||
}
|
||||
|
||||
public static function printsucc($msg = "")
|
||||
{
|
||||
self::printcolor($msg, "32");
|
||||
}
|
||||
|
||||
public static function printwarn($msg = "")
|
||||
{
|
||||
self::printcolor($msg, "33");
|
||||
}
|
||||
}
|
||||
475
lib/Froxlor/Cli/ConfigServices.php
Normal file
475
lib/Froxlor/Cli/ConfigServices.php
Normal file
@@ -0,0 +1,475 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\SImExporter;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Config\ConfigParser;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2022 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
final class ConfigServices extends Command
|
||||
{
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('froxlor:config-services');
|
||||
$this->setDescription('Configure system services');
|
||||
$this->addOption('create', 'c', InputOption::VALUE_NONE, 'Create a services list configuration for the --apply option.')
|
||||
->addOption('apply', 'a', InputOption::VALUE_REQUIRED, 'Configure your services by given configuration file. To create one run the command with the --create option.')
|
||||
->addOption('list', 'l', InputOption::VALUE_NONE, 'Output the services that are going to be configured using a given config file (--apply option). No services will be configured.')
|
||||
->addOption('daemon', 'd', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'When used with --apply you can specify one or multiple daemons. These will be the only services that get configured.')
|
||||
->addOption('import-settings', 'i', InputOption::VALUE_REQUIRED, 'Import settings from another froxlor installation. This can be done standalone or in addition to --apply.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
global $lng;
|
||||
|
||||
if (!file_exists(Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
|
||||
$output->writeln("<error>Could not find froxlor's userdata.inc.php file. You should use this script only with an installed froxlor system.</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
include_once Froxlor::getInstallDir() . 'lng/english.lng.php';
|
||||
include_once Froxlor::getInstallDir() . 'lng/lng_references.php';
|
||||
|
||||
$result = self::SUCCESS;
|
||||
|
||||
// import settings if given
|
||||
if ($input->getOption('import-settings')) {
|
||||
$result = $this->importSettings($input, $output);
|
||||
}
|
||||
|
||||
if ($result == self::SUCCESS) {
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
if ($input->getOption('create')) {
|
||||
$result = $this->createConfig($input, $output, $io);
|
||||
} elseif ($input->getOption('apply')) {
|
||||
$result = $this->applyConfig($input, $output, $io);
|
||||
} elseif ($input->getOption('list') || $input->getOption('daemon')) {
|
||||
$output->writeln('<error>Options --list and --daemon only work together with --apply.</>');
|
||||
$result = self::INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function createConfig(InputInterface $input, OutputInterface $output, SymfonyStyle $io)
|
||||
{
|
||||
$_daemons_config = array(
|
||||
'distro' => ""
|
||||
);
|
||||
|
||||
$config_dir = Froxlor::getInstallDir() . '/lib/configfiles/';
|
||||
// show list of available distro's
|
||||
$distros = glob($config_dir . '*.xml');
|
||||
// tmp array
|
||||
$distributions_select_data = array();
|
||||
|
||||
//set default os.
|
||||
$os_dist = array('ID' => 'bullseye');
|
||||
$os_version = array('0' => '11');
|
||||
$os_default = $os_dist['ID'];
|
||||
|
||||
//read os-release
|
||||
if (file_exists('/etc/os-release')) {
|
||||
$os_dist = parse_ini_file('/etc/os-release', false);
|
||||
if (is_array($os_dist) && array_key_exists('ID', $os_dist) && array_key_exists('VERSION_ID', $os_dist)) {
|
||||
$os_version = explode('.', $os_dist['VERSION_ID'])[0];
|
||||
}
|
||||
}
|
||||
|
||||
// read in all the distros
|
||||
foreach ($distros as $_distribution) {
|
||||
// get configparser object
|
||||
$dist = new \Froxlor\Config\ConfigParser($_distribution);
|
||||
// get distro-info
|
||||
$dist_display = $this->getCompleteDistroName($dist);
|
||||
// store in tmp array
|
||||
$distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
|
||||
//guess if this is the current distro.
|
||||
$ver = explode('.', $dist->distributionVersion)[0];
|
||||
if (strtolower($os_dist['ID']) == strtolower($dist->distributionName) && $os_version == $ver) {
|
||||
$os_default = str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
}
|
||||
}
|
||||
|
||||
// sort by distribution name
|
||||
ksort($distributions_select_data);
|
||||
|
||||
// list all distributions
|
||||
$table_rows = [];
|
||||
$valid_dists = [];
|
||||
foreach ($distributions_select_data as $name => $filename) {
|
||||
$table_rows[] = [$filename, $name];
|
||||
$valid_dists[] = $filename;
|
||||
}
|
||||
$io->table(
|
||||
['ID', 'Distribution'],
|
||||
$table_rows
|
||||
);
|
||||
|
||||
$_daemons_config['distro'] = $io->choice('Choose distribution', $valid_dists, $os_default);
|
||||
|
||||
// go through all services and let user check whether to include it or not
|
||||
$configfiles = new ConfigParser($config_dir . '/' . $_daemons_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
$output->writeln("--- " . strtoupper($si) . " ---");
|
||||
$_daemons_config[$si] = "";
|
||||
|
||||
$daemons = $service->getDaemons();
|
||||
$default_daemon = "";
|
||||
$table_rows = [];
|
||||
$valid_options = [];
|
||||
foreach ($daemons as $di => $dd) {
|
||||
$title = $dd->title;
|
||||
if ($dd->default) {
|
||||
$default_daemon = $di;
|
||||
$title = $title . " (default)";
|
||||
}
|
||||
$table_rows[] = [$di, $title];
|
||||
$valid_options[] = $di;
|
||||
}
|
||||
if ($si != 'system') {
|
||||
$table_rows[] = ['x', 'No'];
|
||||
$valid_options[] = 'x';
|
||||
}
|
||||
$io->table(
|
||||
['Value', 'Name'],
|
||||
$table_rows
|
||||
);
|
||||
|
||||
$daemons['x'] = 'x';
|
||||
if ($si == 'system') {
|
||||
$_daemons_config[$si] = array();
|
||||
// for the system/other services we need a multiple choice possibility
|
||||
$output->writeln("<comment>Select every service you need. Enter empty value when done</>");
|
||||
$sysservice = "";
|
||||
do {
|
||||
$sysservice = $io->ask('Choose service');
|
||||
if (!empty($sysservice)) {
|
||||
$_daemons_config[$si][] = $sysservice;
|
||||
}
|
||||
} while (!empty($sysservice));
|
||||
// add 'cron' as fixed part (doesn't hurt if it exists)
|
||||
if (!in_array('cron', $_daemons_config[$si])) {
|
||||
$_daemons_config[$si][] = 'cron';
|
||||
}
|
||||
} else {
|
||||
// for all others -> only one value
|
||||
$_daemons_config[$si] = $io->choice('Choose service', $valid_options, $default_daemon);
|
||||
}
|
||||
}
|
||||
|
||||
$daemons_config = json_encode($_daemons_config);
|
||||
$output_file = $io->ask("Choose output-filename", "/tmp/froxlor-config-" . date('Ymd') . ".json");
|
||||
file_put_contents($output_file, $daemons_config);
|
||||
$output->writeln("<info>Successfully generated service-configfile '" . $output_file . "'</>");
|
||||
$output->writeln([
|
||||
"",
|
||||
"<info>You can now apply this config running:</>",
|
||||
"php " . Froxlor::getInstallDir() . "bin/froxlor-cli froxlor:config-services --apply=" . $output_file,
|
||||
""
|
||||
]);
|
||||
$proceed = $io->confirm("Do you want to apply the config now?", false);
|
||||
if ($proceed) {
|
||||
passthru("php " . Froxlor::getInstallDir() . "bin/froxlor-cli froxlor:config-services --apply=" . $output_file);
|
||||
}
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function applyConfig(InputInterface $input, OutputInterface $output, SymfonyStyle $io)
|
||||
{
|
||||
$applyFile = $input->getOption('apply');
|
||||
|
||||
if (strtoupper(substr($applyFile, 0, 4)) == 'HTTP') {
|
||||
$output->writeln("Config file seems to be an URL, trying to download");
|
||||
$target = "/tmp/froxlor-config-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($applyFile, $target);
|
||||
$applyFile = $target;
|
||||
}
|
||||
if (!is_file($applyFile)) {
|
||||
$output->writeln('<error>Given config file is not a file</>');
|
||||
return self::INVALID;
|
||||
} elseif (!file_exists($applyFile)) {
|
||||
$output->writeln('<error>Given config file cannot be found (' . $applyFile . ')</>');
|
||||
return self::INVALID;
|
||||
} elseif (!is_readable($applyFile)) {
|
||||
$output->writeln('<error>Given config file cannot be read (' . $applyFile . ')</>');
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
$config = file_get_contents($applyFile);
|
||||
$decoded_config = json_decode($config, true);
|
||||
|
||||
if ($input->getOption('list') != false) {
|
||||
$table_rows = [];
|
||||
foreach ($decoded_config as $service => $daemon) {
|
||||
if (is_array($daemon) && count($daemon) > 0) {
|
||||
foreach ($daemon as $sysdaemon) {
|
||||
$table_rows[] = [$service, $sysdaemon];
|
||||
}
|
||||
} else {
|
||||
if ($daemon == 'x') {
|
||||
$daemon = '--- skipped ---';
|
||||
}
|
||||
$table_rows[] = [$service, $daemon];
|
||||
}
|
||||
}
|
||||
|
||||
$io->table(
|
||||
['Service', 'Selected daemon'],
|
||||
$table_rows
|
||||
);
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$only_daemon = [];
|
||||
if ($input->getOption('daemon') != false) {
|
||||
$only_daemon = $input->getOption('daemon');
|
||||
}
|
||||
|
||||
if (!empty($decoded_config)) {
|
||||
$config_dir = Froxlor::getInstallDir() . 'lib/configfiles/';
|
||||
$configfiles = new ConfigParser($config_dir . '/' . $decoded_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
$replace_arr = $this->getReplacerArray();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
$output->writeln("--- Configuring: " . strtoupper($si) . " ---");
|
||||
if (!isset($decoded_config[$si]) || $decoded_config[$si] == 'x') {
|
||||
$output->writeln('<comment>Skipping ' . strtoupper($si) . ' configuration as desired</>');
|
||||
continue;
|
||||
}
|
||||
$daemons = $service->getDaemons();
|
||||
foreach ($daemons as $di => $dd) {
|
||||
// check for desired service
|
||||
if (($si != 'system' && $decoded_config[$si] != $di) || (is_array($decoded_config[$si]) && !in_array($di, $decoded_config[$si]))) {
|
||||
continue;
|
||||
}
|
||||
$output->writeln("Configuring '" . $di . "'");
|
||||
|
||||
if (!empty($only_daemon) && !in_array($di, $only_daemon)) {
|
||||
$output->writeln('<comment>Skipping ' . $di . ' configuration as desired</>');
|
||||
continue;
|
||||
}
|
||||
// run all cmds
|
||||
$confarr = $dd->getConfig();
|
||||
foreach ($confarr as $action) {
|
||||
switch ($action['type']) {
|
||||
case "install":
|
||||
$output->writeln("Installing required packages");
|
||||
$result = null;
|
||||
passthru(strtr($action['content'], $replace_arr), $result);
|
||||
if (strlen($result) > 1) {
|
||||
echo $result;
|
||||
}
|
||||
break;
|
||||
case "command":
|
||||
exec(strtr($action['content'], $replace_arr));
|
||||
break;
|
||||
case "file":
|
||||
if (array_key_exists('content', $action)) {
|
||||
$output->writeln('<comment>Creating file "' . $action['name'] . '"</>');
|
||||
file_put_contents($action['name'], trim(strtr($action['content'], $replace_arr)));
|
||||
} elseif (array_key_exists('subcommands', $action)) {
|
||||
foreach ($action['subcommands'] as $fileaction) {
|
||||
if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "post") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif ($fileaction['type'] == 'file') {
|
||||
$output->writeln('<comment>Creating file "' . $fileaction['name'] . '"</>');
|
||||
file_put_contents($fileaction['name'], trim(strtr($fileaction['content'], $replace_arr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// set is_configured flag
|
||||
Settings::Set('panel.is_configured', '1', true);
|
||||
// run cronjob at the end to ensure configs are all up to date
|
||||
exec('php ' . Froxlor::getInstallDir() . 'scripts/froxlor_master_cronjob.php --force');
|
||||
// and done
|
||||
$output->writeln('<info>All services have been configured</>');
|
||||
return self::SUCCESS;
|
||||
} else {
|
||||
$output->writeln('<error>Unable to decode given JSON file</>');
|
||||
return self::INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
private function getReplacerArray()
|
||||
{
|
||||
$customer_tmpdir = '/tmp/';
|
||||
if (Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('system.mod_fcgid_tmpdir');
|
||||
} elseif (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('phpfpm.tmpdir');
|
||||
}
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
$known_ns_ips = [];
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, -1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (!is_array($nameserver_ips)) {
|
||||
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver
|
||||
);
|
||||
} else {
|
||||
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
|
||||
}
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
|
||||
// AXFR server
|
||||
if (Settings::Get('system.axfrservers') != '') {
|
||||
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
|
||||
foreach ($axfrservers as $axfrserver) {
|
||||
if (!in_array(trim($axfrserver), $known_ns_ips)) {
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= trim($axfrserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Database::needSqlData();
|
||||
$sql = Database::getSqlData();
|
||||
|
||||
$replace_arr = array(
|
||||
'<SQL_UNPRIVILEGED_USER>' => $sql['user'],
|
||||
'<SQL_UNPRIVILEGED_PASSWORD>' => $sql['passwd'],
|
||||
'<SQL_DB>' => $sql['db'],
|
||||
'<SQL_HOST>' => $sql['host'],
|
||||
'<SQL_SOCKET>' => isset($sql['socket']) ? $sql['socket'] : null,
|
||||
'<SERVERNAME>' => Settings::Get('system.hostname'),
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
'<SSLPROTOCOLS>' => (Settings::Get('system.use_ssl') == '1') ? 'imaps pop3s' : '',
|
||||
'<CUSTOMER_TMP>' => FileDir::makeCorrectDir($customer_tmpdir),
|
||||
'<BASE_PATH>' => Froxlor::getInstallDir(),
|
||||
'<BIND_CONFIG_PATH>' => FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory')),
|
||||
'<WEBSERVER_RELOAD_CMD>' => Settings::Get('system.apachereload_command'),
|
||||
'<CUSTOMER_LOGS>' => FileDir::makeCorrectDir(Settings::Get('system.logfiles_directory')),
|
||||
'<FPM_IPCDIR>' => FileDir::makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir')),
|
||||
'<WEBSERVER_GROUP>' => Settings::Get('system.httpgroup')
|
||||
);
|
||||
return $replace_arr;
|
||||
}
|
||||
|
||||
private function getCompleteDistroName($cparser)
|
||||
{
|
||||
// get distro-info
|
||||
$dist_display = $cparser->distributionName;
|
||||
if ($cparser->distributionCodename != '') {
|
||||
$dist_display .= " " . $cparser->distributionCodename;
|
||||
}
|
||||
if ($cparser->distributionVersion != '') {
|
||||
$dist_display .= " (" . $cparser->distributionVersion . ")";
|
||||
}
|
||||
if ($cparser->deprecated) {
|
||||
$dist_display .= " [deprecated]";
|
||||
}
|
||||
return $dist_display;
|
||||
}
|
||||
|
||||
private function importSettings(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$importFile = $input->getOption('import-settings');
|
||||
|
||||
if (strtoupper(substr($importFile, 0, 4)) == 'HTTP') {
|
||||
$output->writeln("Settings file seems to be an URL, trying to download");
|
||||
$target = "/tmp/froxlor-import-settings-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($importFile, $target);
|
||||
$importFile = $target;
|
||||
}
|
||||
if (!is_file($importFile)) {
|
||||
$output->writeln('<error>Given settings file is not a file</>');
|
||||
return self::INVALID;
|
||||
} elseif (!file_exists($importFile)) {
|
||||
$output->writeln('<error>Given settings file cannot be found (' . $importFile . ')</>');
|
||||
return self::INVALID;
|
||||
} elseif (!is_readable($importFile)) {
|
||||
$output->writeln('<error>Given settings file cannot be read (' . $importFile . ')</>');
|
||||
return self::INVALID;
|
||||
}
|
||||
$imp_content = file_get_contents($importFile);
|
||||
SImExporter::import($imp_content);
|
||||
$output->writeln("<info>Successfully imported settings from '" . $input->getOption('import-settings') . "'</info>");
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function downloadFile($src, $dest)
|
||||
{
|
||||
set_time_limit(0);
|
||||
// This is the file where we save the information
|
||||
$fp = fopen($dest, 'w+');
|
||||
// Here is the file we are downloading, replace spaces with %20
|
||||
$ch = curl_init(str_replace(" ", "%20", $src));
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
// write curl response to file
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
// get curl response
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class ConfigServicesCmd extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'create',
|
||||
'apply',
|
||||
'import-settings',
|
||||
'daemon',
|
||||
'list-daemons',
|
||||
'froxlor-dir',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = '\\Froxlor\\Cli\\Action\\ConfigServicesAction';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--create\t\tlets you create a services list configuration for the 'apply' command");
|
||||
self::println("");
|
||||
self::println("--apply\t\t\tconfigure your services by given configuration file. To create one run the --create command");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json or --apply=http://domain.tld/my-config.json");
|
||||
self::println("");
|
||||
self::println("--list-daemons\t\tOutput the services that are going to be configured using a given config file. No services will be configured.");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json --list-daemons");
|
||||
self::println("");
|
||||
self::println("--daemon\t\tWhen running --apply you can specify a daemon. This will be the only service that gets configured");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json --daemon=apache24");
|
||||
self::println("");
|
||||
self::println("--import-settings\tImport settings from another froxlor installation. This should be done prior to running --apply or alternatively in the same command together.");
|
||||
self::println("\t\t\tExample: --import-settings=/path/to/Froxlor_settings-[version]-[dbversion]-[date].json or --import-settings=http://domain.tld/Froxlor_settings-[version]-[dbversion]-[date].json");
|
||||
self::println("");
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
// self::println("-d\t\t\tenable debug output");
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
88
lib/Froxlor/Cli/PhpSessionclean.php
Normal file
88
lib/Froxlor/Cli/PhpSessionclean.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Database\Database;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2022 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
final class PhpSessionclean extends Command
|
||||
{
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('froxlor:php-sessionclean');
|
||||
$this->setDescription('Cleans old php-session files from tmp folder');
|
||||
$this->addArgument('max-lifetime', InputArgument::OPTIONAL, 'The number of seconds after which data will be seen as "garbage" and potentially cleaned up. Defaults to "1440"');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (!file_exists(Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
|
||||
$output->writeln("<error>Could not find froxlor's userdata.inc.php file. You should use this script only with an installed froxlor system.</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if ($input->hasArgument('max-lifetime') && is_numeric($input->getArgument('max-lifetime')) && $input->getArgument('max-lifetime') > 0) {
|
||||
$this->cleanSessionfiles((int)$input->getArgument('max-lifetime'));
|
||||
} else {
|
||||
// use default max-lifetime value
|
||||
$this->cleanSessionfiles();
|
||||
}
|
||||
return self::SUCCESS;
|
||||
}
|
||||
// php-fpm not enabled
|
||||
$output->writeln('<comment>PHP-FPM not enabled for this installation.</comment>');
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
private function cleanSessionfiles(int $maxlifetime = 1440)
|
||||
{
|
||||
// store paths to clean up
|
||||
$paths_to_clean = [];
|
||||
// get all pool-config directories configured
|
||||
$sel_stmt = Database::prepare("SELECT DISTINCT `config_dir` FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($sel_stmt);
|
||||
while ($fpmd = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$poolfiles = glob(FileDir::makeCorrectFile($fpmd['config_dir'] . '/*.conf'));
|
||||
foreach ($poolfiles as $cf) {
|
||||
$contents = file_get_contents($cf);
|
||||
$pattern = preg_quote('session.save_path', '/');
|
||||
$pattern = "/" . $pattern . ".+?\=(.*)/";
|
||||
if (preg_match_all($pattern, $contents, $matches)) {
|
||||
$paths_to_clean[] = FileDir::makeCorrectDir(trim($matches[1][0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// every path is just needed once
|
||||
$paths_to_clean = array_unique($paths_to_clean);
|
||||
|
||||
if (count($paths_to_clean) > 0) {
|
||||
foreach ($paths_to_clean as $ptc) {
|
||||
// find all files older then maxlifetime and delete them
|
||||
FileDir::safe_exec("find -O3 \"" . $ptc . "\" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin \"+" . $maxlifetime . "\" -delete");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2022 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class PhpSessioncleanCmd extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'froxlor-dir',
|
||||
'max-lifetime',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = '\\Froxlor\\Cli\\Action\\PhpSessioncleanAction';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--max-lifetime\t\tThe number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Defaults to '1440'");
|
||||
self::println("\t\t\tExample: --max-lifetime=2000");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
181
lib/Froxlor/Cli/SwitchServerIp.php
Normal file
181
lib/Froxlor/Cli/SwitchServerIp.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Database\Database;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2022 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
final class SwitchServerIp extends Command
|
||||
{
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('froxlor:switch-server-ip');
|
||||
$this->setDescription('Easily switch IP addresses e.g. after server migration');
|
||||
$this->addOption('switch', 's', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Switch IP-address pair. A pair is separated by comma. For example: --switch=A,B')
|
||||
->addOption('list', 'l', InputOption::VALUE_NONE, 'List all IP addresses currently added for this server in froxlor');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (!file_exists(Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
|
||||
$output->writeln("<error>Could not find froxlor's userdata.inc.php file. You should use this script only with an installed froxlor system.</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
if ($input->getOption('list') == false && $input->getOption('switch') == false) {
|
||||
$output->writeln('<error>Either --list or --switch option must be provided. Nothing to do, exiting.</>');
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
$result = self::SUCCESS;
|
||||
|
||||
if ($input->getOption('list')) {
|
||||
|
||||
$sel_stmt = Database::prepare("SELECT * FROM panel_ipsandports ORDER BY ip ASC, port ASC");
|
||||
Database::pexecute($sel_stmt);
|
||||
$ips = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$table_rows = [];
|
||||
foreach ($ips as $ipdata) {
|
||||
$table_rows[] = [$ipdata['id'], $ipdata['ip'], $ipdata['port']];
|
||||
}
|
||||
|
||||
$io->table(
|
||||
['#', 'IP address', 'Port'],
|
||||
$table_rows
|
||||
);
|
||||
}
|
||||
|
||||
if ($input->getOption('switch')) {
|
||||
$result = $this->switchIPs($input, $output);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function switchIPs(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$ip_list = $input->getOption('switch');
|
||||
|
||||
$has_error = false;
|
||||
foreach ($ip_list as $ips_combo) {
|
||||
$ip_pair = explode(",", $ips_combo);
|
||||
if (count($ip_pair) != 2) {
|
||||
$output->writeln('<error>Invalid option parameter, not a valid IP address pair.</>');
|
||||
$has_error = true;
|
||||
} else {
|
||||
if (filter_var($ip_pair[0], FILTER_VALIDATE_IP) == false) {
|
||||
$output->writeln('<error>Invalid source ip address: ' . $ip_pair[0] . '</>');
|
||||
$has_error = true;
|
||||
}
|
||||
if (filter_var($ip_pair[1], FILTER_VALIDATE_IP) == false) {
|
||||
$output->writeln('<error>Invalid target ip address: ' . $ip_pair[1] . '</>');
|
||||
$has_error = true;
|
||||
}
|
||||
if ($ip_pair[0] == $ip_pair[1] && !$has_error) {
|
||||
$output->writeln('<error>Source and target ip address are equal</>');
|
||||
$has_error = true;
|
||||
}
|
||||
}
|
||||
$ips_to_switch[] = $ip_pair;
|
||||
}
|
||||
if ($has_error) {
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
if (count($ips_to_switch) > 0) {
|
||||
$check_stmt = Database::prepare("SELECT `id` FROM panel_ipsandports WHERE `ip` = :newip");
|
||||
$upd_stmt = Database::prepare("UPDATE panel_ipsandports SET `ip` = :newip WHERE `ip` = :oldip");
|
||||
|
||||
// system.ipaddress
|
||||
$check_sysip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
$check_sysip = Database::pexecute_first($check_sysip_stmt);
|
||||
|
||||
// system.mysql_access_host
|
||||
$check_mysqlip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
$check_mysqlip = Database::pexecute_first($check_mysqlip_stmt);
|
||||
|
||||
// system.axfrservers
|
||||
$check_axfrip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
$check_axfrip = Database::pexecute_first($check_axfrip_stmt);
|
||||
|
||||
foreach ($ips_to_switch as $ip_pair) {
|
||||
$output->writeln('Switching IP <comment>' . $ip_pair[0] . '</> to IP <comment>' . $ip_pair[1] . '</>');
|
||||
|
||||
$ip_check = Database::pexecute_first($check_stmt, array(
|
||||
'newip' => $ip_pair[1]
|
||||
));
|
||||
if ($ip_check) {
|
||||
$output->writeln('<error>Note: ' . $ip_pair[0] . ' not updated to ' . $ip_pair[1] . ' - IP already exists in froxlor\'s database</>');
|
||||
continue;
|
||||
}
|
||||
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'newip' => $ip_pair[1],
|
||||
'oldip' => $ip_pair[0]
|
||||
));
|
||||
$rows_updated = $upd_stmt->rowCount();
|
||||
|
||||
if ($rows_updated == 0) {
|
||||
$output->writeln('<error>Note: ' . $ip_pair[0] . ' not updated to ' . $ip_pair[1] . ' (possibly no entry found in froxlor database. Use --list to see what IP addresses are added in froxlor');
|
||||
continue;
|
||||
}
|
||||
|
||||
// check whether the system.ipaddress needs updating
|
||||
if ($check_sysip['value'] == $ip_pair[0]) {
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newip WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newip' => $ip_pair[1]
|
||||
));
|
||||
$output->writeln('<info>Updated system-ipaddress from <comment>' . $ip_pair[0] . '</comment> to <comment>' . $ip_pair[1] . '</comment></info>');
|
||||
}
|
||||
|
||||
// check whether the system.mysql_access_host needs updating
|
||||
if (strstr($check_mysqlip['value'], $ip_pair[0]) !== false) {
|
||||
$new_mysqlip = str_replace($ip_pair[0], $ip_pair[1], $check_mysqlip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newmysql WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newmysql' => $new_mysqlip
|
||||
));
|
||||
$output->writeln('<info>Updated mysql_access_host from <comment>' . $check_mysqlip['value'] . '</comment> to <comment>' . $new_mysqlip . '</comment></info>');
|
||||
}
|
||||
|
||||
// check whether the system.axfrservers needs updating
|
||||
if (strstr($check_axfrip['value'], $ip_pair[0]) !== false) {
|
||||
$new_axfrip = str_replace($ip_pair[0], $ip_pair[1], $check_axfrip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newaxfr WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newaxfr' => $new_axfrip
|
||||
));
|
||||
$output->writeln('<info>Updated axfr-servers from <comment>' . $check_axfrip['value'] . '</comment> to <comment>' . $new_axfrip . '</comment></info>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$output->writeln("");
|
||||
$output->writeln("<comment>*** ATTENTION *** Remember to replace IP addresses in configuration files if used anywhere.</>");
|
||||
$output->writeln("<info>IP addresses updated</>");
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class SwitchServerIpCmd extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'switch',
|
||||
'list',
|
||||
'froxlor-dir',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = '\\Froxlor\\Cli\\Action\\SwitchServerIpAction';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--switch\t\tlets you switch ip-address A with ip-address B");
|
||||
self::println("\t\t\tExample: --switch=A,B");
|
||||
self::println("\t\t\tExample: --switch=\"A1,B1 A2,B2 A3,B3 ...\"");
|
||||
self::println("");
|
||||
self::println("--list\t\t\tshow all currently used ip-addresses in froxlor");
|
||||
self::println("");
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
// self::println("-d\t\t\tenable debug output");
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ class CronConfig
|
||||
// php sessionclean if enabled
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
$cronfile .= "# Look for and purge old sessions every 30 minutes" . PHP_EOL;
|
||||
$cronfile .= "09,39 * * * * root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/scripts/php-sessionclean.php") . " --froxlor-dir=" . escapeshellarg(\Froxlor\Froxlor::getInstallDir()) . " 1> /dev/null" . PHP_EOL;
|
||||
$cronfile .= "09,39 * * * * root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/bin/froxlor-cli") . " froxlor:php-sessionclean 1> /dev/null" . PHP_EOL;
|
||||
}
|
||||
|
||||
if (\Froxlor\FileDir::isFreeBSD()) {
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Froxlor\UI\Callbacks;
|
||||
|
||||
use Froxlor\PhpHelper;
|
||||
use Froxlor\UI\Panel\UI;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\User;
|
||||
|
||||
/**
|
||||
@@ -65,4 +66,22 @@ class Text
|
||||
{
|
||||
return wordwrap($attributes['data'], 100, '<br>', true);
|
||||
}
|
||||
|
||||
public static function apikeyDetailModal(array $attributes): array
|
||||
{
|
||||
$linker = UI::getLinker();
|
||||
$result = $attributes['fields'];
|
||||
$apikey_data = include Froxlor::getInstallDir() . '/lib/formfields/formfield.api_key.php';
|
||||
|
||||
$body = UI::twig()->render(UI::getTheme().'/user/inline-form.html.twig', [
|
||||
'formaction' => $linker->getLink(array('section' => 'index', 'page' => 'apikeys')),
|
||||
'formdata' => $apikey_data['apikey'],
|
||||
'editid' => $attributes['fields']['id']
|
||||
]);
|
||||
return [
|
||||
'id' => 'akModal' . $attributes['fields']['id'],
|
||||
'title' => 'API-key ' . ($attributes['fields']['loginname'] ?? $attributes['fields']['adminname']),
|
||||
'body' => $body
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,10 @@ class Form
|
||||
|
||||
if (\Froxlor\Validate\Form::validateFormDefinition($form)) {
|
||||
foreach ($form['groups'] as $groupname => $groupdetails) {
|
||||
// check for advanced mode sections
|
||||
if (isset($groupdetails['advanced_mode']) && $groupdetails['advanced_mode'] && (int) Settings::Get('panel.settings_mode') == 0) {
|
||||
continue;
|
||||
}
|
||||
// show overview
|
||||
if ($part == '' || $part == 'all') {
|
||||
if (isset($groupdetails['title']) && $groupdetails['title'] != '') {
|
||||
@@ -48,6 +52,10 @@ class Form
|
||||
if (\Froxlor\Validate\Form::validateFieldDefinition($groupdetails)) {
|
||||
// Collect form field output
|
||||
foreach ($groupdetails['fields'] as $fieldname => $fielddetails) {
|
||||
// check for advanced mode sections
|
||||
if (isset($fielddetails['advanced_mode']) && $fielddetails['advanced_mode'] && (int) Settings::Get('panel.settings_mode') == 0) {
|
||||
continue;
|
||||
}
|
||||
$fields[$fieldname] = self::getFormFieldOutput($fieldname, $fielddetails);
|
||||
$fields[$fieldname] = array_merge($fields[$fieldname], self::prefetchFormFieldData($fieldname, $fielddetails));
|
||||
}
|
||||
|
||||
@@ -171,6 +171,11 @@ class Listing
|
||||
// Set actual link from linker
|
||||
$actions[$key]['href'] = $linker->getLink($action['href']);
|
||||
}
|
||||
|
||||
// modal trigger - always require a valid callback
|
||||
if (isset($action['modal']) && !empty($action['modal'])) {
|
||||
$actions[$key]['modal'] = call_user_func($action['modal'], ['fields' => $item]);
|
||||
}
|
||||
}
|
||||
|
||||
return $actions;
|
||||
@@ -216,7 +221,7 @@ class Listing
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_USERCOLUMNS . "` WHERE `" . $userid . "` = :uid AND `section` = :section
|
||||
");
|
||||
Database::pexecute($del_stmt, ['uid' => CurrentUser::getData($userid), 'section' => $section]);
|
||||
Database::pexecute($del_stmt, ['uid' => CurrentUser::getField($userid), 'section' => $section]);
|
||||
// add new entry
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_USERCOLUMNS . "` SET
|
||||
@@ -225,7 +230,7 @@ class Listing
|
||||
`columns` = :cols
|
||||
");
|
||||
Database::pexecute($ins_stmt, [
|
||||
'uid' => CurrentUser::getData($userid),
|
||||
'uid' => CurrentUser::getField($userid),
|
||||
'section' => $section,
|
||||
'cols' => json_encode($tabellisting[$section])
|
||||
]);
|
||||
@@ -241,7 +246,7 @@ class Listing
|
||||
$sel_stmt = Database::prepare("
|
||||
SELECT `columns` FROM `" . TABLE_PANEL_USERCOLUMNS . "` WHERE `" . $userid . "` = :uid AND `section` = :section
|
||||
");
|
||||
$columns_json = Database::pexecute_first($sel_stmt, ['uid' => CurrentUser::getData($userid), 'section' => $listing]);
|
||||
$columns_json = Database::pexecute_first($sel_stmt, ['uid' => CurrentUser::getField($userid), 'section' => $listing]);
|
||||
if ($columns_json && isset($columns_json['columns'])) {
|
||||
return json_decode($columns_json['columns'], true);
|
||||
}
|
||||
|
||||
57
lib/formfields/formfield.api_key.php
Normal file
57
lib/formfields/formfield.api_key.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
use Froxlor\UI\Panel\UI;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Formfields
|
||||
*
|
||||
*/
|
||||
return [
|
||||
'apikey' => [
|
||||
'title' => UI::getLng('menue.main.apikeys'),
|
||||
'sections' => [
|
||||
'section_a' => [
|
||||
'fields' => [
|
||||
'loginname' => [
|
||||
'label' => UI::getLng('login.username'),
|
||||
'type' => 'label',
|
||||
'value' => $result['loginname'] ?? $result['adminname']
|
||||
],
|
||||
'apikey' => [
|
||||
'label' => 'API key',
|
||||
'type' => 'text',
|
||||
'readonly' => true,
|
||||
'value' => $result['apikey']
|
||||
],
|
||||
'secret' => [
|
||||
'label' => 'Secret',
|
||||
'type' => 'text',
|
||||
'readonly' => true,
|
||||
'value' => $result['secret']
|
||||
],
|
||||
'allowed_from' => [
|
||||
'label' => UI::getLng('apikeys.allowed_from'),
|
||||
'type' => 'text',
|
||||
'value' => $result['allowed_from'],
|
||||
],
|
||||
'valid_until' => [
|
||||
'label' => UI::getLng('apikeys.valid_until'),
|
||||
'type' => 'text',
|
||||
'value' => $result['valid_until'],
|
||||
'format_callback' => [Text::class, 'timestampUntil'],
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -61,12 +61,7 @@ return [
|
||||
'show' => [
|
||||
'icon' => 'fa fa-eye',
|
||||
'title' => $lng['apikeys']['clicktoview'],
|
||||
'href' => [
|
||||
'section' => 'index',
|
||||
'page' => 'apikeys',
|
||||
'action' => '#',
|
||||
'id' => ':id'
|
||||
],
|
||||
'modal' => [Text::class, 'apikeyDetailModal'],
|
||||
],
|
||||
'delete' => [
|
||||
'icon' => 'fa fa-trash',
|
||||
|
||||
@@ -2161,3 +2161,8 @@ $lng['panel']['unspecified'] = 'unspecified';
|
||||
$lng['admin']['smtptestaddr'] = 'Send test-mail to';
|
||||
$lng['admin']['smtptestnote'] = 'Note that the values below reflect your current settings and can only be adjusted there (see link in top right corner)';
|
||||
$lng['panel']['backtooverview'] = 'Back to overview';
|
||||
$lng['panel']['settingsmode'] = 'Mode';
|
||||
$lng['panel']['settingsmodebasic'] = 'Basic';
|
||||
$lng['panel']['settingsmodeadvanced'] = 'Advanced';
|
||||
$lng['panel']['settingsmodetoggle'] = 'Click to toggle mode';
|
||||
$lng['panel']['modalclose'] = 'Close';
|
||||
|
||||
@@ -1799,3 +1799,8 @@ $lng['panel']['unspecified'] = 'keine Angabe';
|
||||
$lng['admin']['smtptestaddr'] = 'Test-Email senden an';
|
||||
$lng['admin']['smtptestnote'] = 'Bitte beachten: Die untenstehenden Werte reflektieren die aktuellen Einstellungen und können auch nur dort angepasst werden (siehe Link in der oberen rechten Ecke)';
|
||||
$lng['panel']['backtooverview'] = 'Zurück zur Übersicht';
|
||||
$lng['panel']['settingsmode'] = 'Modus';
|
||||
$lng['panel']['settingsmodebasic'] = 'Einfach';
|
||||
$lng['panel']['settingsmodeadvanced'] = 'Erweitert';
|
||||
$lng['panel']['settingsmodetoggle'] = 'Modus umschalten';
|
||||
$lng['panel']['modalclose'] = 'Schließen';
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2022 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
// Check if we're in the CLI
|
||||
if (@php_sapi_name() !== 'cli') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
// give control to command line handler
|
||||
try {
|
||||
\Froxlor\Cli\PhpSessioncleanCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\Cli\PhpSessioncleanCmd::printerr($e->getMessage());
|
||||
exit(1);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
{% macro form(form_data, formaction, title = "", hiddenid = "") %}
|
||||
{% macro form(form_data, formaction, title = "", hiddenid = "", nosubmit = false) %}
|
||||
|
||||
{% import "Froxlor/form/formfields.html.twig" as formfields %}
|
||||
|
||||
@@ -21,25 +21,27 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- submit buttons -->
|
||||
<div>
|
||||
{% if hiddenid is not empty %}
|
||||
<input type="hidden" name="id" value="{{ hiddenid }}"/>
|
||||
{% endif %}
|
||||
<input type="hidden" name="page" value="{{ page }}"/>
|
||||
<input type="hidden" name="action" value="{{ action }}"/>
|
||||
<input type="hidden" name="send" value="send"/>
|
||||
|
||||
<div class="col-12 text-end">
|
||||
{% if form_data.buttons is defined and form_data.buttons is iterable %}
|
||||
{% for btn in form_data.buttons %}
|
||||
<button type="{{ btn.type|default("submit") }}" class="btn {{ btn.class|default(" btn-primary") }}">{{ btn.label }}</button>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<button type="reset" class="btn btn-outline-secondary">{{ lng('panel.cancel') }}</button>
|
||||
<button type="submit" class="btn btn-primary">{{ lng('panel.save') }}</button>
|
||||
{% if nosubmit == false %}
|
||||
<!-- submit buttons -->
|
||||
<div>
|
||||
{% if hiddenid is not empty %}
|
||||
<input type="hidden" name="id" value="{{ hiddenid }}"/>
|
||||
{% endif %}
|
||||
<input type="hidden" name="page" value="{{ page }}"/>
|
||||
<input type="hidden" name="action" value="{{ action }}"/>
|
||||
<input type="hidden" name="send" value="send"/>
|
||||
|
||||
<div class="col-12 text-end">
|
||||
{% if form_data.buttons is defined and form_data.buttons is iterable %}
|
||||
{% for btn in form_data.buttons %}
|
||||
<button type="{{ btn.type|default("submit") }}" class="btn {{ btn.class|default(" btn-primary") }}">{{ btn.label }}</button>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<button type="reset" class="btn btn-outline-secondary">{{ lng('panel.cancel') }}</button>
|
||||
<button type="submit" class="btn btn-primary">{{ lng('panel.save') }}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row mb-2">
|
||||
<textarea cols="12" rows="4" readonly class="form-control w-100">`which php` {{ basedir }}install/scripts/config-services.php --froxlor-dir={{ basedir }} --apply={{ params_filename }}
|
||||
<textarea cols="12" rows="4" readonly class="form-control w-100">{{ basedir }}bin/froxlor-cli froxlor:config-services --apply={{ params_filename }}
|
||||
rm {{ params_filename }}</textarea>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
{% extends "Froxlor/settings/index.html.twig" %}
|
||||
|
||||
{% block actions %}
|
||||
<a class="btn btn-outline-primary" href="{{ linker({'section':'settings','page':'overview','part':'all'}) }}">
|
||||
<i class="fa-solid fa-grip me-1"></i>
|
||||
{{ lng('admin.configfiles.overview') }}
|
||||
</a>
|
||||
<a class="btn btn-outline-secondary" href="{{ linker({'section':'settings','page':'importexport'}) }}">
|
||||
<i class="fa-solid fa-file-import me-1"></i>
|
||||
{{ lng('admin.configfiles.importexport') }}
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block settings %}
|
||||
|
||||
{% import "Froxlor/form/formfields.html.twig" as formfields %}
|
||||
|
||||
@@ -11,9 +11,14 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block actions %}
|
||||
<a class="btn btn-outline-primary" href="{{ linker({'section':'settings','page':'overview','part':'all'}) }}">
|
||||
<i class="fa-solid fa-grip me-1"></i>
|
||||
{{ lng('admin.configfiles.overview') }}
|
||||
<a class="btn btn-outline-secondary" href="{{ linker({'section':'settings','page':'toggleSettingsMode'}) }}" title="{{ lng('panel.settingsmodetoggle') }}">
|
||||
{% if get_setting('panel.settings_mode') == 0 %}
|
||||
<i class="fa-solid fa-maximize me-1"></i>
|
||||
{{ lng('panel.settingsmode') }}: {{ lng('panel.settingsmodebasic') }}
|
||||
{% else %}
|
||||
<i class="fa-solid fa-minimize me-1"></i>
|
||||
{{ lng('panel.settingsmode') }}: {{ lng('panel.settingsmodeadvanced') }}
|
||||
{% endif %}
|
||||
</a>
|
||||
<a class="btn btn-outline-secondary" href="{{ linker({'section':'settings','page':'importexport'}) }}">
|
||||
<i class="fa-solid fa-file-import me-1"></i>
|
||||
|
||||
@@ -31,27 +31,45 @@
|
||||
|
||||
{% macro link(data) %}
|
||||
{% apply spaceless %}
|
||||
<a href="{{ data.href }}" {% if data.class is defined %} class="{{ data.class }}" {% endif %} {% if data.target is defined %} target="{{ data.target }}" {% endif %}{% if data.title is defined %} title="{{ data.title }}" {% endif %}>
|
||||
{% if data.icon is defined %}
|
||||
<i class="{{ data.icon }}"></i>
|
||||
{% endif %}
|
||||
{% if data.text is defined %}
|
||||
{{ data.text }}
|
||||
{% endif %}
|
||||
</a>
|
||||
<a href="{{ data.href }}" {% if data.class is defined %} class="{{ data.class }}" {% endif %} {% if data.target is defined %} target="{{ data.target }}" {% endif %} {% if data.title is defined %} title="{{ data.title }}" {% endif %}>
|
||||
{% if data.icon is defined %}
|
||||
<i class="{{ data.icon }}"></i>
|
||||
{% endif %}
|
||||
{% if data.text is defined %}
|
||||
{{ data.text }}
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endapply %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro button(data) %}
|
||||
{% apply spaceless %}
|
||||
<a class="{% if data.class is defined %}btn btn-sm {{ data.class }}{% else %}btn btn-sm btn-outline-secondary{% endif %}" href="{{ data.href }}" {% if data.target is defined %} target="{{ data.target }}" {% endif %}{% if data.title is defined %} title="{{ data.title }}" {% endif %}>
|
||||
{% if data.icon is defined %}
|
||||
<i class="{{ data.icon }}"></i>
|
||||
{% endif %}
|
||||
{% if data.text is defined %}
|
||||
{{ data.text }}
|
||||
{% endif %}
|
||||
</a>
|
||||
<a class="{% if data.class is defined %}btn btn-sm {{ data.class }}{% else %}btn btn-sm btn-outline-secondary{% endif %}" {% if data.modal is defined and data.modal is iterable %} data-bs-toggle="modal" role="button" href="#{{ data.modal.id }}" {% else %} href="{{ data.href }}" {% endif %} {% if data.target is defined %} target="{{ data.target }}" {% endif %} {% if data.title is defined %} title="{{ data.title }}" {% endif %}>
|
||||
{% if data.icon is defined %}
|
||||
<i class="{{ data.icon }}"></i>
|
||||
{% endif %}
|
||||
{% if data.text is defined %}
|
||||
{{ data.text }}
|
||||
{% endif %}
|
||||
</a>
|
||||
{% if data.modal is defined and data.modal is iterable %}
|
||||
<div class="modal fade" id="{{ data.modal.id }}" aria-hidden="true" aria-labelledby="{{ data.modal.id }}Label" tabindex="-1">
|
||||
<div class="modal-dialog {{ data.modal.size|default('modal-xl') }} modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="{{ data.modal.id }}Label">{{ data.modal.title }}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{ lng('panel.modalclose') }}"></button>
|
||||
</div>
|
||||
<div class="modal-body text-start">
|
||||
{{ data.modal.body|raw }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" data-bs-dismiss="modal">{{ lng('panel.modalclose') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endapply %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
2
templates/Froxlor/user/inline-form.html.twig
Normal file
2
templates/Froxlor/user/inline-form.html.twig
Normal file
@@ -0,0 +1,2 @@
|
||||
{% import "Froxlor/form/form.html.twig" as form %}
|
||||
{{ form.form(formdata, formaction|default('#'), formdata.title, editid|default(''), true) }}
|
||||
Reference in New Issue
Block a user