From 79367a563143272385c8666ff02dbe7ab3126f35 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Sun, 8 Sep 2013 15:36:05 +0200 Subject: Save groups membership in VCard export (#1488509) --- program/lib/Roundcube/rcube_addressbook.php | 3 +- program/lib/Roundcube/rcube_ldap.php | 1 + program/lib/Roundcube/rcube_vcard.php | 5 +- program/steps/addressbook/export.inc | 106 +++++++++++++--------------- 4 files changed, 54 insertions(+), 61 deletions(-) diff --git a/program/lib/Roundcube/rcube_addressbook.php b/program/lib/Roundcube/rcube_addressbook.php index 4ed139c45..73d6e4d66 100644 --- a/program/lib/Roundcube/rcube_addressbook.php +++ b/program/lib/Roundcube/rcube_addressbook.php @@ -3,7 +3,7 @@ /* +-----------------------------------------------------------------------+ | This file is part of the Roundcube Webmail client | - | Copyright (C) 2006-2012, The Roundcube Dev Team | + | Copyright (C) 2006-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -35,6 +35,7 @@ abstract class rcube_addressbook /** public properties (mandatory) */ public $primary_key; public $groups = false; + public $export_groups = true; public $readonly = true; public $searchonly = false; public $undelete = false; diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php index cb7fa8466..78573789b 100644 --- a/program/lib/Roundcube/rcube_ldap.php +++ b/program/lib/Roundcube/rcube_ldap.php @@ -34,6 +34,7 @@ class rcube_ldap extends rcube_addressbook public $ready = false; public $group_id = 0; public $coltypes = array(); + public $export_groups = false; // private properties protected $ldap; diff --git a/program/lib/Roundcube/rcube_vcard.php b/program/lib/Roundcube/rcube_vcard.php index a71305c4b..a85eb8873 100644 --- a/program/lib/Roundcube/rcube_vcard.php +++ b/program/lib/Roundcube/rcube_vcard.php @@ -47,6 +47,7 @@ class rcube_vcard 'manager' => 'X-MANAGER', 'spouse' => 'X-SPOUSE', 'edit' => 'X-AB-EDIT', + 'groups' => 'CATEGORIES', ); private $typemap = array( 'IPHONE' => 'mobile', @@ -756,7 +757,7 @@ class rcube_vcard * * @return string Joined and quoted string */ - private static function vcard_quote($s, $sep = ';') + public static function vcard_quote($s, $sep = ';') { if (is_array($s)) { foreach($s as $part) { @@ -765,7 +766,7 @@ class rcube_vcard return(implode($sep, (array)$r)); } - return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', ',' => '\,', ';' => '\;')); + return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', $sep => '\\'.$sep)); } /** diff --git a/program/steps/addressbook/export.inc b/program/steps/addressbook/export.inc index 761f26b75..1e988feab 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-2011, The Roundcube Dev Team | + | Copyright (C) 2008-2013, The Roundcube Dev Team | | Copyright (C) 2011, Kolab Systems AG | | | | Licensed under the GNU General Public License version 3 or | @@ -21,6 +21,46 @@ +-----------------------------------------------------------------------+ */ + +/** + * 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']])) { @@ -42,23 +82,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search while ($record = $result->next()) { // because vcard_map is per-source we need to create vcard here - if (empty($record['vcard']) || empty($record['name'])) { - $vcard = new rcube_vcard(); - $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)); - } - } - } - - $record['vcard'] = $vcard->export(true); - } + prepare_for_export($record, $source); $record['sourceid'] = $s; $key = rcube_addressbook::compose_contact_key($record, $sort_col); @@ -90,23 +114,7 @@ else if (!empty($_REQUEST['_cid'])) { while ($record = $result->next()) { // because vcard_map is per-source we need to create vcard here - if (empty($record['vcard']) || empty($record['name'])) { - $vcard = new rcube_vcard(); - $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)); - } - } - } - - $record['vcard'] = $vcard->export(true); - } + prepare_for_export($record, $source); $record['sourceid'] = $s; $key = rcube_addressbook::compose_contact_key($record, $sort_col); @@ -136,30 +144,12 @@ header('Content-Type: text/x-vcard; charset='.RCMAIL_CHARSET); header('Content-Disposition: attachment; filename="contacts.vcf"'); while ($result && ($row = $result->next())) { - // 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(); + prepare_for_export($row, $CONTACTS); - 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)); - } - } - - echo $vcard->export(true) . rcube_vcard::$eol; - } + // 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; } exit; -- cgit v1.2.3