* * Parse vcards->contacts class fields, and vice-versa * * Copyright (C) 2001 Miles Lott * * -------------------------------------------------------------------------* * This library is part of the phpGroupWare API * * http://www.phpgroupware.org/api * * ------------------------------------------------------------------------ * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by * * the Free Software Foundation; either version 2.1 of the License, * * or any later version. * * This library is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * * along with this library; if not, write to the Free Software Foundation, * * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * \**************************************************************************/ /* $Id$ */ // Prelminary vcard import/export class // The method of calls to this should probably be cleaned up, but // following are some examples: // class vcard { // This array is used by vcard->in to aid in parsing the multiple // attributes that are possible with vcard. // Import is messier than export and needs to be changed. // You MUST use this in conjunction with the vcard->in function: // // $contacts = CreateObject("phpgwapi.contacts"); // $vcard = CreateObject("phpgwapi.vcard"); // $myimport = $vcard->import; // $buffer = array(); // // $fp=fopen($filename,"r"); // while ($data = fgets($fp,8000)) { // list($name,$value,$extra) = split(':', $data); // if (substr($value,0,5) == "http") { // $value = $value . ":".$extra; // } // if ($name && $value) { // reset($vcard->import); // while ( list($fname,$fvalue) = each($vcard->import) ) { // if ( strstr(strtolower($name), $vcard->import[$fname]) ) { // $value = trim($value); // $value = ereg_replace("=0D=0A","\n",$value); // $buffer += array($name => $value); // } // } // } // } // fclose($fp); // // Then, to convert the vcard array to a contacts class array: // //$entry = $vcard->in($buffer); //$contacts->add($phpgw_info["user"]["account_id"],$entry); // var $import = array( 'n' => 'n', 'sound' => 'sound', 'bday' => 'bday', 'note' => 'note', 'tz' => 'tz', 'geo' => 'geo', 'url' => 'url', 'pubkey' => 'pubkey', 'org' => 'org', 'title' => 'title', 'adr' => 'adr', 'label' => 'label', 'tel' => 'tel', 'email' => 'email' ); // This array is used by vcard->out to aid in parsing the multiple // attributes that are possible with vcard. // You MUST use this in conjunction with the vcard->out function: // // $this->vcard = CreateObject("phpgwapi.vcard"); // $myexport = $this->vcard->export; // // while( list($name,$value) = each($currentrecord) ) { // if ($myexport[$name] && ($value != "") ) { // $buffer[$i][$myexport[$name]] = $value; // } // } // // Then, to convert the data array to a vcard string: // // for ($i=0;$ivcard->out($buffer[$i]); // } // var $export = array( 'fn' => 'FN', 'n_given' => 'N;GIVEN', 'n_family' => 'N;FAMILY', 'n_middle' => 'N;MIDDLE', 'n_prefix' => 'N;PREFIX', 'n_suffix' => 'N;SUFFIX', 'sound' => 'SOUND', 'bday' => 'BDAY', 'note' => 'NOTE', 'tz' => 'TZ', 'geo' => 'GEO', 'url' => 'URL', 'pubkey' => 'PUBKEY', 'org_name' => 'ORG;NAME', 'org_unit' => 'ORG;UNIT', 'title' => 'TITLE', 'adr_one_type' => 'ADR;TYPE;WORK', 'adr_two_type' => 'ADR;TYPE;HOME', 'tel_prefer' => 'TEL;PREFER', 'email_type' => 'EMAIL;TYPE;WORK', 'email_home_type' => 'EMAIL;TYPE;HOME', 'adr_one_street' => 'ADR;WORK;STREET', 'adr_one_locality' => 'ADR;WORK;LOCALITY', 'adr_one_region' => 'ADR;WORK;REGION', 'adr_one_postalcode' => 'ADR;WORK;POSTALCODE', 'adr_one_countryname' => 'ADR;WORK;COUNTRYNAME', 'address2' => 'EXT', 'label' => 'LABEL', 'adr_two_street' => 'ADR;HOME;STREET', 'adr_two_locality' => 'ADR;HOME;LOCALITY', 'adr_two_region' => 'ADR;HOME;REGION', 'adr_two_postalcode' => 'ADR;HOME;POSTALCODE', 'adr_two_countryname' => 'ADR;HOME;COUNTRYNAME', 'tel_work' => 'TEL;WORK', 'tel_home' => 'TEL;HOME', 'tel_voice' => 'TEL;VOICE', 'tel_fax' => 'TEL;FAX', 'tel_msg' => 'TEL;MSG', 'tel_cell' => 'TEL;CELL', 'tel_pager' => 'TEL;PAGER', 'tel_bbs' => 'TEL;BBS', 'tel_modem' => 'TEL;MODEM', 'tel_car' => 'TEL;CAR', 'tel_isdn' => 'TEL;ISDN', 'tel_video' => 'TEL;VIDEO', 'email' => 'EMAIL;WORK', 'email_home' => 'EMAIL;HOME' ); var $names = array( 'family' => 'family', 'given' => 'given', 'middle' => 'middle', 'prefix' => 'prefix', 'suffix' => 'suffix' ); // Pass this an associative array of fieldnames and values // returns a clean array based on contacts class std fields // This array can then be passed via $phpgw->contacts->add($ownerid,$buffer) function in($buffer) { global $phpgw; // Following is a lot of pain and little magic while ( list($name,$value) = @each($buffer) ) { $field = split(";",$name); $field[0] = ereg_replace("A\.","",$field[0]); $field[0] = ereg_replace("B\.","",$field[0]); $field[0] = ereg_replace("C\.","",$field[0]); $field[0] = ereg_replace("D\.","",$field[0]); $values = split(";",$value); if ($field[1]) { //echo $field[0]; switch ($field[0]) { case 'LABEL': $buffer['label'] = ereg_replace("=0D=0A","\n",$values[0]); break; case 'NOTE': $buffer['note'] = ereg_replace("=0D=0A","\n",$values[0]); break; case 'ADR': switch ($field[1]) { case 'INTL': switch ($field[2]) { case 'WORK': if ( !stristr($buffer['adr_one_type'],$field[1])) { $buffer['adr_one_type'] .= 'intl;'; } if (!$buffer['adr_one_street']) { $buffer['address2'] = $values[1]; $buffer['adr_one_street'] = $values[2]; $buffer['adr_one_locality'] = $values[3]; $buffer['adr_one_region'] = $values[4]; $buffer['adr_one_postalcode'] = $values[5]; $buffer['adr_one_countryname'] = $values[6]; } break; case 'HOME': if ( !stristr($buffer['adr_two_type'],$field[1]) ) { $buffer['adr_two_type'] .= 'intl;'; } if (!$buffer['adr_two_street']) { $buffer['adr_two_street'] = $values[2]; $buffer['adr_two_locality'] = $values[3]; $buffer['adr_two_region'] = $values[4]; $buffer['adr_two_postalcode'] = $values[5]; $buffer['adr_two_countryname'] = $values[6]; } break; default: break; } break; case 'DOM': switch ($field[2]) { case 'WORK': if ( !stristr($buffer['adr_one_type'],$field[1])) { $buffer['adr_one_type'] .= 'dom;'; } if (!$buffer['adr_one_street']) { $buffer['address2'] = $values[1]; $buffer['adr_one_street'] = $values[2]; $buffer['adr_one_locality'] = $values[3]; $buffer['adr_one_region'] = $values[4]; $buffer['adr_one_postalcode'] = $values[5]; $buffer['adr_one_countryname'] = $values[6]; } break; case 'HOME': if ( !stristr($buffer['adr_two_type'],$field[1]) ) { $buffer['adr_two_type'] .= 'dom;'; } if (!$buffer['adr_two_street']) { $buffer['adr_two_street'] = $values[2]; $buffer['adr_two_locality'] = $values[3]; $buffer['adr_two_region'] = $values[4]; $buffer['adr_two_postalcode'] = $values[5]; $buffer['adr_two_countryname'] = $values[6]; } break; default: break; } break; case 'PARCEL': switch ($field[2]) { case 'WORK': if ( !stristr($buffer['adr_one_type'],$field[1])) { $buffer['adr_one_type'] .= 'parcel;'; } if (!$buffer['adr_one_street']) { $buffer['address2'] = $values[1]; $buffer['adr_one_street'] = $values[2]; $buffer['adr_one_locality'] = $values[3]; $buffer['adr_one_region'] = $values[4]; $buffer['adr_one_postalcode'] = $values[5]; $buffer['adr_one_countryname'] = $values[6]; } break; case 'HOME': if ( !stristr($buffer['adr_two_type'],$field[1]) ) { $buffer['adr_two_type'] .= 'parcel;'; } if (!$buffer['adr_two_street']) { $buffer['adr_two_street'] = $values[2]; $buffer['adr_two_locality'] = $values[3]; $buffer['adr_two_region'] = $values[4]; $buffer['adr_two_postalcode'] = $values[5]; $buffer['adr_two_countryname'] = $values[6]; } break; default: break; } break; case 'POSTAL': switch ($field[2]) { case 'WORK': if ( !stristr($buffer['adr_one_type'],$field[1])) { $buffer['adr_one_type'] .= 'postal;'; } if (!$buffer['adr_one_street']) { $buffer['address2'] = $values[1]; $buffer['adr_one_street'] = $values[2]; $buffer['adr_one_locality'] = $values[3]; $buffer['adr_one_region'] = $values[4]; $buffer['adr_one_postalcode'] = $values[5]; $buffer['adr_one_countryname'] = $values[6]; } break; case 'HOME': if ( !stristr($buffer['adr_two_type'],$field[1]) ) { $buffer['adr_two_type'] .= 'postal;'; } if (!$buffer['adr_two_street']) { $buffer['adr_two_street'] = $values[2]; $buffer['adr_two_locality'] = $values[3]; $buffer['adr_two_region'] = $values[4]; $buffer['adr_two_postalcode'] = $values[5]; $buffer['adr_two_countryname'] = $values[6]; } break; default: break; } break; case 'WORK': if (!$buffer['adr_one_street']) { $buffer['address2'] = $values[1]; $buffer['adr_one_street'] = $values[2]; $buffer['adr_one_locality'] = $values[3]; $buffer['adr_one_region'] = $values[4]; $buffer['adr_one_postalcode'] = $values[5]; $buffer['adr_one_countryname'] = $values[6]; } break; case 'HOME': $buffer['adr_two_street'] = $values[2]; $buffer['adr_two_locality'] = $values[3]; $buffer['adr_two_region'] = $values[4]; $buffer['adr_two_postalcode'] = $values[5]; $buffer['adr_two_countryname'] = $values[6]; break; default: if (!$buffer['adr_one_street']) { $buffer['address2'] = $values[1]; $buffer['adr_one_street'] = $values[2]; $buffer['adr_one_locality'] = $values[3]; $buffer['adr_one_region'] = $values[4]; $buffer['adr_one_postalcode'] = $values[5]; $buffer['adr_one_countryname'] = $values[6]; } break; } break; case 'TEL': // RB 2001/05/07 added for Lotus Organizer ueses TEL;{WORK|HOME};{VOICE|FAX}[;PREF] if ($field[2] == 'FAX' && ($field[1] == 'WORK' || $field[i] == 'HOME')) { /* TODO This is PHP4 only */ array_shift($field); // --> ignore the WORK or HOME if FAX follows, HOME;FAX and HOME;TEL are maped later } switch ($field[1]) { case 'PREF': //echo $field[2]." is preferred"; if ($field[2]) { $buffer['tel_prefer'] .= strtolower($field[2]) . ';'; } break; case 'WORK': // RB don't overwrite TEL;WORK;VOICE (main nr.) with TEL;WORK, TEL;WORK --> tel_isdn $buffer[$buffer['tel_work'] ? 'tel_isdn' : 'tel_work'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'HOME': // RB don't overwrite TEL;HOME;VOICE (main nr.) with TEL;HOME, TEL;HOME --> ophone $buffer[$buffer['tel_home'] ? 'ophone' : 'tel_home' ] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'VOICE': $buffer["tel_voice"] = $values[0]; if ($field[2] == "PREF") { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'FAX': if ($buffer['tel_fax']) { // RB don't overwrite TEL;WORK;FAX with TEL;HOME;FAX, TEL;HOME;FAX --> ophone $buffer['ophone'] = $values[0] . ' Fax'; break; } $buffer['tel_fax'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'MSG': $buffer['tel_msg'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'CELL': $buffer['tel_cell'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'PAGER': $buffer['tel_pager'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'BBS': $buffer['tel_bbs'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'MODEM': $buffer['tel_modem'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'CAR': $buffer['tel_car'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'ISDN': $buffer['tel_isdn'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; case 'VIDEO': $buffer['tel_video'] = $values[0]; if ($field[2] == 'PREF') { $buffer['tel_prefer'] .= strtolower($field[1]) . ';'; } break; default: break; } break; case 'EMAIL': switch ($field[1]) { case 'WORK': $buffer['email'] = $values[0]; $buffer['email_type'] = $field[2]; break; case 'HOME': $buffer['email_home'] = $values[0]; $buffer['email_home_type'] = $field[2]; break; default: if($buffer['email']) { $buffer['email_type'] = $field[2]; } elseif (!$buffer['email']) { $buffer['email'] = $values[0]; $buffer['email_type'] = $field[1]; } break; } break; case 'URL': // RB 2001/05/08 Lotus Organizer uses URL;WORK and URL;HOME (URL;HOME droped if both) $buffer['url'] = $values[0]; break; default: break; } } else { switch ($field[0]) { case 'N': reset($this->names); $j=0; while(list($myname,$myval) = each($this->names) ) { $namel = 'n_' . $myname; $buffer[$namel] = $values[$j]; $j++; } break; case 'FN': $buffer['fn'] = $values[0]; break; case 'TITLE': $buffer['title'] = $values[0]; break; case 'TZ': $buffer['tz'] = $values[0]; break; case 'GEO': $buffer['geo'] = $values[0]; break; case 'URL': $buffer['url'] = $values[0]; break; case 'NOTE': $buffer['note'] = ereg_replace("=0D=0A","\n",$values[0]); break; case 'KEY': $buffer['key'] = ereg_replace("=0D=0A","\n",$values[0]); break; case 'LABEL': $buffer['label'] = ereg_replace("=0D=0A","\n",$values[0]); break; case 'BDAY': #1969-12-31 $tmp = split('-',$values[0]); if ($tmp[0]) { $buffer['bday'] = $tmp[1] . '/' . $tmp[2] . '/' . $tmp[0]; } break; case 'ORG': // RB 2001/05/07 added for Lotus Organizer: ORG:Company;Department $buffer['org_name'] = $values[0]; $buffer['org_unit'] = $values[1]; break; } } } $buffer['tel_prefer'] = substr($buffer['tel_prefer'],0,-1); $buffer['adr_one_type'] = substr($buffer['adr_one_type'],0,-1); $buffer['adr_two_type'] = substr($buffer['adr_two_type'],0,-1); if (count($street = split("\r*\n",$buffer['adr_one_street'],3)) > 1) { $buffer['adr_one_street'] = $street[0]; // RB 2001/05/08 added for Lotus Organizer to split multiline adresses $buffer['address2'] = $street[1]; $buffer['address3'] = $street[2]; } // Lastly, filter out all but standard fields, since they cover the vcard standard // and we don't want $buffer['BEGIN'] etc... $contacts = CreateObject('phpgwapi.contacts'); // RB 2001/05/08 Lotus Organizer uses/needs extrafields from edit.php $all_fields = $contacts->stock_contact_fields + array("ophone" => "ophone","address2" => "address2","address3" => "address3"); while (list($fname,$fvalue) = each($all_fields)) { if($buffer[$fname]) { $entry[$fname] = $buffer[$fname]; // echo '
'.$fname.' = "'.$entry[$fname].'"'."\n"; } } return $entry; } // Takes an array of contacts class fields/values, turns it into a vcard string: // // for ($i=0;$ivcard->out($buffer[$i]); // } // function out($buffer) { $entry = ''; $header = 'BEGIN:VCARD' . "\n"; $header .= 'VERSION:2.1' . "\n"; $header .= 'X-PHPGROUPWARE-FILE-AS:phpGroupWare.org' . "\n"; reset($this->export); while ( list($name,$value) = each($this->export) ) { if (!empty($buffer[$value])) { $mult = explode(';',$value); if (!$mult[1]) { // Normal if (strstr($buffer[$value],"\r\n") || strstr($buffer[$value],"\n")) { $buffer[$value] = ereg_replace("\r\n","=0D=0A",$buffer[$value]); $buffer[$value] = ereg_replace("\n","=0D=0A",$buffer[$value]); $entry .= $value . ';QUOTED-PRINTABLE:' . $buffer[$value]."\n"; } elseif ($value == 'BDAY') { $tmp = split('/',$buffer[$value]); # 12/31/1969 -> 1969-12-31 if ($tmp[0]) { if (strlen($tmp[0]) == 1) { $tmp[0] = '0'.$tmp[0]; } if (strlen($tmp[0]) == 1) { $tmp[1] = '0'.$tmp[1]; } $entry .= 'BDAY:' . $tmp[2] . '-' . $tmp[0] . '-' . $tmp[1] . "\n"; } } else { $entry .= $value . ':' . $buffer[$value] . "\n"; } } else { switch ($mult[0]) { case 'N': switch ($mult[1]) { case 'PREFIX': $prefix = ';' . $buffer[$value]; break; case 'GIVEN': $firstname = ';' . $buffer[$value]; break; case 'MIDDLE': $middle = ';' . $buffer[$value]; break; case 'FAMILY': $lastname = $buffer[$value]; break; case 'SUFFIX': $suffix = ';' . $buffer[$value]; break; } break; case 'ORG': switch ($mult[1]) { case 'NAME': $org_name = $buffer[$value]; break; case 'UNIT': $org_unit = ';' . $buffer[$value]; break; } break; case 'ADR': switch ($mult[1]) { case 'TYPE': $types = explode(';',$buffer[$value]); if ($types[1]) { while ( $type = each($types) ) { $typei[$i][$mult[2]] .= ';' . strtoupper($type[1]); } } elseif ($types[0]) { $typei[$i][$mult[2]] .= ';' . strtoupper($types[0]); } else { $typei[$i][$mult[2]] .= ';' . strtoupper($buffer[$value]); } //echo "TYPE=".$typei[$i][$mult[2]]; break; case 'WORK': $workaddr .= $buffer[$value] . ';'; $workattr = $mult[0] . ';' . $mult[1] . $typei[$i][$mult[1]]; break; case 'HOME': $homeaddr .= $buffer[$value] . ';'; $homeattr = $mult[0] . ';' . $mult[1] . $typei[$i][$mult[1]]; break; default: break; } break; case 'TEL': switch($mult[1]) { case 'PREFER': $prefer = explode(";",$buffer[$value]); if ($prefer[1]) { while ($pref = strtoupper(each($prefer))) { $prefi[$i][$pref] = ';PREF'; } //echo "PREF1"; } elseif ($prefer[0]) { $prefi[$i][strtoupper($prefer[0])] = ';PREF'; //echo "PREF=".strtoupper($prefer[0]); } elseif ($buffer[$value]) { $prefi[$i][$buffer[$value]] = ';PREF'; //echo "PREF3"; } break; case 'WORK': // Wow, this is fun! $entry .= 'A.' . $mult[0] . ';' . $mult[1] . $prefi[$i][$mult[1]] . ':' . $buffer[$value] . "\n"; break; case 'HOME': $entry .= 'B.' . $mult[0] . ';' . $mult[1] . $prefi[$i][$mult[1]] . ':' . $buffer[$value] . "\n"; break; default: $entry .= $mult[0] . ';' . $mult[1] . $prefi[$i][$mult[1]] . ':' . $buffer[$value] . "\n"; break; } break; case 'EMAIL': switch($mult[1]) { case 'TYPE': if ($mult[2] == 'WORK') { $emailtype = ';' . $buffer[$value]; } if ($mult[2] == 'HOME') { $hemailtype = ';' . $buffer[$value]; } break; case 'WORK': $newval = 'A.'.$value; $entry .= $newval . $emailtype . ':' . $buffer[$value] . "\n"; break; case 'HOME': $newval = 'B.' . $value; $entry .= $newval . $hemailtype . ':' . $buffer[$value] . "\n"; break; default: break; } break; default: break; } //end switch ($mult[0]) } //end else } //end if (!empty) } //end while if ($lastname && $firstname) { $entries .= $header; $entries .= 'N:' . $lastname . $firstname . $middle . $prefix . $suffix . "\n"; $entries .= $entry; if (!$buffer["FN"]) { if ($lastname || $firstname ) { $entries .= 'FN:' . substr($firstname,1) . ' ' . $lastname . "\n"; } } if ($org_name || $org_unit) { $entries .= "ORG:" . $org_name . $org_unit . "\n"; } $workattr = ereg_replace("ADR;",'',$workattr); $homeattr = ereg_replace("ADR;",'',$homeattr); if (!$buffer['EXT']) { $buffer['EXT'] = ';'; } if ($workaddr) { $work = 'A.ADR;' . $workattr . ':;' . $buffer['EXT'] . substr($workaddr,0,-1) . "\n"; if (!$buffer['LABEL']) { $wlabel = substr($workaddr,0,-1); $wlabel = ereg_replace(";","=0D=0A",$wlabel); //$wlabel = ereg_replace("(",",",$wlabel); //$wlabel = ereg_replace(")",",",$wlabel); $wlabel = 'LABEL;WORK;QUOTED-PRINTABLE:' . $wlabel . "\n"; } } if ($homeaddr) { $home = "B.ADR;".$homeattr.":;;".substr($homeaddr,0,-1)."\n"; $hlabel = substr($homeaddr,0,-1); $hlabel = ereg_replace(";","=0D=0A",$hlabel); //$hlabel = ereg_replace("(",",",$hlabel); //$hlabel = ereg_replace(")",",",$hlabel); $hlabel = 'LABEL;HOME;QUOTED-PRINTABLE:' . $hlabel . "\n"; } $entries = ereg_replace('PUBKEY','KEY',$entries); $entries .= $work . $home . $wlabel . $hlabel . 'END:VCARD' . "\n"; $entries .= "\n"; $buffer = $entries; return $buffer; } else { return; } } //end function } //end class ?>