+$SEARCH_MODS_DEFAULT = array('name'=>1, 'firstname'=>1, 'surname'=>1, 'email'=>1, '*'=>1);
+
+// general definition of contact coltypes
+$CONTACT_COLTYPES = array(
+ 'name' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('name'), 'category' => 'main'),
+ 'firstname' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('firstname'), 'category' => 'main'),
+ 'surname' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('surname'), 'category' => 'main'),
+ 'email' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('email'), 'subtypes' => array('home','work','other'), 'category' => 'main'),
+ 'middlename' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('middlename'), 'category' => 'main'),
+ 'prefix' => array('type' => 'text', 'size' => 8, 'maxlength' => 20, 'limit' => 1, 'label' => rcube_label('nameprefix'), 'category' => 'main'),
+ 'suffix' => array('type' => 'text', 'size' => 8, 'maxlength' => 20, 'limit' => 1, 'label' => rcube_label('namesuffix'), 'category' => 'main'),
+ 'nickname' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('nickname'), 'category' => 'main'),
+ 'jobtitle' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('jobtitle'), 'category' => 'main'),
+ 'organization' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('organization'), 'category' => 'main'),
+ 'department' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('department'), 'category' => 'main'),
+ 'gender' => array('type' => 'select', 'limit' => 1, 'label' => rcube_label('gender'), 'options' => array('male' => rcube_label('male'), 'female' => rcube_label('female')), 'category' => 'personal'),
+ 'maidenname' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('maidenname'), 'category' => 'personal'),
+ 'phone' => array('type' => 'text', 'size' => 40, 'maxlength' => 20, 'label' => rcube_label('phone'), 'subtypes' => array('home','home2','work','work2','mobile','main','homefax','workfax','car','pager','video','assistant','other'), 'category' => 'main'),
+ 'address' => array('type' => 'composite', 'label' => rcube_label('address'), 'subtypes' => array('home','work','other'), 'childs' => array(
+ 'street' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('street'), 'category' => 'main'),
+ 'locality' => array('type' => 'text', 'size' => 28, 'maxlength' => 50, 'label' => rcube_label('locality'), 'category' => 'main'),
+ 'zipcode' => array('type' => 'text', 'size' => 8, 'maxlength' => 15, 'label' => rcube_label('zipcode'), 'category' => 'main'),
+ 'region' => array('type' => 'text', 'size' => 12, 'maxlength' => 50, 'label' => rcube_label('region'), 'category' => 'main'),
+ 'country' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('country'), 'category' => 'main'),
+ ), 'category' => 'main'),
+ 'birthday' => array('type' => 'date', 'size' => 12, 'maxlength' => 16, 'label' => rcube_label('birthday'), 'limit' => 1, 'render_func' => 'rcmail_format_date_col', 'category' => 'personal'),
+ 'anniversary' => array('type' => 'date', 'size' => 12, 'maxlength' => 16, 'label' => rcube_label('anniversary'), 'limit' => 1, 'render_func' => 'rcmail_format_date_col', 'category' => 'personal'),
+ 'website' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('website'), 'subtypes' => array('homepage','work','blog','profile','other'), 'category' => 'main'),
+ 'im' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('instantmessenger'), 'subtypes' => array('aim','icq','msn','yahoo','jabber','skype','other'), 'category' => 'main'),
+ 'notes' => array('type' => 'textarea', 'size' => 40, 'rows' => 15, 'maxlength' => 500, 'label' => rcube_label('notes'), 'limit' => 1),
+ 'photo' => array('type' => 'image', 'limit' => 1, 'category' => 'main'),
+ 'assistant' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('assistant'), 'category' => 'personal'),
+ 'manager' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('manager'), 'category' => 'personal'),
+ 'spouse' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('spouse'), 'category' => 'personal'),
+ // TODO: define fields for vcards like GEO, KEY
+);
+
+
+// Addressbook UI
+if (!$RCMAIL->action && !$OUTPUT->ajax_call) {
+ // add list of address sources to client env
+ $js_list = $RCMAIL->get_address_sources();
+
+ $source = get_input_value('_source', RCUBE_INPUT_GPC);
+
+ // use first directory by default
+ if (!strlen($source) || !isset($js_list[$source]))
+ $source = $js_list[key($js_list)]['id'];
+
+ // count all/writeable sources
+ $writeable = 0;
+ $count = 0;
+ foreach ($js_list as $sid => $s) {
+ $count++;
+ if (!$s['readonly']) {
+ $writeable++;
+ }
+ // unset hidden sources
+ if ($s['hidden']) {
+ unset($js_list[$sid]);
+ }
+ }
+
+ $search_mods = $RCMAIL->config->get('addressbook_search_mods', $SEARCH_MODS_DEFAULT);
+ $OUTPUT->set_env('search_mods', $search_mods);
+ $OUTPUT->set_env('address_sources', $js_list);
+ $OUTPUT->set_env('writable_source', $writeable);
+
+ $OUTPUT->set_pagetitle(rcube_label('addressbook'));
+ $_SESSION['addressbooks_count'] = $count;
+ $_SESSION['addressbooks_count_writeable'] = $writeable;
+
+ if (!strlen($source))
+ $source = strval(key($js_list));
+
+ $CONTACTS = rcmail_contact_source($source, true);
+}
+
+// remove undo information...
+if ($undo = $_SESSION['contact_undo']) {
+ // ...after timeout
+ $undo_time = $RCMAIL->config->get('undo_timeout', 0);
+ if ($undo['ts'] < time() - $undo_time)
+ $RCMAIL->session->remove('contact_undo');
+}
+
+// instantiate a contacts object according to the given source
+function rcmail_contact_source($source=null, $init_env=false, $writable=false)
+{
+ global $RCMAIL, $OUTPUT, $CONFIG, $CONTACT_COLTYPES;
+
+ if (!strlen($source)) {
+ $source = get_input_value('_source', RCUBE_INPUT_GPC);
+ }
+
+ // Get object
+ $CONTACTS = $RCMAIL->get_address_book($source, $writable);
+ $CONTACTS->set_pagesize($CONFIG['pagesize']);
+
+ // set list properties and session vars
+ if (!empty($_GET['_page']))
+ $CONTACTS->set_page(($_SESSION['page'] = intval($_GET['_page'])));
+ else
+ $CONTACTS->set_page(isset($_SESSION['page']) ? $_SESSION['page'] : 1);
+
+ if (!empty($_REQUEST['_gid']))
+ $CONTACTS->set_group(get_input_value('_gid', RCUBE_INPUT_GPC));
+
+ if (!$init_env)
+ return $CONTACTS;
+
+ $OUTPUT->set_env('readonly', $CONTACTS->readonly);
+ $OUTPUT->set_env('source', $source);
+
+ // reduce/extend $CONTACT_COLTYPES with specification from the current $CONTACT object
+ if (is_array($CONTACTS->coltypes)) {
+ // remove cols not listed by the backend class
+ $contact_cols = $CONTACTS->coltypes[0] ? array_flip($CONTACTS->coltypes) : $CONTACTS->coltypes;
+ $CONTACT_COLTYPES = array_intersect_key($CONTACT_COLTYPES, $contact_cols);
+ // add associative coltypes definition
+ if (!$CONTACTS->coltypes[0]) {
+ foreach ($CONTACTS->coltypes as $col => $colprop)
+ $CONTACT_COLTYPES[$col] = $CONTACT_COLTYPES[$col] ? array_merge($CONTACT_COLTYPES[$col], $colprop) : $colprop;
+ }
+ }
+
+ $OUTPUT->set_env('photocol', is_array($CONTACT_COLTYPES['photo']));
+
+ return $CONTACTS;
+}
+
+
+function rcmail_default_source($writable=false)
+{
+ global $RCMAIL;
+
+ // get list of address sources
+ $first = reset($RCMAIL->get_address_sources($writable));
+
+ // use first directory by default
+ return $first['id'];
+}
+
+function rcmail_set_sourcename($abook)
+{
+ global $OUTPUT;
+
+ // get address book name (for display)
+ if ($abook && $_SESSION['addressbooks_count'] > 1) {
+ $name = $abook->get_name();
+ if (!$name && $source == 0) {
+ $name = rcube_label('personaladrbook');
+ }
+ $OUTPUT->set_env('sourcename', $name);