diff --git a/addressbook/inc/class.uicontacts.inc.php b/addressbook/inc/class.uicontacts.inc.php index fad8460b5d..f9b47bce6e 100644 --- a/addressbook/inc/class.uicontacts.inc.php +++ b/addressbook/inc/class.uicontacts.inc.php @@ -180,7 +180,7 @@ class uicontacts extends bocontacts $sel_options['action'] = array( 'delete' => lang('Delete'), 'csv' => lang('Export as CSV'), -// ToDo: 'vcard' => lang('Export as VCard'), + 'vcard' => lang('Export as VCard'), // ToDo: 'copy' => lang('Copy a contact and edit the copy'), )+$this->get_addressbooks(EGW_ACL_ADD); @@ -330,6 +330,13 @@ class uicontacts extends bocontacts // does not return! $Ok = true; break; + + case 'vcard': + $action_msg = lang('exported'); + ExecMethod('addressbook.vcaladdressbook.export',$checked); + // does not return! + $Ok = false; + break; } foreach($checked as $id) @@ -360,11 +367,6 @@ class uicontacts extends bocontacts } break; - case 'vcard': - $action_msg = lang('exported'); - $Ok = false; // todo - break; - default: // move to an other addressbook if (!is_numeric($action) || !($this->grants[(int) $action] & EGW_ACL_EDIT)) // might be ADD in the future { diff --git a/addressbook/inc/class.vcaladdressbook.inc.php b/addressbook/inc/class.vcaladdressbook.inc.php index 62e6e7d167..1fa69e0bb4 100644 --- a/addressbook/inc/class.vcaladdressbook.inc.php +++ b/addressbook/inc/class.vcaladdressbook.inc.php @@ -1,534 +1,504 @@ * - * -------------------------------------------- * - * This program is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 2 of the License. * - \**************************************************************************/ +/** + * Addressbook - vCard / iCal parser + * + * @link http://www.egroupware.org + * @author Lars Kneschke + * @author Ralf Becker + * @package addressbook + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @version $Id$ + */ - /* $Id$ */ +require_once EGW_SERVER_ROOT.'/addressbook/inc/class.bocontacts.inc.php'; +require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php'; - require_once EGW_SERVER_ROOT.'/addressbook/inc/class.boaddressbook.inc.php'; - require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php'; - - class vcaladdressbook extends boaddressbook +class vcaladdressbook extends bocontacts +{ + /** + * import a vard into addressbook + * + * @param string $_vcard the vcard + * @param int $_abID the internal addressbook id + * @param int $_vcardProfile profile id for mapping from vcard values to egw addressbook + * @return int contact id + */ + function addVCard($_vcard, $_abID) { - #function vcaladdressbook() - #{ - # $this->boaddressbook(); - #} - - /** - * @return int contact id - * @param string $_vcard the vcard - * @param int $_abID the internal addressbook id - * @param int $_vcardProfile profile id for mapping from vcard values to egw addressbook - * @desc import a vard into addressbook - */ - function addVCard($_vcard, $_abID) - { - if(!$contact = $this->vcardtoegw($_vcard)) { - return false; - } - - if($_abID > 0) - { - // update entry - $contact['ab_id'] = $_abID; - return $this->update_entry($contact); - } - else - { - // add entry - return $this->add_entry($contact); - } - } - - /** - * return a vcard - * - * @param int $_id the id of the contact - * @param int $_vcardProfile profile id for mapping from vcard values to egw addressbook - * @return string containing the vcard - */ - function getVCard($_id) - { - require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar/vcard.php'); - - $vCard =& new Horde_iCalendar_vcard; - - if(!is_array($this->supportedFields)) - { - $this->setSupportedFields(); - } - - foreach($this->supportedFields as $databaseFields) - { - foreach($databaseFields as $databaseField) - { - if(!empty($databaseField)) - { - $fields[] = $databaseField; - } - } - } - - #_debug_array($fields); - - if($this->check_perms($_id,EGW_ACL_READ)) - { - //$data = array('id' => $_id, 'fields' => $fields); - $entry = $this->so->read_entry($_id,$fields); - $entry = $this->strip_html($entry); - if($this->xmlrpc) - { - $entry = $this->data2xmlrpc($entry); - } - #_debug_array($entry); - $sysCharSet = $GLOBALS['egw']->translation->charset(); - - foreach($this->supportedFields as $vcardField => $databaseFields) - { - $options = array(); - $value = ''; - foreach($databaseFields as $databaseField) - { - $tempVal = ';'; - if(!empty($databaseField)) - { - #$tempVal = trim('value').';'; - $tempVal = trim($entry[0][$databaseField]).';'; - } - $value .= $tempVal; - } - // remove the last ; - $value = substr($value, 0, -1); - - switch($vcardField) - { - // TODO handle multiple categories - case 'CATEGORIES': - $catData = ExecMethod('phpgwapi.categories.return_single',$value); - $value = $catData[0]['name']; - break; - case 'CLASS': - $value = ($value == 'private' ? 'PRIVATE' : 'PUBLIC'); - break; - case 'BDAY': - if(!empty($value)) - { - $dateParts = explode('/',$value); - $value = sprintf('%04d%02d%02dT000000Z',$dateParts[2],$dateParts[0],$dateParts[1]); - } - break; - } - - $value = $GLOBALS['egw']->translation->convert($value,$sysCharSet,'utf-8'); - - // don't add the entry if it contains only ';' - if(strlen(str_replace(';','',$value)) != 0) - { - $vCard->setAttribute($vcardField, $value); - } - if(preg_match('/([\000-\012\015\016\020-\037\075])/',$value)) - { - $options['ENCODING'] = 'QUOTED-PRINTABLE'; - } - if(preg_match('/([\177-\377])/',$value)) - { - $options['CHARSET'] = 'UTF-8'; - } - $vCard->setParameter($vcardField, $options); - } - - $result = $vCard->exportvCalendar(); - - return $result; - } - - if($this->xmlrpc) - { - $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']); - } - return False; - } - - function search($_vcard) { - if(!$contact = $this->vcardtoegw($_vcard)) { - return false; - } - - if($foundContacts = $this->read_entries(array('query' => $contact))) { - return $foundContacts[0][id]; - } - + if(!$contact = $this->vcardtoegw($_vcard)) { return false; } - - function setSupportedFields($_productManufacturer='file', $_productName='') + + if($_abID) { - $defaultFields[0] = array( - 'ADR' => array('','','adr_one_street','adr_one_locality','adr_one_region', - 'adr_one_postalcode','adr_one_countryname'), - 'CATEGORIES' => array('cat_id'), - 'CLASS' => array('access'), - 'EMAIL' => array('email'), - 'N' => array('n_family','n_given','','',''), - 'NOTE' => array('note'), - 'ORG' => array('org_name',''), - 'TEL;CELL' => array('tel_cell'), - 'TEL;FAX' => array('tel_fax'), - 'TEL;HOME' => array('tel_home'), - 'TEL;WORK' => array('tel_work'), - 'TITLE' => array('title'), - ); + // update entry + $contact['ab_id'] = $_abID; + } + return $this->save($contact); + } - $defaultFields[1] = array( - 'ADR;WORK' => array('','','adr_one_street','adr_one_locality','adr_one_region', - 'adr_one_postalcode','adr_one_countryname'), - 'ADR;HOME' => array('','','adr_two_street','adr_two_locality','adr_two_region', - 'adr_two_postalcode','adr_two_countryname'), - 'BDAY' => array('bday'), - 'CATEGORIES' => array('cat_id'), - 'EMAIL;INTERNET;WORK' => array('email'), - 'EMAIL;INTERNET;HOME' => array('email_home'), - 'N' => array('n_family','n_given','n_middle','n_prefix','n_suffix'), - 'NOTE' => array('note'), - 'ORG' => array('org_name','org_unit'), - 'TEL;CELL;WORK' => array('tel_cell'), - 'TEL;FAX;WORK' => array('tel_fax'), - 'TEL;HOME' => array('tel_home'), - 'TEL;PAGER;WORK' => array('tel_pager'), - 'TEL;WORK' => array('tel_work'), - 'TITLE' => array('title'), - 'URL;WORK' => array('url'), - ); + /** + * return a vcard + * + * @param int/string $_id the id of the contact + * @param int $_vcardProfile profile id for mapping from vcard values to egw addressbook + * @return string containing the vcard + */ + function getVCard($_id) + { + require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar/vcard.php'); - $defaultFields[2] = array( - 'ADR;HOME' => array('','','adr_one_street','adr_one_locality','adr_one_region', - 'adr_one_postalcode','adr_one_countryname'), - 'BDAY' => array('bday'), - 'CATEGORIES' => array('cat_id'), - 'CLASS' => array('access'), - 'EMAIL' => array('email'), - 'N' => array('n_family','n_given','','',''), - 'NOTE' => array('note'), - 'ORG' => array('org_name',''), - 'TEL;CELL;WORK' => array('tel_cell'), - 'TEL;FAX;WORK' => array('tel_fax'), - 'TEL;HOME' => array('tel_home'), - 'TEL;WORK' => array('tel_work'), - 'TITLE' => array('title'), - 'URL' => array('url'), - ); + $vCard =& new Horde_iCalendar_vcard; - $defaultFields[3] = array( - 'ADR;WORK' => array('','','adr_one_street','adr_one_locality','adr_one_region', - 'adr_one_postalcode','adr_one_countryname'), - 'ADR;HOME' => array('','','adr_two_street','adr_two_locality','adr_two_region', - 'adr_two_postalcode','adr_two_countryname'), - 'BDAY' => array('bday'), - 'EMAIL;INTERNET;WORK' => array('email'), - 'EMAIL;INTERNET;HOME' => array('email_home'), - 'N' => array('n_family','n_given','','',''), - 'NOTE' => array('note'), - 'ORG' => array('org_name','org_unit'), - 'TEL;CELL;WORK' => array('tel_cell'), - 'TEL;FAX;WORK' => array('tel_fax'), - 'TEL;HOME' => array('tel_home'), - 'TEL;PAGER;WORK' => array('tel_pager'), - 'TEL;WORK' => array('tel_work'), - 'TITLE' => array('title'), - 'URL;WORK' => array('url'), - ); + if(!is_array($this->supportedFields)) + { + $this->setSupportedFields(); + } + $sysCharSet = $GLOBALS['egw']->translation->charset(); - switch(strtolower($_productManufacturer)) + if(!($entry = $this->read($_id))) + { + return false; + } + foreach($this->supportedFields as $vcardField => $databaseFields) + { + $options = array(); + $value = ''; + foreach($databaseFields as $databaseField) { - case 'nexthaus corporation': - switch(strtolower($_productName)) - { - case 'syncje outlook edition': - default: - $this->supportedFields = $defaultFields[1]; - break; - } - break; + $tempVal = ';'; + if(!empty($databaseField)) + { + $tempVal = trim($entry[$databaseField]).';'; + } + $value .= $tempVal; + } + // remove the last ; + $value = substr($value, 0, -1); - // multisync does not provide anymore information then the manufacturer - // we suppose multisync with evolution - case 'the multisync project': - switch(strtolower($_productName)) + switch($vcardField) + { + // TODO handle multiple categories + case 'CATEGORIES': + $catData = ExecMethod('phpgwapi.categories.return_single',$value); + $value = $catData[0]['name']; + break; + case 'CLASS': + $value = $value ? 'PRIVATE' : 'PUBLIC'; + break; + case 'BDAY': + if(!empty($value)) { - default: - $this->supportedFields = $defaultFields[0]; - break; + $value = str_replace('-','',$value).'T000000Z'; } break; - - case 'siemens': - switch(strtolower($_productName)) - { - case 'sx1': - default: - $this->supportedFields = $defaultFields[3]; - break; - } - break; - - case 'sonyericsson': - switch(strtolower($_productName)) - { - case 'd750i': - default: - $this->supportedFields = $defaultFields[2]; - break; - } - break; - - case 'synthesis ag': - switch(strtolower($_productName)) - { - default: - $this->supportedFields = $defaultFields[0]; - break; - } - break; - - case 'file': // used outside of SyncML, eg. by the calendar itself ==> all possible fields - $this->supportedFields = $defaultFields[1]; - break; - - // the fallback for SyncML - default: - error_log("Client not found: $_productManufacturer $_productName"); - $this->supportedFields = $defaultFields[0]; - break; } + if ($databaseField != 'jpegphoto') + { + $value = $GLOBALS['egw']->translation->convert($value,$sysCharSet,'utf-8'); + } + // don't add the entry if it contains only ';' + if(strlen(str_replace(';','',$value)) != 0) + { + $vCard->setAttribute($vcardField, $value); + } + if(preg_match('/([\000-\012\015\016\020-\037\075])/',$value)) + { + $options['ENCODING'] = 'QUOTED-PRINTABLE'; + } + if(preg_match('/([\177-\377])/',$value)) + { + $options['CHARSET'] = 'UTF-8'; + } + $vCard->setParameter($vcardField, $options); + } + + $result = $vCard->exportvCalendar(); + + return $result; + } + + function search($_vcard) + { + if(!($contact = $this->vcardtoegw($_vcard))) + { + return false; } - function vcardtoegw($_vcard) { - if(!is_array($this->supportedFields)) - { - $this->setSupportedFields(); - } + if(($foundContacts = $this->search($contact))) + { + return $foundContacts[0]['id']; + } + return false; + } - $this->supportedFields[0] = array( - ); + function setSupportedFields($_productManufacturer='file', $_productName='') + { + /** + * ToDo Lars: + * + changes / renamed fields in 1.3+: + * - access --> private (already done by Ralf) + * - tel_msg --> tel_assistent + * - tel_modem --> tel_fax_home + * - tel_isdn --> tel_cell_private + * - tel_voice/ophone --> tel_other + * - address2 --> adr_one_street2 + * - address3 --> adr_two_street2 + * - freebusy_url --> freebusy_uri (i instead l !) + * - fn --> n_fn + * - last_mod --> modified + * + new fields in 1.3+: + * - n_fileas + * - role + * - assistent + * - room + * - calendar_uri + * - url_home + * - created + * - creator (preset with owner) + * - modifier + * - jpegphoto + */ + $defaultFields[0] = array( + 'ADR' => array('','','adr_one_street','adr_one_locality','adr_one_region', + 'adr_one_postalcode','adr_one_countryname'), + 'CATEGORIES' => array('cat_id'), + 'CLASS' => array('private'), + 'EMAIL' => array('email'), + 'N' => array('n_family','n_given','','',''), + 'NOTE' => array('note'), + 'ORG' => array('org_name',''), + 'TEL;CELL' => array('tel_cell'), + 'TEL;FAX' => array('tel_fax'), + 'TEL;HOME' => array('tel_home'), + 'TEL;WORK' => array('tel_work'), + 'TITLE' => array('title'), + ); - require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php'); + $defaultFields[1] = array( + 'ADR;WORK' => array('','','adr_one_street','adr_one_locality','adr_one_region', + 'adr_one_postalcode','adr_one_countryname'), + 'ADR;HOME' => array('','','adr_two_street','adr_two_locality','adr_two_region', + 'adr_two_postalcode','adr_two_countryname'), + 'BDAY' => array('bday'), + 'CATEGORIES' => array('cat_id'), + 'EMAIL;INTERNET;WORK' => array('email'), + 'EMAIL;INTERNET;HOME' => array('email_home'), + 'N' => array('n_family','n_given','n_middle','n_prefix','n_suffix'), + 'NOTE' => array('note'), + 'ORG' => array('org_name','org_unit'), + 'TEL;CELL;WORK' => array('tel_cell'), + 'TEL;FAX;WORK' => array('tel_fax'), + 'TEL;HOME' => array('tel_home'), + 'TEL;PAGER;WORK' => array('tel_pager'), + 'TEL;WORK' => array('tel_work'), + 'TITLE' => array('title'), + 'URL;WORK' => array('url'), + ); - $vCard = Horde_iCalendar::newComponent('vcard', $container); + $defaultFields[2] = array( + 'ADR;HOME' => array('','','adr_one_street','adr_one_locality','adr_one_region', + 'adr_one_postalcode','adr_one_countryname'), + 'BDAY' => array('bday'), + 'CATEGORIES' => array('cat_id'), + 'CLASS' => array('private'), + 'EMAIL' => array('email'), + 'N' => array('n_family','n_given','','',''), + 'NOTE' => array('note'), + 'ORG' => array('org_name',''), + 'TEL;CELL;WORK' => array('tel_cell'), + 'TEL;FAX;WORK' => array('tel_fax'), + 'TEL;HOME' => array('tel_home'), + 'TEL;WORK' => array('tel_work'), + 'TITLE' => array('title'), + 'URL' => array('url'), + ); - if(!$vCard->parsevCalendar($_vcard,'VCARD')) - { - return False; - } - $vcardValues = $vCard->getAllAttributes(); + $defaultFields[3] = array( + 'ADR;WORK' => array('','','adr_one_street','adr_one_locality','adr_one_region', + 'adr_one_postalcode','adr_one_countryname'), + 'ADR;HOME' => array('','','adr_two_street','adr_two_locality','adr_two_region', + 'adr_two_postalcode','adr_two_countryname'), + 'BDAY' => array('bday'), + 'EMAIL;INTERNET;WORK' => array('email'), + 'EMAIL;INTERNET;HOME' => array('email_home'), + 'N' => array('n_family','n_given','','',''), + 'NOTE' => array('note'), + 'ORG' => array('org_name','org_unit'), + 'TEL;CELL;WORK' => array('tel_cell'), + 'TEL;FAX;WORK' => array('tel_fax'), + 'TEL;HOME' => array('tel_home'), + 'TEL;PAGER;WORK' => array('tel_pager'), + 'TEL;WORK' => array('tel_work'), + 'TITLE' => array('title'), + 'URL;WORK' => array('url'), + ); - #print "
$_vcard
"; - - #_debug_array($vcardValues); - - foreach($vcardValues as $key => $vcardRow) - { - $rowName = $vcardRow['name']; - $mailtype = ';INTERNET'; - $tempVal = ';WORK'; - - if(isset($vcardRow['params']['INTERNET'])) + switch(strtolower($_productManufacturer)) + { + case 'nexthaus corporation': + switch(strtolower($_productName)) { - $rowName .= ";INTERNET"; - } - if(isset($vcardRow['params']['CELL'])) - { - $rowName .= ';CELL'; - } - if(isset($vcardRow['params']['FAX'])) - { - $rowName .= ';FAX'; - } - if(isset($vcardRow['params']['PAGER'])) - { - $rowName .= ';PAGER'; - } - if(isset($vcardRow['params']['WORK'])) - { - $rowName .= ';WORK'; - } - if(isset($vcardRow['params']['HOME'])) - { - $rowName .= ';HOME'; - } - - $rowNames[$rowName] = $key; - } - - #error_log('rowNames: '.print_r($rowNames,true)); - - // now we have all rowNames the vcard provides - // we just need to map to the right addressbook fieldnames - // we need also to take care about ADR for example. we do not - // support this. We support only ADR;WORK or ADR;HOME - - foreach($rowNames as $rowName => $vcardKey) - { - switch($rowName) - { - case 'ADR': - case 'TEL': - case 'TEL;FAX': - case 'TEL;CELL': - case 'TEL;PAGER': - if(!isset($rowNames[$rowName. ';WORK'])) - { - $finalRowNames[$rowName. ';WORK'] = $vcardKey; - } - break; - case 'EMAIL': - case 'EMAIL;WORK': - if(!isset($rowNames['EMAIL;INTERNET;WORK'])) - { - $finalRowNames['EMAIL;INTERNET;WORK'] = $vcardKey; - } - break; - case 'EMAIL;HOME': - if(!isset($rowNames['EMAIL;INTERNET;HOME'])) - { - $finalRowNames['EMAIL;INTERNET;HOME'] = $vcardKey; - } - break; - - case 'CATEGORIES': - #cat_id = 7,8 - $vcardData['category'] = array(); - if ($attributes['value']) - { - if (!is_object($this->cat)) - { - if (!is_object($GLOBALS['egw']->categories)) - { - $GLOBALS['egw']->categories =& CreateObject('phpgwapi.categories',$this->owner,'addressbook'); - } - $this->cat =& $GLOBALS['egw']->categories; - } - foreach(explode(',',$attributes['value']) as $cat_name) - { - if (!($cat_id = $this->cat->name2id($cat_name))) - { - $cat_id = $this->cat->add( array('name' => $cat_name,'descr' => $cat_name )); - } - $vcardData['category'][] = $cat_id; - } - } - break; - - case 'VERSION': - break; + case 'syncje outlook edition': default: - $finalRowNames[$rowName] = $vcardKey; + $this->supportedFields = $defaultFields[1]; break; } + break; + + // multisync does not provide anymore information then the manufacturer + // we suppose multisync with evolution + case 'the multisync project': + switch(strtolower($_productName)) + { + default: + $this->supportedFields = $defaultFields[0]; + break; + } + break; + + case 'siemens': + switch(strtolower($_productName)) + { + case 'sx1': + default: + $this->supportedFields = $defaultFields[3]; + break; + } + break; + + case 'sonyericsson': + switch(strtolower($_productName)) + { + case 'd750i': + default: + $this->supportedFields = $defaultFields[2]; + break; + } + break; + + case 'synthesis ag': + switch(strtolower($_productName)) + { + default: + $this->supportedFields = $defaultFields[0]; + break; + } + break; + + case 'file': // used outside of SyncML, eg. by the calendar itself ==> all possible fields + $this->supportedFields = $defaultFields[1]; + break; + + // the fallback for SyncML + default: + error_log("Client not found: $_productManufacturer $_productName"); + $this->supportedFields = $defaultFields[0]; + break; + } + } + + function vcardtoegw($_vcard) + { + // convert from utf-8 to eGW's charset + $_vcard = $GLOBALS['egw']->translation->convert($_vcard,'utf-8'); + + if(!is_array($this->supportedFields)) + { + $this->setSupportedFields(); + } + + $this->supportedFields[0] = array( + ); + + require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php'); + + $vCard = Horde_iCalendar::newComponent('vcard', $container); + + if(!$vCard->parsevCalendar($_vcard,'VCARD')) + { + return False; + } + $vcardValues = $vCard->getAllAttributes(); + + #print "
$_vcard
"; + + #_debug_array($vcardValues); + + foreach($vcardValues as $key => $vcardRow) + { + $rowName = $vcardRow['name']; + + if(isset($vcardRow['params']['INTERNET'])) + { + $rowName .= ";INTERNET"; + } + if(isset($vcardRow['params']['CELL'])) + { + $rowName .= ';CELL'; + } + if(isset($vcardRow['params']['FAX'])) + { + $rowName .= ';FAX'; + } + if(isset($vcardRow['params']['PAGER'])) + { + $rowName .= ';PAGER'; + } + if(isset($vcardRow['params']['WORK'])) + { + $rowName .= ';WORK'; + } + if(isset($vcardRow['params']['HOME'])) + { + $rowName .= ';HOME'; } - #_debug_array($finalRowNames); - $contact = array(); + $rowNames[$rowName] = $key; + } - foreach($finalRowNames as $key => $vcardKey) + #error_log('rowNames: '.print_r($rowNames,true)); + + // now we have all rowNames the vcard provides + // we just need to map to the right addressbook fieldnames + // we need also to take care about ADR for example. we do not + // support this. We support only ADR;WORK or ADR;HOME + + foreach($rowNames as $rowName => $vcardKey) + { + switch($rowName) { - if(isset($this->supportedFields[$key])) - { - $fieldNames = $this->supportedFields[$key]; - foreach($fieldNames as $fieldKey => $fieldName) + case 'ADR': + case 'TEL': + case 'TEL;FAX': + case 'TEL;CELL': + case 'TEL;PAGER': + if(!isset($rowNames[$rowName. ';WORK'])) { - if(!empty($fieldName)) + $finalRowNames[$rowName. ';WORK'] = $vcardKey; + } + break; + case 'EMAIL': + case 'EMAIL;WORK': + if(!isset($rowNames['EMAIL;INTERNET;WORK'])) + { + $finalRowNames['EMAIL;INTERNET;WORK'] = $vcardKey; + } + break; + case 'EMAIL;HOME': + if(!isset($rowNames['EMAIL;INTERNET;HOME'])) + { + $finalRowNames['EMAIL;INTERNET;HOME'] = $vcardKey; + } + break; + + case 'CATEGORIES': + #cat_id = 7,8 + $vcardData['category'] = array(); + if ($attributes['value']) + { + if (!is_object($this->cat)) { - switch($fieldName) + if (!is_object($GLOBALS['egw']->categories)) { - case 'access': - if($vcardValues[$vcardKey]['values'][$fieldKey] == 'PRIVATE') - { - $contact[$fieldName] = 'private'; - } - else - { - $contact[$fieldName] = 'public'; - } - break; - case 'cat_id': - if (!is_object($this->cat)) - { - if (!is_object($GLOBALS['egw']->categories)) - { - $GLOBALS['egw']->categories =& CreateObject('phpgwapi.categories',$GLOBALS['egw_info']['user']['account_id'],'addressbook'); - } - $this->cat =& $GLOBALS['egw']->categories; - } - foreach(explode(',',$vcardValues[$vcardKey]['values'][$fieldKey]) as $cat_name) - { - if (!($cat_id = $this->cat->name2id($cat_name))) - { - $cat_id = $this->cat->add( array('name' => $cat_name,'descr' => $cat_name )); - } - $contact[$fieldName] = $cat_id; - } - break; - default: - $contact[$fieldName] = $vcardValues[$vcardKey]['values'][$fieldKey]; - break; + $GLOBALS['egw']->categories =& CreateObject('phpgwapi.categories',$this->owner,'addressbook'); } + $this->cat =& $GLOBALS['egw']->categories; + } + foreach(explode(',',$attributes['value']) as $cat_name) + { + if (!($cat_id = $this->cat->name2id($cat_name))) + { + $cat_id = $this->cat->add( array('name' => $cat_name,'descr' => $cat_name )); + } + $vcardData['category'][] = $cat_id; + } + } + break; + + case 'VERSION': + break; + default: + $finalRowNames[$rowName] = $vcardKey; + break; + } + } + + #_debug_array($finalRowNames); + $contact = array(); + + foreach($finalRowNames as $key => $vcardKey) + { + if(isset($this->supportedFields[$key])) + { + $fieldNames = $this->supportedFields[$key]; + foreach($fieldNames as $fieldKey => $fieldName) + { + if(!empty($fieldName)) + { + switch($fieldName) + { + case 'private': + $contact[$fieldName] = (int) $vcardValues[$vcardKey]['values'][$fieldKey] == 'PRIVATE'; + break; + case 'cat_id': + if (!is_object($this->cat)) + { + if (!is_object($GLOBALS['egw']->categories)) + { + $GLOBALS['egw']->categories =& CreateObject('phpgwapi.categories',$GLOBALS['egw_info']['user']['account_id'],'addressbook'); + } + $this->cat =& $GLOBALS['egw']->categories; + } + foreach(explode(',',$vcardValues[$vcardKey]['values'][$fieldKey]) as $cat_name) + { + if (!($cat_id = $this->cat->name2id($cat_name))) + { + $cat_id = $this->cat->add( array('name' => $cat_name,'descr' => $cat_name )); + } + $contact[$fieldName] = $cat_id; + } + break; + default: + $contact[$fieldName] = $vcardValues[$vcardKey]['values'][$fieldKey]; + break; } } } } - - #return true; - - /* _debug_array($contact);exit; */ - $contact['fn'] = trim($contact['n_given'].' '.$contact['n_family']); - if(!$contact['tel_work']) - { - $contact['tel_work'] = ''; - } - if(!$contact['tel_home']) - { - $contact['tel_home'] = ''; - } - if(!$contact['tel_voice']) - { - $contact['tel_voice'] = ''; - } - if(!$contact['tel_fax']) - { - $contact['tel_fax'] = ''; - } - if(!$contact['tel_msg']) - { - $contact['tel_msg'] = ''; - } - if(!$contact['tel_cell']) - { - $contact['tel_cell'] = ''; - } - if(!$contact['tel_pager']) - { - $contact['tel_pager'] = ''; - } - if(!$contact['tel_car']) - { - $contact['tel_car'] = ''; - } - if(!$contact['tel_isdn']) - { - $contact['tel_isdn'] = ''; - } - if(!$contact['tel_video']) - { - $contact['tel_video'] = ''; - } - - return $contact; } + $contact['n_fn'] = trim($contact['n_given'].' '.$contact['n_family']); + + return $contact; } + + /** + * Exports some contacts: download or write to a file + * + * @param array $ids contact-ids + * @param string $file filename or null for download + */ + function export($ids,$file=null) + { + if (!$file) + { + $browser =& CreateObject('phpgwapi.browser'); + $browser->content_header('addressbook.vcf','text/x-vcard'); + } + if (!($fp = fopen($file ? $file : 'php://output','w'))) + { + return false; + } + foreach($ids as $id) + { + fwrite($fp,$this->getVCard($id)); + } + fclose($fp); + + if (!$file) + { + $GLOBALS['egw']->common->egw_exit(); + } + return true; + } +}