-
-
';
-
+ return '
'.
+ '
'.
+ ' '.$this->trans('IMAP Servers').'
'.$count.'
';
}
}
@@ -1308,4 +1287,92 @@ protected function output() {
$res .= '
';
return $res;
}
-}
\ No newline at end of file
+}
+/**
+ * @subpackage jmap/output
+ */
+class Hm_Output_stepper_setup_server_jmap extends Hm_Output_Module {
+ protected function output() {
+ if(!in_array('jmap', $this->get('router_module_list'), true)) return '';
+ return '
+
+
+
+ '.$this->trans('Setup JMAP Server').'
+
+
+
+
JMAP
+
+
+ '.$this->trans('Address').'
+
+
+
+
+
+ '.$this->trans('Hide From Combined Pages').'
+
+
+
+ ';
+ }
+}
+
+/**
+ * @subpackage imap/output
+ */
+class Hm_Output_stepper_setup_server_imap extends Hm_Output_Module {
+ protected function output() {
+ $res = '
+
+
IMAP
+
+
+ '.$this->trans('Address').'
+
+
+
+
+
+
+ '.$this->trans('Port').'
+
+
+
+
+
+
+ ';
+
+ if (!$this->get('sieve_filters_enabled')) {
+ $default_value = '';
+ $res .= '
+
+
+
+ '.$this->trans('Enable Sieve').'
+
+
+
+ '.$this->trans('Sieve Host').'
+
+
';
+ }
+ $res .= '
';
+ return $res;
+ }
+}
diff --git a/modules/imap/setup.php b/modules/imap/setup.php
index e2981862f7..e6ba612d08 100644
--- a/modules/imap/setup.php
+++ b/modules/imap/setup.php
@@ -21,11 +21,10 @@
add_handler('servers', 'process_add_imap_server', true, 'imap', 'message_list_type', 'after');
add_handler('servers', 'process_add_jmap_server', true, 'imap', 'process_add_imap_server', 'after');
add_handler('servers', 'save_imap_servers', true, 'imap', 'process_add_jmap_server', 'after');
-add_output('servers', 'add_imap_server_dialog', true, 'imap', 'server_content_start', 'after');
-add_output('servers', 'display_configured_imap_servers', true, 'imap', 'add_imap_server_dialog', 'after');
-add_output('servers', 'add_jmap_server_dialog', true, 'imap', 'display_configured_imap_servers', 'after');
-add_output('servers', 'display_configured_jmap_servers', true, 'imap', 'add_jmap_server_dialog', 'after');
+add_output('servers', 'display_configured_imap_servers', true, 'imap', 'server_config_stepper_accordion_end_part', 'before');
add_output('servers', 'imap_server_ids', true, 'imap', 'page_js', 'before');
+add_output('servers', 'stepper_setup_server_jmap', true, 'imap', 'server_config_stepper_end_part', 'before');
+add_output('servers', 'stepper_setup_server_imap', true, 'imap', 'server_config_stepper_end_part', 'before');
/* settings page data */
add_handler('settings', 'process_sent_since_setting', true, 'imap', 'date', 'after');
diff --git a/modules/imap/site.css b/modules/imap/site.css
index ffd3fc4e01..7b2f4d7339 100644
--- a/modules/imap/site.css
+++ b/modules/imap/site.css
@@ -8,11 +8,11 @@
.hl { padding-right: 5px; color: #666; }
.dl { color: #888; }
.empty_list { text-align: center; color: #ccc; font-size: 2em; font-style: italic; padding: 30px; padding-bottom: 100px; }
-/* .credentials { width: 205px; margin-bottom: 15px !important; } */
-/* .add_server .txt_fld { width: 205px; } */
-/* .add_server .port_fld { width: 50px; } */
-/* .server_title { font-size: 110%; margin-bottom: 0px; color: #666; } */
-.server_subtitle { margin-bottom: 20px; color: #666; overflow: hidden; text-overflow: ellipsis}
+.credentials { width: 205px; margin-bottom: 15px !important; }
+.add_server .txt_fld { width: 205px; }
+.add_server .port_fld { width: 50px; }
+.server_title { font-size: 110%; margin-bottom: 0px; color: #666; }
+.server_subtitle {font-size: x-small; color: teal; overflow: hidden; text-overflow: ellipsis}
.msg_text { min-height: 600px; background-color: #fff; height: 100%; }
.msg_text_inner { min-height: 300px; font-family: monospace; width: 90%; padding: 30px; padding-left: 40px; }
/* .msg_headers { max-width: 100%; border-bottom: solid 1px #ddd; color: #777; padding: 0px; padding-bottom: 10px; padding-top: 10px; } */
diff --git a/modules/ldap_contacts/modules.php b/modules/ldap_contacts/modules.php
index c4bdc5edbe..d4cf70c7e8 100644
--- a/modules/ldap_contacts/modules.php
+++ b/modules/ldap_contacts/modules.php
@@ -317,7 +317,7 @@ class Hm_Handler_load_ldap_settings extends Hm_Handler_Module {
public function process() {
$connections = array();
foreach (ldap_config($this->config) as $name => $vals) {
- if (array_key_exists('auth', $vals) && $vals['auth']) {
+ if (is_array($vals) && array_key_exists('auth', $vals) && $vals['auth']) {
if ((!array_key_exists('user', $vals) || !$vals['user']) &&
(!array_key_exists('pass', $vals) || !$vals['pass'])) {
$connections[$name] = $vals;
diff --git a/modules/nux/modules.php b/modules/nux/modules.php
index e4b474d354..1142a6ad1f 100644
--- a/modules/nux/modules.php
+++ b/modules/nux/modules.php
@@ -251,6 +251,23 @@ public function process() {
}
}
+/**
+ * @subpackage nux/handler
+ */
+class Hm_Handler_get_nux_service_details extends Hm_Handler_Module {
+ public function process() {
+ list($success, $form) = $this->process_form(array('nux_service'));
+ if ($success) {
+ if (Nux_Quick_Services::exists($form['nux_service'])) {
+ $details = Nux_Quick_Services::details($form['nux_service']);
+
+ $this->out('nux_add_service_details', $details);
+ $this->session->set('nux_add_service_details', $details);
+ }
+ }
+ }
+}
+
/**
* @subpackage nux/output
*/
@@ -298,6 +315,16 @@ protected function output() {
}
}
+/**
+ * @subpackage nux/output
+ */
+class Hm_Output_service_details extends Hm_Output_Module {
+ protected function output() {
+ $details = $this->get('nux_add_service_details', array());
+ $this->out('service_details', json_encode($details));
+ }
+}
+
/**
* @subpackage nux/output
*/
diff --git a/modules/nux/services.php b/modules/nux/services.php
index 2ba0401f02..1bdc3dc8da 100644
--- a/modules/nux/services.php
+++ b/modules/nux/services.php
@@ -41,17 +41,17 @@
));
Nux_Quick_Services::add('outlook', array(
- 'server' => 'imap.live.com',
+ 'server' => 'outlook.office365.com',
'type' => 'imap',
'tls' => true,
'port' => 993,
'name' => 'Outlook.com',
'scope' => 'wl.imap',
- /*'smtp' => array(
- 'server' => 'smtp.live.com',
+ 'smtp' => array(
+ 'server' => 'smtp.office365.com',
'port' => 587,
- 'tls'=> 'yes'
- )*/
+ 'tls'=> false
+ )
));
Nux_Quick_Services::add('office365', array(
@@ -77,7 +77,7 @@
'auth' => 'login',
'smtp' => array(
'server' => 'smtp.mail.yahoo.com',
- 'port' => 587,
+ 'port' => 465,
'tls' => true
)
));
diff --git a/modules/nux/setup.php b/modules/nux/setup.php
index b5baa213e0..2a3e519cfb 100644
--- a/modules/nux/setup.php
+++ b/modules/nux/setup.php
@@ -6,7 +6,7 @@
output_source('nux');
/* servers page */
-add_output('servers', 'quick_add_section', true, 'nux', 'server_content_start', 'after');
+add_output('servers', 'quick_add_section', true, 'nux', 'server_config_stepper_accordion_end_part', 'after');
add_output('servers', 'quick_add_dialog', true, 'nux', 'quick_add_section', 'after');
add_handler('ajax_nux_service_select', 'login', false, 'core');
@@ -18,6 +18,14 @@
add_handler('ajax_nux_service_select', 'http_headers', true, 'core');
add_output('ajax_nux_service_select', 'filter_service_select', true);
+add_handler('ajax_get_nux_service_details', 'login', false, 'core');
+add_handler('ajax_get_nux_service_details', 'load_user_data', true, 'core');
+add_handler('ajax_get_nux_service_details', 'get_nux_service_details', true);
+add_handler('ajax_get_nux_service_details', 'language', true, 'core');
+add_handler('ajax_get_nux_service_details', 'date', true, 'core');
+add_handler('ajax_get_nux_service_details', 'http_headers', true, 'core');
+add_output('ajax_get_nux_service_details', 'service_details', true);
+
add_handler('ajax_nux_add_service', 'login', false, 'core');
add_handler('ajax_nux_add_service', 'load_user_data', true, 'core');
add_handler('ajax_nux_add_service', 'setup_nux', true);
@@ -45,7 +53,8 @@
return array(
'allowed_pages' => array(
'ajax_nux_service_select',
- 'ajax_nux_add_service',
+ 'ajax_get_nux_service_details',
+ 'ajax_nux_add_service'
),
'allowed_get' => array(
'code' => FILTER_DEFAULT,
@@ -55,6 +64,7 @@
),
'allowed_output' => array(
'nux_service_step_two' => array(FILTER_UNSAFE_RAW, false),
+ 'service_details' => array(FILTER_UNSAFE_RAW, false),
'nux_account_added' => array(FILTER_VALIDATE_BOOLEAN, false),
'nux_server_id' => array(FILTER_VALIDATE_INT, false),
'nux_service_name' => array(FILTER_DEFAULT, false)
diff --git a/modules/nux/site.js b/modules/nux/site.js
index f8441d8f2f..3cae10a145 100644
--- a/modules/nux/site.js
+++ b/modules/nux/site.js
@@ -57,7 +57,7 @@ var display_final_nux_step = function(res) {
}
);
}
-
+
window.location.href = "?page=servers";
}
};
diff --git a/modules/profiles/functions.php b/modules/profiles/functions.php
new file mode 100644
index 0000000000..2f33deea87
--- /dev/null
+++ b/modules/profiles/functions.php
@@ -0,0 +1,21 @@
+ $name,
+ 'sig' => $signature,
+ 'smtp_id' => $smtp_server_id,
+ 'replyto' => $reply_to,
+ 'default' => $is_default,
+ 'address' => $email,
+ 'server' => $server_mail,
+ 'user' => $email,
+ 'type' => 'imap'
+ );
+
+ Hm_Profiles::add($profile);
+ }
+}
\ No newline at end of file
diff --git a/modules/profiles/modules.php b/modules/profiles/modules.php
index c1fb2a52a9..35b1013c51 100644
--- a/modules/profiles/modules.php
+++ b/modules/profiles/modules.php
@@ -9,6 +9,7 @@
if (!defined('DEBUG_MODE')) { die(); }
require_once APP_PATH.'modules/profiles/hm-profiles.php';
+require APP_PATH.'modules/profiles/functions.php';
/**
* @subpackage profile/handler
@@ -262,9 +263,9 @@ protected function output() {
foreach ($profiles as $id => $profile) {
$smtp = '';
- if ($profile['smtp_id'] !== false && array_key_exists($profile['smtp_id'], $smtp_servers)) {
+ if (isset($profile['smtp_id']) && is_scalar($profile['smtp_id']) && array_key_exists($profile['smtp_id'], $smtp_servers)) {
$smtp = $smtp_servers[$profile['smtp_id']]['name'];
- }
+ }
$res .= '
'.
''.$this->html_safe($profile['name']).' '.
''.$this->html_safe($profile['server']).' '.
diff --git a/modules/sievefilters/functions.php b/modules/sievefilters/functions.php
new file mode 100644
index 0000000000..2b36b22dc7
--- /dev/null
+++ b/modules/sievefilters/functions.php
@@ -0,0 +1,447 @@
+
+
+
General
+ Input a name and order for your filter. In filters, the order of execution is important. You can define an order value (or priority value) for your filter. Filters will run from lowest to highest priority value.
+
+
+ Filter Name:
+
+
+
+ Priority:
+
+
+
+
Sieve Script
+ Paste the Sieve script in the field below. Manually added scripts cannot be edited with the filters interface.
+
+
+
+
+ ';
+ }
+}
+
+
+if (!hm_exists('get_classic_filter_modal_content')) {
+ function get_classic_filter_modal_content()
+ {
+ return '
+
+
General
+ Input a name and order for your filter. In filters, the order of execution is important. You can define an order value (or priority value) for your filter. Filters will run from lowest to highest priority value.
+
+
+ Filter Name:
+
+
+
+ Priority:
+
+
+
+ Test:
+
+ ANYOF (OR)
+ ALLOF (AND)
+
+
+
+
Conditions & Actions
+ Filters must have at least one action and one condition
+
+
+
+
+
+
Conditions
+
+
+ Add Condition
+
+
+
+
+
+
+
+
+
Actions
+
+
+ Add Action
+
+
+
+
+
+
';
+ }
+}
+
+if (!hm_exists('get_mailbox_filters')) {
+ function get_mailbox_filters($mailbox, $site_config, $user_config, $html=false)
+ {
+ $factory = get_sieve_client_factory($site_config);
+ try {
+ $client = $factory->init($user_config, $mailbox);
+ $scripts = [];
+ foreach ($client->listScripts() as $script) {
+ if (strstr($script, 'cypht')) {
+ $scripts[] = $script;
+ }
+ }
+ } catch (Exception $e) {
+ Hm_Msgs::add("ERRSieve: {$e->getMessage()}");
+ return !$html ? []: '';
+ }
+
+ if ($html == false) {
+ return $scripts;
+ }
+
+ $scripts_sorted = [];
+ foreach ($scripts as $script_name) {
+ $exp_name = explode('-', $script_name);
+ if (end($exp_name) == 'cypht') {
+ $base_class = 'script';
+ }
+ else if (end($exp_name) == 'cyphtfilter') {
+ $base_class = 'filter';
+ }
+ else {
+ continue;
+ }
+ $parsed_name = str_replace('_', ' ', $exp_name[0]);
+ $scripts_sorted[$script_name] = $exp_name[sizeof($exp_name) - 2];
+ }
+ asort($scripts_sorted);
+
+ $script_list = '';
+ foreach ($scripts_sorted as $script_name => $sc) {
+ $exp_name = explode('-', $script_name);
+ $parsed_name = str_replace('_', ' ', $exp_name[0]);
+ $script_list .= '
+
+ '. $exp_name[sizeof($exp_name) - 2] .'
+ ' . str_replace('_', ' ', implode('-', array_slice($exp_name, 0, count($exp_name) - 2))) . '
+
+
+
+
+
+
+
+
+
+ ';
+ }
+ return $script_list;
+ }
+}
+
+if (!hm_exists('generate_main_script')) {
+ function generate_main_script($script_list)
+ {
+ $sorted_list = [];
+ foreach ($script_list as $script_name) {
+ if ($script_name == 'main_script') {
+ continue;
+ }
+
+ if (strstr($script_name, 'cypht')) {
+ $ex_name = explode('-', $script_name);
+ $sorted_list[$script_name] = $ex_name[1];
+ }
+ }
+ asort($sorted_list);
+ $include_header = 'require ["include"];'."\n\n";
+ $include_body = '';
+
+ // Block List MUST be the first script executed
+ $include_body .= 'include :personal "blocked_senders";'."\n";
+
+ foreach ($sorted_list as $script_name => $include_script) {
+ $include_body .= 'include :personal "'.$script_name.'";'."\n";
+ }
+ return $include_header.$include_body;
+ }
+}
+
+if (!hm_exists('generate_script_name')) {
+ function generate_script_name($name, $priority)
+ {
+ return str_replace(' ', '_', strtolower($name)).'-'.$priority.'-cypht';
+ }
+}
+
+if (!hm_exists('generate_filter_name')) {
+ function generate_filter_name($name, $priority)
+ {
+ return str_replace(' ', '_', strtolower($name)).'-'.$priority.'-cyphtfilter';
+ }
+}
+
+if (!hm_exists('get_sieve_client_factory')) {
+ function get_sieve_client_factory($site_config)
+ {
+ if (!is_null($site_config) && isset($site_config) && $factory_class = $site_config->get('sieve_client_factory')) {
+ return new $factory_class;
+ } else {
+ return new Hm_Sieve_Client_Factory;
+ }
+ }
+}
+
+if (!hm_exists('get_domain')) {
+ function get_domain($email)
+ {
+ $domain = explode('@', $email)[1];
+ if (preg_match('/(?P
[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
+ return $regs['domain'];
+ }
+ return false;
+ }
+}
+
+if (!hm_exists('default_reject_message')) {
+ function default_reject_message($user_config, $imap_server_id)
+ {
+ $reject_message = '';
+ if ($user_config->get('sieve_block_default_reject_message')) {
+ if (array_key_exists($imap_server_id, $user_config->get('sieve_block_default_reject_message'))) {
+ $reject_message = $user_config->get('sieve_block_default_reject_message')[$imap_server_id];
+ }
+ }
+ return $reject_message;
+ }
+}
+
+if (!hm_exists('block_filter')) {
+ function block_filter($filter, $user_config, $action, $imap_server_id, $sender, $custom_reject_message = '')
+ {
+ $ret = ['action' => $action];
+
+ if (explode('@', $sender)[0] == '*') {
+ $filter->addRequirement('regex');
+ }
+ $custom_condition = new \PhpSieveManager\Filters\Condition(
+ "", 'anyof'
+ );
+ $cond = \PhpSieveManager\Filters\FilterCriteria::if('header');
+ $cond->contains('"From" ["'.$sender.'"]');
+
+ if ($action == 'default') {
+ $default_behaviour = 'Discard';
+ if ($user_config->get('sieve_block_default_behaviour')) {
+ if (array_key_exists($imap_server_id, $user_config->get('sieve_block_default_behaviour'))) {
+ $default_behaviour = $user_config->get('sieve_block_default_behaviour')[$imap_server_id];
+ if ($default_behaviour == 'Reject') {
+ $reject_message = default_reject_message($user_config, $imap_server_id);
+ }
+ }
+ }
+ } elseif ($action == 'discard') {
+ $default_behaviour = 'Discard';
+ } elseif ($action == 'reject_default') {
+ $default_behaviour = 'Reject';
+ $reject_message = default_reject_message($user_config, $imap_server_id);
+ $ret['reject_message'] = $reject_message;
+ } elseif ($action == 'reject_with_message') {
+ $default_behaviour = 'Reject';
+ $reject_message = $custom_reject_message;
+ $ret['reject_message'] = $custom_reject_message;
+ } elseif ($action == 'blocked') {
+ $default_behaviour = 'Move';
+ }
+
+ $custom_condition->addCriteria($cond);
+
+ if ($default_behaviour == 'Discard') {
+ $custom_condition->addAction(
+ new \PhpSieveManager\Filters\Actions\DiscardFilterAction()
+ );
+ }
+ elseif ($default_behaviour == 'Reject') {
+ $filter->addRequirement('reject');
+ $custom_condition->addAction(
+ new \PhpSieveManager\Filters\Actions\RejectFilterAction([$reject_message])
+ );
+ }
+ elseif ($default_behaviour == 'Move') {
+ $filter->addRequirement('fileinto');
+ $custom_condition->addAction(
+ new \PhpSieveManager\Filters\Actions\FileIntoFilterAction(['Blocked'])
+ );
+ }
+
+ $custom_condition->addAction(
+ new \PhpSieveManager\Filters\Actions\StopFilterAction()
+ );
+
+ $filter->setCondition($custom_condition);
+
+ return $ret;
+ }
+}
+
+if (!hm_exists('block_filter_dropdown')) {
+ function block_filter_dropdown($mod, $with_scope = true, $submit_id = 'block_sender', $submit_title = 'Block') {
+ $ret = '';
+ return $ret;
+ }
+}
+
+if (!hm_exists('get_blocked_senders_array')) {
+ function get_blocked_senders_array($mailbox, $site_config, $user_config)
+ {
+ $factory = get_sieve_client_factory($site_config);
+ try {
+ $client = $factory->init($user_config, $mailbox);
+ $scripts = $client->listScripts();
+
+ if (array_search('blocked_senders', $scripts, true) === false) {
+ return [];
+ }
+
+ $blocked_senders = [];
+ $current_script = $client->getScript('blocked_senders');
+ if ($current_script != '') {
+ $base64_obj = str_replace("# ", "", preg_split('#\r?\n#', $current_script, 0)[1]);
+ $blocked_list = json_decode(base64_decode($base64_obj));
+ if (!$blocked_list) {
+ return [];
+ }
+ foreach ($blocked_list as $blocked_sender) {
+ if (explode('@', $blocked_sender)[0] == '') {
+ $blocked_sender = '*' . $blocked_sender;
+ }
+ $blocked_senders[] = $blocked_sender;
+ }
+ }
+ return $blocked_senders;
+ } catch (Exception $e) {
+ Hm_Msgs::add("ERRSieve: {$e->getMessage()}");
+ return [];
+ }
+ }
+}
+
+if (!hm_exists('get_blocked_senders')){
+ function get_blocked_senders($mailbox, $mailbox_id, $icon_svg, $icon_block_domain_svg, $site_config, $user_config, $module) {
+ $factory = get_sieve_client_factory($site_config);
+ try {
+ $client = $factory->init($user_config, $mailbox);
+ $scripts = $client->listScripts();
+ if (array_search('blocked_senders', $scripts, true) === false) {
+ return '';
+ }
+ $current_script = $client->getScript('blocked_senders');
+ $blocked_list_actions = [];
+ if ($current_script != '') {
+ $script_split = preg_split('#\r?\n#', $current_script, 0);
+ if (!isset($script_split[1])) {
+ return '';
+ }
+ $base64_obj = str_replace("# ", "", $script_split[1]);
+ $blocked_list = json_decode(base64_decode($base64_obj));
+ if (!$blocked_list) {
+ return '';
+ }
+ if (isset($script_split[2])) {
+ $base64_obj_actions = str_replace("# ", "", $script_split[2]);
+ $blocked_list_actions = json_decode(base64_decode($base64_obj_actions), true);
+ }
+ foreach ($blocked_list as $blocked_sender) {
+ if (explode('@', $blocked_sender)[0] == '') {
+ $blocked_sender = '*'.$blocked_sender;
+ }
+ $blocked_senders[] = $blocked_sender;
+ }
+ }
+
+ $actions_map = [
+ 'blocked' => $module->trans('Move To Blocked'),
+ 'reject_with_message' => $module->trans('Reject With Message'),
+ 'reject_default' => $module->trans('Reject'),
+ 'discard' => $module->trans('Discard'),
+ 'default' => $module->trans('Default'),
+ ];
+ $ret = '';
+ foreach ($blocked_senders as $sender) {
+ $reject_message = $blocked_list_actions[$sender]['reject_message'];
+ $ret .= ''.$sender.' ';
+ if (is_array($blocked_list_actions) && array_key_exists($sender, $blocked_list_actions)) {
+ $action = $blocked_list_actions[$sender]['action'] ?: 'default';
+ $ret .= $actions_map[$action];
+ if ($action == 'reject_with_message') {
+ $ret .= ' - '.$reject_message;
+ }
+ } else {
+ $action = 'default';
+ $ret .= 'Default';
+ }
+ $ret .= ' ';
+ $ret .= ' ';
+ if (!strstr($sender, '*')) {
+ $ret .= ' ';
+ }
+ $ret .= ' ';
+ }
+ return $ret;
+ } catch (Exception $e) {
+ Hm_Msgs::add("ERRSieve: {$e->getMessage()}");
+ return '';
+ }
+ }
+}
+
+if (!hm_exists('initialize_sieve_client_factory')) {
+ function initialize_sieve_client_factory($site_config, $user_config, $imapServer)
+ {
+ $factory = get_sieve_client_factory($site_config);
+ return $factory->init($user_config, $imapServer);
+ }
+
+}
\ No newline at end of file
diff --git a/modules/sievefilters/hm-sieve.php b/modules/sievefilters/hm-sieve.php
new file mode 100644
index 0000000000..c2a0a71ea2
--- /dev/null
+++ b/modules/sievefilters/hm-sieve.php
@@ -0,0 +1,21 @@
+
+connect($imap_account['user'], $imap_account['pass'], $sieve_tls, "", "PLAIN");
+ return $client;
+ } else {
+ $errorMsg = 'Invalid config host';
+ if (isset($imap_account['name'])) {
+ $errorMsg .= ' for ' . $imap_account['name'];
+ }
+ throw new Exception($errorMsg);
+ }
+ }
+}
+
diff --git a/modules/sievefilters/modules.php b/modules/sievefilters/modules.php
index 097a414309..be18178774 100644
--- a/modules/sievefilters/modules.php
+++ b/modules/sievefilters/modules.php
@@ -12,6 +12,8 @@
require_once APP_PATH.'modules/imap/functions.php';
require_once APP_PATH.'modules/imap/hm-imap.php';
+require_once APP_PATH.'modules/sievefilters/hm-sieve.php';
+require_once APP_PATH.'modules/sievefilters/functions.php';
/**
* @subpackage sievefilters/handler
@@ -202,74 +204,6 @@ public function process() {
}
}
-function get_blocked_senders($mailbox, $mailbox_id, $icon_svg, $icon_block_domain_svg, $site_config, $user_config, $module) {
- $factory = get_sieve_client_factory($site_config);
- try {
- $client = $factory->init($user_config, $mailbox);
- $scripts = $client->listScripts();
- if (array_search('blocked_senders', $scripts, true) === false) {
- return '';
- }
- $current_script = $client->getScript('blocked_senders');
- $blocked_list_actions = [];
- if ($current_script != '') {
- $script_split = preg_split('#\r?\n#', $current_script, 0);
- if (!isset($script_split[1])) {
- return '';
- }
- $base64_obj = str_replace("# ", "", $script_split[1]);
- $blocked_list = json_decode(base64_decode($base64_obj));
- if (!$blocked_list) {
- return '';
- }
- if (isset($script_split[2])) {
- $base64_obj_actions = str_replace("# ", "", $script_split[2]);
- $blocked_list_actions = json_decode(base64_decode($base64_obj_actions), true);
- }
- foreach ($blocked_list as $blocked_sender) {
- if (explode('@', $blocked_sender)[0] == '') {
- $blocked_sender = '*'.$blocked_sender;
- }
- $blocked_senders[] = $blocked_sender;
- }
- }
-
- $actions_map = [
- 'blocked' => $module->trans('Move To Blocked'),
- 'reject_with_message' => $module->trans('Reject With Message'),
- 'reject_default' => $module->trans('Reject'),
- 'discard' => $module->trans('Discard'),
- 'default' => $module->trans('Default'),
- ];
- $ret = '';
- foreach ($blocked_senders as $sender) {
- $reject_message = $blocked_list_actions[$sender]['reject_message'];
- $ret .= ''.$sender.' ';
- if (is_array($blocked_list_actions) && array_key_exists($sender, $blocked_list_actions)) {
- $action = $blocked_list_actions[$sender]['action'] ?: 'default';
- $ret .= $actions_map[$action];
- if ($action == 'reject_with_message') {
- $ret .= ' - '.$reject_message;
- }
- } else {
- $action = 'default';
- $ret .= 'Default';
- }
- $ret .= ' ';
- $ret .= ' ';
- if (!strstr($sender, '*')) {
- $ret .= ' ';
- }
- $ret .= ' ';
- }
- return $ret;
- } catch (Exception $e) {
- Hm_Msgs::add("ERRSieve: {$e->getMessage()}");
- return '';
- }
-}
-
-
/**
* @subpackage sievefilters/handler
*/
@@ -1228,39 +1162,6 @@ protected function output() {
}
}
-function get_blocked_senders_array($mailbox, $site_config, $user_config) {
- $factory = get_sieve_client_factory($site_config);
- try {
- $client = $factory->init($user_config, $mailbox);
- $scripts = $client->listScripts();
-
- if (array_search('blocked_senders', $scripts, true) === false) {
- return [];
- }
-
- $blocked_senders = [];
- $current_script = $client->getScript('blocked_senders');
- if ($current_script != '') {
- $base64_obj = str_replace("# ", "", preg_split('#\r?\n#', $current_script, 0)[1]);
- $blocked_list = json_decode(base64_decode($base64_obj));
- if (!$blocked_list) {
- return [];
- }
- foreach ($blocked_list as $blocked_sender) {
- if (explode('@', $blocked_sender)[0] == '') {
- $blocked_sender = '*'.$blocked_sender;
- }
- $blocked_senders[] = $blocked_sender;
- }
- }
- return $blocked_senders;
- } catch (Exception $e) {
- Hm_Msgs::add("ERRSieve: {$e->getMessage()}");
- return [];
- }
-}
-
-
/**
* @subpackage sievefilters/handler
*/
@@ -1437,8 +1338,9 @@ public function process() {
$this->out('sieve_server_capabilities', self::$capabilities[$imap_account['sieve_config_host']]);
continue;
}
- $clientFactory = new Hm_Sieve_Client_Factory();
- $client = $clientFactory->init(null, $imap_account);
+
+ $client = initialize_sieve_client_factory(null, null, $imap_account);
+
if ($client) {
$this->out('sieve_server_capabilities', $client->getCapabilities());
self::$capabilities[$imap_account['sieve_config_host']] = $client->getCapabilities();
@@ -1447,351 +1349,4 @@ public function process() {
}
}
}
-}
-
-if (!hm_exists('get_script_modal_content')) {
- function get_script_modal_content()
- {
- return '
-
-
General
- Input a name and order for your filter. In filters, the order of execution is important. You can define an order value (or priority value) for your filter. Filters will run from lowest to highest priority value.
-
-
- Filter Name:
-
-
-
- Priority:
-
-
-
-
Sieve Script
- Paste the Sieve script in the field below. Manually added scripts cannot be edited with the filters interface.
-
-
-
-
-
';
- }
-}
-
-
-if (!hm_exists('get_classic_filter_modal_content')) {
- function get_classic_filter_modal_content()
- {
- return '
-
-
General
- Input a name and order for your filter. In filters, the order of execution is important. You can define an order value (or priority value) for your filter. Filters will run from lowest to highest priority value.
-
-
- Filter Name:
-
-
-
- Priority:
-
-
-
- Test:
-
- ANYOF (OR)
- ALLOF (AND)
-
-
-
-
Conditions & Actions
- Filters must have at least one action and one condition
-
-
-
-
-
-
Conditions
-
-
- Add Condition
-
-
-
-
-
-
-
-
-
Actions
-
-
- Add Action
-
-
-
-
-
-
';
- }
-}
-
-if (!hm_exists('get_mailbox_filters')) {
- function get_mailbox_filters($mailbox, $site_config, $user_config, $html=false)
- {
- $factory = get_sieve_client_factory($site_config);
- try {
- $client = $factory->init($user_config, $mailbox);
- $scripts = [];
- foreach ($client->listScripts() as $script) {
- if (strstr($script, 'cypht')) {
- $scripts[] = $script;
- }
- }
- } catch (Exception $e) {
- Hm_Msgs::add("ERRSieve: {$e->getMessage()}");
- return !$html ? []: '';
- }
-
- if ($html == false) {
- return $scripts;
- }
-
- $scripts_sorted = [];
- foreach ($scripts as $script_name) {
- $exp_name = explode('-', $script_name);
- if (end($exp_name) == 'cypht') {
- $base_class = 'script';
- }
- else if (end($exp_name) == 'cyphtfilter') {
- $base_class = 'filter';
- }
- else {
- continue;
- }
- $parsed_name = str_replace('_', ' ', $exp_name[0]);
- $scripts_sorted[$script_name] = $exp_name[sizeof($exp_name) - 2];
- }
- asort($scripts_sorted);
-
- $script_list = '';
- foreach ($scripts_sorted as $script_name => $sc) {
- $exp_name = explode('-', $script_name);
- $parsed_name = str_replace('_', ' ', $exp_name[0]);
- $script_list .= '
-
- '. $exp_name[sizeof($exp_name) - 2] .'
- ' . str_replace('_', ' ', implode('-', array_slice($exp_name, 0, count($exp_name) - 2))) . '
-
-
-
-
-
-
-
-
-
- ';
- }
- return $script_list;
- }
-}
-
-if (!hm_exists('generate_main_script')) {
- function generate_main_script($script_list)
- {
- $sorted_list = [];
- foreach ($script_list as $script_name) {
- if ($script_name == 'main_script') {
- continue;
- }
-
- if (strstr($script_name, 'cypht')) {
- $ex_name = explode('-', $script_name);
- $sorted_list[$script_name] = $ex_name[1];
- }
- }
- asort($sorted_list);
- $include_header = 'require ["include"];'."\n\n";
- $include_body = '';
-
- // Block List MUST be the first script executed
- $include_body .= 'include :personal "blocked_senders";'."\n";
-
- foreach ($sorted_list as $script_name => $include_script) {
- $include_body .= 'include :personal "'.$script_name.'";'."\n";
- }
- return $include_header.$include_body;
- }
-}
-
-if (!hm_exists('generate_script_name')) {
- function generate_script_name($name, $priority)
- {
- return str_replace(' ', '_', strtolower($name)).'-'.$priority.'-cypht';
- }
-}
-
-if (!hm_exists('generate_filter_name')) {
- function generate_filter_name($name, $priority)
- {
- return str_replace(' ', '_', strtolower($name)).'-'.$priority.'-cyphtfilter';
- }
-}
-
-if (!hm_exists('get_sieve_client_factory')) {
- function get_sieve_client_factory($site_config)
- {
- if ($factory_class = $site_config->get('sieve_client_factory')) {
- return new $factory_class;
- } else {
- return new Hm_Sieve_Client_Factory;
- }
- }
-}
-
-if (!hm_exists('get_domain')) {
- function get_domain($email)
- {
- $domain = explode('@', $email)[1];
- if (preg_match('/(?P[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
- return $regs['domain'];
- }
- return false;
- }
-}
-
-if (!hm_exists('default_reject_message')) {
- function default_reject_message($user_config, $imap_server_id)
- {
- $reject_message = '';
- if ($user_config->get('sieve_block_default_reject_message')) {
- if (array_key_exists($imap_server_id, $user_config->get('sieve_block_default_reject_message'))) {
- $reject_message = $user_config->get('sieve_block_default_reject_message')[$imap_server_id];
- }
- }
- return $reject_message;
- }
-}
-
-if (!hm_exists('block_filter')) {
- function block_filter($filter, $user_config, $action, $imap_server_id, $sender, $custom_reject_message = '')
- {
- $ret = ['action' => $action];
-
- if (explode('@', $sender)[0] == '*') {
- $filter->addRequirement('regex');
- }
- $custom_condition = new \PhpSieveManager\Filters\Condition(
- "", 'anyof'
- );
- $cond = \PhpSieveManager\Filters\FilterCriteria::if('header');
- $cond->contains('"From" ["'.$sender.'"]');
-
- if ($action == 'default') {
- $default_behaviour = 'Discard';
- if ($user_config->get('sieve_block_default_behaviour')) {
- if (array_key_exists($imap_server_id, $user_config->get('sieve_block_default_behaviour'))) {
- $default_behaviour = $user_config->get('sieve_block_default_behaviour')[$imap_server_id];
- if ($default_behaviour == 'Reject') {
- $reject_message = default_reject_message($user_config, $imap_server_id);
- }
- }
- }
- } elseif ($action == 'discard') {
- $default_behaviour = 'Discard';
- } elseif ($action == 'reject_default') {
- $default_behaviour = 'Reject';
- $reject_message = default_reject_message($user_config, $imap_server_id);
- $ret['reject_message'] = $reject_message;
- } elseif ($action == 'reject_with_message') {
- $default_behaviour = 'Reject';
- $reject_message = $custom_reject_message;
- $ret['reject_message'] = $custom_reject_message;
- } elseif ($action == 'blocked') {
- $default_behaviour = 'Move';
- }
-
- $custom_condition->addCriteria($cond);
-
- if ($default_behaviour == 'Discard') {
- $custom_condition->addAction(
- new \PhpSieveManager\Filters\Actions\DiscardFilterAction()
- );
- }
- elseif ($default_behaviour == 'Reject') {
- $filter->addRequirement('reject');
- $custom_condition->addAction(
- new \PhpSieveManager\Filters\Actions\RejectFilterAction([$reject_message])
- );
- }
- elseif ($default_behaviour == 'Move') {
- $filter->addRequirement('fileinto');
- $custom_condition->addAction(
- new \PhpSieveManager\Filters\Actions\FileIntoFilterAction(['Blocked'])
- );
- }
-
- $custom_condition->addAction(
- new \PhpSieveManager\Filters\Actions\StopFilterAction()
- );
-
- $filter->setCondition($custom_condition);
-
- return $ret;
- }
-}
-
-if (!hm_exists('block_filter_dropdown')) {
- function block_filter_dropdown($mod, $with_scope = true, $submit_id = 'block_sender', $submit_title = 'Block') {
- $ret = '';
- return $ret;
- }
-}
-
-class Hm_Sieve_Client_Factory {
- public function init($user_config = null, $imap_account = null)
- {
- if ($imap_account && ! empty($imap_account['sieve_config_host'])) {
- list($sieve_host, $sieve_port, $sieve_tls) = parse_sieve_config_host($imap_account['sieve_config_host']);
- $client = new PhpSieveManager\ManageSieve\Client($sieve_host, $sieve_port);
- $client->connect($imap_account['user'], $imap_account['pass'], $sieve_tls, "", "PLAIN");
- return $client;
- } else {
- $errorMsg = 'Invalid config host';
- if (isset($imap_account['name'])) {
- $errorMsg .= ' for ' . $imap_account['name'];
- }
- throw new Exception($errorMsg);
- }
- }
}
\ No newline at end of file
diff --git a/modules/smtp/functions.php b/modules/smtp/functions.php
new file mode 100644
index 0000000000..f9e9852119
--- /dev/null
+++ b/modules/smtp/functions.php
@@ -0,0 +1,30 @@
+ $name,
+ 'server' => $address,
+ 'hide' => false,
+ 'port' => $port,
+ 'user' => $user,
+ 'pass' => $pass,
+ 'tls' => $tls);
+
+ $smtp_server_id = Hm_SMTP_List::add($smtp_list);
+ $server = Hm_SMTP_List::get($smtp_server_id, false);
+
+ $result = Hm_SMTP_List::service_connect($smtp_server_id, $server, $user, $pass, false);
+
+ return $result;
+ }
+}
+
+if (!hm_exists('delete_smtp_server')) {
+ function delete_smtp_server($smtp_server_id) {
+ Hm_SMTP_List::del($smtp_server_id);
+ }
+}
\ No newline at end of file
diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php
index b15f9327d6..14432a235a 100644
--- a/modules/smtp/modules.php
+++ b/modules/smtp/modules.php
@@ -11,6 +11,7 @@
use League\CommonMark\GithubFlavoredMarkdownConverter;
define('MAX_RECIPIENT_WARNING', 20);
+require_once APP_PATH.'modules/smtp/functions.php';
require APP_PATH.'modules/smtp/hm-smtp.php';
require APP_PATH.'modules/smtp/hm-mime-message.php';
@@ -59,9 +60,9 @@ public function process() {
if (!array_key_exists('From', $msg_header) || count($msg_header) == 0) {
return;
}
-
+
# Attachment Download
- # Draft attachments must be redownloaded and added to the file cache to prevent
+ # Draft attachments must be redownloaded and added to the file cache to prevent
# attachments from being deleted when editing a previously saved draft.
$attached_files = [];
$this->session->set('uploaded_files', array());
@@ -118,7 +119,7 @@ public function process() {
if (!$this->module_is_supported('imap')) {
return;
}
-
+
if (array_key_exists('forward', $this->request->get)) {
$path = explode('_', $this->request->get['list_path']);
$imap = Hm_IMAP_List::connect($path[1]);
@@ -228,26 +229,26 @@ public function process() {
Hm_Msgs::add('ERRerror '.$file['error'].' in file '.$this->request->get['resumableFilename']);
continue;
}
-
+
if(isset($this->request->get['resumableIdentifier']) && trim($this->request->get['resumableIdentifier'])!=''){
$temp_dir = $filepath.'/'.$userpath.'/chunks-'.$this->request->get['resumableIdentifier'];
}
$dest_file = $temp_dir.'/'.$this->request->get['resumableFilename'].'.part'.$this->request->get['resumableChunkNumber'];
-
+
// create the temporary directory
if (!is_dir($temp_dir)) {
mkdir($temp_dir, 0777, true);
}
-
+
// move the temporary file
if (!move_uploaded_file($file['tmp_name'], $dest_file)) {
Hm_Msgs::add('ERRError saving (move_uploaded_file) chunk '.$this->request->get['resumableChunkNumber'].' for file '.$this->request->get['resumableFilename']);
} else {
// check if all the parts present, and create the final destination file
$result = createFileFromChunks($temp_dir, $this->request->get['resumableFilename'],
- $this->request->get['resumableChunkSize'],
+ $this->request->get['resumableChunkSize'],
$this->request->get['resumableTotalSize'],
- $this->request->get['resumableTotalChunks']);
+ $this->request->get['resumableTotalChunks']);
}
}
}
@@ -273,7 +274,7 @@ public function process() {
delete_uploaded_files($this->session, $draft_id);
return;
}
-
+
if ($this->module_is_supported('imap')) {
$uploaded_files = explode(',', $uploaded_files);
$userpath = md5($this->session->get('username', false));
@@ -347,7 +348,7 @@ public function process() {
if ($draft_id <= 0 && array_key_exists('uid', $this->request->get)) {
$draft_id = $this->request->get['uid'];
}
-
+
$this->out('uploaded_files', get_uploaded_files($draft_id, $this->session));
$compose_type = $this->user_config->get('smtp_compose_type_setting', 0);
if ($this->get('is_mobile', false)) {
@@ -388,6 +389,7 @@ public function process() {
'server' => $form['new_smtp_address'],
'port' => $form['new_smtp_port'],
'tls' => $tls));
+
Hm_Msgs::add('Added SMTP server!');
$this->session->record_unsaved('SMTP server added');
}
@@ -539,11 +541,11 @@ class Hm_Handler_profile_status extends Hm_Handler_Module {
public function process() {
$profiles = $this->user_config->get('profiles');
$profile_value = $this->request->post['profile_value'];
-
+
if (!strstr($profile_value, '.')) {
Hm_Msgs::add('ERRPlease create a profile for saving sent messages');
return;
- }
+ }
$profile = profile_from_compose_smtp_id($profiles, $profile_value);
if (!$profile) {
Hm_Msgs::add('ERRPlease create a profile for saving sent messages');
@@ -635,7 +637,7 @@ function get_mime_type($filename)
* @subpackage smtp/handler
*/
class Hm_Handler_process_compose_form_submit extends Hm_Handler_Module {
- public function process() {
+ public function process() {
/* not sending */
if (!array_key_exists('smtp_send', $this->request->post)) {
$this->out('enable_attachment_reminder', $this->user_config->get('enable_attachment_reminder_setting', false));
@@ -759,7 +761,7 @@ public function process() {
if ($form['post_archive']) {
$msg_path = explode('_', $this->request->post['compose_msg_path']);
$msg_uid = $this->request->post['compose_msg_uid'];
-
+
$imap = Hm_IMAP_List::connect($msg_path[1]);
if ($imap->select_mailbox(hex2bin($msg_path[2]))) {
$specials = get_special_folders($this, $msg_path[1]);
@@ -863,19 +865,19 @@ protected function output() {
$size_in_kbs = 0;
$num_chunks = 0;
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->get('attachment_dir')));
- $files = array();
-
+ $files = array();
+
foreach ($rii as $file) {
if ($file->getFilename() == '.' || $file->getFilename() == '..') {
continue;
}
- if ($file->isDir()){
+ if ($file->isDir()){
continue;
}
if (strpos($file->getPathname(), '.part') !== False) {
$num_chunks++;
$size_in_kbs += filesize($file->getPathname());
- $files[] = $file->getPathname();
+ $files[] = $file->getPathname();
}
}
if ($size_in_kbs > 0) {
@@ -998,7 +1000,7 @@ protected function output() {
$msg_path = $this->get('list_path', '');
$msg_uid = $this->get('uid', '');
$from = $this->get('compose_from');
-
+
if (!$msg_path) {
$msg_path = $this->get('compose_msg_path', '');
}
@@ -1063,13 +1065,13 @@ protected function output() {
}
$draft_id = $msg_uid;
}
-
+
// User clicked on compose
if ($reply_type) {
$imap_server_id = explode('_', $msg_path)[1];
$imap_server = Hm_IMAP_List::get($imap_server_id, false);
$reply_from = process_address_fld($reply['msg_headers']['From']);
-
+
if ($reply_type == 'reply_all' && $reply_from[0]['email'] != $imap_server['user'] && strpos($to, $reply_from[0]['email']) === false) {
$to .= ', '.$reply_from[0]['label'].' '.$reply_from[0]['email'];
}
@@ -1350,8 +1352,15 @@ protected function output() {
if ($this->get('single_server_mode')) {
return '';
}
- $res = '';
- foreach ($this->get('smtp_servers', array()) as $index => $vals) {
+
+ $list = $this->get('smtp_servers', array());
+
+ if (empty($list)) {
+ return '';
+ }
+
+ $res = 'SMTP Servers
';
+ foreach ($list as $index => $vals) {
$no_edit = false;
@@ -1373,24 +1382,34 @@ protected function output() {
$disabled = '';
$pass_value = '';
}
- $res .= ' ';
return $res;
}
}
@@ -1431,6 +1455,48 @@ protected function output() {
}
}
+/**
+ * @subpackage
+ */
+class Hm_Output_stepper_setup_server_smtp extends Hm_Output_Module {
+ protected function output() {
+ return '
+
+ ';
+ }
+}
+
/**
* @subpackage smtp/functions
*/
@@ -1584,7 +1650,7 @@ function save_uploaded_file($id, $atts, $session) {
function format_attachment_row($file, $output_mod) {
$unique_identifier = str_replace(' ', '_', $output_mod->html_safe($file['name']));
return '
'.
'= $totalSize) {
- // create the final destination file
+ // create the final destination file
if (($fp = fopen($temp_dir.'/../'.$fileName, 'w')) !== false) {
for ($i=1; $i<=$total_files; $i++) {
fwrite($fp, file_get_contents($temp_dir.'/'.$fileName.'.part'.$i));
@@ -1730,7 +1796,7 @@ function createFileFromChunks($temp_dir, $fileName, $chunkSize, $totalSize,$tota
return false;
}
- // rename the temporary directory (to avoid access from other
+ // rename the temporary directory (to avoid access from other
// concurrent chunks uploads) and than delete it
if (rename($temp_dir, $temp_dir.'_UNUSED')) {
rrmdir($temp_dir.'_UNUSED');
@@ -1800,7 +1866,7 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache, $uploaded_files
$cache = Hm_IMAP_List::get_cache($mod_cache, $imap_profile['id']);
$imap = Hm_IMAP_List::connect($imap_profile['id'], $cache);
$draft_folder = $imap->select_mailbox($specials['draft']);
-
+
$mime = new Hm_MIME_Msg(
$atts['draft_to'],
$atts['draft_subject'],
@@ -1813,14 +1879,14 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache, $uploaded_files
$name,
$atts['draft_in_reply_to']
);
-
+
$mime->add_attachments($uploaded_files);
$res = $mime->process_attachments();
-
+
$msg = str_replace("\r\n", "\n", $mime->get_mime_msg());
$msg = str_replace("\n", "\r\n", $msg);
$msg = rtrim($msg)."\r\n";
-
+
if ($imap->append_start($specials['draft'], strlen($msg), false, true)) {
$imap->append_feed($msg."\r\n");
if (!$imap->append_end()) {
diff --git a/modules/smtp/setup.php b/modules/smtp/setup.php
index e28d90c743..df0086c50b 100644
--- a/modules/smtp/setup.php
+++ b/modules/smtp/setup.php
@@ -29,8 +29,8 @@
add_handler('servers', 'process_add_smtp_server', true, 'smtp', 'load_smtp_servers_from_config', 'after');
add_handler('servers', 'add_smtp_servers_to_page_data', true, 'smtp', 'process_add_smtp_server', 'after');
add_handler('servers', 'save_smtp_servers', true, 'smtp', 'add_smtp_servers_to_page_data', 'after');
-add_output('servers', 'add_smtp_server_dialog', true, 'smtp', 'server_content_start', 'after');
-add_output('servers', 'display_configured_smtp_servers', true, 'smtp', 'add_smtp_server_dialog', 'after');
+add_output('servers', 'stepper_setup_server_smtp', true, 'smtp', 'server_config_stepper', 'after');
+add_output('servers', 'display_configured_smtp_servers', true, 'smtp', 'server_config_stepper_accordion_end_part', 'before');
add_handler('settings', 'process_compose_type', true, 'smtp', 'save_user_settings', 'before');
add_handler('settings', 'process_auto_bcc', true, 'smtp', 'save_user_settings', 'before');