From 308eced49dc03667234b695b8767082f4ca83093 Mon Sep 17 00:00:00 2001 From: Victor Emanouilov Date: Tue, 30 Jan 2024 11:52:38 +0200 Subject: [PATCH 01/12] fix double require of hm-profiles.php file in profiles and nux modules --- modules/profiles/modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/profiles/modules.php b/modules/profiles/modules.php index 119c25b7b0..6a14188c9e 100644 --- a/modules/profiles/modules.php +++ b/modules/profiles/modules.php @@ -8,7 +8,7 @@ if (!defined('DEBUG_MODE')) { die(); } -require APP_PATH.'modules/profiles/hm-profiles.php'; +require_once APP_PATH.'modules/profiles/hm-profiles.php'; /** * @subpackage profile/handler From 4f7dd1ca9a9cdee86b31a40eaedaf26cacc58c5f Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 23 Sep 2022 02:26:47 -0300 Subject: [PATCH 02/12] SMTP servers unique ids This update implements the 'id' field in SMTP Server objects and uses uniqid to generate unique ids for each server. --- lib/servers.php | 8 ++++- modules/profiles/modules.php | 6 +++- modules/smtp/hm-smtp.php | 8 +++-- modules/smtp/modules.php | 62 ++++++++++++++++++++++++++++-------- 4 files changed, 65 insertions(+), 19 deletions(-) diff --git a/lib/servers.php b/lib/servers.php index 1257e3e663..a69b8fea2d 100644 --- a/lib/servers.php +++ b/lib/servers.php @@ -23,7 +23,12 @@ public static function connect($id, $cache=false, $user=false, $pass=false, $sav if (!array_key_exists($id, self::$server_list)) { return false; } - $server = self::$server_list[$id]; + foreach (self::$server_list as $server_l) { + if ($server['id'] == $id) { + $server = $server_l; + } + } + if ($server['object']) { return $server['object']; } @@ -31,6 +36,7 @@ public static function connect($id, $cache=false, $user=false, $pass=false, $sav if ($user === false || $pass === false) { return false; } + if (self::service_connect($id, $server, $user, $pass, $cache)) { return self::enable_server($id, $user, $pass, $save_credentials); } diff --git a/modules/profiles/modules.php b/modules/profiles/modules.php index 6a14188c9e..378363b3e0 100644 --- a/modules/profiles/modules.php +++ b/modules/profiles/modules.php @@ -346,7 +346,11 @@ function profile_form($form_vals, $id, $smtp_servers, $imap_servers, $out_mod) { $res .= '
'; $res .= ''; $res .= '
'; diff --git a/modules/smtp/hm-smtp.php b/modules/smtp/hm-smtp.php index a2b003ce9f..806655c271 100644 --- a/modules/smtp/hm-smtp.php +++ b/modules/smtp/hm-smtp.php @@ -16,6 +16,7 @@ class Hm_SMTP_List { public static function service_connect($id, $server, $user, $pass, $cache=false) { $config = array( + 'id' => $id, 'server' => $server['server'], 'port' => $server['port'], 'tls' => $server['tls'], @@ -28,9 +29,10 @@ public static function service_connect($id, $server, $user, $pass, $cache=false) if (array_key_exists('no_auth', $server)) { $config['no_auth'] = true; } - self::$server_list[$id]['object'] = new Hm_SMTP($config); - if (!self::$server_list[$id]['object']->connect()) { - return self::$server_list[$id]['object']; + self::$server_list[]['object'] = new Hm_SMTP($config); + + if (!end(self::$server_list)['object']->connect()) { + return end(self::$server_list)['object']; } return false; } diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index 9393e4de45..eb466033a6 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -389,6 +389,7 @@ public function process() { } if ($con = @fsockopen($form['new_smtp_address'], $form['new_smtp_port'], $errno, $errstr, 2)) { Hm_SMTP_List::add( array( + 'id' => uniqid(), 'name' => $form['new_smtp_name'], 'server' => $form['new_smtp_address'], 'port' => $form['new_smtp_port'], @@ -413,8 +414,24 @@ public function process() { * @subpackage smtp/handler */ class Hm_Handler_add_smtp_servers_to_page_data extends Hm_Handler_Module { + + private function generateId($servers) { + $changed = false; + foreach ($servers as $index => $server) { + if (!array_key_exists('id', $server)) { + $servers[$index]['id'] = uniqid(); + $changed = true; + } + } + if ($changed) { + $this->session->record_unsaved('SMTP server ID updated'); + } + return $servers; + } + public function process() { $servers = Hm_SMTP_List::dump(); + $servers = $this->generateId($servers); $this->out('smtp_servers', $servers); $this->out('compose_drafts', $this->session->get('compose_drafts', array())); } @@ -424,8 +441,24 @@ public function process() { * @subpackage smtp/handler */ class Hm_Handler_save_smtp_servers extends Hm_Handler_Module { + + private function generateId($servers) { + $changed = false; + foreach ($servers as $index => $server) { + if (!array_key_exists('id', $server)) { + $servers[$index]['id'] = uniqid(); + $changed = true; + } + } + if ($changed) { + $this->session->record_unsaved('SMTP server ID updated'); + } + return $servers; + } + public function process() { $servers = Hm_SMTP_List::dump(false, true); + $servers = $this->generateId($servers); $this->user_config->set('smtp_servers', $servers); } } @@ -446,6 +479,7 @@ public function process() { Hm_Msgs::add('ERRThis server and username are already configured'); return; } + $form['smtp_server_id'] = uniqid(); $smtp = Hm_SMTP_List::connect($form['smtp_server_id'], false, $form['smtp_user'], $form['smtp_pass'], true); if (smtp_authed($smtp)) { $just_saved_credentials = true; @@ -1452,36 +1486,36 @@ function smtp_server_dropdown($data, $output_mod, $recip, $selected_id=false) { $selected = false; $default = false; foreach ($data['smtp_servers'] as $id => $vals) { - foreach (profiles_by_smtp_id($profiles, $id) as $index => $profile) { + foreach (profiles_by_smtp_id($profiles, $vals['id']) as $index => $profile) { if ($profile['default']) { - $default = $id.'.'.($index + 1); + $default = $vals['id'].'.'.($index + 1); } - if ((string) $selected_id === sprintf('%s.%s', $id, ($index + 1))) { - $selected = $id.'.'.($index + 1); + if ((string) $selected_id === sprintf('%s.%s', $vals['id'], ($index + 1))) { + $selected = $vals['id'].'.'.($index + 1); } elseif ($recip && trim($recip) == $profile['address']) { - $selected = $id.'.'.($index + 1); + $selected = $vals['id'].'.'.($index + 1); } } - if (!$selected && $selected_id !== false && $id == $selected_id) { - $selected = $id; + if (!$selected && $selected_id !== false && $vals['id'] == $selected_id) { + $selected = $vals['id']; } if (!$selected && $recip && trim($recip) == trim($vals['user'])) { - $selected = $id; + $selected = $vals['id']; } } if ($selected === false && $default !== false) { $selected = $default; } foreach ($data['smtp_servers'] as $id => $vals) { - $smtp_profiles = profiles_by_smtp_id($profiles, $id); + $smtp_profiles = profiles_by_smtp_id($profiles, $vals['id']); if (count($smtp_profiles) > 0) { foreach ($smtp_profiles as $index => $profile) { $res .= ''; } @@ -1491,7 +1525,7 @@ function smtp_server_dropdown($data, $output_mod, $recip, $selected_id=false) { if ($selected === $id) { $res .= 'selected="selected" '; } - $res .= 'value="'.$output_mod->html_safe($id).'">'; + $res .= 'value="'.$output_mod->html_safe($vals['id']).'">'; $res .= $output_mod->html_safe(sprintf("%s - %s", $vals['user'], $vals['name'])); $res .= ''; } @@ -1620,7 +1654,7 @@ function get_primary_recipient($profiles, $headers, $smtp_servers, $is_draft=Fal $addresses = array_unique($addresses); foreach ($addresses as $address) { foreach ($smtp_servers as $id => $vals) { - foreach (profiles_by_smtp_id($profiles, $id) as $profile) { + foreach (profiles_by_smtp_id($profiles, $vals['id']) as $profile) { if ($profile['address'] == $address) { return $address; } @@ -2083,7 +2117,7 @@ function default_smtp_server($user_config, $session, $request, $config, $user, $ $smtp_tls = $config->get('default_smtp_tls', true); $servers = $user_config->get('smtp_servers', array()); foreach ($servers as $index => $server) { - Hm_SMTP_List::add($server, $index); + Hm_SMTP_List::add($server, $server['id']); } $attributes = array( 'name' => $config->get('default_smtp_name', 'Default'), From caea86cb2167270ba04514deb9aa7c828928affe Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 30 Sep 2022 16:33:04 -0300 Subject: [PATCH 03/12] All other id entities (JMAP, Feeds, Profiles...) --- lib/servers.php | 23 +- modules/feeds/modules.php | 5 +- modules/imap/handler_modules.php | 1 + modules/imap/output_modules.php | 34 +- modules/pop3/modules.php | 1130 ++++++++++++++++++++++++++++++ modules/profiles/modules.php | 3 +- 6 files changed, 1164 insertions(+), 32 deletions(-) create mode 100644 modules/pop3/modules.php diff --git a/lib/servers.php b/lib/servers.php index a69b8fea2d..c16b0513c3 100644 --- a/lib/servers.php +++ b/lib/servers.php @@ -186,15 +186,10 @@ trait Hm_Server_List { * @param int $id server id * @return void */ - public static function add($atts, $id=false) { + public static function add($atts) { $atts['object'] = false; $atts['connected'] = false; - if ($id !== false) { - self::$server_list[$id] = $atts; - } - else { - self::$server_list[] = $atts; - } + self::$server_list[] = $atts; } /** @@ -203,9 +198,11 @@ public static function add($atts, $id=false) { * @return bool true on success */ public static function del($id) { - if (array_key_exists($id, self::$server_list)) { - unset(self::$server_list[$id]); - return true; + foreach (self::$server_list as $idx => $srv) { + if ($srv['id'] == $id) { + unset(self::$server_list[$idx]); + return true; + } } return false; } @@ -236,8 +233,10 @@ public static function dump($id=false, $full=false) { * @return array */ public static function get($id, $full) { - if (array_key_exists($id, self::$server_list)) { - $server = self::$server_list[$id]; + foreach (self::$server_list as $srv) { + if ($srv['id'] == $id) { + $server = $srv; + } if (!$full) { return self::clean($server); } diff --git a/modules/feeds/modules.php b/modules/feeds/modules.php index 9aa24fa642..8521447994 100644 --- a/modules/feeds/modules.php +++ b/modules/feeds/modules.php @@ -398,6 +398,7 @@ public function process() { if ($found) { $this->out('reload_folders', true); Hm_Feed_List::add(array( + 'id' => uniqid(), 'name' => $form['new_feed_name'], 'server' => $href, 'tls' => false, @@ -449,7 +450,7 @@ public function process() { class Hm_Handler_load_feeds_for_search extends Hm_Handler_Module { public function process() { foreach (Hm_Feed_List::dump() as $index => $vals) { - $this->append('data_sources', array('callback' => 'feeds_search_page_content', 'type' => 'feeds', 'name' => $vals['name'], 'id' => $index)); + $this->append('data_sources', array('callback' => 'feeds_search_page_content', 'type' => 'feeds', 'name' => $vals['name'], 'id' => $vals['id'])); } } @@ -492,7 +493,7 @@ public function process() { if ($server_id !== false && $index != $server_id) { continue; } - $this->append('data_sources', array('callback' => $callback, 'type' => 'feeds', 'name' => $vals['name'], 'id' => $index)); + $this->append('data_sources', array('callback' => $callback, 'type' => 'feeds', 'name' => $vals['name'], 'id' => $vals['id'])); } } } diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index 522b940e0c..0b2e88cf91 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -1309,6 +1309,7 @@ public function process() { if (array_key_exists('host', $parsed) && @get_headers($form['new_jmap_address'])) { Hm_IMAP_List::add(array( + 'id' => uniqid(), 'name' => $form['new_jmap_name'], 'server' => $form['new_jmap_address'], 'hide' => $hidden, diff --git a/modules/imap/output_modules.php b/modules/imap/output_modules.php index 5e2a5de567..003c035636 100644 --- a/modules/imap/output_modules.php +++ b/modules/imap/output_modules.php @@ -424,7 +424,7 @@ protected function output() { } $res = ''; foreach ($this->get('imap_servers', array()) as $index => $vals) { - + $server_id = $vals['id']; if (array_key_exists('type', $vals) && $vals['type'] == 'jmap') { continue; } @@ -459,24 +459,24 @@ protected function output() { $res .= '
'; $res .= ''; - $res .= ''; + $res .= ''; // IMAP Username $res .= '
'; - $res .= ''; - $res .= '
'; + $res .= ''; + $res .= ''; // IMAP Password $res .= '
'; - $res .= ''; - $res .= '
'; + $res .= ''; + $res .= ''; // Sieve Host (Conditional) if ($this->get('sieve_filters_enabled') && isset($vals['sieve_config_host'])) { $default_value = $vals['sieve_config_host']; $res .= '
'; - $res .= ''; - $res .= '
'; + $res .= ''; + $res .= ''; } // Buttons @@ -654,7 +654,7 @@ protected function output() { } $res = ''; foreach ($this->get('imap_servers', array()) as $index => $vals) { - + $server_id = $vals['id']; if (!array_key_exists('type', $vals) || $vals['type'] != 'jmap') { continue; } @@ -683,21 +683,21 @@ protected function output() { } $res .= '
'; $res .= sprintf('
%s
%s
', - $this->html_safe($vals['name']), $this->html_safe($vals['server'])); + $this->html_safe($vals['name']), $this->html_safe($vals['server'])); $res .= ''; $res .= ''; - $res .= ''; + $res .= ''; // JMAP Username $res .= '
'; - $res .= ''; - $res .= '
'; + $res .= ''; + $res .= '
'; // JMAP Password $res .= '
'; - $res .= ''; - $res .= '
'; + $res .= ''; + $res .= '
'; // Buttons if (!isset($vals['user']) || !$vals['user']) { @@ -735,8 +735,8 @@ class Hm_Output_display_imap_status extends Hm_Output_Module { protected function output() { $res = ''; foreach ($this->get('imap_servers', array()) as $index => $vals) { - $res .= 'IMAP'.$vals['name'].''. - ''; + $res .= 'IMAP'.$vals['name'].''. + ''; } return $res; } diff --git a/modules/pop3/modules.php b/modules/pop3/modules.php new file mode 100644 index 0000000000..27c80f0ef7 --- /dev/null +++ b/modules/pop3/modules.php @@ -0,0 +1,1130 @@ +request->get)) { + $path = $this->request->get['list_path']; + if (preg_match("/^pop3_(\d+)$/", $path, $matches)) { + $this->out('list_path', $path, false); + $details = Hm_POP3_List::dump($matches[1]); + $title = array('POP3', $details['name'], 'INBOX'); + if ($this->get('list_page', 0)) { + $title[] = sprintf('Page %d', $this->get('list_page', 0)); + } + if (!empty($details)) { + $this->out('list_meta', false); + $this->out('mailbox_list_title', $title); + $this->out('custom_list_controls', ' '); + } + } + } + if (array_key_exists('page', $this->request->get) && $this->request->get['page'] == 'search') { + $this->out('list_path', 'search', false); + } + } +} + +/** + * Check the status of a POP3 connection + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_status extends Hm_Handler_Module { + /** + * Used in an ajax request on the home page to determine a POP3 server status + */ + public function process() { + list($success, $form) = $this->process_form(array('pop3_server_ids')); + if ($success) { + $ids = explode(',', $form['pop3_server_ids']); + foreach ($ids as $id) { + $start_time = microtime(true); + $pop3 = Hm_POP3_List::connect($id, false); + if (pop3_authed($pop3)) { + $this->out('pop3_connect_time', microtime(true) - $start_time); + $this->out('pop3_connect_status', 'Authenticated'); + $this->out('pop3_status_server_id', $id); + } + } + } + } +} + +/** + * Perform a message action on a POP3 message + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_message_action extends Hm_Handler_Module { + /** + * read or unread a POP3 message + * @todo add support for more message actions + */ + public function process() { + list($success, $form) = $this->process_form(array('action_type', 'message_ids')); + if ($success) { + $id_list = explode(',', $form['message_ids']); + $server_ids = array(); + foreach ($id_list as $msg_id) { + if (preg_match("/^pop3_(\d)+_(\d)+$/", $msg_id)) { + $parts = explode('_', $msg_id); + $server_ids[] = $parts[1]; + switch($form['action_type']) { + case 'unread': + Hm_POP3_Uid_Cache::unread($msg_id); + break; + case 'read': + Hm_POP3_Uid_Cache::read($msg_id); + break; + } + } + } + if (count($server_ids) > 0) { + foreach ($server_ids as $id) { + bust_pop3_cache($this->cache, $id); + } + } + } + } +} + +/** + * Build the data for a POP3 folder page + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_folder_page extends Hm_Handler_Module { + /** + * Connect to a POP3 server and fetch message headers + * @todo see if this can be broken up into smaller functions + */ + public function process() { + + $msgs = array(); + list($success, $form) = $this->process_form(array('pop3_server_id')); + if ($success) { + $unread_only = false; + $login_time = $this->session->get('login_time', false); + if ($login_time) { + $this->out('login_time', $login_time); + } + $page = 1; + $terms = false; + if (array_key_exists('list_page', $this->request->get)) { + $page = $this->request->get['list_page']; + } + if (array_key_exists('pop3_search', $this->request->post)) { + $limit = DEFAULT_PER_SOURCE; + $terms = $this->session->get('search_terms', false); + if (!$terms) { + return; + } + $since = $this->session->get('search_since', DEFAULT_SINCE); + $fld = $this->session->get('search_fld', 'TEXT'); + $date = process_since_argument($since); + $cutoff_timestamp = strtotime($date); + } + elseif ($this->get('list_path') == 'unread' || (array_key_exists('pop3_unread_only', $this->request->post) && $this->request->post['pop3_unread_only'])) { + $limit = $this->user_config->get('unread_per_source_setting', DEFAULT_PER_SOURCE); + $date = process_since_argument($this->user_config->get('unread_since_setting', DEFAULT_SINCE)); + $unread_only = true; + $cutoff_timestamp = strtotime($date); + if ($login_time && $login_time > $cutoff_timestamp) { + $cutoff_timestamp = $login_time; + } + } + elseif ($this->get('list_path') == 'email') { + $limit = $this->user_config->get('all_email_per_source_setting', DEFAULT_PER_SOURCE); + $date = process_since_argument($this->user_config->get('all_email_since_setting', DEFAULT_SINCE)); + $cutoff_timestamp = strtotime($date); + } + elseif ($this->get('list_path') == 'combined_inbox') { + $limit = $this->user_config->get('all_per_source_setting', DEFAULT_PER_SOURCE); + $date = process_since_argument($this->user_config->get('all_since_setting', DEFAULT_SINCE)); + $cutoff_timestamp = strtotime($date); + } + else { + $limit = DEFAULT_PER_SOURCE; + $date = false; + $cutoff_timestamp = strtotime($date); + } + $cache = false; + if (!$unread_only) { + $cache = Hm_POP3_List::get_cache($this->cache, $form['pop3_server_id']); + } + if ($cache) { + $this->out('pop3_cache_used', true); + } + $pop3 = Hm_POP3_List::connect($form['pop3_server_id'], $cache); + $details = Hm_POP3_List::dump($form['pop3_server_id']); + $path = sprintf("pop3_%d", $form['pop3_server_id']); + if (pop3_authed($pop3)) { + $this->out('pop3_mailbox_page_path', $path); + $list = array_reverse(array_unique(array_keys($pop3->mlist()))); + $total = count($list); + $list = array_slice($list, (($page - 1) * $limit), $limit); + foreach ($list as $id) { + $msg_headers = $pop3->msg_headers($id); + if (!empty($msg_headers)) { + if ($date && isset($msg_headers['date'])) { + if (!Hm_POP3_Uid_Cache::is_unread(sprintf('pop3_%d_%d', $form['pop3_server_id'], $id)) && strtotime($msg_headers['date']) < $cutoff_timestamp) { + continue; + } + } + if ($unread_only && Hm_POP3_Uid_Cache::is_read(sprintf('pop3_%d_%d', $form['pop3_server_id'], $id))) { + continue; + } + if ($terms) { + $body = implode('', $pop3->retr_full($id)); + if (!search_pop3_msg($body, $msg_headers, $terms, $fld)) { + continue; + } + } + $msg_headers['server_name'] = $details['name']; + $msg_headers['server_id'] = $form['pop3_server_id']; + $msgs[$id] = $msg_headers; + } + } + $this->out('pop3_mailbox_page', $msgs); + $this->out('pop3_server_id', $form['pop3_server_id']); + $this->out('list_page', $page); + if (!$date) { + $this->out('page_links', build_page_links($limit, $page, $total, $path)); + } + } + } + } +} + +/** + * Fetch a message from a POP3 server + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_message_content extends Hm_Handler_Module { + /** + * Connect to a POP3 server and download a message + */ + public function process() { + + list($success, $form) = $this->process_form(array('pop3_uid', 'pop3_list_path')); + if ($success) { + $id = (int) substr($form['pop3_list_path'], 5); + $cache = Hm_POP3_List::get_cache($this->cache, $id); + $pop3 = Hm_POP3_List::connect($id, $cache); + $details = Hm_POP3_List::dump($id); + if (pop3_authed($pop3)) { + $msg_lines = $pop3->retr_full($form['pop3_uid']); + $header_list = array(); + $body = array(); + $headers = true; + $last_header = false; + + $bodies = array(); + $has_multipart = false; + $boundary = ''; + $boundaries = array(); + $multipart_headers = false; + $multipart_header_list = array(); + + foreach ($msg_lines as $line) { + if ($headers) { + if (substr($line, 0, 1) == "\t" + || substr($line, 0, 1) == " ") { + $header_list[$last_header] .= decode_fld($line); + } + elseif (strstr($line, ':')) { + $parts = explode(':', $line, 2); + if (count($parts) == 2) { + $header_list[$parts[0]] = decode_fld($parts[1]); + $last_header = $parts[0]; + } + } + if (array_key_exists('Content-Type', $header_list) + && strstr($header_list['Content-Type'], 'multipart') + && $boundary = strstr($header_list['Content-Type'], 'boundary=')) { + $has_multipart = true; + $boundary = str_replace('boundary=', '', $boundary); + $boundary = str_replace('"', '', $boundary); + if (array_search($boundary, $boundaries) === false) { + $boundaries[] = $boundary; + } + } + } + elseif ($multipart_headers) { + if (substr($line, 0, 1) == "\t" + || substr($line, 0, 1) == " ") { + $multipart_header_list[$last_header] .= decode_fld($line); + } + elseif (strstr($line, ':')) { + $parts = explode(':', $line, 2); + if (count($parts) == 2) { + $multipart_header_list[$parts[0]] = decode_fld($parts[1]); + $last_header = $parts[0]; + } + } + if (array_key_exists('Content-Type', $multipart_header_list) + && strstr($multipart_header_list['Content-Type'], 'multipart') + && $boundary = strstr($multipart_header_list['Content-Type'], 'boundary=')) { + $has_multipart = true; + $boundary = str_replace('boundary=', '', $boundary); + $boundary = str_replace('"', '', $boundary); + if (array_search($boundary, $boundaries) === false) { + $boundaries[] = $boundary; + } + } + } + else { + $boundary = '####unmatch-boundary'; + foreach ($boundaries as $_boundary) { + if (strstr($line, $_boundary)) { + $boundary = $_boundary; + break; + } + } + if ($has_multipart === true && strstr($line, $boundary)) { + if (array_key_exists('Content-Type', $multipart_header_list) + && strstr($multipart_header_list['Content-Type'], 'html')) { + $body['content-type'] = 'html'; + } + else { + $body['content-type'] = 'text'; + } + if (array_key_exists('Content-Transfer-Encoding', $multipart_header_list) + && strstr($multipart_header_list['Content-Transfer-Encoding'], 'base64')) { + $body['text'] = base64_decode(str_replace(array("\r", "\n"), '', $body['text'])); + } + if (array_key_exists('Content-Type', $multipart_header_list) + && $charset = strstr($multipart_header_list['Content-Type'], 'charset=')) { + $charset = str_replace('charset=', '', $charset); + $body['text'] = mb_convert_encoding($body['text'], 'UTF-8', $charset); + } + if (array_key_exists('text', $body)) { + $bodies[] = $body; + } + $body = array('text' => ''); + + $multipart_headers = true; + $multipart_header_list = array(); + } + else { + if (array_key_exists('text', $body)) { + $body['text'] .= $line; + } + else { + $body['text'] = $line; + } + } + } + + if (!trim($line)) { + $headers = false; + if ($multipart_headers === true) { + $multipart_headers = false; + } + } + } + $this->out('pop3_message_headers', $header_list); + + if ($has_multipart === false) { + if (array_key_exists('Content-Type', $header_list) + && strstr($header_list['Content-Type'], 'html')) { + $body['content-type'] = 'html'; + } + if (array_key_exists('Content-Transfer-Encoding', $header_list) + && strstr($header_list['Content-Transfer-Encoding'], 'base64')) { + $body['text'] = base64_decode(str_replace(array("\r", "\n"), '', $body['text'])); + } + if (array_key_exists('Content-Type', $header_list) + && $charset = strstr($header_list['Content-Type'], 'charset=')) { + $charset = trim(str_replace('charset=', '', $charset)); + if (strtolower($charset) != 'utf-8') { + $body['text'] = mb_convert_encoding($body['text'], 'UTF-8', $charset); + } + } + $bodies[] = $body; + } + + $this->out('pop3_message_body', $bodies); + $this->out('pop3_mailbox_page_path', $form['pop3_list_path']); + $this->out('pop3_server_id', $id); + bust_pop3_cache($this->cache, $id); + Hm_POP3_Uid_Cache::read(sprintf("pop3_%s_%s", $id, $form['pop3_uid'])); + } + } + } +} + +/** + * Save a POP3 server on the servers page + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_save extends Hm_Handler_Module { + /** + * Authenticate and save a POP3 server on the settings page + */ + public function process() { + $just_saved_credentials = false; + if (isset($this->request->post['pop3_save'])) { + list($success, $form) = $this->process_form(array('pop3_user', 'pop3_pass', 'pop3_server_id')); + if (!$success) { + Hm_Msgs::add('ERRUsername and Password are required to save a connection'); + return; + } + if (in_server_list('Hm_POP3_List', $form['pop3_server_id'], $form['pop3_user'])) { + Hm_Msgs::add('ERRThis server and username are already configured'); + return; + } + $pop3 = Hm_POP3_List::connect($form['pop3_server_id'], false, $form['pop3_user'], $form['pop3_pass'], true); + if (pop3_authed($pop3)) { + $just_saved_credentials = true; + Hm_Msgs::add("Server saved"); + $this->session->record_unsaved('POP3 server saved'); + } + else { + Hm_POP3_List::forget_credentials($form['pop3_server_id']); + Hm_Msgs::add("ERRUnable to save this server, are the username and password correct?"); + } + } + $this->out('just_saved_credentials', $just_saved_credentials); + } +} + +/** + * Forget the username and password for a POP3 server + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_forget extends Hm_Handler_Module { + /** + * Used on the settings page to forget the username/password of a POP3 server + */ + public function process() { + $just_forgot_credentials = false; + if (isset($this->request->post['pop3_forget'])) { + list($success, $form) = $this->process_form(array('pop3_server_id')); + if ($success) { + Hm_POP3_List::forget_credentials($form['pop3_server_id']); + $just_forgot_credentials = true; + Hm_Msgs::add('Server credentials forgotten'); + $this->session->record_unsaved('POP3 server credentials forgotten'); + } + else { + $this->out('old_form', $form); + } + } + $this->out('just_forgot_credentials', $just_forgot_credentials); + } +} + +/** + * Delete a POP3 server from the settings page + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_delete extends Hm_Handler_Module { + /** + * Delete a POP3 server + */ + public function process() { + if (isset($this->request->post['pop3_delete'])) { + list($success, $form) = $this->process_form(array('pop3_server_id')); + if ($success) { + $res = Hm_POP3_List::del($form['pop3_server_id']); + if ($res) { + $this->out('deleted_server_id', $form['pop3_server_id']); + Hm_Msgs::add('Server deleted'); + $this->session->record_unsaved('POP3 server deleted'); + } + } + else { + $this->out('old_form', $form); + } + } + } +} + +/** + * Test a connection to a POP3 server + * @subpackage pop3/handler + */ +class Hm_Handler_pop3_connect extends Hm_Handler_Module { + /** + * Used on the servers page to test a POP3 connection + */ + public function process() { + $pop3 = false; + if (isset($this->request->post['pop3_connect'])) { + list($success, $form) = $this->process_form(array('pop3_user', 'pop3_pass', 'pop3_server_id')); + if ($success) { + $pop3 = Hm_POP3_List::connect($form['pop3_server_id'], false, $form['pop3_user'], $form['pop3_pass']); + } + elseif (isset($form['pop3_server_id'])) { + $pop3 = Hm_POP3_List::connect($form['pop3_server_id'], false); + } + if ($pop3 && $pop3->state == 'authed') { + Hm_Msgs::add("Successfully authenticated to the POP3 server : " . $form['pop3_user']); + } + else { + Hm_Msgs::add("ERRFailed to authenticate to the POP3 server : " . $form['pop3_user']); + } + } + } +} + +/** + * Save a POP3 server cache + * @subpackage pop3/handler + */ +class Hm_Handler_save_pop3_cache extends Hm_Handler_Module { + /** + * Save a POP3 server cache in the session + * + */ + public function process() { + $cache = array(); + if ($this->get('pop3_cache_used')) { + return; + } + $servers = Hm_POP3_List::dump(false, true); + foreach ($servers as $id => $server) { + if (isset($server['object']) && is_object($server['object'])) { + $cache[$id] = $server['object']->dump_cache(); + } + } + if (count($cache) > 0) { + foreach ($cache as $id => $data) { + $this->cache->set('pop3'.$id, $cache[$id]); + } + } + } +} + +/** + * Load POP3 servers up for the search page + * @subpackage pop3/handler + */ +class Hm_Handler_load_pop3_servers_for_search extends Hm_Handler_Module { + /** + * Add POP3 servers to the data sources list for the search page + */ + public function process() { + foreach (Hm_POP3_List::dump() as $index => $vals) { + $this->append('data_sources', array('callback' => 'pop3_search_page_content', 'type' => 'pop3', 'name' => $vals['name'], 'id' => $index)); + } + } +} + +/** + * Load POP3 server for combined message views + * @subpackage pop3/handler + */ +class Hm_Handler_load_pop3_servers_for_message_list extends Hm_Handler_Module { + /** + * Load POP3 servers for a combined message list + */ + public function process() { + $server_id = false; + $callback = false; + if (array_key_exists('list_path', $this->request->get)) { + $path = $this->request->get['list_path']; + } + else { + $path = ''; + } + switch ($path) { + case 'unread': + $callback = 'pop3_combined_unread_content'; + break; + case 'combined_inbox': + $callback = 'pop3_combined_inbox_content'; + break; + case 'email': + $callback = 'pop3_all_mail_content'; + break; + default: + if (preg_match("/^pop3_(\d+)$/", $path, $matches)) { + $server_id = $matches[1]; + $callback = 'load_pop3_list'; + } + else { + $callback = 'pop3_unread_background'; + } + break; + } + if ($callback) { + foreach (Hm_POP3_List::dump() as $index => $vals) { + if ($server_id !== false && $server_id != $index) { + continue; + } + if ($callback == 'pop3_unread_background') { + $this->append('data_sources', array('callback' => $callback, 'group' => 'background', 'type' => 'pop3', 'name' => $vals['name'], 'id' => $index)); + } + else { + $this->append('data_sources', array('callback' => $callback, 'type' => 'pop3', 'name' => $vals['name'], 'id' => $index)); + } + } + } + } +} + +/** + * Load POP3 servers from the user config + * @subpackage pop3/handler + */ +class Hm_Handler_load_pop3_servers_from_config extends Hm_Handler_Module { + /** + * Setup the POP3 server list + */ + public function process() { + $servers = $this->user_config->get('pop3_servers', array()); + $added = false; + $max = 0; + $index = 0; + foreach ($servers as $server) { + Hm_POP3_List::add( $server, $index ); + if (array_key_exists('default', $server) && $server['default']) { + $added = true; + } + $max = $index; + $index++; + } + $max++; + if (!$added) { + $auth_server = $this->session->get('pop3_auth_server_settings', array()); + if (array_key_exists('name', $auth_server)) { + $name = $auth_server['name']; + } + else { + $name = $this->config->get('pop3_auth_name', 'Default'); + } + if (!empty($auth_server)) { + Hm_POP3_List::add(array( + 'name' => $name, + 'default' => true, + 'server' => $auth_server['server'], + 'port' => $auth_server['port'], + 'tls' => $auth_server['tls'], + 'user' => $auth_server['username'], + 'pass' => $auth_server['password']), + $max); + } + } + Hm_POP3_Uid_Cache::load($this->session->get('pop3_read_uids', array())); + } +} + +/** + * Add a new POP3 server + * @subpackage pop3/handler + */ +class Hm_Handler_process_add_pop3_server extends Hm_Handler_Module { + /** + * Used on the servers page to process adding a new POP3 server + */ + public function process() { + if (isset($this->request->post['submit_pop3_server'])) { + list($success, $form) = $this->process_form(array('new_pop3_name', 'new_pop3_address', 'new_pop3_port')); + if (!$success) { + $this->out('old_form', $form); + Hm_Msgs::add('ERRYou must supply a name, a server and a port ' . $form['pop3_user']); + } + else { + $tls = false; + if (array_key_exists('tls', $this->request->post) && $this->request->post['tls']) { + $tls = true; + } + if ($con = fsockopen($form['new_pop3_address'], $form['new_pop3_port'], $errno, $errstr, 2)) { + Hm_POP3_List::add( array( + 'id' => uniqid(), + 'name' => $form['new_pop3_name'], + 'server' => $form['new_pop3_address'], + 'port' => $form['new_pop3_port'], + 'tls' => $tls)); + Hm_Msgs::add('Added server!'); + $this->session->record_unsaved('POP3 server added'); + } + else { + Hm_Msgs::add(sprintf('ERRCound not add server: %s, %s', $errstr, $form['pop3_user'])); + } + } + } + } +} + +/** + * Add a list of POP3 servers for the output modules + * @subpackage pop3/handler + */ +class Hm_Handler_add_pop3_servers_to_page_data extends Hm_Handler_Module { + /** + * Used to add POP3 server ids to an output page + */ + public function process() { + $servers = Hm_POP3_List::dump(); + $this->out('pop3_servers', $servers); + } +} + +/** + * Load POP3 folder data used by the folder list + * @subpackage pop3/handler + */ +class Hm_Handler_load_pop3_folders extends Hm_Handler_Module { + /** + * Add POP3 folders to the folder list E-mail section + */ + public function process() { + $servers = Hm_POP3_List::dump(); + $folders = array(); + if (!empty($servers)) { + foreach ($servers as $id => $server) { + if ($server['name'] == 'Default-Auth-Server') { + $server['name'] = 'Default'; + } + $folders[$id] = $server['name']; + } + } + $this->out('pop3_folders', $folders); + } +} + +/** + * Save POP3 server list + * @subpackage pop3/handler + */ +class Hm_Handler_save_pop3_servers extends Hm_Handler_Module { + /** + * Save POP3 servers in the session + */ + public function process() { + $servers = Hm_POP3_List::dump(false, true); + foreach ($servers as $index => $vals) { + if (array_key_exists('object', $vals) && $vals['object']) { + unset($servers[$index]['object']); + } + } + $this->user_config->set('pop3_servers', $servers); + $this->session->set('pop3_read_uids', Hm_POP3_Uid_Cache::dump()); + Hm_POP3_List::clean_up(); + } +} + +/** + * Format the add POP3 server dialog + * @subpackage pop3/output + */ +class Hm_Output_add_pop3_server_dialog extends Hm_Output_Module { + /** + * Build the HTML for the add server dialog + */ + protected function output() { + if ($this->get('single_server_mode')) { + return ''; + } + $count = count($this->get('pop3_servers', array())); + $count = sprintf($this->trans('%d configured'), $count); + return '
'. + ''. + ' '.$this->trans('POP3 Servers').'
'.$count.'
'. + ''. + '
'.$this->trans('Add a POP3 Server').'
'. + ''. + ''. + ''. + ''. + ''. + '
'. + '
'. + '
'. + '
'. + '
'.$this->trans('STARTTLS or unencrypted').'
'; + } +} + +/** + * Format a list of configured POP3 servers + * @subpackage pop3/output + */ +class Hm_Output_display_configured_pop3_servers extends Hm_Output_Module { + /** + * Build HTML for configured POP3 servers on the servers page + */ + protected function output() { + if ($this->get('single_server_mode')) { + return ''; + } + $res = ''; + foreach ($this->get('pop3_servers', array()) as $index => $vals) { + + $no_edit = false; + + if (array_key_exists('user', $vals) && !array_key_exists('nopass', $vals)) { + $disabled = 'disabled="disabled"'; + $user_pc = $vals['user']; + $pass_pc = $this->trans('[saved]'); + } + elseif (array_key_exists('user', $vals) && array_key_exists('nopass', $vals)) { + $user_pc = $vals['user']; + $pass_pc = $this->trans('Password'); + $disabled = ''; + } + else { + $user_pc = ''; + $pass_pc = $this->trans('Password'); + $disabled = ''; + } + if ($vals['name'] == 'Default-Auth-Server') { + $vals['name'] = $this->trans('Default'); + $no_edit = true; + } + $res .= '
'; + $res .= sprintf('
%s
%s/%d %s
', + $this->html_safe($vals['name']), $this->html_safe($vals['server']), $this->html_safe($vals['port']), $vals['tls'] ? 'TLS' : '' ); + $res .= + '
'. + ''. + ' '. + ''. + ''. + ' '. + ''; + if (!$no_edit) { + if (!isset($vals['user']) || !$vals['user']) { + $res .= ''; + $res .= ''; + } + else { + $res .= ''; + $res .= ''; + $res .= ''; + } + $res .= ''; + } + $res .= '
'; + } + $res .= '
'; + return $res; + } +} + +/** + * Format POP3 folders for the folder list + * @subpackage pop3/output + */ +class Hm_Output_filter_pop3_folders extends Hm_Output_Module { + /** + * Build the HTML for POP3 accounts in the folder list + */ + protected function output() { + $res = ''; + foreach ($this->get('pop3_folders', array()) as $id => $folder) { + $res .= '
  • '. + ''; + if (!$this->get('hide_folder_icons')) { + $res .= ' '; + } + $res .= $this->html_safe($folder).'
  • '; + } + if ($res) { + $this->append('folder_sources', array('email_folders', $res)); + } + return ''; + } +} + +/** + * Format a POP3 message for display + * @subpackage pop3/output + */ +class Hm_Output_filter_pop3_message_content extends Hm_Output_Module { + /** + * Build the HTML for a POP3 message view + */ + protected function output() { + if ($this->get('pop3_message_headers')) { + $txt = ''; + $from = ''; + $small_headers = array('subject', 'date', 'from'); + $headers = $this->get('pop3_message_headers'); + $txt .= ''. + ''; + foreach ($small_headers as $fld) { + foreach ($headers as $name => $value) { + if ($fld == strtolower($name)) { + if ($fld == 'from') { + $from = $value; + } + if ($fld == 'subject') { + $txt .= ''; + } + else { + $txt .= ''; + } + break; + } + } + } + foreach ($headers as $name => $value) { + if (!in_array(strtolower($name), $small_headers)) { + $txt .= ''; + } + } + $txt .= '
    '; + if (isset($headers['Flags']) && stristr($headers['Flags'], 'flagged')) { + $txt .= ' '; + } + $txt .= $this->html_safe($value).'
    '.$this->trans($name).''.$this->html_safe($value).'
    '. + ''.$this->trans('All').''. + ''. + ' | '.$this->trans('Reply').''. + ' | '.$this->trans('Forward').''. + ' | '.$this->trans('Attach').''. + ' | '.$this->trans('raw').''. + ' | '.$this->trans('Flag').''. + '
    '; + + $this->out('msg_headers', $txt); + } + $txt = '
    '; + if ($this->get('pop3_message_body')) { + foreach ($this->get('pop3_message_body') as $body) { + if (array_key_exists('content-type', $body) && $body['content-type'] === 'html') { + $txt .= format_msg_html($body['text']); + } + else { + $txt .= format_msg_text($body['text'], $this); + } + } + } + $txt .= '
    '; + $this->out('msg_text', $txt); + } +} + +/** + * Format a list of POP3 messages + * @subpackage pop3/output + */ +class Hm_Output_filter_pop3_message_list extends Hm_Output_Module { + /** + * Build the HTML for a set of POP3 messages + */ + protected function output() { + $res = array(); + if ($this->get('pop3_mailbox_page')) { + $style = $this->get('news_list_style') ? 'news' : 'email'; + if ($this->get('is_mobile')) { + $style = 'news'; + } + if ($this->get('login_time')) { + $login_time = $this->get('login_time'); + } + else { + $login_time = false; + } + $res = format_pop3_message_list($this->get('pop3_mailbox_page'), $this, $style, $login_time, $this->get('list_path')); + } + $this->out('formatted_message_list', $res); + } +} + +/** + * Output POP3 server ids + * @subpackage pop3/output + */ +class Hm_Output_pop3_server_ids extends Hm_Output_Module { + /** + * Put a list of POP3 server ids in a hidden page element + */ + protected function output() { + return ''; + } +} + +/** + * Format a POP3 status response row + * @subpackage pop3/output + */ +class Hm_Output_display_pop3_status extends Hm_Output_Module { + /** + * Build the HTML for a POP3 status row on the home page + */ + protected function output() { + $res = ''; + foreach ($this->get('pop3_servers', array()) as $index => $vals) { + if ($vals['name'] == 'Default-Auth-Server') { + $vals['name'] = $this->trans('Default'); + } + $res .= 'POP3'.$vals['name'].''. + ''; + } + return $res; + } +} + +/** + * Format POP3 status response data + * @subpackage pop3/output + */ +class Hm_Output_filter_pop3_status_data extends Hm_Output_Module { + /** + * Build ajax response for a status row on the home page + */ + protected function output() { + if ($this->get('pop3_connect_status') == 'Authenticated') { + $this->out('pop3_status_display', ''. + $this->trans(ucwords($this->get('pop3_connect_status'))).' in '.round($this->get('pop3_connect_time'), 3)); + } + else { + $this->out('pop3_status_display', ''.$this->trans('Down').''); + } + } +} + +/** + * Format a list of POP3 messages + * @subpackage pop3/functions + * @param array $msg_list list of message data + * @param object $mod Hm_Output_Module + * @param string $style list style + * @param string $login_time timestamp of last login + * @param string $list_parent list type + * @return array + */ +if (!hm_exists('format_pop3_message_list')) { +function format_pop3_message_list($msg_list, $output_module, $style, $login_time, $list_parent) { + $res = array(); + $show_icons = $output_module->get('msg_list_icons'); + foreach($msg_list as $msg_id => $msg) { + $icon = 'env_open'; + $row_class = 'email'; + if ($msg['server_name'] == 'Default-Auth-Server') { + $msg['server_name'] = 'Default'; + } + $id = sprintf("pop3_%s_%s", $msg['server_id'], $msg_id); + $subject = display_value('subject', $msg, false, $output_module->trans('[No Subject]')); + $from = display_value('from', $msg); + $nofrom = ''; + if ($style == 'email' && !$from) { + $nofrom = ' nofrom'; + $from = '[No From]'; + } + $date = display_value('date', $msg, false, $output_module->trans('[No Date]')); + if ($date) { + $date = translate_time_str($date, $output_module); + } + $timestamp = display_value('date', $msg, 'time'); + $url = '?page=message&uid='.$msg_id.'&list_path='.sprintf('pop3_%d', $msg['server_id']).'&list_parent='.$list_parent; + if ($output_module->get('list_page', 0)) { + $url .= '&list_page='.$output_module->html_safe($output_module->get('list_page', 1)); + } + if (Hm_POP3_Uid_Cache::is_read($id)) { + $flags = array(); + } + elseif (Hm_POP3_Uid_Cache::is_unread($id)) { + $flags = array('unseen'); + $icon = 'env_closed'; + $row_class .= ' unseen'; + } + elseif (isset($msg['date']) && $login_time && strtotime($msg['date']) <= $login_time) { + $flags = array(); + } + else { + $icon = 'env_closed'; + $flags = array('unseen'); + } + $row_class .= ' '.str_replace(' ', '_', $msg['server_name']); + if (!$show_icons) { + $icon = false; + } + if ($style == 'news') { + $res[$id] = message_list_row(array( + array('checkbox_callback', $id), + array('icon_callback', $flags), + array('subject_callback', $subject, $url, $flags, $icon), + array('safe_output_callback', 'source', $msg['server_name']), + array('safe_output_callback', 'from'.$nofrom, $from), + array('date_callback', $date, $timestamp), + ), + $id, + $style, + $output_module, + $row_class + ); + } + else { + $res[$id] = message_list_row(array( + array('checkbox_callback', $id), + array('safe_output_callback', 'source', $msg['server_name'], $icon), + array('safe_output_callback', 'from'.$nofrom, $from), + array('subject_callback', $subject, $url, $flags), + array('date_callback', $date, $timestamp), + array('icon_callback', $flags) + ), + $id, + $style, + $output_module, + $row_class + ); + } + } + return $res; +}} + +/** + * Search a POP3 message + * @subpackage pop3/functions + * @param string $body message body + * @param array $headers message headers + * @param string $terms search terms + * @param string $fld field to search + * @return bool + */ +if (!hm_exists('search_pop3_msg')) { +function search_pop3_msg($body, $headers, $terms, $fld) { + if ($fld == 'TEXT') { + if (stristr($body, $terms)) { + return true; + } + } + if ($fld == 'SUBJECT') { + if (array_key_exists('subject', $headers) && stristr($headers['subject'], $terms)) { + return true; + } + } + if ($fld == 'FROM') { + if (array_key_exists('from', $headers) && stristr($headers['from'], $terms)) { + return true; + } + } +}} + +/** + * @subpackage pop3/functions + */ +if (!hm_exists('bust_pop3_cache')) { +function bust_pop3_cache($hm_cache, $id) { + $hm_cache->del('pop3'.$id); + Hm_Debug::add('Busted POP3 cache for id '.$id); +}} + +/** + * @subpackage pop3/functions + */ +if (!hm_exists('pop3_authed')) { +function pop3_authed($pop3) { + return is_object($pop3) && $pop3->state == 'authed'; +}} + diff --git a/modules/profiles/modules.php b/modules/profiles/modules.php index 378363b3e0..7f4f02cb19 100644 --- a/modules/profiles/modules.php +++ b/modules/profiles/modules.php @@ -116,6 +116,7 @@ public function process() { $data = $this->get('profiles'); $profile = array( + 'id' => uniqid(), 'name' => html_entity_decode($form['profile_name'], ENT_QUOTES), 'sig' => $sig, 'smtp_id' => $form['profile_smtp'], @@ -281,7 +282,7 @@ protected function output() { ''.$this->html_safe($smtp).''. ''.(strlen($profile['sig']) > 0 ? $this->trans('Yes') : $this->trans('No')).''. ''.($profile['default'] ? $this->trans('Yes') : $this->trans('No')).''. - ''. + ''. ''. ''; } From bd2737113febd612a1e7ab17abdb2b7d882bd30a Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Sat, 1 Oct 2022 09:54:40 -0300 Subject: [PATCH 04/12] Hotfix profiles ids --- modules/profiles/modules.php | 15 ++++++++++----- modules/profiles/setup.php | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/profiles/modules.php b/modules/profiles/modules.php index 7f4f02cb19..27c47b0e78 100644 --- a/modules/profiles/modules.php +++ b/modules/profiles/modules.php @@ -20,13 +20,18 @@ public function process() { $id = $this->request->get['profile_id']; } $accounts = $this->get('profiles'); - if ($id !== false) { - if (count($accounts) > $id) { - $this->out('edit_profile', $accounts[$id]); - $this->out('default_email_domain', $this->config->get('default_email_domain')); - $this->out('edit_profile_id', $id); + + foreach ($accounts as $acc) { + if ($acc['id'] == $id) { + $account = $acc; } } + + if ($id !== false) { + $this->out('edit_profile', $account); + $this->out('default_email_domain', $this->config->get('default_email_domain')); + $this->out('edit_profile_id', $id); + } else { $this->out('new_profile_id', count($accounts)); } diff --git a/modules/profiles/setup.php b/modules/profiles/setup.php index 2f47f8cf1c..eaf7869e02 100644 --- a/modules/profiles/setup.php +++ b/modules/profiles/setup.php @@ -29,7 +29,7 @@ ), 'allowed_post' => array( 'profile_name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, - 'profile_id' => FILTER_VALIDATE_INT, + 'profile_id' => FILTER_UNSAFE_RAW, 'profile_replyto' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'profile_smtp' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'profile_imap' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, @@ -39,6 +39,6 @@ 'profile_delete' => FILTER_SANITIZE_FULL_SPECIAL_CHARS ), 'allowed_get' => array( - 'profile_id' => FILTER_VALIDATE_INT, + 'profile_id' => FILTER_UNSAFE_RAW, ), ); From 1da06d57ccf45d6e6f7603d0acb8cd7561bdcec4 Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Tue, 24 Jan 2023 21:02:32 -0300 Subject: [PATCH 05/12] Repository layer for Handlers and centralized entity and id management Include profiles implementation --- lib/module.php | 149 +++++++++++++++++++++++++++++++++++ lib/modules.php | 13 +++ lib/modules_exec.php | 1 + lib/repository.php | 6 ++ modules/profiles/modules.php | 46 ++++------- modules/profiles/setup.php | 1 - 6 files changed, 184 insertions(+), 32 deletions(-) create mode 100644 lib/repository.php diff --git a/lib/module.php b/lib/module.php index 99d921ba09..6837c2ddf9 100644 --- a/lib/module.php +++ b/lib/module.php @@ -283,6 +283,151 @@ private function validate_source($target, $source, $session, $request) { } } +abstract class Hm_Repository { + + private $name; + + private $entities; + + private $default_entity_id; + + private $session; + + private $user_config; + + public function __construct($name, $session, $user_config) { + $this->session = $session; + $this->name = $name; + $this->user_config = $user_config; + $this->load(); + } + + private function load() { + $this->entities = $this->user_config->get($this->name.'_entities'); + $this->default_entity_id = $this->user_config->get($this->name.'_entity_default_id'); + } + + public function __call(string $name, array $arguments) { + if (preg_match('/findBy([A-Z])\w+/', $name)) { + return ''; + } + throw new Exception("Argument " . $name . ' not found in ' . get_class($this)); + } + + public function setDefault($default) { + if (is_scalar($default)) { + $this->default_entity_id = $default; + } + if (is_array($default)) { + $this->default_entity_id = $default['id']; + } + if (is_object($default)) { + $this->default_entity_id = $default->id; + } + $this->commit(); + } + + public function count() { + return count($this->entities); + } + + public function getAll() { + return $this->entities; + } + + public function findById($id) { + if (array_key_exists($id, $this->entities)) { + return $this->entities[$id]; + } + return false; + } + + private function generateId() { + return uniqid(); + } + + private function commit() { + $this->user_config->set($this->name.'_entities', $this->entities); + $this->user_config->set($this->name.'_entity_default_id', $this->default_entity_id); + $this->session->set('user_data', $this->user_config->dump()); + } + + private function saveArrayEntity($entity) { + $created = false; + if (!array_key_exists('id', $entity)) { + $created = true; + $entity['id'] = $this->generateId(); + } + $this->entities[$entity['id']] = $entity; + $this->commit(); + if ($created) { + $this->session->record_unsaved(ucfirst($this->name).' added'); + } else { + $this->session->record_unsaved(ucfirst($this->name).' updated'); + } + } + + public function save($entity) { + if (is_array($entity)) { + return $this->saveArrayEntity($entity); + } + throw new Exception("Entity must be an array or object"); + } + + public function deleteById($id) { + unset($this->entities[$id]); + $this->commit(); + return true; + } + + public function delete($id_or_entity) { + if (is_scalar($id_or_entity)) { + return $this->deleteById($id_or_entity); + } + } +} + +class Hm_ModulesRepositoryRegistry { + + private $modules; + + private $repositories = array(); + + private $session; + + private $user_config; + + public function add_repository($name, $object) { + $this->repositories[$name] = $object; + } + + public function __construct($modules, $session, $user_config) { + $this->modules = $modules; + $this->session = $session; + $this->user_config = $user_config; + $this->load_default_repositories(); + #$this->repositories = array(); + #$modules_path = getcwd() . '../modules'; + #foreach (glob($modules_path . '/*' , GLOB_ONLYDIR) as $dir) { + # + #} + } + + private function load_default_repositories() { + require_once getcwd() . '/lib/repository.php'; + foreach ($this->modules as $module) { + $this->add_repository($module, new Hm_BaseRepository($module, $this->session, $this->user_config)); + } + } + + public function __get(string $name) { + if (array_key_exists($name, $this->repositories)) { + return $this->repositories[$name]; + } + throw new Exception("Repository not registered"); + } +} + /** * Base class for data input processing modules, called "handler modules" * @@ -320,6 +465,9 @@ abstract class Hm_Handler_Module { public $user_config; public $cache; + + public $repositories; + /** * Assign input and state sources * @param object $parent instance of the Hm_Request_Handler class @@ -336,6 +484,7 @@ public function __construct($parent, $page, $output=array(), $protected=array()) $this->user_config = $parent->user_config; $this->output = $output; $this->protected = $protected; + $this->repositories = new Hm_ModulesRepositoryRegistry($parent->site_config->get_modules(), $this->session, $this->user_config); } /** diff --git a/lib/modules.php b/lib/modules.php index ae500e9da2..52558368e2 100644 --- a/lib/modules.php +++ b/lib/modules.php @@ -405,6 +405,19 @@ function add_handler($page, $mod, $logged_in, $source=false, $marker=false, $pla Hm_Handler_Modules::add($page, $mod, $logged_in, $marker, $placement, $queue, $source); } +/** + * Add a repository to the module + * + * Repository name for ProfileRepository class is 'profile' + * Filename for ProfileRepository class is 'profile' + * + * @param $class_name + * @return void + */ +function add_repository($repository_name) { + +} + /** * Add an output module to a specific page * @param string $mod name of the module to add diff --git a/lib/modules_exec.php b/lib/modules_exec.php index 2df65262a1..5a390f0e43 100644 --- a/lib/modules_exec.php +++ b/lib/modules_exec.php @@ -218,6 +218,7 @@ class Hm_Module_Exec { public $filters = array(); public $handlers = array(); public $outputs = array(); + public $repositories = array(); /** * @param object $config site config diff --git a/lib/repository.php b/lib/repository.php new file mode 100644 index 0000000000..5f6d8f9bb9 --- /dev/null +++ b/lib/repository.php @@ -0,0 +1,6 @@ +get('profiles'); - if (count($data) > $form['profile_id']) { - $profiles = new Hm_Profiles($this); - $del_profile = $profiles->get($form['profile_id']); - if ($del_profile && array_key_exists('autocreate', $del_profile)) { + + if (($profile = $this->repositories->profiles->findById($form['profile_id']))) { + if (array_key_exists('autocreate', $profile)) { Hm_Msgs::add('ERRAutomatically created profile cannot be deleted'); return; } - if ($profiles->del($form['profile_id'])) { - $this->session->record_unsaved('Profile deleted'); - Hm_Msgs::add('Profile Deleted'); - $profiles->save($this->user_config); - $user_data = $this->user_config->dump(); - $this->session->set('user_data', $user_data); - } + $this->repositories->profiles->delete($form['profile_id']); + Hm_Msgs::add('Profile Deleted'); + } else { + Hm_Msgs::add('ERRProfile ID not found'); + return; } } } @@ -119,9 +115,7 @@ public function process() { $default = true; } - $data = $this->get('profiles'); $profile = array( - 'id' => uniqid(), 'name' => html_entity_decode($form['profile_name'], ENT_QUOTES), 'sig' => $sig, 'smtp_id' => $form['profile_smtp'], @@ -133,24 +127,15 @@ public function process() { 'type' => 'imap' ); $profiles = new Hm_Profiles($this); - if (count($data) > $form['profile_id']) { - if ($profiles->edit($form['profile_id'], $profile)) { - $this->session->record_unsaved('Profile updated'); - Hm_Msgs::add('Profile Updated'); - } - } - else { - if ($profiles->add($profile)) { - $this->session->record_unsaved('Profile added'); - Hm_Msgs::add('Profile Added'); - } + if ($this->repositories->profiles->findById($form['profile_id'])) { + $profile['id'] = $form['profile_id']; + $this->repositories->profiles->save($profile); } + if ($default) { $profiles->set_default($form['profile_id']); } - $profiles->save($this->user_config); - $user_data = $this->user_config->dump(); - $this->session->set('user_data', $user_data); + $this->repositories->profiles->save($profile); } } @@ -159,9 +144,8 @@ public function process() { */ class Hm_Handler_profile_data extends Hm_Handler_Module { public function process() { - $accounts = array(); - $profiles = new Hm_Profiles($this); - $this->out('profiles', $profiles->list_all()); + #$profiles = new Hm_Profiles($this); + $this->out('profiles', $this->repositories->profiles->getAll()); } } diff --git a/modules/profiles/setup.php b/modules/profiles/setup.php index eaf7869e02..1f229fe327 100644 --- a/modules/profiles/setup.php +++ b/modules/profiles/setup.php @@ -1,7 +1,6 @@ Date: Tue, 24 Jan 2023 21:12:08 -0300 Subject: [PATCH 06/12] Profile use setDefault method --- modules/profiles/modules.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/profiles/modules.php b/modules/profiles/modules.php index 79349f52fa..f27082d4bc 100644 --- a/modules/profiles/modules.php +++ b/modules/profiles/modules.php @@ -126,14 +126,13 @@ public function process() { 'user' => $user, 'type' => 'imap' ); - $profiles = new Hm_Profiles($this); if ($this->repositories->profiles->findById($form['profile_id'])) { $profile['id'] = $form['profile_id']; $this->repositories->profiles->save($profile); } if ($default) { - $profiles->set_default($form['profile_id']); + $this->repositories->profiles->setDefault($form['profile_id']); } $this->repositories->profiles->save($profile); } From ce621090672367703f7f466cfbeed77f38b3d254 Mon Sep 17 00:00:00 2001 From: Victor Emanouilov Date: Wed, 14 Feb 2024 17:55:59 +0200 Subject: [PATCH 07/12] migrate profiles, imap/smtp/feed server list to repository trait with unique ID management to get rid of array index integer values mixing up when deleting entries --- config/app.php | 9 - lib/framework.php | 1 + lib/module.php | 148 ---- lib/modules_exec.php | 1 - lib/repository.php | 73 +- lib/servers.php | 46 +- modules/core/handler_modules.php | 10 +- modules/core/setup.php | 2 +- modules/feeds/hm-feed.php | 4 + modules/feeds/modules.php | 17 +- modules/feeds/setup.php | 4 +- modules/gmail_contacts/modules.php | 2 +- modules/imap/functions.php | 15 +- modules/imap/handler_modules.php | 50 +- modules/imap/hm-imap.php | 4 + modules/imap/output_modules.php | 2 +- modules/imap/setup.php | 2 +- modules/imap_folders/modules.php | 5 +- modules/nux/modules.php | 19 +- modules/nux/setup.php | 2 +- modules/pop3/modules.php | 1130 ---------------------------- modules/profiles/hm-profiles.php | 110 +-- modules/profiles/modules.php | 28 +- modules/profiles/setup.php | 2 +- modules/sievefilters/setup.php | 2 +- modules/smtp/hm-smtp.php | 4 + modules/smtp/modules.php | 73 +- modules/smtp/setup.php | 8 +- 28 files changed, 206 insertions(+), 1567 deletions(-) delete mode 100644 modules/pop3/modules.php diff --git a/config/app.php b/config/app.php index 7eda3d5978..629a1b8cd5 100644 --- a/config/app.php +++ b/config/app.php @@ -724,15 +724,6 @@ // */ // 'feeds', - // /* - // | ---- - // | POP3 - // | ---- - // | - // | POP3 E-mail account support - // */ - // 'pop3', - // /* // | ----- // | JMAP diff --git a/lib/framework.php b/lib/framework.php index c4144ed9c5..78538ea4b2 100644 --- a/lib/framework.php +++ b/lib/framework.php @@ -9,6 +9,7 @@ define('VERSION', .1); /* load the framework */ +require APP_PATH.'lib/repository.php'; require APP_PATH.'lib/module.php'; require APP_PATH.'lib/modules.php'; require APP_PATH.'lib/modules_exec.php'; diff --git a/lib/module.php b/lib/module.php index 6837c2ddf9..ce1216a5d8 100644 --- a/lib/module.php +++ b/lib/module.php @@ -283,151 +283,6 @@ private function validate_source($target, $source, $session, $request) { } } -abstract class Hm_Repository { - - private $name; - - private $entities; - - private $default_entity_id; - - private $session; - - private $user_config; - - public function __construct($name, $session, $user_config) { - $this->session = $session; - $this->name = $name; - $this->user_config = $user_config; - $this->load(); - } - - private function load() { - $this->entities = $this->user_config->get($this->name.'_entities'); - $this->default_entity_id = $this->user_config->get($this->name.'_entity_default_id'); - } - - public function __call(string $name, array $arguments) { - if (preg_match('/findBy([A-Z])\w+/', $name)) { - return ''; - } - throw new Exception("Argument " . $name . ' not found in ' . get_class($this)); - } - - public function setDefault($default) { - if (is_scalar($default)) { - $this->default_entity_id = $default; - } - if (is_array($default)) { - $this->default_entity_id = $default['id']; - } - if (is_object($default)) { - $this->default_entity_id = $default->id; - } - $this->commit(); - } - - public function count() { - return count($this->entities); - } - - public function getAll() { - return $this->entities; - } - - public function findById($id) { - if (array_key_exists($id, $this->entities)) { - return $this->entities[$id]; - } - return false; - } - - private function generateId() { - return uniqid(); - } - - private function commit() { - $this->user_config->set($this->name.'_entities', $this->entities); - $this->user_config->set($this->name.'_entity_default_id', $this->default_entity_id); - $this->session->set('user_data', $this->user_config->dump()); - } - - private function saveArrayEntity($entity) { - $created = false; - if (!array_key_exists('id', $entity)) { - $created = true; - $entity['id'] = $this->generateId(); - } - $this->entities[$entity['id']] = $entity; - $this->commit(); - if ($created) { - $this->session->record_unsaved(ucfirst($this->name).' added'); - } else { - $this->session->record_unsaved(ucfirst($this->name).' updated'); - } - } - - public function save($entity) { - if (is_array($entity)) { - return $this->saveArrayEntity($entity); - } - throw new Exception("Entity must be an array or object"); - } - - public function deleteById($id) { - unset($this->entities[$id]); - $this->commit(); - return true; - } - - public function delete($id_or_entity) { - if (is_scalar($id_or_entity)) { - return $this->deleteById($id_or_entity); - } - } -} - -class Hm_ModulesRepositoryRegistry { - - private $modules; - - private $repositories = array(); - - private $session; - - private $user_config; - - public function add_repository($name, $object) { - $this->repositories[$name] = $object; - } - - public function __construct($modules, $session, $user_config) { - $this->modules = $modules; - $this->session = $session; - $this->user_config = $user_config; - $this->load_default_repositories(); - #$this->repositories = array(); - #$modules_path = getcwd() . '../modules'; - #foreach (glob($modules_path . '/*' , GLOB_ONLYDIR) as $dir) { - # - #} - } - - private function load_default_repositories() { - require_once getcwd() . '/lib/repository.php'; - foreach ($this->modules as $module) { - $this->add_repository($module, new Hm_BaseRepository($module, $this->session, $this->user_config)); - } - } - - public function __get(string $name) { - if (array_key_exists($name, $this->repositories)) { - return $this->repositories[$name]; - } - throw new Exception("Repository not registered"); - } -} - /** * Base class for data input processing modules, called "handler modules" * @@ -466,8 +321,6 @@ abstract class Hm_Handler_Module { public $cache; - public $repositories; - /** * Assign input and state sources * @param object $parent instance of the Hm_Request_Handler class @@ -484,7 +337,6 @@ public function __construct($parent, $page, $output=array(), $protected=array()) $this->user_config = $parent->user_config; $this->output = $output; $this->protected = $protected; - $this->repositories = new Hm_ModulesRepositoryRegistry($parent->site_config->get_modules(), $this->session, $this->user_config); } /** diff --git a/lib/modules_exec.php b/lib/modules_exec.php index 5a390f0e43..2df65262a1 100644 --- a/lib/modules_exec.php +++ b/lib/modules_exec.php @@ -218,7 +218,6 @@ class Hm_Module_Exec { public $filters = array(); public $handlers = array(); public $outputs = array(); - public $repositories = array(); /** * @param object $config site config diff --git a/lib/repository.php b/lib/repository.php index 5f6d8f9bb9..c690e54afd 100644 --- a/lib/repository.php +++ b/lib/repository.php @@ -1,6 +1,73 @@ get(self::$name, []); + foreach ($initial as $entity) { + self::add($entity, false); + } + } + + protected static function generateId() { + return uniqid(); + } + + public static function save() { + self::$user_config->set(self::$name, self::$entities); + self::$session->set('user_data', self::$user_config->dump()); + } + + public static function add($entity, $save = true) { + if (! array_key_exists('id', $entity)) { + $entity['id'] = self::generateId(); + } + self::$entities[$entity['id']] = $entity; + if ($save) { + self::save(); + } + } + + public static function edit($id, $entity) { + if (array_key_exists($id, self::$entities)) { + self::$entities[$id] = $entity; + self::save(); + return true; + } + return false; + } + + public static function del($id) { + if (array_key_exists($id, self::$entities)) { + unset(self::$entities[$id]); + self::save(); + return true; + } + return false; + + } + + public static function get($id) { + if (array_key_exists($id, self::$entities)) { + return self::$entities[$id]; + } + return false; + } + + public static function getAll() { + return self::$entities; + } + + public static function count() { + return count(self::$entities); + } +} diff --git a/lib/servers.php b/lib/servers.php index c16b0513c3..c15bf91be8 100644 --- a/lib/servers.php +++ b/lib/servers.php @@ -23,11 +23,7 @@ public static function connect($id, $cache=false, $user=false, $pass=false, $sav if (!array_key_exists($id, self::$server_list)) { return false; } - foreach (self::$server_list as $server_l) { - if ($server['id'] == $id) { - $server = $server_l; - } - } + $server = self::$server_list[$id]; if ($server['object']) { return $server['object']; @@ -179,6 +175,14 @@ public static function toggle_hidden($id, $hide) { trait Hm_Server_List { use Hm_Server_Modify; + use Hm_Repository { + Hm_Repository::add as repo_add; + Hm_Repository::get as repo_get; + } + + public static function init($name, $user_config) { + self::initRepo($name, $user_config, self::$server_list); + } /** * Add a server definition @@ -189,22 +193,7 @@ trait Hm_Server_List { public static function add($atts) { $atts['object'] = false; $atts['connected'] = false; - self::$server_list[] = $atts; - } - - /** - * Remove a server - * @param int $id server id - * @return bool true on success - */ - public static function del($id) { - foreach (self::$server_list as $idx => $srv) { - if ($srv['id'] == $id) { - unset(self::$server_list[$idx]); - return true; - } - } - return false; + self::repo_add($atts); } /** @@ -233,16 +222,11 @@ public static function dump($id=false, $full=false) { * @return array */ public static function get($id, $full) { - foreach (self::$server_list as $srv) { - if ($srv['id'] == $id) { - $server = $srv; - } - if (!$full) { - return self::clean($server); - } - return $server; + $server = self::repo_get($id); + if ($server && ! $full) { + return self::clean($server); } - return array(); + return $server; } /* @@ -250,7 +234,7 @@ public static function get($id, $full) { * @return array */ public static function clean($server) { - if (!array_key_exists('pass', $server) || !$server['pass']) { + if (! array_key_exists('pass', $server) || ! $server['pass']) { $server['nopass'] = true; } unset($server['pass']); diff --git a/modules/core/handler_modules.php b/modules/core/handler_modules.php index efbb38bec4..fde7f0eb0a 100644 --- a/modules/core/handler_modules.php +++ b/modules/core/handler_modules.php @@ -42,7 +42,7 @@ public function process() { $current = Hm_SMTP_List::dump($server['id']); $current['pass'] = $form['password']; unset($current['nopass']); - Hm_SMTP_List::add($current, $server['id']); + Hm_SMTP_List::edit($server['id'], $current); $smtp = Hm_SMTP_List::connect($server['id'], false); if ($smtp->state == 'authed') { Hm_Msgs::add('Password Updated'); @@ -50,7 +50,7 @@ public function process() { } else { unset($current['pass']); - Hm_SMTP_List::add($current, $server['id']); + Hm_SMTP_List::edit($server['id'], $current); Hm_Msgs::add('ERRUnable to authenticate to the SMTP server'); $this->out('connect_status', false); } @@ -59,7 +59,7 @@ public function process() { $current = Hm_IMAP_List::dump($server['id']); $current['pass'] = $form['password']; unset($current['nopass']); - Hm_IMAP_List::add($current, $server['id']); + Hm_IMAP_List::edit($server['id'], $current); $imap = Hm_IMAP_List::connect($server['id'], false); if ($imap->get_state() == 'authenticated') { Hm_Msgs::add('Password Updated'); @@ -67,7 +67,7 @@ public function process() { } else { unset($current['pass']); - Hm_IMAP_List::add($current, $server['id']); + Hm_IMAP_List::edit($server['id'], $current); Hm_Msgs::add('ERRUnable to authenticate to the IMAP server'); $this->out('connect_status', false); } @@ -92,7 +92,6 @@ public function process() { if ($this->module_is_supported('imap')) { foreach (Hm_IMAP_List::dump() as $index => $vals) { if (array_key_exists('nopass', $vals)) { - $vals['id'] = $index; $vals['type'] = 'IMAP'; $key = 'imap_'.$index; $missing[$key] = $vals; @@ -102,7 +101,6 @@ public function process() { if ($this->module_is_supported('smtp')) { foreach (Hm_SMTP_List::dump() as $index => $vals) { if (array_key_exists('nopass', $vals)) { - $vals['id'] = $index; $vals['type'] = 'SMTP'; $key = 'smtp_'.$index; $missing[$key] = $vals; diff --git a/modules/core/setup.php b/modules/core/setup.php index 84e7e572c1..b129365c5e 100644 --- a/modules/core/setup.php +++ b/modules/core/setup.php @@ -193,7 +193,7 @@ 'formatted_message_list' => array(FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), 'just_saved_credentials' => array(FILTER_VALIDATE_BOOLEAN, false), 'just_forgot_credentials' => array(FILTER_VALIDATE_BOOLEAN, false), - 'deleted_server_id' => array(FILTER_VALIDATE_INT, false), + 'deleted_server_id' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'msg_headers' => array(FILTER_UNSAFE_RAW, false), 'msg_text' => array(FILTER_UNSAFE_RAW, false), 'msg_parts' => array(FILTER_UNSAFE_RAW, false), diff --git a/modules/feeds/hm-feed.php b/modules/feeds/hm-feed.php index 4a131f6daa..8e085ec1e4 100644 --- a/modules/feeds/hm-feed.php +++ b/modules/feeds/hm-feed.php @@ -16,6 +16,10 @@ class Hm_Feed_List { use Hm_Server_List; + public static function init($user_config, $session) { + self::initRepo('feeds', $user_config, $session, self::$server_list); + } + /* * Connect to an RSS/ATOM feed * @param int $id server id diff --git a/modules/feeds/modules.php b/modules/feeds/modules.php index 8521447994..6469096d86 100644 --- a/modules/feeds/modules.php +++ b/modules/feeds/modules.php @@ -23,13 +23,13 @@ public function process() { $this->out('message_list_since', $this->user_config->get('feed_since_setting', DEFAULT_SINCE)); $this->out('per_source_limit', $this->user_config->get('feed_limit_setting', DEFAULT_PER_SOURCE)); } - elseif (preg_match("/^feeds_\d+$/", $path)) { + elseif (preg_match("/^feeds_.+$/", $path)) { $this->out('message_list_since', $this->user_config->get('feed_since_setting', DEFAULT_SINCE)); $this->out('per_source_limit', $this->user_config->get('feed_limit_setting', DEFAULT_PER_SOURCE)); $this->out('list_path', $path, false); $this->out('custom_list_controls', ' '); $parts = explode('_', $path, 2); - $details = Hm_Feed_List::dump(intval($parts[1])); + $details = Hm_Feed_List::dump($parts[1]); if (!empty($details)) { $this->out('mailbox_list_title', array('Feeds', $details['name'])); } @@ -398,7 +398,6 @@ public function process() { if ($found) { $this->out('reload_folders', true); Hm_Feed_List::add(array( - 'id' => uniqid(), 'name' => $form['new_feed_name'], 'server' => $href, 'tls' => false, @@ -415,12 +414,7 @@ public function process() { */ class Hm_Handler_load_feeds_from_config extends Hm_Handler_Module { public function process() { - $feeds = $this->user_config->get('feeds', array()); - $index = 0; - foreach ($feeds as $index => $feed) { - Hm_Feed_List::add($feed, $index); - $index++; - } + Hm_Feed_List::init($this->user_config, $this->session); Hm_Feed_Uid_Cache::load($this->cache->get('feed_read_uids', array(), true)); } } @@ -482,7 +476,7 @@ public function process() { $callback = 'feeds_combined_content'; break; default: - if (preg_match("/^feeds_(\d+)$/", $path, $matches)) { + if (preg_match("/^feeds_(.+)$/", $path, $matches)) { $server_id = $matches[1]; $callback = 'load_feed_list'; } @@ -504,8 +498,7 @@ public function process() { */ class Hm_Handler_save_feeds extends Hm_Handler_Module { public function process() { - $feeds = Hm_Feed_List::dump(); - $this->user_config->set('feeds', $feeds); + Hm_Feed_List::save(); $this->cache->set('feed_read_uids', Hm_Feed_Uid_Cache::dump(), 0, true); } } diff --git a/modules/feeds/setup.php b/modules/feeds/setup.php index f51c2db947..c8647adbc3 100644 --- a/modules/feeds/setup.php +++ b/modules/feeds/setup.php @@ -53,9 +53,9 @@ add_handler('ajax_feed_combined', 'login', false, 'core'); add_handler('ajax_feed_combined', 'load_user_data', true, 'core'); add_handler('ajax_feed_combined', 'language', true, 'core'); +add_handler('ajax_feed_combined', 'load_feeds_from_config', true); add_handler('ajax_feed_combined', 'message_list_type', true, 'core'); add_handler('ajax_feed_combined', 'feed_list_type', true); -add_handler('ajax_feed_combined', 'load_feeds_from_config', true); add_handler('ajax_feed_combined', 'close_session_early', true, 'core'); add_handler('ajax_feed_combined', 'feed_list_content', true); add_handler('ajax_feed_combined', 'date', true, 'core'); @@ -113,7 +113,7 @@ 'feed_connect_time' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'feed_detail_display' => array(FILTER_UNSAFE_RAW, false), 'feed_status_display' => array(FILTER_UNSAFE_RAW, false), - 'feed_status_server_id' => array(FILTER_VALIDATE_INT, false), + 'feed_status_server_id' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'feed_server_ids' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'feed_msg_headers' => array(FILTER_UNSAFE_RAW, false), 'feed_msg_text' => array(FILTER_UNSAFE_RAW, false), diff --git a/modules/gmail_contacts/modules.php b/modules/gmail_contacts/modules.php index bb7a783781..57579861f3 100644 --- a/modules/gmail_contacts/modules.php +++ b/modules/gmail_contacts/modules.php @@ -83,7 +83,7 @@ function fetch_gmail_contacts($config, $contact_store, $session=false, $max_goog $results = imap_refresh_oauth2_token($server, $config); if (!empty($results)) { if (Hm_IMAP_List::update_oauth2_token($id, $results[1], $results[0])) { - Hm_Debug::add(sprintf('Oauth2 token refreshed for IMAP server id %d', $id)); + Hm_Debug::add(sprintf('Oauth2 token refreshed for IMAP server id %s', $id)); $server = Hm_IMAP_List::dump($id, true); } } diff --git a/modules/imap/functions.php b/modules/imap/functions.php index 03ff5ccae9..27743d88f9 100644 --- a/modules/imap/functions.php +++ b/modules/imap/functions.php @@ -118,23 +118,23 @@ function format_imap_folder_section($folders, $id, $output_mod) { $folder_name = bin2hex($folder_name); $results .= '
  • '; if ($folder['children']) { - $results .= ''; + $results .= ''; } else { $results .= ' '; } if (!$folder['noselect']) { if (strlen($output_mod->html_safe($folder['basename']))>15) { - $results .= 'html_safe($folder_name). '" href="?page=message_list&list_path='. - urlencode('imap_'.intval($id).'_'.$output_mod->html_safe($folder_name)). + urlencode('imap_'.$id.'_'.$output_mod->html_safe($folder_name)). '"title="'.$output_mod->html_safe($folder['basename']). '">'.substr($output_mod->html_safe($folder['basename']),0,15).'...'; } else{ - $results .= 'html_safe($folder_name). '" href="?page=message_list&list_path='. - urlencode('imap_'.intval($id).'_'.$output_mod->html_safe($folder_name)). + urlencode('imap_'.$id.'_'.$output_mod->html_safe($folder_name)). '">'.$output_mod->html_safe($folder['basename']).''; } } @@ -193,7 +193,7 @@ function format_imap_message_list($msg_list, $output_module, $parent_list=false, $row_class = 'email'; $icon = 'env_open'; if (!$parent_list) { - $parent_value = sprintf('imap_%d_%s', $msg['server_id'], $msg['folder']); + $parent_value = sprintf('imap_%s_%s', $msg['server_id'], $msg['folder']); } else { $parent_value = $parent_list; @@ -256,7 +256,7 @@ function format_imap_message_list($msg_list, $output_module, $parent_list=false, if ($msg['folder'] && hex2bin($msg['folder']) != 'INBOX') { $source .= '-'.preg_replace("/^INBOX.{1}/", '', hex2bin($msg['folder'])); } - $url = '?page=message&uid='.$msg['uid'].'&list_path='.sprintf('imap_%d_%s', $msg['server_id'], $msg['folder']).'&list_parent='.$parent_value; + $url = '?page=message&uid='.$msg['uid'].'&list_path='.sprintf('imap_%s_%s', $msg['server_id'], $msg['folder']).'&list_parent='.$parent_value; if ($list_page) { $url .= '&list_page='.$output_module->html_safe($list_page); } @@ -716,7 +716,6 @@ function merge_imap_search_results($ids, $search_type, $session, $hm_cache, $fol $sent_results = array(); $status = array(); foreach($ids as $index => $id) { - $id = intval($id); $cache = Hm_IMAP_List::get_cache($hm_cache, $id); $imap = Hm_IMAP_List::connect($id, $cache); if (imap_authed($imap)) { diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index 0b2e88cf91..39b65fea7d 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -588,7 +588,7 @@ public function process() { $this->out('list_path', $path, false); $this->out('move_copy_controls', true); $parts = explode('_', $path, 3); - $details = Hm_IMAP_List::dump(intval($parts[1])); + $details = Hm_IMAP_List::dump($parts[1]); $custom_link = 'add'; foreach (imap_data_sources(false, $this->user_config->get('custom_imap_sources', array())) as $vals) { if ($vals['id'] == $parts[1] && $vals['folder'] == $parts[2]) { @@ -698,7 +698,7 @@ public function process() { if (isset($this->request->post['folder'])) { $folder = $this->request->post['folder']; } - $path = sprintf("imap_%d_%s", $form['imap_server_id'], $folder); + $path = sprintf("imap_%s_%s", $form['imap_server_id'], $folder); $page_cache = $this->cache->get('imap_folders_'.$path); if (array_key_exists('imap_prefetch', $this->request->post)) { $prefetched = $this->session->get('imap_prefetched_ids', array()); @@ -763,7 +763,7 @@ public function process() { $list_page = 1; } } - $path = sprintf("imap_%d_%s", $form['imap_server_id'], $form['folder']); + $path = sprintf("imap_%s_%s", $form['imap_server_id'], $form['folder']); $details = Hm_IMAP_List::dump($form['imap_server_id']); $cache = Hm_IMAP_List::get_cache($this->cache, $form['imap_server_id']); $imap = Hm_IMAP_List::connect($form['imap_server_id'], $cache); @@ -1093,7 +1093,7 @@ public function process() { } else { foreach ($uids as $uid) { - $moved[] = sprintf("imap_%d_%s_%s", $server, $uid, $folder); + $moved[] = sprintf("imap_%s_%s_%s", $server, $uid, $folder); } } } @@ -1111,7 +1111,7 @@ public function process() { } else { foreach ($uids as $uid) { - $moved[] = sprintf("imap_%d_%s_%s", $server, $uid, $folder); + $moved[] = sprintf("imap_%s_%s_%s", $server, $uid, $folder); } } } @@ -1309,7 +1309,6 @@ public function process() { if (array_key_exists('host', $parsed) && @get_headers($form['new_jmap_address'])) { Hm_IMAP_List::add(array( - 'id' => uniqid(), 'name' => $form['new_jmap_name'], 'server' => $form['new_jmap_address'], 'hide' => $hidden, @@ -1413,8 +1412,7 @@ class Hm_Handler_save_imap_servers extends Hm_Handler_Module { * Save IMAP servers in the user config */ public function process() { - $servers = Hm_IMAP_List::dump(false, true); - $this->user_config->set('imap_servers', $servers); + Hm_IMAP_List::save(); Hm_IMAP_List::clean_up(); } } @@ -1510,33 +1508,21 @@ class Hm_Handler_load_imap_servers_from_config extends Hm_Handler_Module { * This list is cached in the session between page loads by Hm_Handler_save_imap_servers */ public function process() { - $servers = $this->user_config->get('imap_servers', array()); - $added = false; - $updated = false; - $new_servers = array(); - if (count($servers) == 0) { - $max = 0; - } else { - $max = max(array_keys($servers)); - } - foreach ($servers as $id => $server) { + Hm_IMAP_List::init($this->user_config, $this->session); + $has_default = false; + foreach (Hm_IMAP_List::getAll() as $id => $server) { if ($this->session->loaded) { if (array_key_exists('expiration', $server)) { $updated = true; $server['expiration'] = 1; } } - $new_servers[] = $server; - Hm_IMAP_List::add($server, $id); + Hm_IMAP_List::edit($id, $server); if (array_key_exists('default', $server) && $server['default']) { - $added = true; + $has_default = true; } } - $max++; - if ($updated) { - $this->user_config->set('imap_servers', $new_servers); - } - if (!$added) { + if (!$has_default) { $auth_server = $this->session->get('imap_auth_server_settings', array()); if (!empty($auth_server)) { if (array_key_exists('name', $auth_server)) { @@ -1557,9 +1543,7 @@ public function process() { if (! empty($auth_server['sieve_config_host'])) { $imap_details['sieve_config_host'] = $auth_server['sieve_config_host']; } - Hm_IMAP_List::add($imap_details, $max); - $servers = Hm_IMAP_List::dump(false, true); - $this->user_config->set('imap_servers', $servers); + Hm_IMAP_List::add($imap_details); } } } @@ -1585,16 +1569,14 @@ public function process() { $results = imap_refresh_oauth2_token($server, $this->config); if (!empty($results)) { if (Hm_IMAP_List::update_oauth2_token($server_id, $results[1], $results[0])) { - Hm_Debug::add(sprintf('Oauth2 token refreshed for IMAP server id %d', $server_id)); + Hm_Debug::add(sprintf('Oauth2 token refreshed for IMAP server id %s', $server_id)); $updated++; } } } } if ($updated > 0) { - $servers = Hm_IMAP_List::dump(false, true); - $this->user_config->set('imap_servers', $servers); - $this->session->set('user_data', $this->user_config->dump()); + Hm_IMAP_List::save(); } } } @@ -1914,7 +1896,7 @@ public function process() { $msg_struct_current['type'] = 'text'; $msg_struct_current['subtype'] = 'plain'; } - $this->session->set(sprintf('reply_details_imap_%d_%s_%s', $form['imap_server_id'], $form['folder'], $form['imap_msg_uid']), + $this->session->set(sprintf('reply_details_imap_%s_%s_%s', $form['imap_server_id'], $form['folder'], $form['imap_msg_uid']), array('ts' => time(), 'msg_struct' => $msg_struct_current, 'msg_text' => ($save_reply_text ? $msg_text : ''), 'msg_headers' => $msg_headers)); } } diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index 0dd9416955..481aee2740 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -22,6 +22,10 @@ class Hm_IMAP_List { public static $use_cache = true; + public static function init($user_config, $session) { + self::initRepo('imap_servers', $user_config, $session, self::$server_list); + } + public static function service_connect($id, $server, $user, $pass, $cache=false) { if (array_key_exists('type', $server) && $server['type'] == 'jmap') { self::$server_list[$id]['object'] = new Hm_JMAP(); diff --git a/modules/imap/output_modules.php b/modules/imap/output_modules.php index 003c035636..9cfa4e3aad 100644 --- a/modules/imap/output_modules.php +++ b/modules/imap/output_modules.php @@ -831,7 +831,7 @@ protected function output() { $res = ''; if ($this->get('imap_folders')) { foreach ($this->get('imap_folders', array()) as $id => $folder) { - $res .= '
  • '; + $res .= '
  • '; if (!$this->get('hide_folder_icons')) { $res .= ''; } diff --git a/modules/imap/setup.php b/modules/imap/setup.php index 4ba7d7d30a..8bb9dde488 100644 --- a/modules/imap/setup.php +++ b/modules/imap/setup.php @@ -333,7 +333,7 @@ 'imap_connect_time' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'imap_detail_display' => array(FILTER_UNSAFE_RAW, false), 'imap_status_display' => array(FILTER_UNSAFE_RAW, false), - 'imap_status_server_id' => array(FILTER_VALIDATE_INT, false), + 'imap_status_server_id' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'imap_expanded_folder_path' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'imap_expanded_folder_formatted' => array(FILTER_UNSAFE_RAW, false), 'imap_server_ids' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), diff --git a/modules/imap_folders/modules.php b/modules/imap_folders/modules.php index 7abdc726b3..c5df4710e3 100644 --- a/modules/imap_folders/modules.php +++ b/modules/imap_folders/modules.php @@ -320,6 +320,7 @@ public function process() { class Hm_Handler_folders_server_id extends Hm_Handler_Module { public function process() { if (array_key_exists('imap_server_id', $this->request->get)) { + var_dump($this->request->get['imap_server_id']); $this->out('folder_server', $this->request->get['imap_server_id']); } } @@ -339,12 +340,12 @@ public function process() { */ class Hm_Output_folders_server_select extends Hm_Output_Module { protected function output() { - $server_id = $this->get('folder_server', -1); + $server_id = $this->get('folder_server', ''); $res = '
    '; $res .= ''; $res .= '
    '. - '
    '.$this->trans('Add a POP3 Server').'
    '. - ''. - ''. - ''. - ''. - ''. - '
    '. - '
    '. - '
    '. - '
    '. - '
    '.$this->trans('STARTTLS or unencrypted').'
    '; - } -} - -/** - * Format a list of configured POP3 servers - * @subpackage pop3/output - */ -class Hm_Output_display_configured_pop3_servers extends Hm_Output_Module { - /** - * Build HTML for configured POP3 servers on the servers page - */ - protected function output() { - if ($this->get('single_server_mode')) { - return ''; - } - $res = ''; - foreach ($this->get('pop3_servers', array()) as $index => $vals) { - - $no_edit = false; - - if (array_key_exists('user', $vals) && !array_key_exists('nopass', $vals)) { - $disabled = 'disabled="disabled"'; - $user_pc = $vals['user']; - $pass_pc = $this->trans('[saved]'); - } - elseif (array_key_exists('user', $vals) && array_key_exists('nopass', $vals)) { - $user_pc = $vals['user']; - $pass_pc = $this->trans('Password'); - $disabled = ''; - } - else { - $user_pc = ''; - $pass_pc = $this->trans('Password'); - $disabled = ''; - } - if ($vals['name'] == 'Default-Auth-Server') { - $vals['name'] = $this->trans('Default'); - $no_edit = true; - } - $res .= '
    '; - $res .= sprintf('
    %s
    %s/%d %s
    ', - $this->html_safe($vals['name']), $this->html_safe($vals['server']), $this->html_safe($vals['port']), $vals['tls'] ? 'TLS' : '' ); - $res .= - '
    '. - ''. - ' '. - ''. - ''. - ' '. - ''; - if (!$no_edit) { - if (!isset($vals['user']) || !$vals['user']) { - $res .= ''; - $res .= ''; - } - else { - $res .= ''; - $res .= ''; - $res .= ''; - } - $res .= ''; - } - $res .= '
    '; - } - $res .= '
    '; - return $res; - } -} - -/** - * Format POP3 folders for the folder list - * @subpackage pop3/output - */ -class Hm_Output_filter_pop3_folders extends Hm_Output_Module { - /** - * Build the HTML for POP3 accounts in the folder list - */ - protected function output() { - $res = ''; - foreach ($this->get('pop3_folders', array()) as $id => $folder) { - $res .= '
  • '. - ''; - if (!$this->get('hide_folder_icons')) { - $res .= ' '; - } - $res .= $this->html_safe($folder).'
  • '; - } - if ($res) { - $this->append('folder_sources', array('email_folders', $res)); - } - return ''; - } -} - -/** - * Format a POP3 message for display - * @subpackage pop3/output - */ -class Hm_Output_filter_pop3_message_content extends Hm_Output_Module { - /** - * Build the HTML for a POP3 message view - */ - protected function output() { - if ($this->get('pop3_message_headers')) { - $txt = ''; - $from = ''; - $small_headers = array('subject', 'date', 'from'); - $headers = $this->get('pop3_message_headers'); - $txt .= ''. - ''; - foreach ($small_headers as $fld) { - foreach ($headers as $name => $value) { - if ($fld == strtolower($name)) { - if ($fld == 'from') { - $from = $value; - } - if ($fld == 'subject') { - $txt .= ''; - } - else { - $txt .= ''; - } - break; - } - } - } - foreach ($headers as $name => $value) { - if (!in_array(strtolower($name), $small_headers)) { - $txt .= ''; - } - } - $txt .= '
    '; - if (isset($headers['Flags']) && stristr($headers['Flags'], 'flagged')) { - $txt .= ' '; - } - $txt .= $this->html_safe($value).'
    '.$this->trans($name).''.$this->html_safe($value).'
    '. - ''.$this->trans('All').''. - ''. - ' | '.$this->trans('Reply').''. - ' | '.$this->trans('Forward').''. - ' | '.$this->trans('Attach').''. - ' | '.$this->trans('raw').''. - ' | '.$this->trans('Flag').''. - '
    '; - - $this->out('msg_headers', $txt); - } - $txt = '
    '; - if ($this->get('pop3_message_body')) { - foreach ($this->get('pop3_message_body') as $body) { - if (array_key_exists('content-type', $body) && $body['content-type'] === 'html') { - $txt .= format_msg_html($body['text']); - } - else { - $txt .= format_msg_text($body['text'], $this); - } - } - } - $txt .= '
    '; - $this->out('msg_text', $txt); - } -} - -/** - * Format a list of POP3 messages - * @subpackage pop3/output - */ -class Hm_Output_filter_pop3_message_list extends Hm_Output_Module { - /** - * Build the HTML for a set of POP3 messages - */ - protected function output() { - $res = array(); - if ($this->get('pop3_mailbox_page')) { - $style = $this->get('news_list_style') ? 'news' : 'email'; - if ($this->get('is_mobile')) { - $style = 'news'; - } - if ($this->get('login_time')) { - $login_time = $this->get('login_time'); - } - else { - $login_time = false; - } - $res = format_pop3_message_list($this->get('pop3_mailbox_page'), $this, $style, $login_time, $this->get('list_path')); - } - $this->out('formatted_message_list', $res); - } -} - -/** - * Output POP3 server ids - * @subpackage pop3/output - */ -class Hm_Output_pop3_server_ids extends Hm_Output_Module { - /** - * Put a list of POP3 server ids in a hidden page element - */ - protected function output() { - return ''; - } -} - -/** - * Format a POP3 status response row - * @subpackage pop3/output - */ -class Hm_Output_display_pop3_status extends Hm_Output_Module { - /** - * Build the HTML for a POP3 status row on the home page - */ - protected function output() { - $res = ''; - foreach ($this->get('pop3_servers', array()) as $index => $vals) { - if ($vals['name'] == 'Default-Auth-Server') { - $vals['name'] = $this->trans('Default'); - } - $res .= 'POP3'.$vals['name'].''. - ''; - } - return $res; - } -} - -/** - * Format POP3 status response data - * @subpackage pop3/output - */ -class Hm_Output_filter_pop3_status_data extends Hm_Output_Module { - /** - * Build ajax response for a status row on the home page - */ - protected function output() { - if ($this->get('pop3_connect_status') == 'Authenticated') { - $this->out('pop3_status_display', ''. - $this->trans(ucwords($this->get('pop3_connect_status'))).' in '.round($this->get('pop3_connect_time'), 3)); - } - else { - $this->out('pop3_status_display', ''.$this->trans('Down').''); - } - } -} - -/** - * Format a list of POP3 messages - * @subpackage pop3/functions - * @param array $msg_list list of message data - * @param object $mod Hm_Output_Module - * @param string $style list style - * @param string $login_time timestamp of last login - * @param string $list_parent list type - * @return array - */ -if (!hm_exists('format_pop3_message_list')) { -function format_pop3_message_list($msg_list, $output_module, $style, $login_time, $list_parent) { - $res = array(); - $show_icons = $output_module->get('msg_list_icons'); - foreach($msg_list as $msg_id => $msg) { - $icon = 'env_open'; - $row_class = 'email'; - if ($msg['server_name'] == 'Default-Auth-Server') { - $msg['server_name'] = 'Default'; - } - $id = sprintf("pop3_%s_%s", $msg['server_id'], $msg_id); - $subject = display_value('subject', $msg, false, $output_module->trans('[No Subject]')); - $from = display_value('from', $msg); - $nofrom = ''; - if ($style == 'email' && !$from) { - $nofrom = ' nofrom'; - $from = '[No From]'; - } - $date = display_value('date', $msg, false, $output_module->trans('[No Date]')); - if ($date) { - $date = translate_time_str($date, $output_module); - } - $timestamp = display_value('date', $msg, 'time'); - $url = '?page=message&uid='.$msg_id.'&list_path='.sprintf('pop3_%d', $msg['server_id']).'&list_parent='.$list_parent; - if ($output_module->get('list_page', 0)) { - $url .= '&list_page='.$output_module->html_safe($output_module->get('list_page', 1)); - } - if (Hm_POP3_Uid_Cache::is_read($id)) { - $flags = array(); - } - elseif (Hm_POP3_Uid_Cache::is_unread($id)) { - $flags = array('unseen'); - $icon = 'env_closed'; - $row_class .= ' unseen'; - } - elseif (isset($msg['date']) && $login_time && strtotime($msg['date']) <= $login_time) { - $flags = array(); - } - else { - $icon = 'env_closed'; - $flags = array('unseen'); - } - $row_class .= ' '.str_replace(' ', '_', $msg['server_name']); - if (!$show_icons) { - $icon = false; - } - if ($style == 'news') { - $res[$id] = message_list_row(array( - array('checkbox_callback', $id), - array('icon_callback', $flags), - array('subject_callback', $subject, $url, $flags, $icon), - array('safe_output_callback', 'source', $msg['server_name']), - array('safe_output_callback', 'from'.$nofrom, $from), - array('date_callback', $date, $timestamp), - ), - $id, - $style, - $output_module, - $row_class - ); - } - else { - $res[$id] = message_list_row(array( - array('checkbox_callback', $id), - array('safe_output_callback', 'source', $msg['server_name'], $icon), - array('safe_output_callback', 'from'.$nofrom, $from), - array('subject_callback', $subject, $url, $flags), - array('date_callback', $date, $timestamp), - array('icon_callback', $flags) - ), - $id, - $style, - $output_module, - $row_class - ); - } - } - return $res; -}} - -/** - * Search a POP3 message - * @subpackage pop3/functions - * @param string $body message body - * @param array $headers message headers - * @param string $terms search terms - * @param string $fld field to search - * @return bool - */ -if (!hm_exists('search_pop3_msg')) { -function search_pop3_msg($body, $headers, $terms, $fld) { - if ($fld == 'TEXT') { - if (stristr($body, $terms)) { - return true; - } - } - if ($fld == 'SUBJECT') { - if (array_key_exists('subject', $headers) && stristr($headers['subject'], $terms)) { - return true; - } - } - if ($fld == 'FROM') { - if (array_key_exists('from', $headers) && stristr($headers['from'], $terms)) { - return true; - } - } -}} - -/** - * @subpackage pop3/functions - */ -if (!hm_exists('bust_pop3_cache')) { -function bust_pop3_cache($hm_cache, $id) { - $hm_cache->del('pop3'.$id); - Hm_Debug::add('Busted POP3 cache for id '.$id); -}} - -/** - * @subpackage pop3/functions - */ -if (!hm_exists('pop3_authed')) { -function pop3_authed($pop3) { - return is_object($pop3) && $pop3->state == 'authed'; -}} - diff --git a/modules/profiles/hm-profiles.php b/modules/profiles/hm-profiles.php index 137ff8981e..b1e652bcca 100644 --- a/modules/profiles/hm-profiles.php +++ b/modules/profiles/hm-profiles.php @@ -13,100 +13,87 @@ */ class Hm_Profiles { - private $data = array(); + use Hm_Repository; - public function __construct($hmod) { - $this->load($hmod); - } + private static $data = array(); - public function load($hmod) { - $this->load_new($hmod); - if (count($this->data) == 0) { + public static function init($hmod) { + self::initRepo('profiles', $hmod->user_config, $hmod->session, self::$data); + if (self::count() == 0) { if (PHP_VERSION_ID < 70000) { try { - $this->load_legacy($hmod); + self::loadLegacy($hmod); } catch (Exception $e) { - $this->data = array(); + self::$data = array(); } } if (PHP_VERSION_ID >= 70000) { try { - $this->load_legacy($hmod); + self::loadLegacy($hmod); } catch (Throwable $e) { - $this->data = array(); + self::$data = array(); } } } - if (count($this->data) == 0) { - $this->create_default($hmod); + if (self::count() == 0) { + self::createDefault($hmod); } } - public function load_new($hmod) { - $profiles = $hmod->user_config->get('profiles', array()); - foreach ($profiles as $profile) { - $this->data[] = $profile; - } - } - - public function save($user_config) { - $user_config->set('profiles', $this->data); - } - - public function add($data) { - $this->data[] = $data; - } - - public function set_default($id) { - if (!array_key_exists($id, $this->data)) { + public static function setDefault($id) { + if (! array_key_exists($id, self::$data)) { return false; } - foreach ($this->data as $p_id => $vals) { + foreach (self::$data as $p_id => $vals) { if ($vals['default']) { - $this->data[$p_id]['default'] = false; + $vals['default'] = false; + self::edit($p_id, $vals); } } - $this->data[$id]['default'] = true; + $vals = self::get($id); + $vals['default'] = true; + self::edit($id, $vals); return true; } - public function create_default($hmod) { - if (!$hmod->module_is_supported('imap') || !$hmod->module_is_supported('smtp')) { + public static function createDefault($hmod) { + if (! $hmod->module_is_supported('imap') || ! $hmod->module_is_supported('smtp')) { return; } - if (!$hmod->config->get('autocreate_profile')) { + if (! $hmod->config->get('autocreate_profile')) { return; } $imap_servers = Hm_IMAP_List::dump(); $smtp_servers = Hm_SMTP_List::dump(); - list($address, $reply_to) = outbound_address_check($hmod, $imap_servers[0]['user'], ''); if (count($imap_servers) == 1 && count($smtp_servers) == 1) { - $this->data[] = array( + $imap_server = reset($imap_servers); + $smtp_server = reset($smtp_servers); + list($address, $reply_to) = outbound_address_check($hmod, $imap_server['user'], ''); + self::add(array( 'default' => true, 'name' => 'Default', 'address' => $address, 'replyto' => $reply_to, - 'smtp_id' => 0, + 'smtp_id' => $smtp_server['id'], 'sig' => '', 'type' => 'imap', 'autocreate' => true, - 'user' => $imap_servers[0]['user'], - 'server' => $imap_servers[0]['server'], - ); + 'user' => $imap_server['user'], + 'server' => $imap_server['server'], + )); } } - public function load_legacy($hmod) { - $profiles = array(); + public static function loadLegacy($hmod) { if ($hmod->module_is_supported('imap')) { foreach (Hm_IMAP_List::dump() as $id => $server) { $profile = $hmod->user_config->get('profile_imap_'.$server['server'].'_'.$server['user'], array( 'profile_default' => false, 'profile_name' => '', 'profile_address' => '', 'profile_replyto' => '', 'profile_smtp' => '', 'profile_sig' => '')); - if (!$profile['profile_name']) { + if (! $profile['profile_name']) { continue; } - $profiles[] = array( + self::add(array( 'default' => $profile['profile_default'], 'name' => $profile['profile_name'], 'address' => array_key_exists('profile_address', $profile) ? $profile['profile_address'] : '', @@ -116,37 +103,8 @@ public function load_legacy($hmod) { 'type' => 'imap', 'user' => $server['user'], 'server' => $server['server'], - ); + )); } } - $this->data = $profiles; - } - - public function edit($id, $data) { - if (array_key_exists($id, $this->data)) { - $this->data[$id] = $data; - return true; - } - return false; - } - - public function del($id) { - if (array_key_exists($id, $this->data)) { - unset($this->data[$id]); - return true; - } - return false; - - } - - public function get($id) { - if (array_key_exists($id, $this->data)) { - return $this->data[$id]; - } - return false; - } - - public function list_all() { - return $this->data; } } diff --git a/modules/profiles/modules.php b/modules/profiles/modules.php index f27082d4bc..9924683fc4 100644 --- a/modules/profiles/modules.php +++ b/modules/profiles/modules.php @@ -43,18 +43,15 @@ public function process() { */ class Hm_Handler_compose_profile_data extends Hm_Handler_Module { public function process() { - $profiles = new Hm_Profiles($this); + Hm_Profiles::init($this); $compose_profiles = array(); - $all_profiles = array(); - foreach ($profiles->list_all() as $id => $vals) { - $vals['id'] = $id; - if ($vals['smtp_id'] !== false && $vals['smtp_id'] !== '') { + foreach (Hm_Profiles::getAll() as $id => $vals) { + if (! empty($vals['smtp_id'])) { $compose_profiles[] = $vals; } - $all_profiles[] = $vals; } $this->out('compose_profiles', $compose_profiles); - $this->out('profiles', $all_profiles); + $this->out('profiles', Hm_Profiles::getAll()); } } @@ -68,12 +65,12 @@ public function process() { return; } - if (($profile = $this->repositories->profiles->findById($form['profile_id']))) { + if (($profile = Hm_Profiles::get($form['profile_id']))) { if (array_key_exists('autocreate', $profile)) { Hm_Msgs::add('ERRAutomatically created profile cannot be deleted'); return; } - $this->repositories->profiles->delete($form['profile_id']); + Hm_Profiles::del($form['profile_id']); Hm_Msgs::add('Profile Deleted'); } else { Hm_Msgs::add('ERRProfile ID not found'); @@ -126,15 +123,16 @@ public function process() { 'user' => $user, 'type' => 'imap' ); - if ($this->repositories->profiles->findById($form['profile_id'])) { + if (Hm_Profiles::get($form['profile_id'])) { $profile['id'] = $form['profile_id']; - $this->repositories->profiles->save($profile); + Hm_Profiles::edit($form['profile_id'], $profile); + } else { + Hm_Profiles::add($profile); } if ($default) { - $this->repositories->profiles->setDefault($form['profile_id']); + Hm_Profiles::setDefault($form['profile_id']); } - $this->repositories->profiles->save($profile); } } @@ -143,8 +141,8 @@ public function process() { */ class Hm_Handler_profile_data extends Hm_Handler_Module { public function process() { - #$profiles = new Hm_Profiles($this); - $this->out('profiles', $this->repositories->profiles->getAll()); + Hm_Profiles::init($this); + $this->out('profiles', Hm_Profiles::getAll()); } } diff --git a/modules/profiles/setup.php b/modules/profiles/setup.php index 1f229fe327..3851bce14d 100644 --- a/modules/profiles/setup.php +++ b/modules/profiles/setup.php @@ -32,7 +32,7 @@ 'profile_replyto' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'profile_smtp' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'profile_imap' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, - 'profile_default' => FILTER_VALIDATE_INT, + 'profile_default' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'profile_address' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'profile_sig' => FILTER_UNSAFE_RAW, 'profile_delete' => FILTER_SANITIZE_FULL_SPECIAL_CHARS diff --git a/modules/sievefilters/setup.php b/modules/sievefilters/setup.php index 5f77f3d802..abfd01f746 100644 --- a/modules/sievefilters/setup.php +++ b/modules/sievefilters/setup.php @@ -141,7 +141,7 @@ 'actions_json' => FILTER_UNSAFE_RAW, 'filter_test_type' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'imap_msg_uid' => FILTER_VALIDATE_INT, - 'imap_server_id' => FILTER_VALIDATE_INT, + 'imap_server_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'folder' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'sender' => FILTER_UNSAFE_RAW, 'selected_behaviour' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, diff --git a/modules/smtp/hm-smtp.php b/modules/smtp/hm-smtp.php index 806655c271..e4a89e4bf6 100644 --- a/modules/smtp/hm-smtp.php +++ b/modules/smtp/hm-smtp.php @@ -14,6 +14,10 @@ class Hm_SMTP_List { use Hm_Server_List; + public static function init($user_config, $session) { + self::initRepo('smtp_servers', $user_config, $session, self::$server_list); + } + public static function service_connect($id, $server, $user, $pass, $cache=false) { $config = array( 'id' => $id, diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index eb466033a6..cbbf3acafc 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -303,13 +303,8 @@ public function process() { */ class Hm_Handler_load_smtp_servers_from_config extends Hm_Handler_Module { public function process() { - $servers = $this->user_config->get('smtp_servers', array()); - $index = 0; - foreach ($servers as $server) { - Hm_SMTP_List::add( $server, $index ); - $index++; - } - if (count($servers) == 0 && $this->page == 'compose') { + Hm_SMTP_List::init($this->user_config, $this->session); + if (Hm_SMTP_List::count() == 0 && $this->page == 'compose') { Hm_Msgs::add('ERRYou need at least one configured SMTP server to send outbound messages'); } $draft = array(); @@ -388,8 +383,7 @@ public function process() { $tls = true; } if ($con = @fsockopen($form['new_smtp_address'], $form['new_smtp_port'], $errno, $errstr, 2)) { - Hm_SMTP_List::add( array( - 'id' => uniqid(), + Hm_SMTP_List::add(array( 'name' => $form['new_smtp_name'], 'server' => $form['new_smtp_address'], 'port' => $form['new_smtp_port'], @@ -414,24 +408,8 @@ public function process() { * @subpackage smtp/handler */ class Hm_Handler_add_smtp_servers_to_page_data extends Hm_Handler_Module { - - private function generateId($servers) { - $changed = false; - foreach ($servers as $index => $server) { - if (!array_key_exists('id', $server)) { - $servers[$index]['id'] = uniqid(); - $changed = true; - } - } - if ($changed) { - $this->session->record_unsaved('SMTP server ID updated'); - } - return $servers; - } - public function process() { $servers = Hm_SMTP_List::dump(); - $servers = $this->generateId($servers); $this->out('smtp_servers', $servers); $this->out('compose_drafts', $this->session->get('compose_drafts', array())); } @@ -441,25 +419,8 @@ public function process() { * @subpackage smtp/handler */ class Hm_Handler_save_smtp_servers extends Hm_Handler_Module { - - private function generateId($servers) { - $changed = false; - foreach ($servers as $index => $server) { - if (!array_key_exists('id', $server)) { - $servers[$index]['id'] = uniqid(); - $changed = true; - } - } - if ($changed) { - $this->session->record_unsaved('SMTP server ID updated'); - } - return $servers; - } - public function process() { - $servers = Hm_SMTP_List::dump(false, true); - $servers = $this->generateId($servers); - $this->user_config->set('smtp_servers', $servers); + Hm_SMTP_List::save(); } } @@ -527,7 +488,6 @@ public function process() { if ($res) { $this->out('deleted_server_id', $form['smtp_server_id']); Hm_Msgs::add('Server deleted'); - $this->session->record_unsaved('SMTP server deleted'); } } } @@ -548,10 +508,8 @@ public function process() { $results = smtp_refresh_oauth2_token($smtp_details, $this->config); if (!empty($results)) { if (Hm_SMTP_List::update_oauth2_token($form['smtp_server_id'], $results[1], $results[0])) { - Hm_Debug::add(sprintf('Oauth2 token refreshed for SMTP server id %d', $form['smtp_server_id'])); - $servers = Hm_SMTP_List::dump(false, true); - $this->user_config->set('smtp_servers', $servers); - $this->session->set('user_data', $this->user_config->dump()); + Hm_Debug::add(sprintf('Oauth2 token refreshed for SMTP server id %s', $form['smtp_server_id'])); + Hm_SMTP_List::save(); } } } @@ -1988,10 +1946,8 @@ function smtp_refresh_oauth2_token_on_send($smtp_details, $mod, $smtp_id) { $results = smtp_refresh_oauth2_token($smtp_details, $mod->config); if (!empty($results)) { if (Hm_SMTP_List::update_oauth2_token($smtp_id, $results[1], $results[0])) { - Hm_Debug::add(sprintf('Oauth2 token refreshed for SMTP server id %d', $smtp_id)); - $servers = Hm_SMTP_List::dump(false, true); - $mod->user_config->set('smtp_servers', $servers); - $mod->session->set('user_data', $mod->user_config->dump()); + Hm_Debug::add(sprintf('Oauth2 token refreshed for SMTP server id %s', $smtp_id)); + Hm_SMTP_List::save(); } } } @@ -2046,9 +2002,9 @@ function repopulate_compose_form($draft, $handler_mod) { function server_from_compose_smtp_id($id) { $pos = strpos($id, '.'); if ($pos === false) { - return intval($id); + return $id; } - return intval(substr($id, 0, $pos)); + return substr($id, 0, $pos); }} /** @@ -2115,10 +2071,7 @@ function default_smtp_server($user_config, $session, $request, $config, $user, $ } $smtp_port = $config->get('default_smtp_port', 465); $smtp_tls = $config->get('default_smtp_tls', true); - $servers = $user_config->get('smtp_servers', array()); - foreach ($servers as $index => $server) { - Hm_SMTP_List::add($server, $server['id']); - } + Hm_SMTP_List::init($user_config, $session); $attributes = array( 'name' => $config->get('default_smtp_name', 'Default'), 'default' => true, @@ -2132,10 +2085,6 @@ function default_smtp_server($user_config, $session, $request, $config, $user, $ $attributes['no_auth'] = true; } Hm_SMTP_List::add($attributes); - $smtp_servers = Hm_SMTP_List::dump(false, true); - $user_config->set('smtp_servers', $smtp_servers); - $user_data = $user_config->dump(); - $session->set('user_data', $user_data); Hm_Debug::add('Default SMTP server added'); }} diff --git a/modules/smtp/setup.php b/modules/smtp/setup.php index c5c7df4c70..06b7a043e6 100644 --- a/modules/smtp/setup.php +++ b/modules/smtp/setup.php @@ -115,7 +115,7 @@ 'reply' => FILTER_VALIDATE_INT, 'reply_all' => FILTER_VALIDATE_INT, 'forward' => FILTER_VALIDATE_INT, - 'draft_id' => FILTER_VALIDATE_INT, + 'draft_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'hm_ajax_hook' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'compose_to' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'mailto_uri' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, @@ -134,7 +134,7 @@ 'allowed_output' => array( 'file_details' => array(FILTER_UNSAFE_RAW, false), 'draft_subject' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), - 'draft_id' => array(FILTER_VALIDATE_INT, false), + 'draft_id' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'profile_value' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), 'msg_sent_and_archived' => array(FILTER_VALIDATE_BOOLEAN, false), 'sent_msg_id' => array(FILTER_VALIDATE_BOOLEAN, false), @@ -153,7 +153,7 @@ 'smtp_delete' => FILTER_VALIDATE_INT, 'smtp_send' => FILTER_VALIDATE_INT, 'submit_smtp_server' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, - 'smtp_server_id' => FILTER_VALIDATE_INT, + 'smtp_server_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'smtp_user' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'smtp_pass' => FILTER_UNSAFE_RAW, 'delete_uploaded_files' => FILTER_VALIDATE_BOOLEAN, @@ -167,7 +167,7 @@ 'compose_bcc' => FILTER_UNSAFE_RAW, 'compose_smtp_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'compose_delivery_receipt' => FILTER_VALIDATE_BOOLEAN, - 'draft_id' => FILTER_VALIDATE_INT, + 'draft_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'draft_body' => FILTER_UNSAFE_RAW, 'draft_subject' => FILTER_UNSAFE_RAW, 'draft_to' => FILTER_UNSAFE_RAW, From 9abc74592762c701f7fe5d6e6605831ef974c108 Mon Sep 17 00:00:00 2001 From: Victor Emanouilov Date: Thu, 15 Feb 2024 16:13:26 +0200 Subject: [PATCH 08/12] fix tests after repository ID changes and bootstrap switch --- lib/repository.php | 1 + lib/servers.php | 2 +- scripts/commit_check.sh | 3 +- tests/phpunit/bootstrap.php | 5 + tests/phpunit/helpers.php | 1 + tests/phpunit/modules/core/functions.php | 10 +- .../modules/core/message_functions.php | 2 +- .../modules/core/message_list_functions.php | 6 +- tests/phpunit/modules/core/modules.php | 186 ++++++++++++++---- tests/phpunit/servers.php | 78 ++++---- tests/phpunit/stubs.php | 3 + 11 files changed, 215 insertions(+), 82 deletions(-) diff --git a/lib/repository.php b/lib/repository.php index c690e54afd..c22684e5f4 100644 --- a/lib/repository.php +++ b/lib/repository.php @@ -35,6 +35,7 @@ public static function add($entity, $save = true) { if ($save) { self::save(); } + return $entity['id']; } public static function edit($id, $entity) { diff --git a/lib/servers.php b/lib/servers.php index c15bf91be8..e40cb7225c 100644 --- a/lib/servers.php +++ b/lib/servers.php @@ -193,7 +193,7 @@ public static function init($name, $user_config) { public static function add($atts) { $atts['object'] = false; $atts['connected'] = false; - self::repo_add($atts); + return self::repo_add($atts); } /** diff --git a/scripts/commit_check.sh b/scripts/commit_check.sh index aa2babad27..b5817552fc 100755 --- a/scripts/commit_check.sh +++ b/scripts/commit_check.sh @@ -42,6 +42,7 @@ php_check() { find . -name "*.php" -print \ | grep -v .autoload-legacy.php \ | grep -v PhpCsFixer.php \ + | grep -v ./vendor \ | xargs -L 1 php -l err_condition } @@ -49,7 +50,7 @@ php_check() { # syntax check on all javascript files js_check() { echo; echo -e "$YELLOW JS CHECK $END"; echo - find . -name "*.js" \ + find . -name "*.js" | grep -v ./vendor | grep -v ./third_party \ | while read fname; do echo $fname; acorn --ecma2020 --silent "$fname"; if [[ $? != 0 ]]; diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php index 9cab67ed47..f7cb35b36d 100644 --- a/tests/phpunit/bootstrap.php +++ b/tests/phpunit/bootstrap.php @@ -28,4 +28,9 @@ /* get the stubs */ require APP_PATH.'tests/phpunit/stubs.php'; +$mock_config = new Hm_Mock_Config(); +$user_config = new Hm_User_Config_File($mock_config); +$session = new Hm_PHP_Session($mock_config, 'Hm_Auth_DB'); +Hm_Server_Wrapper::init($user_config, $session); + ?> diff --git a/tests/phpunit/helpers.php b/tests/phpunit/helpers.php index dcf8fe8d73..8bebd7ce12 100644 --- a/tests/phpunit/helpers.php +++ b/tests/phpunit/helpers.php @@ -72,6 +72,7 @@ public function prep() { } Hm_Handler_Modules::add('test', $this->mod, false, false, false, true, $this->set); $this->module_exec->handler_response = $this->input; + Hm_Server_Wrapper::init($this->module_exec->user_config, $this->ses_obj); } public function run_only() { $this->module_exec->run_handler_modules($this->req_obj, $this->ses_obj, 'test'); diff --git a/tests/phpunit/modules/core/functions.php b/tests/phpunit/modules/core/functions.php index a9fa342bc7..65964270fd 100644 --- a/tests/phpunit/modules/core/functions.php +++ b/tests/phpunit/modules/core/functions.php @@ -201,11 +201,11 @@ public function test_merge_folder_list_details() { * @runInSeparateProcess */ public function test_in_server_list() { - Hm_Server_Wrapper::add(array('user' => 'testuser', 'pass' => 'testpass', 'name' => 'test2', 'server' => 'test2', 'port' => 0, 'tls' => 1), 0); - $this->assertFalse(in_server_list('Hm_Server_Wrapper', 0, 'foo')); - $this->assertFalse(in_server_list('Hm_Server_Wrapper', 1, 'foo')); - Hm_Server_Wrapper::add(array('user' => 'testuser', 'pass' => 'testpass', 'name' => 'test2', 'server' => 'test2', 'port' => 0, 'tls' => 1), 1); - $this->assertTrue(in_server_list('Hm_Server_Wrapper', 1, 'testuser')); + Hm_Server_Wrapper::add(array('user' => 'testuser', 'pass' => 'testpass', 'name' => 'test2', 'server' => 'test2', 'port' => 0, 'tls' => 1, 'id' => 'a0')); + $this->assertFalse(in_server_list('Hm_Server_Wrapper', 'a0', 'foo')); + $this->assertFalse(in_server_list('Hm_Server_Wrapper', 'a1', 'foo')); + Hm_Server_Wrapper::add(array('user' => 'testuser', 'pass' => 'testpass', 'name' => 'test2', 'server' => 'test2', 'port' => 0, 'tls' => 1, 'id' => 'a1')); + $this->assertTrue(in_server_list('Hm_Server_Wrapper', 'a1', 'testuser')); } /** * @preserveGlobalState disabled diff --git a/tests/phpunit/modules/core/message_functions.php b/tests/phpunit/modules/core/message_functions.php index 5c6895c925..ca81027da1 100644 --- a/tests/phpunit/modules/core/message_functions.php +++ b/tests/phpunit/modules/core/message_functions.php @@ -16,7 +16,7 @@ public function test_format_msg_html() { $test = 'foo'; $this->assertEquals('foo', format_msg_html($test)); $test = ''; - $this->assertEquals('', format_msg_html($test)); + $this->assertEquals('', format_msg_html($test)); $test ='foobar'; $this->assertEquals('foobar', format_msg_html($test)); } diff --git a/tests/phpunit/modules/core/message_list_functions.php b/tests/phpunit/modules/core/message_list_functions.php index 5dc21c0fdc..6f03c14810 100644 --- a/tests/phpunit/modules/core/message_list_functions.php +++ b/tests/phpunit/modules/core/message_list_functions.php @@ -107,7 +107,7 @@ public function test_icon_callback() { */ public function test_message_controls() { $mod = new Hm_Output_Test(array('msg_controls_extra' => 'foo', 'foo' => 'bar', 'bar' => 'foo'), array('bar')); - $this->assertEquals('', message_controls($mod)); + $this->assertEquals('', message_controls($mod)); } /** * @preserveGlobalState disabled @@ -132,7 +132,7 @@ public function test_list_sources() { * @runInSeparateProcess */ public function test_list_controls() { - $this->assertEquals('
    foobazbar
    + $this->assertEquals('
    foobazbar
    foobazbar
    @@ -172,7 +172,7 @@ public function test_build_page_links() { $this->assertEquals(' 1 ... 4 5 6 7 8 9 10 11 12 13 14 ... 100 ', build_page_links(10, 10, 1000, '/')); $this->assertEquals('', build_page_links(10, 1, 10, '/')); $this->assertEquals(' 1 2 3 4 5 6 7 8 9 10 ', build_page_links(10, 1, 100, '/', true, true)); - $this->assertEquals('← 1 2 3 →', build_page_links(10, 1, 30, '/', true, true, "cypht")); + $this->assertEquals(' 1 2 3 ', build_page_links(10, 1, 30, '/', true, true, "cypht")); } } ?> diff --git a/tests/phpunit/modules/core/modules.php b/tests/phpunit/modules/core/modules.php index cfe39cdccc..902365bee7 100644 --- a/tests/phpunit/modules/core/modules.php +++ b/tests/phpunit/modules/core/modules.php @@ -27,11 +27,13 @@ public function test_process_pw_update() { $test->run(); $this->assertEquals(array(), Hm_Msgs::get()); - $test->post = array('server_pw_id' => 0, 'password' => 'foo'); + $test->post = array('server_pw_id' => 'a1', 'password' => 'foo'); $test->run(); $this->assertEquals(array(), Hm_Msgs::get()); - $test->input = array('missing_pw_servers' => array(0 => array('id' => 0, 'type' => 'SMTP'))); + Hm_SMTP_List::add(array('user' => 'testuser', 'nopass' => 1, 'name' => 'test', 'server' => 'test', 'port' => 0, 'tls' => 1, 'id' => 'a1')); + + $test->input = array('missing_pw_servers' => array('a1' => array('id' => 'a1', 'type' => 'SMTP'))); $res = $test->run(); $this->assertEquals(array('ERRUnable to authenticate to the SMTP server'), Hm_Msgs::get()); $this->assertFalse($res->handler_response['connect_status']); @@ -43,7 +45,9 @@ public function test_process_pw_update() { $this->assertTrue($res->handler_response['connect_status']); Hm_Msgs::flush(); - $test->input = array('missing_pw_servers' => array(0 => array('id' => 0, 'type' => 'IMAP'))); + Hm_IMAP_List::add(array('user' => 'testuser', 'nopass' => 1, 'name' => 'test', 'server' => 'test', 'port' => 0, 'tls' => 1, 'id' => 'a1')); + + $test->input = array('missing_pw_servers' => array('a1' => array('id' => 'a1', 'type' => 'IMAP'))); $res = $test->run(); $this->assertEquals(array('ERRUnable to authenticate to the IMAP server'), Hm_Msgs::get()); $this->assertFalse($res->handler_response['connect_status']); @@ -483,7 +487,7 @@ public function test_logout() { $test->prep(); $test->ses_obj->auth_state = true; $test->run_only(); - $this->assertEquals(array('Saved user data on logout', 'Session destroyed on logout'), Hm_Msgs::get()); + $this->assertEquals(array('Saved user data on logout, Session destroyed on logout'), Hm_Msgs::get()); Hm_Msgs::flush(); $test->post = array('save_and_logout' => true); @@ -576,7 +580,7 @@ public function test_search_from_folder_list() { public function test_search_content_start() { $test = new Output_Test('search_content_start', 'core'); $res = $test->run(); - $this->assertEquals(array('
    Search'), $res->output_response); + $this->assertEquals(array('
    Search'), $res->output_response); } /** * @preserveGlobalState disabled @@ -627,10 +631,10 @@ public function test_search_form_content() { public function test_search_form_end() { $test = new Output_Test('search_form_end', 'core'); $res = $test->run(); - $this->assertEquals(array('
    RefreshSources
    + $this->assertEquals(array('
    -
    RefreshSources
    +
    Sources
    '), $res->output_response); } /** @@ -691,7 +695,7 @@ public function test_fancy_login_start() { $test->handler_response = array('fancy_login_allowed' => true); $res = $test->run(); $this->assertEquals(array('