| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663 | 
							- <?php
 - 
 - /**
 -  +-----------------------------------------------------------------------+
 -  | This file is part of the Roundcube Webmail client                     |
 -  | Copyright (C) 2008-2012, The Roundcube Dev Team                       |
 -  |                                                                       |
 -  | Licensed under the GNU General Public License version 3 or            |
 -  | any later version with exceptions for skins & plugins.                |
 -  | See the README file for a full license statement.                     |
 -  |                                                                       |
 -  | PURPOSE:                                                              |
 -  |   CSV to vCard data conversion                                        |
 -  +-----------------------------------------------------------------------+
 -  | Author: Aleksander Machniak <alec@alec.pl>                            |
 -  +-----------------------------------------------------------------------+
 - */
 - 
 - /**
 -  * CSV to vCard data converter
 -  *
 -  * @package    Framework
 -  * @subpackage Addressbook
 -  * @author     Aleksander Machniak <alec@alec.pl>
 -  */
 - class rcube_csv2vcard
 - {
 -     /**
 -      * CSV to vCard fields mapping
 -      *
 -      * @var array
 -      */
 -     protected $csv2vcard_map = array(
 -         // MS Outlook 2010
 -         'anniversary'           => 'anniversary',
 -         'assistants_name'       => 'assistant',
 -         'assistants_phone'      => 'phone:assistant',
 -         'birthday'              => 'birthday',
 -         'business_city'         => 'locality:work',
 -         'business_countryregion' => 'country:work',
 -         'business_fax'          => 'phone:work,fax',
 -         'business_phone'        => 'phone:work',
 -         'business_phone_2'      => 'phone:work2',
 -         'business_postal_code'  => 'zipcode:work',
 -         'business_state'        => 'region:work',
 -         'business_street'       => 'street:work',
 -         //'business_street_2'     => '',
 -         //'business_street_3'     => '',
 -         'car_phone'             => 'phone:car',
 -         'categories'            => 'groups',
 -         //'children'              => '',
 -         'company'               => 'organization',
 -         //'company_main_phone'    => '',
 -         'department'            => 'department',
 -         'email_2_address'       => 'email:other',
 -         //'email_2_type'          => '',
 -         'email_3_address'       => 'email:other',
 -         //'email_3_type'          => '',
 -         'email_address'         => 'email:pref',
 -         //'email_type'            => '',
 -         'first_name'            => 'firstname',
 -         'gender'                => 'gender',
 -         'home_city'             => 'locality:home',
 -         'home_countryregion'    => 'country:home',
 -         'home_fax'              => 'phone:home,fax',
 -         'home_phone'            => 'phone:home',
 -         'home_phone_2'          => 'phone:home2',
 -         'home_postal_code'      => 'zipcode:home',
 -         'home_state'            => 'region:home',
 -         'home_street'           => 'street:home',
 -         //'home_street_2'         => '',
 -         //'home_street_3'         => '',
 -         //'initials'              => '',
 -         //'isdn'                  => '',
 -         'job_title'             => 'jobtitle',
 -         //'keywords'              => '',
 -         //'language'              => '',
 -         'last_name'             => 'surname',
 -         //'location'              => '',
 -         'managers_name'         => 'manager',
 -         'middle_name'           => 'middlename',
 -         //'mileage'               => '',
 -         'mobile_phone'          => 'phone:cell',
 -         'notes'                 => 'notes',
 -         //'office_location'       => '',
 -         'other_city'            => 'locality:other',
 -         'other_countryregion'   => 'country:other',
 -         'other_fax'             => 'phone:other,fax',
 -         'other_phone'           => 'phone:other',
 -         'other_postal_code'     => 'zipcode:other',
 -         'other_state'           => 'region:other',
 -         'other_street'          => 'street:other',
 -         //'other_street_2'        => '',
 -         //'other_street_3'        => '',
 -         'pager'                 => 'phone:pager',
 -         'primary_phone'         => 'phone:pref',
 -         //'profession'            => '',
 -         //'radio_phone'           => '',
 -         'spouse'                => 'spouse',
 -         'suffix'                => 'suffix',
 -         'title'                 => 'title',
 -         'web_page'              => 'website:homepage',
 - 
 -         // Thunderbird
 -         'birth_day'             => 'birthday-d',
 -         'birth_month'           => 'birthday-m',
 -         'birth_year'            => 'birthday-y',
 -         'display_name'          => 'displayname',
 -         'fax_number'            => 'phone:fax',
 -         'home_address'          => 'street:home',
 -         //'home_address_2'        => '',
 -         'home_country'          => 'country:home',
 -         'home_zipcode'          => 'zipcode:home',
 -         'mobile_number'         => 'phone:cell',
 -         'nickname'              => 'nickname',
 -         'organization'          => 'organization',
 -         'pager_number'          => 'phone:pager',
 -         'primary_email'         => 'email:pref',
 -         'secondary_email'       => 'email:other',
 -         'web_page_1'            => 'website:homepage',
 -         'web_page_2'            => 'website:other',
 -         'work_phone'            => 'phone:work',
 -         'work_address'          => 'street:work',
 -         //'work_address_2'        => '',
 -         'work_country'          => 'country:work',
 -         'work_zipcode'          => 'zipcode:work',
 -         'last'                  => 'surname',
 -         'first'                 => 'firstname',
 -         'work_city'             => 'locality:work',
 -         'work_state'            => 'region:work',
 -         'home_city_short'       => 'locality:home',
 -         'home_state_short'      => 'region:home',
 - 
 -         // Atmail
 -         'date_of_birth'         => 'birthday',
 -         'email'                 => 'email:pref',
 -         'home_mobile'           => 'phone:cell',
 -         'home_zip'              => 'zipcode:home',
 -         'info'                  => 'notes',
 -         'user_photo'            => 'photo',
 -         'url'                   => 'website:homepage',
 -         'work_company'          => 'organization',
 -         'work_dept'             => 'departament',
 -         'work_fax'              => 'phone:work,fax',
 -         'work_mobile'           => 'phone:work,cell',
 -         'work_title'            => 'jobtitle',
 -         'work_zip'              => 'zipcode:work',
 -         'group'                 => 'groups',
 - 
 -         // GMail
 -         'groups'                => 'groups',
 -         'group_membership'      => 'groups',
 -         'given_name'            => 'firstname',
 -         'additional_name'       => 'middlename',
 -         'family_name'           => 'surname',
 -         'name'                  => 'displayname',
 -         'name_prefix'           => 'prefix',
 -         'name_suffix'           => 'suffix',
 -     );
 - 
 -     /**
 -      * CSV label to text mapping for English
 -      *
 -      * @var array
 -      */
 -     protected $label_map = array(
 -         // MS Outlook 2010
 -         'anniversary'       => "Anniversary",
 -         'assistants_name'   => "Assistant's Name",
 -         'assistants_phone'  => "Assistant's Phone",
 -         'birthday'          => "Birthday",
 -         'business_city'     => "Business City",
 -         'business_countryregion' => "Business Country/Region",
 -         'business_fax'      => "Business Fax",
 -         'business_phone'    => "Business Phone",
 -         'business_phone_2'  => "Business Phone 2",
 -         'business_postal_code' => "Business Postal Code",
 -         'business_state'    => "Business State",
 -         'business_street'   => "Business Street",
 -         //'business_street_2' => "Business Street 2",
 -         //'business_street_3' => "Business Street 3",
 -         'car_phone'         => "Car Phone",
 -         'categories'        => "Categories",
 -         //'children'          => "Children",
 -         'company'           => "Company",
 -         //'company_main_phone' => "Company Main Phone",
 -         'department'        => "Department",
 -         //'directory_server'  => "Directory Server",
 -         'email_2_address'   => "E-mail 2 Address",
 -         //'email_2_type'      => "E-mail 2 Type",
 -         'email_3_address'   => "E-mail 3 Address",
 -         //'email_3_type'      => "E-mail 3 Type",
 -         'email_address'     => "E-mail Address",
 -         //'email_type'        => "E-mail Type",
 -         'first_name'        => "First Name",
 -         'gender'            => "Gender",
 -         'home_city'         => "Home City",
 -         'home_countryregion' => "Home Country/Region",
 -         'home_fax'          => "Home Fax",
 -         'home_phone'        => "Home Phone",
 -         'home_phone_2'      => "Home Phone 2",
 -         'home_postal_code'  => "Home Postal Code",
 -         'home_state'        => "Home State",
 -         'home_street'       => "Home Street",
 -         //'home_street_2'     => "Home Street 2",
 -         //'home_street_3'     => "Home Street 3",
 -         //'initials'          => "Initials",
 -         //'isdn'              => "ISDN",
 -         'job_title'         => "Job Title",
 -         //'keywords'          => "Keywords",
 -         //'language'          => "Language",
 -         'last_name'         => "Last Name",
 -         //'location'          => "Location",
 -         'managers_name'     => "Manager's Name",
 -         'middle_name'       => "Middle Name",
 -         //'mileage'           => "Mileage",
 -         'mobile_phone'      => "Mobile Phone",
 -         'notes'             => "Notes",
 -         //'office_location'   => "Office Location",
 -         'other_city'        => "Other City",
 -         'other_countryregion' => "Other Country/Region",
 -         'other_fax'         => "Other Fax",
 -         'other_phone'       => "Other Phone",
 -         'other_postal_code' => "Other Postal Code",
 -         'other_state'       => "Other State",
 -         'other_street'      => "Other Street",
 -         //'other_street_2'    => "Other Street 2",
 -         //'other_street_3'    => "Other Street 3",
 -         'pager'             => "Pager",
 -         'primary_phone'     => "Primary Phone",
 -         //'profession'        => "Profession",
 -         //'radio_phone'       => "Radio Phone",
 -         'spouse'            => "Spouse",
 -         'suffix'            => "Suffix",
 -         'title'             => "Title",
 -         'web_page'          => "Web Page",
 - 
 -         // Thunderbird
 -         'birth_day'         => "Birth Day",
 -         'birth_month'       => "Birth Month",
 -         'birth_year'        => "Birth Year",
 -         'display_name'      => "Display Name",
 -         'fax_number'        => "Fax Number",
 -         'home_address'      => "Home Address",
 -         //'home_address_2'    => "Home Address 2",
 -         'home_country'      => "Home Country",
 -         'home_zipcode'      => "Home ZipCode",
 -         'mobile_number'     => "Mobile Number",
 -         'nickname'          => "Nickname",
 -         'organization'      => "Organization",
 -         'pager_number'      => "Pager Namber",
 -         'primary_email'     => "Primary Email",
 -         'secondary_email'   => "Secondary Email",
 -         'web_page_1'        => "Web Page 1",
 -         'web_page_2'        => "Web Page 2",
 -         'work_phone'        => "Work Phone",
 -         'work_address'      => "Work Address",
 -         //'work_address_2'    => "Work Address 2",
 -         'work_city'         => "Work City",
 -         'work_country'      => "Work Country",
 -         'work_state'        => "Work State",
 -         'work_zipcode'      => "Work ZipCode",
 - 
 -         // Atmail
 -         'date_of_birth'     => "Date of Birth",
 -         'email'             => "Email",
 -         //'email_2'         => "Email2",
 -         //'email_3'         => "Email3",
 -         //'email_4'         => "Email4",
 -         //'email_5'         => "Email5",
 -         'home_mobile'       => "Home Mobile",
 -         'home_zip'          => "Home Zip",
 -         'info'              => "Info",
 -         'user_photo'        => "User Photo",
 -         'url'               => "URL",
 -         'work_company'      => "Work Company",
 -         'work_dept'         => "Work Dept",
 -         'work_fax'          => "Work Fax",
 -         'work_mobile'       => "Work Mobile",
 -         'work_title'        => "Work Title",
 -         'work_zip'          => "Work Zip",
 -         'group'             => "Group",
 - 
 -         // GMail
 -         'groups'            => "Groups",
 -         'group_membership'  => "Group Membership",
 -         'given_name'        => "Given Name",
 -         'additional_name'   => "Additional Name",
 -         'family_name'       => "Family Name",
 -         'name'              => "Name",
 -         'name_prefix'       => "Name Prefix",
 -         'name_suffix'       => "Name Suffix",
 -     );
 - 
 -     /**
 -      * Special fields map for GMail format
 -      *
 -      * @var array
 -      */
 -     protected $gmail_label_map = array(
 -         'E-mail' => array(
 -             'Value' => array(
 -                 'home' => 'email:home',
 -                 'work' => 'email:work',
 -                 '*'    => 'email:other',
 -             ),
 -         ),
 -         'Phone' => array(
 -             'Value' => array(
 -                 'home'    => 'phone:home',
 -                 'homefax' => 'phone:homefax',
 -                 'main'    => 'phone:pref',
 -                 'pager'   => 'phone:pager',
 -                 'mobile'  => 'phone:cell',
 -                 'work'    => 'phone:work',
 -                 'workfax' => 'phone:workfax',
 -             ),
 -         ),
 -         'Relation' => array(
 -             'Value' => array(
 -                 'spouse' => 'spouse',
 -             ),
 -         ),
 -         'Website' => array(
 -             'Value' => array(
 -                 'profile'  => 'website:profile',
 -                 'blog'     => 'website:blog',
 -                 'homepage' => 'website:homepage',
 -                 'work'     => 'website:work',
 -             ),
 -         ),
 -         'Address' => array(
 -             'Street' => array(
 -                 'home' => 'street:home',
 -                 'work' => 'street:work',
 -             ),
 -             'City' => array(
 -                 'home' => 'locality:home',
 -                 'work' => 'locality:work',
 -             ),
 -             'Region' => array(
 -                 'home' => 'region:home',
 -                 'work' => 'region:work',
 -             ),
 -             'Postal Code' => array(
 -                 'home' => 'zipcode:home',
 -                 'work' => 'zipcode:work',
 -             ),
 -             'Country' => array(
 -                 'home' => 'country:home',
 -                 'work' => 'country:work',
 -             ),
 -         ),
 -         'Organization' => array(
 -             'Name' => array(
 -                 '' => 'organization',
 -             ),
 -             'Title' => array(
 -                 '' => 'jobtitle',
 -             ),
 -             'Department' => array(
 -                 '' => 'department',
 -             ),
 -         ),
 -     );
 - 
 - 
 -     protected $local_label_map = array();
 -     protected $vcards          = array();
 -     protected $map             = array();
 -     protected $gmail_map       = array();
 - 
 - 
 -     /**
 -      * Class constructor
 -      *
 -      * @param string $lang File language
 -      */
 -     public function __construct($lang = 'en_US')
 -     {
 -         // Localize fields map
 -         if ($lang && $lang != 'en_US') {
 -             if (file_exists(RCUBE_LOCALIZATION_DIR . "$lang/csv2vcard.inc")) {
 -                 include RCUBE_LOCALIZATION_DIR . "$lang/csv2vcard.inc";
 -             }
 - 
 -             if (!empty($map)) {
 -                 $this->local_label_map = array_merge($this->label_map, $map);
 -             }
 -         }
 - 
 -         $this->label_map = array_flip($this->label_map);
 -         $this->local_label_map = array_flip($this->local_label_map);
 -     }
 - 
 -     /**
 -      * Import contacts from CSV file
 -      *
 -      * @param string $csv Content of the CSV file
 -      */
 -     public function import($csv)
 -     {
 -         // convert to UTF-8
 -         $head      = substr($csv, 0, 4096);
 -         $charset   = rcube_charset::detect($head, RCUBE_CHARSET);
 -         $csv       = rcube_charset::convert($csv, $charset);
 -         $csv       = preg_replace(array('/^[\xFE\xFF]{2}/', '/^\xEF\xBB\xBF/', '/^\x00+/'), '', $csv); // also remove BOM
 -         $head      = '';
 -         $prev_line = false;
 - 
 -         $this->map       = array();
 -         $this->gmail_map = array();
 - 
 -         // Parse file
 -         foreach (preg_split("/[\r\n]+/", $csv) as $line) {
 -             if (!empty($prev_line)) {
 -                 $line = '"' . $line;
 -             }
 - 
 -             $elements = $this->parse_line($line);
 - 
 -             if (empty($elements)) {
 -                 continue;
 -             }
 - 
 -             // Parse header
 -             if (empty($this->map)) {
 -                 $this->parse_header($elements);
 -                 if (empty($this->map)) {
 -                     break;
 -                 }
 -             }
 -             // Parse data row
 -             else {
 -                 // handle multiline elements (e.g. Gmail)
 -                 if (!empty($prev_line)) {
 -                     $first = array_shift($elements);
 - 
 -                     if ($first[0] == '"') {
 -                         $prev_line[count($prev_line)-1] = '"' . $prev_line[count($prev_line)-1] . "\n" . substr($first, 1);
 -                     }
 -                     else {
 -                         $prev_line[count($prev_line)-1] .= "\n" . $first;
 -                     }
 - 
 -                     $elements = array_merge($prev_line, $elements);
 -                 }
 - 
 -                 $last_element = $elements[count($elements)-1];
 -                 if ($last_element[0] == '"') {
 -                     $elements[count($elements)-1] = substr($last_element, 1);
 -                     $prev_line = $elements;
 -                     continue;
 -                 }
 -                 $this->csv_to_vcard($elements);
 -                 $prev_line = false;
 -             }
 -         }
 -     }
 - 
 -     /**
 -      * Export vCards
 -      *
 -      * @return array rcube_vcard List of vcards
 -      */
 -     public function export()
 -     {
 -         return $this->vcards;
 -     }
 - 
 -     /**
 -      * Parse CSV file line
 -      */
 -     protected function parse_line($line)
 -     {
 -         $line = trim($line);
 -         if (empty($line)) {
 -             return null;
 -         }
 - 
 -         $fields = rcube_utils::explode_quoted_string(',', $line);
 - 
 -         // remove quotes if needed
 -         if (!empty($fields)) {
 -             foreach ($fields as $idx => $value) {
 -                 if (($len = strlen($value)) > 1 && $value[0] == '"' && $value[$len-1] == '"') {
 -                     // remove surrounding quotes
 -                     $value = substr($value, 1, -1);
 -                     // replace doubled quotes inside the string with single quote
 -                     $value = str_replace('""', '"', $value);
 - 
 -                     $fields[$idx] = $value;
 -                 }
 -             }
 -         }
 - 
 -         return $fields;
 -     }
 - 
 -     /**
 -      * Parse CSV header line, detect fields mapping
 -      */
 -     protected function parse_header($elements)
 -     {
 -         $map1 = array();
 -         $map2 = array();
 -         $size = count($elements);
 - 
 -         // check English labels
 -         for ($i = 0; $i < $size; $i++) {
 -             $label = $this->label_map[$elements[$i]];
 -             if ($label && !empty($this->csv2vcard_map[$label])) {
 -                 $map1[$i] = $this->csv2vcard_map[$label];
 -             }
 -         }
 - 
 -         // check localized labels
 -         if (!empty($this->local_label_map)) {
 -             for ($i = 0; $i < $size; $i++) {
 -                 $label = $this->local_label_map[$elements[$i]];
 - 
 -                 // special localization label
 -                 if ($label && $label[0] == '_') {
 -                     $label = substr($label, 1);
 -                 }
 - 
 -                 if ($label && !empty($this->csv2vcard_map[$label])) {
 -                     $map2[$i] = $this->csv2vcard_map[$label];
 -                 }
 -             }
 -         }
 - 
 -         $this->map = count($map1) >= count($map2) ? $map1 : $map2;
 - 
 -         // support special Gmail format
 -         foreach ($this->gmail_label_map as $key => $items) {
 -             $num = 1;
 -             while (($_key = "$key $num - Type") && ($found = array_search($_key, $elements)) !== false) {
 -                 $this->gmail_map["$key:$num"] = array('_key' => $key, '_idx' => $found);
 -                 foreach (array_keys($items) as $item_key) {
 -                     $_key = "$key $num - $item_key";
 -                     if (($found = array_search($_key, $elements)) !== false) {
 -                         $this->gmail_map["$key:$num"][$item_key] = $found;
 -                     }
 -                 }
 - 
 -                 $num++;
 -             }
 -         }
 -     }
 - 
 -     /**
 -      * Convert CSV data row to vCard
 -      */
 -     protected function csv_to_vcard($data)
 -     {
 -         $contact = array();
 -         foreach ($this->map as $idx => $name) {
 -             $value = $data[$idx];
 -             if ($value !== null && $value !== '') {
 -                 if (!empty($contact[$name])) {
 -                     $contact[$name]   = (array) $contact[$name];
 -                     $contact[$name][] = $value;
 -                 }
 -                 else {
 -                    $contact[$name] = $value;
 -                 }
 -             }
 -         }
 - 
 -         // Gmail format support
 -         foreach ($this->gmail_map as $idx => $item) {
 -             $type = preg_replace('/[^a-z]/', '', strtolower($data[$item['_idx']]));
 -             $key  = $item['_key'];
 - 
 -             unset($item['_idx']);
 -             unset($item['_key']);
 - 
 -             foreach ($item as $item_key => $item_idx) {
 -                 $value = $data[$item_idx];
 -                 if ($value !== null && $value !== '') {
 -                     foreach (array($type, '*') as $_type) {
 -                         if ($data_idx = $this->gmail_label_map[$key][$item_key][$_type]) {
 -                             $value = explode(' ::: ', $value);
 - 
 -                             if (!empty($contact[$data_idx])) {
 -                                 $contact[$data_idx]   = array_merge((array) $contact[$data_idx], $value);
 -                             }
 -                             else {
 -                                 $contact[$data_idx] = $value;
 -                             }
 -                             break;
 -                         }
 -                     }
 -                 }
 -             }
 -         }
 - 
 -         if (empty($contact)) {
 -             return;
 -         }
 - 
 -         // Handle special values
 -         if (!empty($contact['birthday-d']) && !empty($contact['birthday-m']) && !empty($contact['birthday-y'])) {
 -             $contact['birthday'] = $contact['birthday-y'] .'-' .$contact['birthday-m'] . '-' . $contact['birthday-d'];
 -         }
 - 
 -         if (!empty($contact['groups'])) {
 -             // categories/groups separator in vCard is ',' not ';'
 -             $contact['groups'] = str_replace(',', '', $contact['groups']);
 -             $contact['groups'] = str_replace(';', ',', $contact['groups']);
 - 
 -             if (!empty($this->gmail_map)) {
 -                 // remove "* " added by GMail
 -                 $contact['groups'] = str_replace('* ', '', $contact['groups']);
 -                 // replace strange delimiter
 -                 $contact['groups'] = str_replace(' ::: ', ',', $contact['groups']);
 -             }
 -         }
 - 
 -         // Empty dates, e.g. "0/0/00", "0000-00-00 00:00:00"
 -         foreach (array('birthday', 'anniversary') as $key) {
 -             if (!empty($contact[$key])) {
 -                 $date = preg_replace('/[0[:^word:]]/', '', $contact[$key]);
 -                 if (empty($date)) {
 -                     unset($contact[$key]);
 -                 }
 -             }
 -         }
 - 
 -         if (!empty($contact['gender']) && ($gender = strtolower($contact['gender']))) {
 -             if (!in_array($gender, array('male', 'female'))) {
 -                 unset($contact['gender']);
 -             }
 -         }
 - 
 -         // Convert address(es) to rcube_vcard data
 -         foreach ($contact as $idx => $value) {
 -             $name = explode(':', $idx);
 -             if (in_array($name[0], array('street', 'locality', 'region', 'zipcode', 'country'))) {
 -                 $contact['address:'.$name[1]][$name[0]] = $value;
 -                 unset($contact[$idx]);
 -             }
 -         }
 - 
 -         // Create vcard object
 -         $vcard = new rcube_vcard();
 -         foreach ($contact as $name => $value) {
 -             $name = explode(':', $name);
 -             if (is_array($value) && $name[0] != 'address') {
 -                 foreach ((array) $value as $val) {
 -                     $vcard->set($name[0], $val, $name[1]);
 -                 }
 -             }
 -             else {
 -                 $vcard->set($name[0], $value, $name[1]);
 -             }
 -         }
 - 
 -         // add to the list
 -         $this->vcards[] = $vcard;
 -     }
 - }
 
 
  |