Thomas Bruederli
2014-03-21 d2215764898919f1ea3b461fb08ac430db4340a4
commit | author | age
0dbac3 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/steps/addressbook/export.inc                                  |
6  |                                                                       |
e019f2 7  | This file is part of the Roundcube Webmail client                     |
79367a 8  | Copyright (C) 2008-2013, The Roundcube Dev Team                       |
f5d2ee 9  | Copyright (C) 2011-2013, Kolab Systems AG                             |
7fe381 10  |                                                                       |
T 11  | Licensed under the GNU General Public License version 3 or            |
12  | any later version with exceptions for skins & plugins.                |
13  | See the README file for a full license statement.                     |
0dbac3 14  |                                                                       |
T 15  | PURPOSE:                                                              |
16  |   Export the selected address book as vCard file                      |
17  |                                                                       |
18  +-----------------------------------------------------------------------+
19  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
ecf295 20  | Author: Aleksander Machniak <machniak@kolabsys.com>                   |
0dbac3 21  +-----------------------------------------------------------------------+
T 22 */
79367a 23
ecf295 24 // Use search result
f5d2ee 25 if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) {
0203f1 26     $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
ecf295 27     $search  = (array)$_SESSION['search'][$_REQUEST['_search']];
A 28     $records = array();
29
30     // Get records from all sources
31     foreach ($search as $s => $set) {
32         $source = $RCMAIL->get_address_book($s);
33
34         // reset page
35         $source->set_page(1);
36         $source->set_pagesize(99999);
37         $source->set_search_set($set);
38
39         // get records
40         $result = $source->list_records();
41
8e8f3b 42         while ($record = $result->next()) {
AM 43             // because vcard_map is per-source we need to create vcard here
79367a 44             prepare_for_export($record, $source);
8e8f3b 45
AM 46             $record['sourceid'] = $s;
13dc9f 47             $key = rcube_addressbook::compose_contact_key($record, $sort_col);
8e8f3b 48             $records[$key] = $record;
ecf295 49         }
8e8f3b 50
ecf295 51         unset($result);
A 52     }
53
54     // sort the records
55     ksort($records, SORT_LOCALE_STRING);
56
57     // create resultset object
58     $count  = count($records);
59     $result = new rcube_result_set($count);
60     $result->records = array_values($records);
61 }
9a6c38 62 // selected contacts
TB 63 else if (!empty($_REQUEST['_cid'])) {
64     $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
8e8f3b 65     $records  = array();
9a6c38 66
8e8f3b 67     // Selected contact IDs (with multi-source support)
AM 68     $cids = rcmail_get_cids();
9a6c38 69
8e8f3b 70     foreach ($cids as $s => $ids) {
AM 71         $source = $RCMAIL->get_address_book($s);
72         $result = $source->search('ID', $ids, 1, true, true);
73
74         while ($record = $result->next()) {
75             // because vcard_map is per-source we need to create vcard here
79367a 76             prepare_for_export($record, $source);
8e8f3b 77
AM 78             $record['sourceid'] = $s;
13dc9f 79             $key = rcube_addressbook::compose_contact_key($record, $sort_col);
8e8f3b 80             $records[$key] = $record;
AM 81         }
9a6c38 82     }
TB 83
84     ksort($records, SORT_LOCALE_STRING);
85
86     // create resultset object
87     $count  = count($records);
88     $result = new rcube_result_set($count);
89     $result->records = array_values($records);
90 }
ecf295 91 // selected directory/group
A 92 else {
93     $CONTACTS = rcmail_contact_source(null, true);
94
95     // get contacts for this user
96     $CONTACTS->set_page(1);
97     $CONTACTS->set_pagesize(99999);
98     $result = $CONTACTS->list_records(null, 0, true);
99 }
0dbac3 100
T 101 // send downlaod headers
6b2b2e 102 header('Content-Type: text/x-vcard; charset='.RCUBE_CHARSET);
8e8f3b 103 header('Content-Disposition: attachment; filename="contacts.vcf"');
0dbac3 104
T 105 while ($result && ($row = $result->next())) {
79367a 106     prepare_for_export($row, $CONTACTS);
cbf891 107
79367a 108     // fix folding and end-of-line chars
TB 109     $row['vcard'] = preg_replace('/\r|\n\s+/', '', $row['vcard']);
110     $row['vcard'] = preg_replace('/\n/', rcube_vcard::$eol, $row['vcard']);
111     echo rcube_vcard::rfc2425_fold($row['vcard']) . rcube_vcard::$eol;
0dbac3 112 }
T 113
114 exit;
f5d2ee 115
AM 116
117 /**
118  * Copy contact record properties into a vcard object
119  */
120 function prepare_for_export(&$record, $source = null)
121 {
122     $groups = $source && $source->groups && $source->export_groups ? $source->get_record_groups($record['ID']) : null;
123
124     if (empty($record['vcard'])) {
125         $vcard = new rcube_vcard();
126         if ($source) {
127             $vcard->extend_fieldmap($source->vcard_map);
128         }
129         $vcard->load($record['vcard']);
130         $vcard->reset();
131
132         foreach ($record as $key => $values) {
133             list($field, $section) = explode(':', $key);
134             foreach ((array)$values as $value) {
135                 if (is_array($value) || @strlen($value)) {
136                     $vcard->set($field, $value, strtoupper($section));
137                 }
138             }
139         }
140
141         // append group names
142         if ($groups) {
143             $vcard->set('groups', join(',', $groups), null);
144         }
145
146         $record['vcard'] = $vcard->export(true);
147     }
148     // patch categories to alread existing vcard block
149     else if ($record['vcard'] && !empty($groups) && !strpos($record['vcard'], 'CATEGORIES:')) {
150         $vgroups = 'CATEGORIES:' . rcube_vcard::vcard_quote(join(',', $groups));
151         $record['vcard'] = str_replace('END:VCARD', $vgroups . rcube_vcard::$eol . 'END:VCARD', $record['vcard']);
152     }
153 }