Aleksander Machniak
2016-02-13 a62ff159f0ae72d2794ab538dfc1848bdf5504a4
commit | author | age
4e17e6 1 <?php
T 2
a95874 3 /**
4e17e6 4  +-----------------------------------------------------------------------+
T 5  | program/steps/addressbook/save.inc                                    |
6  |                                                                       |
e019f2 7  | This file is part of the Roundcube Webmail client                     |
c97625 8  | Copyright (C) 2005-2013, The Roundcube Dev Team                       |
7fe381 9  |                                                                       |
T 10  | Licensed under the GNU General Public License version 3 or            |
11  | any later version with exceptions for skins & plugins.                |
12  | See the README file for a full license statement.                     |
4e17e6 13  |                                                                       |
T 14  | PURPOSE:                                                              |
15  |   Save a contact entry or to add a new one                            |
16  |                                                                       |
17  +-----------------------------------------------------------------------+
18  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
19  +-----------------------------------------------------------------------+
20 */
21
c97625 22 $CONTACTS      = rcmail_contact_source(null, true, true);
AM 23 $cid           = rcube_utils::get_input_value('_cid', rcube_utils::INPUT_POST);
6f0968 24 $return_action = empty($cid) ? 'add' : 'edit';
57f0c8 25
2dd2bf 26 // Source changed, display the form again
A 27 if (!empty($_GET['_reload'])) {
c97625 28     $RCMAIL->overwrite_action($return_action);
AM 29     return;
2dd2bf 30 }
A 31
f11541 32 // cannot edit record
6f0968 33 if ($CONTACTS->readonly) {
c97625 34     $OUTPUT->show_message('contactreadonly', 'error');
AM 35     $RCMAIL->overwrite_action($return_action);
36     return;
0501b6 37 }
T 38
39 // read POST values into hash array
40 $a_record = array();
41 foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
c97625 42     if ($colprop['composite']) {
AM 43         continue;
0501b6 44     }
6128ad 45
c97625 46     $fname = '_'.$col;
AM 47
48     // gather form data of composite fields
49     if ($colprop['childs']) {
50         $values = array();
51         foreach ($colprop['childs'] as $childcol => $cp) {
52             $vals = rcube_utils::get_input_value('_'.$childcol, rcube_utils::INPUT_POST, true);
53             foreach ((array)$vals as $i => $val) {
54                 $values[$i][$childcol] = $val;
55             }
6128ad 56         }
AM 57
c97625 58         $subtypes = isset($_REQUEST['_subtype_' . $col]) ? (array)rcube_utils::get_input_value('_subtype_' . $col, rcube_utils::INPUT_POST) : array('');
AM 59         foreach ($subtypes as $i => $subtype) {
60             $suffix = $subtype ? ':'.$subtype : '';
61             if ($values[$i]) {
62                 $a_record[$col.$suffix][] = $values[$i];
63             }
52830e 64         }
TB 65     }
c97625 66     // assign values and subtypes
AM 67     else if (is_array($_POST[$fname])) {
68         $values   = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true);
69         $subtypes = rcube_utils::get_input_value('_subtype_' . $col, rcube_utils::INPUT_POST);
70
71         foreach ($values as $i => $val) {
72             if ($col == 'email') {
73                 // extract email from full address specification, e.g. "Name" <addr@domain.tld>
74                 $addr = rcube_mime::decode_address_list($val, 1, false);
75                 if (!empty($addr) && ($addr = array_pop($addr)) && $addr['mailto']) {
76                     $val = $addr['mailto'];
77                 }
78             }
79
80             $subtype = $subtypes[$i] ? ':'.$subtypes[$i] : '';
81             $a_record[$col.$subtype][] = $val;
82         }
83     }
84     else if (isset($_POST[$fname])) {
85         $a_record[$col] = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true);
86
87         // normalize the submitted date strings
88         if ($colprop['type'] == 'date') {
89             if ($a_record[$col] && ($dt = rcube_utils::anytodatetime($a_record[$col]))) {
90                 $a_record[$col] = $dt->format('Y-m-d');
91             }
92             else {
93                 unset($a_record[$col]);
94             }
95         }
96     }
0501b6 97 }
T 98
1e36b7 99 // Generate contact's display name (must be before validation)
A 100 if (empty($a_record['name'])) {
101     $a_record['name'] = rcube_addressbook::compose_display_name($a_record, true);
c97625 102
1e36b7 103     // Reset it if equals to email address (from compose_display_name())
6b87f8 104     $email = rcube_addressbook::get_col_values('email', $a_record, true);
AM 105     if ($a_record['name'] == $email[0]) {
1e36b7 106         $a_record['name'] = '';
6b87f8 107     }
1e36b7 108 }
07b95d 109
T 110 // do input checks (delegated to $CONTACTS instance)
111 if (!$CONTACTS->validate($a_record)) {
a01df7 112     $err = (array)$CONTACTS->get_error();
6b2b2e 113     $OUTPUT->show_message($err['message'] ? rcube::Q($err['message']) : 'formincomplete', 'warning');
3d8b54 114     $GLOBALS['EDIT_RECORD'] = $a_record;  // store submitted data to be used in edit form
6b2b2e 115     $RCMAIL->overwrite_action($return_action);
07b95d 116     return;
6f0968 117 }
A 118
0501b6 119 // get raw photo data if changed
T 120 if (isset($a_record['photo'])) {
121     if ($a_record['photo'] == '-del-') {
122         $a_record['photo'] = '';
123     }
124     else if ($tempfile = $_SESSION['contacts']['files'][$a_record['photo']]) {
125         $tempfile = $RCMAIL->plugins->exec_hook('attachment_get', $tempfile);
126         if ($tempfile['status'])
827159 127             $a_record['photo'] = $tempfile['data'] ?: @file_get_contents($tempfile['path']);
0501b6 128     }
T 129     else
130         unset($a_record['photo']);
ecf295 131
0501b6 132     // cleanup session data
4591de 133     $RCMAIL->plugins->exec_hook('attachments_cleanup', array('group' => 'contact'));
0501b6 134     $RCMAIL->session->remove('contacts');
79dd16 135 }
A 136
6b2b2e 137 $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC);
79dd16 138
4e17e6 139 // update an existing contact
c97625 140 if (!empty($cid)) {
AM 141     $plugin = $RCMAIL->plugins->exec_hook('contact_update',
142         array('id' => $cid, 'record' => $a_record, 'source' => $source));
143     $a_record = $plugin['record'];
6f0968 144
c97625 145     if (!$plugin['abort'])
AM 146         $result = $CONTACTS->update($cid, $a_record);
147     else
148         $result = $plugin['result'];
ce92ba 149
c97625 150     if ($result) {
765a0b 151         // show confirmation
AM 152         $OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
153
154         // in search mode, just reload the list (#1490015)
155         if ($_REQUEST['_search']) {
156             $OUTPUT->command('parent.command', 'list');
157             $OUTPUT->send('iframe');
158         }
159
c97625 160         // LDAP DN change
AM 161         if (is_string($result) && strlen($result)>1) {
162             $newcid = $result;
163             // change cid in POST for 'show' action
164             $_POST['_cid'] = $newcid;
165         }
166
a62ff1 167         // refresh contact data for list update and 'show' action
AM 168         $CONTACT_RECORD = $CONTACTS->get_record($newcid ?: $cid, true);
169
170         // Update contacts list
c97625 171         $a_js_cols = array();
a62ff1 172         $record = $CONTACT_RECORD;
c97625 173         $record['email'] = reset($CONTACTS->get_col_values('email', $record, true));
AM 174         $record['name']  = rcube_addressbook::compose_list_name($record);
175
176         foreach (array('name') as $col) {
177             $a_js_cols[] = rcube::Q((string)$record[$col]);
178         }
179
3d36e8 180         // performance: unset some big data items we don't need here
AM 181         $record = array_intersect_key($record, array('ID' => 1,'email' => 1,'name' => 1));
182         $record['_type'] = 'person';
183
c97625 184         // update the changed col in list
AM 185         $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record);
186
187         $RCMAIL->overwrite_action('show');
e83f03 188     }
c97625 189     else {
AM 190         // show error message
191         $err = $CONTACTS->get_error();
827159 192         $OUTPUT->show_message($plugin['message'] ?: ($err['message'] ?: 'errorsaving'), 'error', null, false);
c97625 193         $RCMAIL->overwrite_action('show');
AM 194     }
f11541 195 }
4e17e6 196
T 197 // insert a new contact
ce92ba 198 else {
c97625 199     // Name of the addressbook already selected on the list
AM 200     $orig_source = rcube_utils::get_input_value('_orig_source', rcube_utils::INPUT_GPC);
70c311 201
c97625 202     if (!strlen($source)) {
AM 203         $source = $orig_source;
8458c7 204     }
c97625 205
AM 206     // show notice if existing contacts with same e-mail are found
207     foreach ($CONTACTS->get_col_values('email', $a_record, true) as $email) {
208         if ($email && ($res = $CONTACTS->search('email', $email, 1, false, true)) && $res->count) {
209             $OUTPUT->show_message('contactexists', 'notice', null, false);
210             break;
211         }
212     }
213
214     $plugin = $RCMAIL->plugins->exec_hook('contact_create', array(
215         'record' => $a_record, 'source' => $source));
216     $a_record = $plugin['record'];
217
218     // insert record and send response
219     if (!$plugin['abort'])
220         $insert_id = $CONTACTS->insert($a_record);
cf57b2 221     else
c97625 222         $insert_id = $plugin['result'];
4e17e6 223
c97625 224     if ($insert_id) {
AM 225         $CONTACTS->reset();
d1d2c4 226
c97625 227         // add new contact to the specified group
AM 228         if ($CONTACTS->groups && $CONTACTS->group_id) {
229             $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array(
230                 'group_id' => $CONTACTS->group_id, 'ids' => $insert_id, 'source' => $source));
1a3c91 231
c97625 232             if (!$plugin['abort']) {
9e2603 233                 if (($maxnum = $RCMAIL->config->get('max_group_members', 0)) && ($CONTACTS->count()->count + 1 > $maxnum)) {
AM 234                     // @FIXME: should we remove the contact?
235                     $msgtext = $RCMAIL->gettext(array('name' => 'maxgroupmembersreached', 'vars' => array('max' => $maxnum)));
236                     $OUTPUT->command('parent.display_message', $msgtext, 'warning');
237                 }
238                 else {
239                     $CONTACTS->add_to_group($plugin['group_id'], $plugin['ids']);
240                 }
c97625 241             }
AM 242         }
243
765a0b 244         // show confirmation
AM 245         $OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
246
e66a77 247         $OUTPUT->command('parent.set_rowcount', $RCMAIL->gettext('loading'));
AM 248         $OUTPUT->command('parent.list_contacts');
c97625 249
AM 250         $OUTPUT->send('iframe');
1a3c91 251     }
A 252     else {
c97625 253         // show error message
AM 254         $err = $CONTACTS->get_error();
827159 255         $OUTPUT->show_message($plugin['message'] ?: ($err['message'] ?: 'errorsaving'), 'error', null, false);
c97625 256         $RCMAIL->overwrite_action('add');
1a3c91 257     }
f11541 258 }