diff options
author | Hugues Hiegel <root@paranoid> | 2014-08-05 16:46:22 +0200 |
---|---|---|
committer | Hugues Hiegel <root@paranoid> | 2014-08-05 16:46:22 +0200 |
commit | 59478e06c25303a790a0840ab2ac30662c4ef781 (patch) | |
tree | 8d5e964a8f94adaef41efebb0597629f11495c42 /program/steps/addressbook | |
parent | 7c494b677f9e470ee0d32e62cfa8dc709f39e748 (diff) |
c'est la merde..working
Diffstat (limited to 'program/steps/addressbook')
-rw-r--r-- | program/steps/addressbook/copy.inc | 12 | ||||
-rw-r--r-- | program/steps/addressbook/delete.inc | 38 | ||||
-rw-r--r-- | program/steps/addressbook/export.inc | 113 | ||||
-rw-r--r-- | program/steps/addressbook/func.inc | 187 | ||||
-rw-r--r-- | program/steps/addressbook/import.inc | 71 | ||||
-rw-r--r-- | program/steps/addressbook/list.inc | 49 | ||||
-rw-r--r-- | program/steps/addressbook/save.inc | 29 | ||||
-rw-r--r-- | program/steps/addressbook/show.inc | 63 | ||||
-rw-r--r-- | program/steps/addressbook/undo.inc | 25 |
9 files changed, 234 insertions, 353 deletions
diff --git a/program/steps/addressbook/copy.inc b/program/steps/addressbook/copy.inc index d4387194a..480a9b52e 100644 --- a/program/steps/addressbook/copy.inc +++ b/program/steps/addressbook/copy.inc @@ -57,16 +57,10 @@ foreach ($cids as $source => $cid) foreach ($cid as $cid) { $a_record = $CONTACTS->get_record($cid, true); - // avoid copying groups - if ($a_record['_type'] == 'group') - continue; - // Check if contact exists, if so, we'll need it's ID // Note: Some addressbooks allows empty email address field - // @TODO: should we check all email addresses? - $email = $CONTACTS->get_col_values('email', $a_record, true); - if (!empty($email)) - $result = $TARGET->search('email', $email[0], 1, true, true); + if (!empty($a_record['email'])) + $result = $TARGET->search('email', $a_record['email'], 1, true, true); else if (!empty($a_record['name'])) $result = $TARGET->search('name', $a_record['name'], 1, true, true); else @@ -120,7 +114,7 @@ foreach ($cids as $source => $cid) } } -if (!$success) +if ($success == 0) $OUTPUT->show_message($errormsg, 'error'); else $OUTPUT->show_message('copysuccess', 'notice', array('nr' => $success)); diff --git a/program/steps/addressbook/delete.inc b/program/steps/addressbook/delete.inc index 3bb2ef500..56118583c 100644 --- a/program/steps/addressbook/delete.inc +++ b/program/steps/addressbook/delete.inc @@ -68,14 +68,48 @@ foreach ($cids as $source => $cid) $page = isset($_SESSION['page']) ? $_SESSION['page'] : 1; // update saved search after data changed -if (($records = rcmail_search_update(true)) !== false) { +if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) { + $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name'); + $afields = $RCMAIL->config->get('contactlist_fields'); + $search = (array)$_SESSION['search'][$search_request]; + $records = array(); + + // Get records from all sources (refresh search) + foreach ($search as $s => $set) { + $source = $RCMAIL->get_address_book($s); + + // reset page + $source->set_page(1); + $source->set_pagesize(9999); + $source->set_search_set($set); + + // get records + $result = $source->list_records($afields); + + if (!$result->count) { + unset($search[$s]); + continue; + } + + while ($row = $result->next()) { + $row['sourceid'] = $s; + $key = rcube_addressbook::compose_contact_key($row, $sort_col); + $records[$key] = $row; + } + unset($result); + + $search[$s] = $source->get_search_set(); + } + + $_SESSION['search'][$search_request] = $search; + // create resultset object $count = count($records); $first = ($page-1) * $PAGE_SIZE; $result = new rcube_result_set($count, $first); - $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE); // get records from the next page to add to the list + $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE); if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) { // sort the records ksort($records, SORT_LOCALE_STRING); diff --git a/program/steps/addressbook/export.inc b/program/steps/addressbook/export.inc index 1e988feab..11c9ca493 100644 --- a/program/steps/addressbook/export.inc +++ b/program/steps/addressbook/export.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/export.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2008-2013, The Roundcube Dev Team | + | Copyright (C) 2008-2011, The Roundcube Dev Team | | Copyright (C) 2011, Kolab Systems AG | | | | Licensed under the GNU General Public License version 3 or | @@ -21,46 +21,6 @@ +-----------------------------------------------------------------------+ */ - -/** - * Copy contact record properties into a vcard object - */ -function prepare_for_export(&$record, $source = null) -{ - $groups = $source && $source->groups && $source->export_groups ? $source->get_record_groups($record['ID']) : null; - - if (empty($record['vcard'])) { - $vcard = new rcube_vcard(); - if ($source) { - $vcard->extend_fieldmap($source->vcard_map); - } - $vcard->load($record['vcard']); - $vcard->reset(); - - foreach ($record as $key => $values) { - list($field, $section) = explode(':', $key); - foreach ((array)$values as $value) { - if (is_array($value) || @strlen($value)) { - $vcard->set($field, $value, strtoupper($section)); - } - } - } - - // append group names - if ($groups) { - $vcard->set('groups', join(',', $groups), null); - } - - $record['vcard'] = $vcard->export(true); - } - // patch categories to alread existing vcard block - else if ($record['vcard'] && !empty($groups) && !strpos($record['vcard'], 'CATEGORIES:')) { - $vgroups = 'CATEGORIES:' . rcube_vcard::vcard_quote(join(',', $groups)); - $record['vcard'] = str_replace('END:VCARD', $vgroups . rcube_vcard::$eol . 'END:VCARD', $record['vcard']); - } -} - - // Use search result if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) { @@ -80,15 +40,11 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search // get records $result = $source->list_records(); - while ($record = $result->next()) { - // because vcard_map is per-source we need to create vcard here - prepare_for_export($record, $source); - - $record['sourceid'] = $s; - $key = rcube_addressbook::compose_contact_key($record, $sort_col); - $records[$key] = $record; + while ($row = $result->next()) { + $row['sourceid'] = $s; + $key = rcube_addressbook::compose_contact_key($row, $sort_col); + $records[$key] = $row; } - unset($result); } @@ -100,35 +56,6 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search $result = new rcube_result_set($count); $result->records = array_values($records); } -// selected contacts -else if (!empty($_REQUEST['_cid'])) { - $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name'); - $records = array(); - - // Selected contact IDs (with multi-source support) - $cids = rcmail_get_cids(); - - foreach ($cids as $s => $ids) { - $source = $RCMAIL->get_address_book($s); - $result = $source->search('ID', $ids, 1, true, true); - - while ($record = $result->next()) { - // because vcard_map is per-source we need to create vcard here - prepare_for_export($record, $source); - - $record['sourceid'] = $s; - $key = rcube_addressbook::compose_contact_key($record, $sort_col); - $records[$key] = $record; - } - } - - ksort($records, SORT_LOCALE_STRING); - - // create resultset object - $count = count($records); - $result = new rcube_result_set($count); - $result->records = array_values($records); -} // selected directory/group else { $CONTACTS = rcmail_contact_source(null, true); @@ -141,15 +68,33 @@ else { // send downlaod headers header('Content-Type: text/x-vcard; charset='.RCMAIL_CHARSET); -header('Content-Disposition: attachment; filename="contacts.vcf"'); +header('Content-Disposition: attachment; filename="rcube_contacts.vcf"'); while ($result && ($row = $result->next())) { - prepare_for_export($row, $CONTACTS); + // we already have a vcard record + if ($row['vcard'] && $row['name']) { + // fix folding and end-of-line chars + $row['vcard'] = preg_replace('/\r|\n\s+/', '', $row['vcard']); + $row['vcard'] = preg_replace('/\n/', rcube_vcard::$eol, $row['vcard']); + echo rcube_vcard::rfc2425_fold($row['vcard']) . rcube_vcard::$eol; + } + // copy values into vcard object + else { + $vcard = new rcube_vcard(); + $vcard->extend_fieldmap($CONTACTS->vcard_map); + $vcard->load($row['vcard']); + $vcard->reset(); + + foreach ($row as $key => $values) { + list($field, $section) = explode(':', $key); + foreach ((array)$values as $value) { + if (is_array($value) || @strlen($value)) + $vcard->set($field, $value, strtoupper($section)); + } + } - // fix folding and end-of-line chars - $row['vcard'] = preg_replace('/\r|\n\s+/', '', $row['vcard']); - $row['vcard'] = preg_replace('/\n/', rcube_vcard::$eol, $row['vcard']); - echo rcube_vcard::rfc2425_fold($row['vcard']) . rcube_vcard::$eol; + echo $vcard->export(true) . rcube_vcard::$eol; + } } exit; diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc index f94d15338..989b7c1c4 100644 --- a/program/steps/addressbook/func.inc +++ b/program/steps/addressbook/func.inc @@ -183,10 +183,11 @@ function rcmail_directory_list($attrib) $attrib['id'] = 'rcmdirectorylist'; $out = ''; + $local_id = '0'; $jsdata = array(); $line_templ = html::tag('li', array( - 'id' => 'rcmli%s', 'class' => '%s', 'noclose' => true), + 'id' => 'rcmli%s', 'class' => '%s'), html::a(array('href' => '%s', 'rel' => '%s', 'onclick' => "return ".JS_OBJECT_NAME.".command('list','%s',this)"), '%s')); @@ -212,7 +213,7 @@ function rcmail_directory_list($attrib) $name = !empty($source['name']) ? $source['name'] : $id; $out .= sprintf($line_templ, - rcube_utils::html_identifier($id, true), + html_identifier($id), $class_name, Q(rcmail_url(null, array('_source' => $id))), $source['id'], @@ -223,11 +224,10 @@ function rcmail_directory_list($attrib) $groupdata = rcmail_contact_groups($groupdata); $jsdata = $groupdata['jsdata']; $out = $groupdata['out']; - $out .= '</li>'; } $line_templ = html::tag('li', array( - 'id' => 'rcmli%s', 'class' => '%s'), + 'id' => 'rcmliS%s', 'class' => '%s'), html::a(array('href' => '#', 'rel' => 'S%s', 'onclick' => "return ".JS_OBJECT_NAME.".command('listsearch', '%s', this)"), '%s')); @@ -245,17 +245,14 @@ function rcmail_directory_list($attrib) $class_name .= ' ' . $source['class_name']; $out .= sprintf($line_templ, - rcube_utils::html_identifier('S'.$id, true), + html_identifier($id), $class_name, $id, $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id))); } $OUTPUT->set_env('contactgroups', $jsdata); - $OUTPUT->set_env('collapsed_abooks', (string)$RCMAIL->config->get('collapsed_abooks','')); $OUTPUT->add_gui_object('folderlist', $attrib['id']); - $OUTPUT->include_script('treelist.js'); - // add some labels to client $OUTPUT->add_label('deletegroupconfirm', 'groupdeleting', 'addingmember', 'removingmember'); @@ -267,23 +264,19 @@ function rcmail_contact_groups($args) { global $RCMAIL; - $groups_html = ''; $groups = $RCMAIL->get_address_book($args['source'])->list_groups(); if (!empty($groups)) { $line_templ = html::tag('li', array( - 'id' => 'rcmli%s', 'class' => 'contactgroup'), + 'id' => 'rcmliG%s', 'class' => 'contactgroup'), html::a(array('href' => '#', 'rel' => '%s:%s', 'onclick' => "return ".JS_OBJECT_NAME.".command('listgroup',{'source':'%s','id':'%s'},this)"), '%s')); - // append collapse/expand toggle and open a new <ul> - $is_collapsed = strpos($RCMAIL->config->get('collapsed_abooks',''), '&'.rawurlencode($args['source']).'&') !== false; - $args['out'] .= html::div('treetoggle ' . ($is_collapsed ? 'collapsed' : 'expanded'), ' '); - + $jsdata = array(); foreach ($groups as $group) { - $groups_html .= sprintf($line_templ, - rcube_utils::html_identifier('G' . $args['source'] . $group['ID'], true), + $args['out'] .= sprintf($line_templ, + html_identifier($args['source'] . $group['ID']), $args['source'], $group['ID'], $args['source'], $group['ID'], Q($group['name']) ); @@ -293,10 +286,6 @@ function rcmail_contact_groups($args) } } - $args['out'] .= html::tag('ul', - array('class' => 'groups', 'style' => ($is_collapsed || empty($groups) ? "display:none;" : null)), - $groups_html); - return $args; } @@ -307,7 +296,7 @@ function rcmail_contacts_list($attrib) global $CONTACTS, $OUTPUT; // define list of cols to be displayed - $a_show_cols = array('name','action'); + $a_show_cols = array('name'); // add id to message list table if not specified if (!strlen($attrib['id'])) @@ -322,7 +311,7 @@ function rcmail_contacts_list($attrib) $OUTPUT->include_script('list.js'); // add some labels to client - $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'movingcontact', 'contactdeleting'); + $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'contactdeleting'); return $out; } @@ -336,73 +325,31 @@ function rcmail_js_contacts_list($result, $prefix='') return; // define list of cols to be displayed - $a_show_cols = array('name','action'); + $a_show_cols = array('name'); while ($row = $result->next()) { - $row['CID'] = $row['ID']; - $row['email'] = reset(rcube_addressbook::get_col_values('email', $row, true)); - - $source_id = $OUTPUT->get_env('source'); $a_row_cols = array(); - $classes = array($row['_type'] ? $row['_type'] : 'person'); + $classes = array('person'); // org records will follow some day // build contact ID with source ID if (isset($row['sourceid'])) { $row['ID'] = $row['ID'].'-'.$row['sourceid']; - $source_id = $row['sourceid']; } // format each col foreach ($a_show_cols as $col) { - $val = ''; - switch ($col) { - case 'name': - $val = Q(rcube_addressbook::compose_list_name($row)); - break; - - case 'action': - if ($row['_type'] == 'group') { - $val = html::a(array( - 'href' => '#list', - 'rel' => $row['ID'], - 'title' => rcube_label('listgroup'), - 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", JS_OBJECT_NAME, $source_id, $row['CID']), - ), '»'); - } - else - $val = ' '; - break; - - default: - $val = Q($row[$col]); - break; - } - - $a_row_cols[$col] = $val; + $val = $col == 'name' ? rcube_addressbook::compose_list_name($row) : $row[$col]; + $a_row_cols[$col] = Q($val); } if ($row['readonly']) $classes[] = 'readonly'; - $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes), array_intersect_key($row, array('ID'=>1,'readonly'=>1,'_type'=>1,'email'=>1,'name'=>1))); + $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes)); } } -function rcmail_contacts_list_title($attrib) -{ - global $OUTPUT; - - $attrib += array('label' => 'contacts', 'id' => 'rcmabooklisttitle', 'tag' => 'span'); - unset($attrib['name']); - - $OUTPUT->add_gui_object('addresslist_title', $attrib['id']); - $OUTPUT->add_label('contacts'); - - return html::tag($attrib['tag'], $attrib, rcube_label($attrib['label']), html::$common_attrib); -} - - // similar function as /steps/settings/identities.inc::rcmail_identity_frame() function rcmail_contact_frame($attrib) { @@ -471,7 +418,7 @@ function rcmail_get_type_label($type) function rcmail_contact_form($form, $record, $attrib = null) { - global $RCMAIL; + global $RCMAIL, $CONFIG; // Allow plugins to modify contact form content $plugin = $RCMAIL->plugins->exec_hook('contact_form', array( @@ -480,7 +427,7 @@ function rcmail_contact_form($form, $record, $attrib = null) $form = $plugin['form']; $record = $plugin['record']; $edit_mode = $RCMAIL->action != 'show'; - $del_button = $attrib['deleteicon'] ? html::img(array('src' => $RCMAIL->output->get_skin_file($attrib['deleteicon']), 'alt' => rcube_label('delete'))) : rcube_label('delete'); + $del_button = $attrib['deleteicon'] ? html::img(array('src' => $CONFIG['skin_path'] . $attrib['deleteicon'], 'alt' => rcube_label('delete'))) : rcube_label('delete'); unset($attrib['deleteicon']); $out = ''; @@ -593,13 +540,22 @@ function rcmail_contact_form($form, $record, $attrib = null) // iterate over possible subtypes and collect values with their subtype if (is_array($colprop['subtypes'])) { $values = $subtypes = array(); - foreach (rcube_addressbook::get_col_values($field, $record) as $st => $vals) { - foreach((array)$vals as $value) { - $i = count($values); - $subtypes[$i] = $st; - $values[$i] = $value; + foreach ($colprop['subtypes'] as $i => $st) { + $newval = false; + if ($record[$field.':'.$st]) { + $subtypes[count($values)] = $st; + $newval = $record[$field.':'.$st]; + } + else if ($i == 0 && $record[$field]) { + $subtypes[count($values)] = $st; + $newval = $record[$field]; + } + if ($newval !== false) { + if (is_array($newval) && isset($newval[0])) + $values = array_merge($values, $newval); + else + $values[] = $newval; } - // TODO: add $st to $select_subtype if missing ? } } else { @@ -737,42 +693,23 @@ function rcmail_contact_form($form, $record, $attrib = null) function rcmail_contact_photo($attrib) { - global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL; + global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL, $CONFIG; if ($result = $CONTACTS->get_result()) $record = $result->first(); - $photo_img = $attrib['placeholder'] ? $RCMAIL->output->get_skin_file($attrib['placeholder']) : 'program/resources/blank.gif'; - if ($record['_type'] == 'group' && $attrib['placeholdergroup']) - $photo_img = $RCMAIL->output->get_skin_file($attrib['placeholdergroup']); - + $photo_img = $attrib['placeholder'] ? $CONFIG['skin_path'] . $attrib['placeholder'] : 'program/resources/blank.gif'; $RCMAIL->output->set_env('photo_placeholder', $photo_img); unset($attrib['placeholder']); $plugin = $RCMAIL->plugins->exec_hook('contact_photo', array('record' => $record, 'data' => $record['photo'])); - // check if we have photo data from contact form - if ($GLOBALS['EDIT_RECORD']) { - $rec = $GLOBALS['EDIT_RECORD']; - if ($rec['photo'] == '-del-') { - $record['photo'] = ''; - } - else if ($_SESSION['contacts']['files'][$rec['photo']]) { - $record['photo'] = $file_id = $rec['photo']; - } - } - if ($plugin['url']) $photo_img = $plugin['url']; else if (preg_match('!^https?://!i', $record['photo'])) $photo_img = $record['photo']; - else if ($record['photo']) { - $url = array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID); - if ($file_id) { - $url['_photo'] = $ff_value = $file_id; - } - $photo_img = $RCMAIL->url($url); - } + else if ($record['photo']) + $photo_img = $RCMAIL->url(array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID)); else $ff_value = '-del-'; // will disable delete-photo action @@ -795,54 +732,6 @@ function rcmail_format_date_col($val) return format_date($val, $RCMAIL->config->get('date_format', 'Y-m-d'), false); } -/** - * Updates saved search after data changed - */ -function rcmail_search_update($return = false) -{ - global $RCMAIL; - - if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) { - $search = (array)$_SESSION['search'][$search_request]; - $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name'); - $afields = $return ? $RCMAIL->config->get('contactlist_fields') : array('name', 'email'); - $records = array(); - - foreach ($search as $s => $set) { - $source = $RCMAIL->get_address_book($s); - - // reset page - $source->set_page(1); - $source->set_pagesize(9999); - $source->set_search_set($set); - - // get records - $result = $source->list_records($afields); - - if (!$result->count) { - unset($search[$s]); - continue; - } - - if ($return) { - while ($row = $result->next()) { - $row['sourceid'] = $s; - $key = rcube_addressbook::compose_contact_key($row, $sort_col); - $records[$key] = $row; - } - unset($result); - } - - $search[$s] = $source->get_search_set(); - } - - $_SESSION['search'][$search_request] = $search; - - return $records; - } - - return false; -} /** * Returns contact ID(s) and source(s) from GET/POST data @@ -900,7 +789,6 @@ $OUTPUT->add_handlers(array( 'directorylist' => 'rcmail_directory_list', // 'groupslist' => 'rcmail_contact_groups', 'addresslist' => 'rcmail_contacts_list', - 'addresslisttitle' => 'rcmail_contacts_list_title', 'addressframe' => 'rcmail_contact_frame', 'recordscountdisplay' => 'rcmail_rowcount_display', 'searchform' => array($OUTPUT, 'search_form') @@ -909,6 +797,7 @@ $OUTPUT->add_handlers(array( // register action aliases $RCMAIL->register_action_map(array( 'add' => 'edit.inc', + 'photo' => 'show.inc', 'group-create' => 'groups.inc', 'group-rename' => 'groups.inc', 'group-delete' => 'groups.inc', diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc index 60f5d7b61..915aac884 100644 --- a/program/steps/addressbook/import.inc +++ b/program/steps/addressbook/import.inc @@ -40,7 +40,6 @@ function rcmail_import_form($attrib) 'multiple' => 'multiple', )); $form = html::p(null, html::label('rcmimportfile', rcube_label('importfromfile')) . $upload->show()); - $table = new html_table(array('cols' => 2)); // addressbook selector if (count($writable_books) > 1) { @@ -49,31 +48,17 @@ function rcmail_import_form($attrib) foreach ($writable_books as $book) $select->add($book['name'], $book['id']); - $table->add('title', html::label('rcmimporttarget', rcube_label('importtarget'))); - $table->add(null, $select->show($target)); + $form .= html::p(null, html::label('rcmimporttarget', rcube_label('importtarget')) + . $select->show($target)); } else { $abook = new html_hiddenfield(array('name' => '_target', 'value' => key($writable_books))); $form .= $abook->show(); } - // selector for group import options - if (count($writable_books) >= 1 || $writable_books[0]->groups) { - $select = new html_select(array('name' => '_groups', 'id' => 'rcmimportgroups', 'is_escaped' => true)); - $select->add(rcube_label('none'), '0'); - $select->add(rcube_label('importgroupsall'), '1'); - $select->add(rcube_label('importgroupsexisting'), '2'); - - $table->add('title', html::label('rcmimportgroups', rcube_label('importgroups'))); - $table->add(null, $select->show(get_input_value('_groups', RCUBE_INPUT_GPC))); - } - - // checkbox to replace the entire address book $check_replace = new html_checkbox(array('name' => '_replace', 'value' => 1, 'id' => 'rcmimportreplace')); - $table->add('title', html::label('rcmimportreplace', rcube_label('importreplace'))); - $table->add(null, $check_replace->show(get_input_value('_replace', RCUBE_INPUT_GPC))); - - $form .= $table->show(array('id' => null) + $attrib); + $form .= html::p(null, $check_replace->show(get_input_value('_replace', RCUBE_INPUT_GPC)) . + html::label('rcmimportreplace', rcube_label('importreplace'))); $OUTPUT->set_env('writable_source', !empty($writable_books)); $OUTPUT->add_label('selectimportfile','importwait'); @@ -149,50 +134,19 @@ function rcmail_import_buttons($attrib) } -/** - * Returns the matching group id. If group doesn't exist, it'll be created if allowed. - */ -function rcmail_import_group_id($group_name, $CONTACTS, $create, &$import_groups) -{ - $group_id = 0; - foreach ($import_groups as $key => $group) { - if (strtolower($group['name']) == strtolower($group_name)) { - $group_id = $group['ID']; - break; - } - } - - // create a new group - if (!$group_id && $create) { - $new_group = $CONTACTS->create_group($group_name); - if (!$new_group['ID']) - $new_group['ID'] = $new_group['id']; - $import_groups[] = $new_group; - $group_id = $new_group['ID']; - } - - return $group_id; -} - - /** The import process **/ $importstep = 'rcmail_import_form'; if (is_array($_FILES['_file'])) { - $replace = (bool)get_input_value('_replace', RCUBE_INPUT_GPC); - $target = get_input_value('_target', RCUBE_INPUT_GPC); - $with_groups = intval(get_input_value('_groups', RCUBE_INPUT_GPC)); + $replace = (bool)get_input_value('_replace', RCUBE_INPUT_GPC); + $target = get_input_value('_target', RCUBE_INPUT_GPC); $vcards = array(); $upload_error = null; $CONTACTS = $RCMAIL->get_address_book($target, true); - if (!$CONTACTS->groups) { - $with_groups = false; - } - if ($CONTACTS->readonly) { $OUTPUT->show_message('addresswriterror', 'error'); } @@ -252,10 +206,6 @@ if (is_array($_FILES['_file'])) { $CONTACTS->delete_all(); } - if ($with_groups) { - $import_groups = $CONTACTS->list_groups(); - } - foreach ($vcards as $vcard) { $a_record = $vcard->get_assoc(); @@ -308,15 +258,6 @@ if (is_array($_FILES['_file'])) { $success = $plugin['result']; if ($success) { - // assign groups for this contact (if enabled) - if ($with_groups && !empty($a_record['groups'])) { - foreach (explode(',', $a_record['groups'][0]) as $group_name) { - if ($group_id = rcmail_import_group_id($group_name, $CONTACTS, $with_groups == 1, $import_groups)) { - $CONTACTS->add_to_group($group_id, $success); - } - } - } - $IMPORT_STATS->inserted++; $IMPORT_STATS->names[] = $a_record['name'] ? $a_record['name'] : $email; } diff --git a/program/steps/addressbook/list.inc b/program/steps/addressbook/list.inc index aca58d279..1bb28658b 100644 --- a/program/steps/addressbook/list.inc +++ b/program/steps/addressbook/list.inc @@ -19,20 +19,47 @@ +-----------------------------------------------------------------------+ */ -if (!empty($_GET['_page'])) - $page = intval($_GET['_page']); -else - $page = !empty($_SESSION['page']) ? $_SESSION['page'] : 1; - -$_SESSION['page'] = $page; +$afields = $RCMAIL->config->get('contactlist_fields'); // Use search result -if (($records = rcmail_search_update(true)) !== false) { +if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) +{ + $search = (array)$_SESSION['search'][$_REQUEST['_search']]; + $records = array(); + + if (!empty($_GET['_page'])) + $page = intval($_GET['_page']); + else + $page = isset($_SESSION['page']) ? $_SESSION['page'] : 1; + + $_SESSION['page'] = $page; + $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name'); + + // Get records from all sources + foreach ($search as $s => $set) { + $source = $RCMAIL->get_address_book($s); + + // reset page + $source->set_page(1); + $source->set_pagesize(9999); + $source->set_search_set($set); + + // get records + $result = $source->list_records($afields); + + while ($row = $result->next()) { + $row['sourceid'] = $s; + $key = rcube_addressbook::compose_contact_key($row, $sort_col); + $records[$key] = $row; + } + unset($result); + } + // sort the records ksort($records, SORT_LOCALE_STRING); // create resultset object - $count = count($records); + $count = count($records); $first = ($page-1) * $PAGE_SIZE; $result = new rcube_result_set($count, $first); @@ -45,7 +72,6 @@ if (($records = rcmail_search_update(true)) !== false) { } // List selected directory else { - $afields = $RCMAIL->config->get('contactlist_fields'); $CONTACTS = rcmail_contact_source(null, true); // get contacts for this user @@ -55,11 +81,6 @@ else { $OUTPUT->show_message('contactsearchonly', 'notice'); $OUTPUT->command('command', 'advanced-search'); } - - if ($CONTACTS->group_id) { - $OUTPUT->command('set_group_prop', array('ID' => $CONTACTS->group_id) - + array_intersect_key((array)$CONTACTS->get_group($CONTACTS->group_id), array('name'=>1,'email'=>1))); - } } // update message count display diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc index 2adc53bcf..25bfbd48b 100644 --- a/program/steps/addressbook/save.inc +++ b/program/steps/addressbook/save.inc @@ -59,34 +59,15 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) { } // assign values and subtypes else if (is_array($_POST[$fname])) { - $values = get_input_value($fname, RCUBE_INPUT_POST, true); + $values = get_input_value($fname, RCUBE_INPUT_POST, true); $subtypes = get_input_value('_subtype_' . $col, RCUBE_INPUT_POST); - foreach ($values as $i => $val) { - if ($col == 'email') { - // extract email from full address specification, e.g. "Name" <addr@domain.tld> - $addr = rcube_mime::decode_address_list($val, 1, false); - if (!empty($addr) && ($addr = array_pop($addr)) && $addr['mailto']) { - $val = $addr['mailto']; - } - } - $subtype = $subtypes[$i] ? ':'.$subtypes[$i] : ''; $a_record[$col.$subtype][] = $val; } } else if (isset($_POST[$fname])) { $a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST, true); - - // normalize the submitted date strings - if ($colprop['type'] == 'date') { - if ($timestamp = rcube_utils::strtotime($a_record[$col])) { - $a_record[$col] = date('Y-m-d', $timestamp); - } - else { - unset($a_record[$col]); - } - } } } @@ -94,10 +75,8 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) { if (empty($a_record['name'])) { $a_record['name'] = rcube_addressbook::compose_display_name($a_record, true); // Reset it if equals to email address (from compose_display_name()) - $email = rcube_addressbook::get_col_values('email', $a_record, true); - if ($a_record['name'] == $email[0]) { + if ($a_record['name'] == $a_record['email'][0]) $a_record['name'] = ''; - } } // do input checks (delegated to $CONTACTS instance) @@ -155,11 +134,11 @@ if (!empty($cid)) $record['email'] = reset($CONTACTS->get_col_values('email', $record, true)); $record['name'] = rcube_addressbook::compose_list_name($record); - foreach (array('name') as $col) + foreach (array('name', 'email') as $col) $a_js_cols[] = Q((string)$record[$col]); // update the changed col in list - $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record); + $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source); // show confirmation $OUTPUT->show_message('successfullysaved', 'confirmation', null, false); diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc index efab5e9e5..d583a6d36 100644 --- a/program/steps/addressbook/show.inc +++ b/program/steps/addressbook/show.inc @@ -38,6 +38,58 @@ if ($cid && ($record = $CONTACTS->get_record($cid, true))) { // get address book name (for display) rcmail_set_sourcename($CONTACTS); +// return raw photo of the given contact +if ($RCMAIL->action == 'photo') { + // search for contact first + if (!$record && ($email = get_input_value('_email', RCUBE_INPUT_GPC))) { + foreach ($RCMAIL->get_address_sources() as $s) { + $abook = $RCMAIL->get_address_book($s['id']); + $result = $abook->search(array('email'), $email, 1, true, true, 'photo'); + while ($result && ($record = $result->iterate())) { + if ($record['photo']) + break 2; + } + } + } + + // read the referenced file + if (($file_id = get_input_value('_photo', RCUBE_INPUT_GPC)) && ($tempfile = $_SESSION['contacts']['files'][$file_id])) { + $tempfile = $RCMAIL->plugins->exec_hook('attachment_display', $tempfile); + if ($tempfile['status']) { + if ($tempfile['data']) + $data = $tempfile['data']; + else if ($tempfile['path']) + $data = file_get_contents($tempfile['path']); + } + } + else if ($record['photo']) { + $data = is_array($record['photo']) ? $record['photo'][0] : $record['photo']; + if (!preg_match('![^a-z0-9/=+-]!i', $data)) + $data = base64_decode($data, true); + } + + // let plugins do fancy things with contact photos + $plugin = $RCMAIL->plugins->exec_hook('contact_photo', array('record' => $record, 'email' => $email, 'data' => $data)); + + // redirect to url provided by a plugin + if ($plugin['url']) + $RCMAIL->output->redirect($plugin['url']); + else + $data = $plugin['data']; + + // deliver alt image + if (!$data && ($alt_img = get_input_value('_alt', RCUBE_INPUT_GPC)) && is_file($alt_img)) + $data = file_get_contents($alt_img); + + // cache for one day if requested by email + if (!$cid && $email) + $RCMAIL->output->future_expire_header(86400); + + header('Content-Type: ' . rc_image_content_type($data)); + echo $data ? $data : file_get_contents('program/resources/blank.gif'); + exit; +} + function rcmail_contact_head($attrib) { @@ -49,6 +101,8 @@ function rcmail_contact_head($attrib) return false; } + $microformats = array('name' => 'fn', 'email' => 'email'); + $form = array( 'head' => array( // section 'head' is magic! 'content' => array( @@ -123,7 +177,7 @@ function rcmail_contact_details($attrib) } -function rcmail_render_email_value($email) +function rcmail_render_email_value($email, $col) { return html::a(array( 'href' => 'mailto:' . $email, @@ -134,7 +188,7 @@ function rcmail_render_email_value($email) } -function rcmail_render_url_value($url) +function rcmail_render_url_value($url, $col) { $prefix = preg_match('!^(http|ftp)s?://!', $url) ? '' : 'http://'; return html::a(array( @@ -155,8 +209,9 @@ function rcmail_contact_record_groups($contact_id) return ''; } - $members = $CONTACTS->get_record_groups($contact_id); - $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0)); + $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0)); + + $members = $CONTACTS->get_record_groups($contact_id); $checkbox = new html_checkbox(array('name' => '_gid[]', 'class' => 'groupmember', 'disabled' => $CONTACTS->readonly)); diff --git a/program/steps/addressbook/undo.inc b/program/steps/addressbook/undo.inc index c23bd1cb6..9c171143c 100644 --- a/program/steps/addressbook/undo.inc +++ b/program/steps/addressbook/undo.inc @@ -46,7 +46,30 @@ foreach ((array)$undo['data'] as $source => $cid) } // update saved search after data changed -rcmail_search_update(); +if ($delcnt && ($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) { + $search = (array)$_SESSION['search'][$search_request]; + + foreach ($search as $s => $set) { + $source = $RCMAIL->get_address_book($s); + + // reset page + $source->set_page(1); + $source->set_pagesize(9999); + $source->set_search_set($set); + + // get records + $result = $source->list_records(array('name', 'email')); + + if (!$result->count) { + unset($search[$s]); + continue; + } + + $search[$s] = $source->get_search_set(); + } + + $_SESSION['search'][$search_request] = $search; +} $RCMAIL->session->remove('contact_undo'); |