diff --git a/language/az.php b/language/az.php index bfe68921a8..1be35d4143 100755 --- a/language/az.php +++ b/language/az.php @@ -583,7 +583,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'qoşmalar,fayl,qoşma,qoşulub,qoşulur,qapalı,CV,qoşma məktub' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'qoşmalar,fayl,qoşma,qoşulub,qoşulur,qapalı,CV,qoşma məktub', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/de.php b/language/de.php index a19653bdd9..afbd3bf954 100755 --- a/language/de.php +++ b/language/de.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'anbei,im anhang,siehe anhang,angehängt,angefügt,beigefügt,beiliegend' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'anbei,im anhang,siehe anhang,angehängt,angefügt,beigefügt,beiliegend', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/en.php b/language/en.php index 68961c99f6..a62e8bbaed 100755 --- a/language/en.php +++ b/language/en.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false, + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/es.php b/language/es.php index 735d37ea6b..8c3925ccab 100755 --- a/language/es.php +++ b/language/es.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false, + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/et.php b/language/et.php index 6a045bcb00..247c8e7ec6 100755 --- a/language/et.php +++ b/language/et.php @@ -588,7 +588,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false, + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/fa.php b/language/fa.php index d035327906..8ce0422865 100755 --- a/language/fa.php +++ b/language/fa.php @@ -632,7 +632,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'ضمیمه،فایل،ضمیمه کردن،ضمیمه شده،در حال ضمیمه کردن، الصاق شده،CV،عنوان نامه' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'ضمیمه،فایل،ضمیمه کردن،ضمیمه شده،در حال ضمیمه کردن، الصاق شده،CV،عنوان نامه', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/fr.php b/language/fr.php index cf081f33df..00f7283ca5 100755 --- a/language/fr.php +++ b/language/fr.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => 'Échec de la connexion au serveur Sieve', 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'pièce jointe,fichier joint,fichier,joindre,joins,joint,attaché,inclus,ci-inclus,CV,lettre d’accompagnement,PJ,P.J' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'pièce jointe,fichier joint,fichier,joindre,joins,joint,attaché,inclus,ci-inclus,CV,lettre d’accompagnement,PJ,P.J', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/hu.php b/language/hu.php index a549094130..e3406598bc 100755 --- a/language/hu.php +++ b/language/hu.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'csatolmány,file,csatolás,csatolt,csatolni,közrezárt,CV,kisérőlevél' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'csatolmány,file,csatolás,csatolt,csatolni,közrezárt,CV,kisérőlevél', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/id.php b/language/id.php index 0b35d766c1..088ab5d85b 100755 --- a/language/id.php +++ b/language/id.php @@ -587,7 +587,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'lampiran,file,terlampir,dilampirkan,melampirkan,lampiran tertutup,CV,sampul surat' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'lampiran,file,terlampir,dilampirkan,melampirkan,lampiran tertutup,CV,sampul surat', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/it.php b/language/it.php index 2744947cc1..f4fa424ee5 100755 --- a/language/it.php +++ b/language/it.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'allegato,allegati,allegata,allegate,allega,allego,alleghi,attaccato,file,attachment,attach' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'allegato,allegati,allegata,allegate,allega,allego,alleghi,attaccato,file,attachment,attach', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/ja.php b/language/ja.php index 80d44b363d..a1d3be83fb 100755 --- a/language/ja.php +++ b/language/ja.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => '添付,ファイル,添付ファイル,同封,添え状' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => '添付,ファイル,添付ファイル,同封,添え状', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/nl.php b/language/nl.php index 97aabe6b91..0d9b70fbd1 100755 --- a/language/nl.php +++ b/language/nl.php @@ -580,7 +580,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false, + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/pt-BR.php b/language/pt-BR.php index 06993868e0..bab7d2844d 100755 --- a/language/pt-BR.php +++ b/language/pt-BR.php @@ -579,7 +579,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false, + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/ro.php b/language/ro.php index 30fbd0935e..7baa011f61 100755 --- a/language/ro.php +++ b/language/ro.php @@ -579,7 +579,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'atașament,atasament,atas,atasat,ataș,attach,fisier,fișier,attach,atach,attache' + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => 'atașament,atasament,atas,atasat,ataș,attach,fisier,fișier,attach,atach,attache', + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/ru.php b/language/ru.php index cf5576df16..7dc9f3f54b 100755 --- a/language/ru.php +++ b/language/ru.php @@ -581,7 +581,12 @@ 'Connection To Sieve Server Failed' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false, + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); ?> diff --git a/language/zh-Hans.php b/language/zh-Hans.php index 922b8f8f09..149ed6f917 100644 --- a/language/zh-Hans.php +++ b/language/zh-Hans.php @@ -578,5 +578,10 @@ 'Sieve server capabilities' => false, 'Warn for unsaved changes' => false, 'We couldn\'t find the attachment you referred to. Please confirm if you attached it or provide the details again.' => false, - 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false + 'attachment,file,attach,attached,attaching,enclosed,CV,cover letter' => false, + 'Automatically add outgoing email addresses' => false, + 'Trusted Senders' => false, + 'Collected Recipients' => false, + 'Personal Addresses' => false, + 'Contact Group' => false, ); diff --git a/modules/contacts/modules.php b/modules/contacts/modules.php index ddb70162f6..5e2d011579 100644 --- a/modules/contacts/modules.php +++ b/modules/contacts/modules.php @@ -10,6 +10,68 @@ require APP_PATH.'modules/contacts/hm-contacts.php'; +/** + * @subpackage contacts/handler + */ +class Hm_Handler_process_contact_auto_collect_setting extends Hm_Handler_Module { + public function process() { + function contact_auto_collect_callback($val) { + return $val; + } + process_site_setting('contact_auto_collect', $this, 'contact_auto_collect_callback', false, true); + } +} + +/** + * @subpackage contacts/handler + */ +class Hm_Handler_store_contact_message extends Hm_Handler_Module { + public function process() { + if ($this->get('collect_contacts', false)) { + $addresses = process_address_fld($this->request->post['compose_to']); + $contacts = $this->get('contact_store'); + $contact_list = $contacts->getAll(); + $existingEmails = array_column($contact_list, 'email_address'); + // Extract email addresses from the new format of $addresses + $newEmails = array_column($addresses, 'email'); + if (!empty($newEmails)) { + $newContacts = array_filter($newEmails, function ($email) use ($existingEmails) { + return !in_array($email, $existingEmails); + }); + + if (!empty($newContacts)) { + $newContacts = array_map(function ($email) { + return ['source' => 'local', 'email_address' => $email, 'display_name' => $email, 'group' => $this->trans('Collected Recipients')]; + }, $newContacts); + $contacts->add_contact($newContacts[0]); + $this->session->record_unsaved('Contact Added'); + Hm_Msgs::add('Contact Added'); + } + } + } + } +} + +/** + * @subpackage contacts/handler + */ +class Hm_Handler_store_contact_allow_images extends Hm_Handler_Module { + public function process() { + if ($this->get('imap_allow_images', false) && $this->get('collect_contacts', false)) { + $email = str_replace(['<', '>'], '', $this->get('collected_contact_email', '')); + $name = $this->get('collected_contact_name', ''); + $contacts = $this->get('contact_store'); + $contact_list = $contacts->getAll(); + $existingEmails = array_column($contact_list, 'email_address'); + if (!in_array($email, $existingEmails)) { + $contacts->add_contact(['source' => 'local', 'email_address' => $email, 'display_name' => $name, 'group' => $this->trans('Trusted Senders')]); + $this->session->record_unsaved('Contact Added'); + Hm_Msgs::add('Contact Added'); + } + } + } +} + /** * @subpackage contacts/handler */ @@ -112,6 +174,26 @@ public function process() { } } +/** + * @subpackage contacts/output + */ +class Hm_Output_contact_auto_collect_setting extends Hm_Output_Module { + protected function output() { + $checked = ''; + $settings = $this->get('user_settings', array()); + $reset = ''; + if (array_key_exists('contact_auto_collect', $settings) && $settings['contact_auto_collect']) { + $checked = ' checked="checked"'; + } else { + $reset = 'Refresh'; + } + + return '' . + '' . $reset . ''; + } +} + /** * @subpackage contacts/output */ @@ -218,12 +300,44 @@ protected function output() { } $res .= '
'.$this->trans('Contacts').'
'; + + $contacts = $this->get('contact_store'); $editable = $this->get('contact_edit', array()); + + $res = '
'; + $tabIndex = 1; + $contactGroups = []; + if ($contacts) { - $total = count($contacts->dump()); - $contacts->sort('email_address'); foreach ($contacts->page($current_page, $per_page) as $id => $contact) { + $group = $contact->value('group'); + if (!$group || empty($group)) { + $group = 'Personal Addresses'; // Set the group to "Personal Addresses" when it's null or empty + } + if (!array_key_exists($group, $contactGroups)) { + $contactGroups[$group] = []; + } + $contactGroups[$group][] = $contact; + } + } + + foreach ($contactGroups as $group => $groupContacts) { + $res .= ''; + $res .= ''; + + $tabIndex++; + } + $tabIndex = 1; + $res .= '
'; + $res .= ''; + + $res .= ''; + return $res; } } @@ -339,6 +466,7 @@ function build_contact_detail($output_mod, $contact, $id) { return $res; }} + /** * @subpackage contacts/functions */ diff --git a/modules/contacts/setup.php b/modules/contacts/setup.php index 48e84b8d5d..5e7a34319e 100644 --- a/modules/contacts/setup.php +++ b/modules/contacts/setup.php @@ -14,15 +14,19 @@ add_output('contacts', 'contacts_content_start', true, 'contacts', 'content_section_start', 'after'); add_output('contacts', 'contacts_list', true, 'contacts', 'contacts_content_start', 'after'); add_output('contacts', 'contacts_content_end', true, 'contacts', 'contacts_list', 'after'); +add_output('settings', 'contact_auto_collect_setting', true, 'contacts', 'max_google_contacts_number', 'after'); add_output('ajax_hm_folders', 'contacts_page_link', true, 'contacts', 'logout_menu_item', 'before'); add_handler('compose', 'load_contacts', true, 'contacts', 'load_user_data', 'after'); add_handler('compose', 'process_send_to_contact', true, 'contacts', 'save_user_data', 'before'); +add_handler('compose', 'load_contacts', true, 'contacts', 'process_compose_form_submit', 'after'); +add_handler('compose', 'store_contact_message', true, 'contacts', 'load_contacts', 'after'); add_handler('ajax_imap_message_content', 'load_contacts', true, 'contacts', 'load_user_data', 'after'); add_handler('ajax_imap_message_content', 'find_message_contacts', true, 'contacts', 'imap_message_content', 'after'); add_output('ajax_imap_message_content', 'add_message_contacts', true, 'contacts', 'filter_message_headers', 'after'); +add_handler('ajax_imap_message_content', 'store_contact_allow_images', true, 'contacts', 'imap_message_content', 'after'); setup_base_ajax_page('ajax_add_contact', 'core'); add_handler('ajax_add_contact', 'load_contacts', true, 'contacts', 'load_user_data', 'after'); @@ -41,6 +45,7 @@ setup_base_page('export_contact', 'core'); add_handler('export_contact', 'load_contacts', true, 'contacts', 'load_user_data', 'after'); add_handler('export_contact', 'process_export_contacts', true, 'contacts', 'load_contacts', 'after'); +add_handler('settings', 'process_contact_auto_collect_setting', true, 'contacts', 'date', 'after'); return array( 'allowed_pages' => array( @@ -61,6 +66,17 @@ 'contact_source' => FILTER_DEFAULT, 'contact_type' => FILTER_DEFAULT, 'import_contact' => FILTER_DEFAULT, + 'contact_email' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'contact_name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'contact_phone' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'contact_group' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'contact_id' => FILTER_VALIDATE_INT, + 'contact_value' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'edit_contact' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'add_contact' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'contact_source' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'contact_type' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'contact_auto_collect' => FILTER_VALIDATE_BOOLEAN ), 'allowed_get' => array( 'contact_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, @@ -72,7 +88,11 @@ 'allowed_output' => array( 'contact_deleted' => array(FILTER_VALIDATE_INT, false), 'imported_contact' => array(FILTER_DEFAULT, FILTER_REQUIRE_ARRAY), - 'contact_suggestions' => array(FILTER_DEFAULT, FILTER_REQUIRE_ARRAY) + 'contact_suggestions' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_REQUIRE_ARRAY), + 'collect_contacts' => array(FILTER_VALIDATE_BOOLEAN, false), + 'imap_allow_images' => array(FILTER_VALIDATE_BOOLEAN, false), + 'collected_contact_email' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), + 'collected_contact_name' => array(FILTER_SANITIZE_FULL_SPECIAL_CHARS, false), ), ); diff --git a/modules/contacts/site.css b/modules/contacts/site.css index 32e77aa8bb..13c29774b7 100644 --- a/modules/contacts/site.css +++ b/modules/contacts/site.css @@ -1,3 +1,13 @@ +.add_contact_form input { margin: 5px; margin-left: 0px; } +.add_contact_form { padding-top: 10px; display: block; } +.contact_list { margin-left: 0px; margin-right: 10px; margin-top: 20px; width: 50%; } +.contact_list td { white-space: nowrap; padding-right: 20px; padding-bottom: 5px; vertical-align: -5px; padding-top: 5px; border-bottom: solid 1px #ddd; } +.gmail_contacts { margin-top: 50px; } +.contact_list_title { padding-top: 0px !important; padding-bottom: 10px; } +.show_contact img, .edit_contact img, .send_to_contact img, .delete_contact img { opacity: .5; margin-left: 10px; cursor: pointer; } +.contact_controls { text-align: right; } +.add_contact_row { position: absolute; top: 22px; right: 10px; font-size: 90%; z-index: 100} +.add_contact_row img { opacity: .4; margin-right: 10px; } .add_contact_controls { display: none; } .contact_suggestion { display: block; } .close_autocomplete { float: right; } diff --git a/modules/core/output_modules.php b/modules/core/output_modules.php index fbcef74508..2f8d3e8e96 100644 --- a/modules/core/output_modules.php +++ b/modules/core/output_modules.php @@ -511,6 +511,10 @@ protected function output() { $res .= ''; } } + // load pcss3t.cs only if one of: ['contacts','local_contacts','ldap_contacts','gmail_contacts'] is enabled + if(count(array_intersect(['contacts','local_contacts','ldap_contacts','gmail_contacts'], $mods)) > 0){ + $res .= ''; + } } else { $res .= 'out('msg_attachment_remove_args', $download_args.'&imap_remove_attachment=1'); $this->out('msg_show_args', sprintf("page=message&uid=%s&list_path=imap_%s_%s&imap_show_message=1", $form['imap_msg_uid'], $form['imap_server_id'], $form['folder'])); + if ($this->get('imap_allow_images', false)) { + if ($this->module_is_supported('contacts') && $this->user_config->get('contact_auto_collect_setting', false)) { + $this->out('collect_contacts', true); + $this->out('collected_contact_email', $msg_headers["Return-Path"]); + $this->out('collected_contact_name', $msg_headers["From"]); + } + } + if (!$prefetch) { clear_existing_reply_details($this->session); if ($part == 0) { diff --git a/modules/local_contacts/modules.php b/modules/local_contacts/modules.php index e83331b6ec..cfe1d5fdff 100644 --- a/modules/local_contacts/modules.php +++ b/modules/local_contacts/modules.php @@ -23,7 +23,7 @@ public function process() { if (!empty($addresses)) { $contacts = $this->get('contact_store'); foreach ($addresses as $vals) { - $contacts->add_contact(array('source' => 'local', 'email_address' => $vals['email'], 'display_name' => $vals['name'])); + $contacts->add_contact(array('source' => 'local', 'email_address' => $vals['email'], 'display_name' => $vals['name'], 'group' => isset($vals['contact_group']) ? $vals['contact_group'] : 'Personal Addresses')); } Hm_Msgs::add('Contact Added'); } @@ -59,6 +59,12 @@ public function process() { if (array_key_exists('contact_phone', $this->request->post) && $this->request->post['contact_phone']) { $details['phone_number'] = $this->request->post['contact_phone']; } + if (array_key_exists('contact_group', $this->request->post) && $this->request->post['contact_group']) { + $details['group'] = $this->request->post['contact_group']; + } + else { + $details['group'] = 'Personal Addresses'; + } $contacts->add_contact($details); Hm_Msgs::add('Contact Added'); } @@ -161,6 +167,12 @@ public function process() { if (array_key_exists('contact_phone', $this->request->post)) { $details['phone_number'] = $this->request->post['contact_phone']; } + if (array_key_exists('contact_group', $this->request->post)) { + $details['group'] = $this->request->post['contact_group']; + } + else { + $details['group'] = 'Personal Addresses'; + } if ($contacts->update_contact($form['contact_id'], $details)) { Hm_Msgs::add('Contact Updated'); } @@ -176,7 +188,6 @@ public function process() { if (array_key_exists('contact_source', $this->request->get) && $this->request->get['contact_source'] == 'local' && array_key_exists('contact_type', $this->request->get) && $this->request->get['contact_type'] == 'local' && array_key_exists('contact_id', $this->request->get)) { - $contacts = $this->get('contact_store'); $contact = $contacts->get($this->request->get['contact_id']); if (is_object($contact)) { @@ -221,11 +232,15 @@ protected function output() { if (array_key_exists('phone_number', $current)) { $phone = $current['phone_number']; } - $form_class = 'contact_update_form mt-3'; + if (array_key_exists('group', $current)) { + $group = $current['group']; + } + $form_class = 'contact_update_form mt-3'; $title = $this->trans('Update Local'); $button = ''. ''; } + // var_dump($group);die(); return '
'. ''. '
'. @@ -239,7 +254,14 @@ protected function output() { 'value="'.$this->html_safe($name).'" />
'. ''. '
'.$button.' html_safe($phone).'" />
'. + ''. + '
'. + $button.'
'; } } diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index aa6e134f44..b15f9327d6 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -751,6 +751,9 @@ public function process() { else { Hm_Debug::add(sprintf('Unable to save sent message, no IMAP server found for SMTP server: %s', $smtp_details['server'])); } + if ($this->module_is_supported('contacts') && $this->user_config->get('contact_auto_collect_setting', false)) { + $this->out('collect_contacts', true); + } // Archive replied message if ($form['post_archive']) { diff --git a/scripts/config_gen.php b/scripts/config_gen.php index 6c8e778b2f..df3f350f8a 100644 --- a/scripts/config_gen.php +++ b/scripts/config_gen.php @@ -194,6 +194,12 @@ function get_module_assignments($settings) { $assets[] = sprintf("modules/%s/assets", $mod); } } + // load pcss3t.cs only if one of: ['contacts','local_contacts','ldap_contacts','gmail_contacts'] is enabled + if(count(array_intersect(['contacts','local_contacts','ldap_contacts','gmail_contacts'], $mods)) > 0){ + if (is_readable(sprintf("third_party/contact-group.css", 'third_party'))) { + $css .= file_get_contents(sprintf("third_party/contact-group.css", 'third_party')); + } + } } return array($js, $css, $filters, $assets); } diff --git a/third_party/contact-group.css b/third_party/contact-group.css new file mode 100644 index 0000000000..85dbf184d9 --- /dev/null +++ b/third_party/contact-group.css @@ -0,0 +1,137 @@ +.contact-group { margin: 0;padding: 0;border: 0;outline: none;font-size: 0;text-align: left;padding-top: 15px; } +.contact-group>input { position: absolute;left: -9999px; } +.contact-group>label { position: relative;display: inline-block;margin: 0;padding: 0;border: 0;outline: none;cursor: pointer;transition: all 0.1s;-o-transition: all 0.1s;-ms-transition: all 0.1s;-moz-transition: all 0.1s;-webkit-transition: all 0.1s; } +.contact-group>label i { display: block;float: left;margin: 16px 8px 0 -2px;padding: 0;border: 0;outline: none;font-family: FontAwesome;font-style: normal;font-size: 17px; } +.contact-group>input:checked+label { cursor: default; } +.contact-group>ul { list-style: none;position: relative;display: block;overflow: hidden;margin: 0;padding: 0;border: 0;outline: none;font-size: 13px; } +.contact-group>ul>li { position: absolute;width: 100%;overflow: auto;padding: 20px 0px;box-sizing: border-box;-moz-box-sizing: border-box;opacity: 0;transition: all 0.5s;-o-transition: all 0.5s;-ms-transition: all 0.5s;-moz-transition: all 0.5s;-webkit-transition: all 0.5s; } +.contact-group>.tab-content-first:checked~ul .tab-content-first, +.contact-group>.tab-content-2:checked~ul .tab-content-2, +.contact-group>.tab-content-3:checked~ul .tab-content-3, +.contact-group>.tab-content-4:checked~ul .tab-content-4, +.contact-group>.tab-content-5:checked~ul .tab-content-5, +.contact-group>.tab-content-6:checked~ul .tab-content-6, +.contact-group>.tab-content-7:checked~ul .tab-content-7, +.contact-group>.tab-content-8:checked~ul .tab-content-8, +.contact-group>.tab-content-9:checked~ul .tab-content-9, +.contact-group>.tab-content-last:checked~ul .tab-content-last { z-index: 1;top: 0;left: 0;opacity: 1;-webkit-transform: scale(1, 1);-webkit-transform: rotate(0deg); } +/*----------------------------------------------------------------------------*/ +/* EXTENSIONS */ +/*----------------------------------------------------------------------------*/ +.contact-group-height-auto>ul { height: auto !important;} +.contact-group-height-auto>ul>li { position: static;display: none;height: auto !important; } +.contact-group-height-auto>.tab-content-first:checked~ul .tab-content-first, +.contact-group-height-auto>.tab-content-2:checked~ul .tab-content-2, +.contact-group-height-auto>.tab-content-3:checked~ul .tab-content-3, +.contact-group-height-auto>.tab-content-4:checked~ul .tab-content-4, +.contact-group-height-auto>.tab-content-5:checked~ul .tab-content-5, +.contact-group-height-auto>.tab-content-last:checked~ul .tab-content-last { display: block; } +.contact-group .grid-row { margin-top: 20px;} +.contact-group .grid-row:after { content: '';display: table;clear: both; } +.contact-group .grid-row:first-child { margin-top: 0;} +.contact-group .grid-col { display: block;float: left;margin-left: 2%; } +.contact-group .grid-col:first-child { margin-left: 0;} +.contact-group .grid-col .inner { padding: 10px 0;border-radius: 5px;background: #BDCBE5;text-align: center; } +.contact-group .grid-col-1 { width: 15%; } +.contact-group .grid-col-2 { width: 32%; } +.contact-group .grid-col-3 { width: 49%; } +.contact-group .grid-col-4 { width: 66%; } +.contact-group .grid-col-5 { width: 83%; } +.contact-group .grid-col-offset-1 { margin-left: 19%; } +.contact-group .grid-col-offset-1:first-child { margin-left: 17%; } +.contact-group .grid-col-offset-2 { margin-left: 36%; } +.contact-group .grid-col-offset-2:first-child { margin-left: 34%; } +.contact-group .grid-col-offset-3 { margin-left: 53%; } + +.contact-group .grid-col-offset-3:first-child { margin-left: 51%; } + +.contact-group .grid-col-offset-4 { margin-left: 70%; } + +.contact-group .grid-col-offset-4:first-child { margin-left: 68%; } +.contact-group .grid-col-offset-5:first-child { margin-left: 85%; } + +.contact-group .typography { color: #666; } +.contact-group .typography h1, +.contact-group .typography h2, +.contact-group .typography h3, +.contact-group .typography h4, +.contact-group .typography h5, +.contact-group .typography h6 { margin: 40px 0 0 0; padding: 0; text-align: left; color: #333; } +.contact-group .typography h1 { font-size: 40px; line-height: 60px; text-shadow: 3px 3px rgba(0, 0, 0, 0.1); } +.contact-group .typography h2 { font-size: 32px; line-height: 48px; text-shadow: 2px 2px rgba(0, 0, 0, 0.1); } +.contact-group .typography h3 { font-size: 26px;line-height: 38px;text-shadow: 1px 1px rgba(0, 0, 0, 0.1); } +.contact-group .typography h4 { font-size: 20px;line-height: 30px; } +.contact-group .typography h5 { font-size: 15px;line-height: 23px;text-transform: uppercase; } +.contact-group .typography h6 { font-size: 13px;line-height: 20px;font-weight: 700;text-transform: uppercase; } +.contact-group .typography p { margin: 20px 0 0 0;padding: 0;line-height: 20px;text-align: left; } +.contact-group .typography ul, +.contact-group .typography ol { list-style: none; margin: 20px 0 0 0; padding: 0; } +.contact-group .typography li { position: relative; margin-top: 5px; padding-left: 20px; } +.contact-group .typography li ul,.contact-group .typography li ol { margin-top: 5px; } +.contact-group .typography ul li:before {content: '';position: absolute;top: 8px;left: 0;width: 6px;height: 4px;background: #404040;} +.contact-group .typography ol { counter-reset: list1; } +.contact-group .typography ol>li:before { counter-increment: list1; content: counter(list1)'.'; position: absolute; top: 0; left: 0; } +.contact-group .typography a { text-decoration: underline; color: #008080; } +.contact-group .typography a:hover { text-decoration: none; } +.contact-group .typography .pic { padding: 4px; border: 1px dotted #ccc; } +.contact-group .typography .pic img { display: block; } +.contact-group .typography .pic-right { float: right; margin: 0 0 10px 20px;} +.contact-group .typography .link {text-decoration: underline;color: #008080;cursor: pointer;} +.contact-group .typography .link:hover {text-decoration: none;} +.contact-group .typography h1:first-child,.contact-group .typography h2:first-child,.contact-group .typography h3:first-child,.contact-group .typography h4:first-child,.contact-group .typography h5:first-child,.contact-group .typography h6:first-child,.contact-group .typography p:first-child { margin-top: 0; } +.contact-group .typography .text-center { text-align: center; } +.contact-group .typography .text-right { text-align: right; } +.contact-group-steps>label { cursor: default; } + +/* animation effects */ +.contact-group-effect-scale>ul>li { -webkit-transform: scale(0.1, 0.1); } +.contact-group-effect-rotate>ul>li { -webkit-transform: rotate(180deg); } +.contact-group-effect-slide-top>ul>li { top: -40px; } +.contact-group-effect-slide-right>ul>li { left: 80px; } +.contact-group-effect-slide-bottom>ul>li { top: 40px; } +.contact-group-effect-slide-left>ul>li { left: -80px; } + +/*----------------------------------------------------------------------------*/ +/* LAYOUTS */ +/*----------------------------------------------------------------------------*/ +.contact-group-layout-top-right { text-align: right; } +.contact-group-layout-top-center { text-align: center; } +.contact-group>.right { float: right; } + +/*----------------------------------------------------------------------------*/ +/* RESPONSIVENESS */ +/*----------------------------------------------------------------------------*/ +@media screen and (max-width: 980px) {} +/* phone */ +@media screen and (max-width: 767px) { + .contact-group>label { display: block; } + .contact-group>.right { float: none; } +} +/*----------------------------------------------------------------------------*/ +/* THEMES */ +/*----------------------------------------------------------------------------*/ +.contact-group>label { padding: 0 20px; background: #e5e5e5; font-size: 13px; line-height: 49px; } +.contact-group>label:hover { background: #f2f2f2; } +.contact-group>input:checked+label { background: #f2f2f2; } +.contact-group>ul { background: #fff;text-align: left; } +.contact-group-steps>label:hover { background: #e5e5e5; } + +/* theme 1 */ +.contact-group-theme-1>label { margin: 0 5px 5px 0;border-radius: 5px;background: #fff;box-shadow: 0 2px rgba(0, 0, 0, 0.2);color: #808080;opacity: 0.8; } +.contact-group-theme-1>label:hover { opacity: 1; } +.contact-group-theme-1>input:checked+label { margin-bottom: 0; padding-bottom: 5px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; color: 008080; opacity: 1; } +.contact-group-theme-1>ul { border-radius: 5px; } +.contact-group-theme-1>.tab-content-first:checked~ul { border-top-left-radius: 0; } +@media screen and (max-width: 767px) { + .contact-group-theme-1>label { margin-right: 0 } + .contact-group-theme-1>input:checked+label { margin-bottom: 5px; padding-bottom: 0; border-radius: 5px } + .contact-group-theme-1>.tab-content-first:checked~ul { border-top-left-radius: 5px; } +} + +/*----------------------------------------------------------------------------*/ +/* CUSTOMIZATION */ +/*----------------------------------------------------------------------------*/ + +/* height */ +.contact-group>ul, +.contact-group>ul>li {height: 100vh;} \ No newline at end of file