You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. +-----------------------------------------------------------------------+
  4. | program/steps/addressbook/move.inc |
  5. | |
  6. | This file is part of the Roundcube Webmail client |
  7. | Copyright (C) 2007-2013, The Roundcube Dev Team |
  8. | |
  9. | Licensed under the GNU General Public License version 3 or |
  10. | any later version with exceptions for skins & plugins. |
  11. | See the README file for a full license statement. |
  12. | |
  13. | PURPOSE: |
  14. | Move a contact record from one direcotry to another |
  15. +-----------------------------------------------------------------------+
  16. | Author: Thomas Bruederli <roundcube@gmail.com> |
  17. | Author: Aleksander Machniak <alec@alec.pl> |
  18. +-----------------------------------------------------------------------+
  19. */
  20. // only process ajax requests
  21. if (!$OUTPUT->ajax_call) {
  22. return;
  23. }
  24. $cids = rcmail_get_cids();
  25. $target = rcube_utils::get_input_value('_to', rcube_utils::INPUT_POST);
  26. $target_group = rcube_utils::get_input_value('_togid', rcube_utils::INPUT_POST);
  27. $all = 0;
  28. $deleted = 0;
  29. $success = 0;
  30. $errormsg = 'moveerror';
  31. $maxnum = $RCMAIL->config->get('max_group_members', 0);
  32. $page = $_SESSION['page'] ?: 1;
  33. foreach ($cids as $source => $source_cids) {
  34. // Something wrong, target not specified
  35. if (!strlen($target)) {
  36. break;
  37. }
  38. // It maight happen when moving records from search result
  39. // Do nothing, go to next source
  40. if ((string)$target === (string)$source) {
  41. continue;
  42. }
  43. $CONTACTS = $RCMAIL->get_address_book($source);
  44. $TARGET = $RCMAIL->get_address_book($target);
  45. if (!$TARGET || !$TARGET->ready || $TARGET->readonly) {
  46. break;
  47. }
  48. if (!$CONTACTS || !$CONTACTS->ready || $CONTACTS->readonly) {
  49. continue;
  50. }
  51. $ids = array();
  52. foreach ($source_cids as $idx => $cid) {
  53. $a_record = $CONTACTS->get_record($cid, true);
  54. // avoid moving groups
  55. if ($a_record['_type'] == 'group') {
  56. unset($source_cids[$idx]);
  57. continue;
  58. }
  59. // Check if contact exists, if so, we'll need it's ID
  60. // Note: Some addressbooks allows empty email address field
  61. // @TODO: should we check all email addresses?
  62. $email = $CONTACTS->get_col_values('email', $a_record, true);
  63. if (!empty($email))
  64. $result = $TARGET->search('email', $email[0], 1, true, true);
  65. else if (!empty($a_record['name']))
  66. $result = $TARGET->search('name', $a_record['name'], 1, true, true);
  67. else
  68. $result = new rcube_result_set();
  69. // insert contact record
  70. if (!$result->count) {
  71. $plugin = $RCMAIL->plugins->exec_hook('contact_create', array(
  72. 'record' => $a_record, 'source' => $target, 'group' => $target_group));
  73. if (!$plugin['abort']) {
  74. if ($insert_id = $TARGET->insert($plugin['record'], false)) {
  75. $ids[] = $insert_id;
  76. $success++;
  77. }
  78. }
  79. else if ($plugin['result']) {
  80. $ids = array_merge($ids, $plugin['result']);
  81. $success++;
  82. }
  83. }
  84. else {
  85. $record = $result->first();
  86. $ids[] = $record['ID'];
  87. $errormsg = empty($email) ? 'contactnameexists' : 'contactexists';
  88. }
  89. }
  90. // remove source contacts
  91. if ($success && !empty($source_cids)) {
  92. $all += count($source_cids);
  93. $plugin = $RCMAIL->plugins->exec_hook('contact_delete', array(
  94. 'id' => $source_cids, 'source' => $source));
  95. $del_status = !$plugin['abort'] ? $CONTACTS->delete($source_cids) : $plugin['result'];
  96. if ($del_status) {
  97. $deleted += $del_status;
  98. }
  99. }
  100. // assign to group
  101. if ($target_group && $TARGET->groups && !empty($ids)) {
  102. $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array(
  103. 'group_id' => $target_group, 'ids' => $ids, 'source' => $target));
  104. if (!$plugin['abort']) {
  105. $TARGET->reset();
  106. $TARGET->set_group($target_group);
  107. if ($maxnum && ($TARGET->count()->count + count($plugin['ids']) > $maxnum)) {
  108. $OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum));
  109. $OUTPUT->send();
  110. }
  111. if (($cnt = $TARGET->add_to_group($target_group, $plugin['ids'])) && $cnt > $success)
  112. $success = $cnt;
  113. }
  114. else if ($plugin['result']) {
  115. $success = $plugin['result'];
  116. }
  117. $errormsg = $plugin['message'] ?: 'moveerror';
  118. }
  119. }
  120. if (!$deleted || $deleted != $all) {
  121. $OUTPUT->command('list_contacts');
  122. }
  123. else {
  124. // update saved search after data changed
  125. if (($records = rcmail_search_update(true)) !== false) {
  126. // create resultset object
  127. $count = count($records);
  128. $first = ($page-1) * $PAGE_SIZE;
  129. $result = new rcube_result_set($count, $first);
  130. $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
  131. // last page and it's empty, display previous one
  132. if ($result->count && $result->count <= ($PAGE_SIZE * ($page - 1))) {
  133. $OUTPUT->command('list_page', 'prev');
  134. $rowcount = $RCMAIL->gettext('loading');
  135. }
  136. // get records from the next page to add to the list
  137. else if ($pages > 1 && $page < $pages) {
  138. // sort the records
  139. ksort($records, SORT_LOCALE_STRING);
  140. $first += $PAGE_SIZE;
  141. // create resultset object
  142. $res = new rcube_result_set($count, $first - $deleted);
  143. if ($PAGE_SIZE < $count) {
  144. $records = array_slice($records, $first - $deleted, $deleted);
  145. }
  146. $res->records = array_values($records);
  147. $records = $res;
  148. }
  149. else {
  150. unset($records);
  151. }
  152. }
  153. else {
  154. // count contacts for this user
  155. $result = $CONTACTS->count();
  156. $pages = ceil(($result->count + $deleted) / $PAGE_SIZE);
  157. // last page and it's empty, display previous one
  158. if ($result->count && $result->count <= ($PAGE_SIZE * ($page - 1))) {
  159. $OUTPUT->command('list_page', 'prev');
  160. $rowcount = $RCMAIL->gettext('loading');
  161. }
  162. // get records from the next page to add to the list
  163. else if ($pages > 1 && $page < $pages) {
  164. $CONTACTS->set_page($page);
  165. $records = $CONTACTS->list_records(null, -$deleted);
  166. }
  167. }
  168. // update message count display
  169. $OUTPUT->set_env('pagecount', ceil($result->count / $PAGE_SIZE));
  170. $OUTPUT->command('set_rowcount', $rowcount ?: rcmail_get_rowcount_text($result));
  171. // add new rows from next page (if any)
  172. if (!empty($records)) {
  173. rcmail_js_contacts_list($records);
  174. }
  175. }
  176. if (!$success)
  177. $OUTPUT->show_message($errormsg, 'error');
  178. else
  179. $OUTPUT->show_message('movesuccess', 'notice', array('nr' => $success));
  180. // send response
  181. $OUTPUT->send();