Changeset 4683 in subversion for trunk/roundcubemail/program/include/rcube_vcard.php
- Timestamp:
- Apr 22, 2011 4:03:40 AM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/roundcubemail/program/include/rcube_vcard.php
r4658 r4683 105 105 $this->organization = $this->raw['ORG'][0][0]; 106 106 $this->business = ($this->raw['X-ABSHOWAS'][0][0] == 'COMPANY') || (join('', (array)$this->raw['N'][0]) == '' && !empty($this->organization)); 107 107 108 108 foreach ((array)$this->raw['EMAIL'] as $i => $raw_email) 109 109 $this->email[$i] = is_array($raw_email) ? $raw_email[0] : $raw_email; 110 110 111 111 // make the pref e-mail address the first entry in $this->email 112 112 $pref_index = $this->get_type_index('EMAIL', 'pref'); … … 135 135 $out = array('name' => $this->displayname); 136 136 $typemap = $this->typemap; 137 137 138 138 // copy name fields to output array 139 139 foreach (array('firstname','surname','middlename','nickname','organization') as $col) { … … 141 141 $out[$col] = $this->$col; 142 142 } 143 143 144 144 if ($this->raw['N'][0][3]) 145 145 $out['prefix'] = $this->raw['N'][0][3]; 146 146 if ($this->raw['N'][0][4]) 147 147 $out['suffix'] = $this->raw['N'][0][4]; 148 148 149 149 // convert from raw vcard data into associative data for Roundcube 150 150 foreach (array_flip($this->fieldmap) as $tag => $col) { … … 153 153 $k = -1; 154 154 $key = $col; 155 155 156 156 $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); 157 157 while ($k < count($raw['type']) && ($subtype == 'internet' || $subtype == 'pref')) 158 158 $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); 159 159 160 160 // read vcard 2.1 subtype 161 161 if (!$subtype) { … … 171 171 if (preg_match('/^(email|phone|address|website)/', $key) && !$subtype) 172 172 $subtype = 'other'; 173 173 174 174 if ($subtype) 175 175 $key .= ':' . $subtype; … … 188 188 } 189 189 } 190 190 191 191 // handle special IM fields as used by Apple 192 192 foreach ($this->immap as $tag => $type) { … … 195 195 } 196 196 } 197 197 198 198 // copy photo data 199 199 if ($this->raw['PHOTO']) 200 200 $out['photo'] = $this->raw['PHOTO'][0][0]; 201 201 202 202 return $out; 203 203 } … … 212 212 return $folded ? self::rfc2425_fold($vcard) : $vcard; 213 213 } 214 215 214 215 216 216 /** 217 217 * Clear the given fields in the loaded vcard data … … 223 223 if (!$fields) 224 224 $fields = array_merge(array_values($this->fieldmap), array_keys($this->immap), array('FN','N','ORG','NICKNAME','EMAIL','ADR','BDAY')); 225 225 226 226 foreach ($fields as $f) 227 227 unset($this->raw[$f]); … … 231 231 if (!$this->raw['FN']) 232 232 $this->raw['FN'] = array(); 233 233 234 234 $this->email = array(); 235 235 } … … 248 248 $type = strtoupper($type); 249 249 $typemap = array_flip($this->typemap); 250 250 251 251 switch ($field) { 252 252 case 'name': … … 254 254 $this->raw['FN'][0][0] = $value; 255 255 break; 256 256 257 257 case 'surname': 258 258 $this->raw['N'][0][0] = $value; 259 259 break; 260 260 261 261 case 'firstname': 262 262 $this->raw['N'][0][1] = $value; 263 263 break; 264 264 265 265 case 'middlename': 266 266 $this->raw['N'][0][2] = $value; 267 267 break; 268 268 269 269 case 'prefix': 270 270 $this->raw['N'][0][3] = $value; 271 271 break; 272 272 273 273 case 'suffix': 274 274 $this->raw['N'][0][4] = $value; 275 275 break; 276 276 277 277 case 'nickname': 278 278 $this->raw['NICKNAME'][0][0] = $value; 279 279 break; 280 280 281 281 case 'organization': 282 282 $this->raw['ORG'][0][0] = $value; 283 283 break; 284 284 285 285 case 'photo': 286 286 if (strpos($value, 'http:') === 0) { … … 293 293 } 294 294 break; 295 295 296 296 case 'email': 297 297 $this->raw['EMAIL'][] = array(0 => $value, 'type' => array_filter(array('INTERNET', $type))); 298 298 $this->email[] = $value; 299 299 break; 300 300 301 301 case 'im': 302 302 // save IM subtypes into extension fields … … 351 351 } 352 352 } 353 353 354 354 return $result; 355 355 } 356 357 356 357 358 358 /** 359 359 * Convert a whole vcard (array) to UTF-8. … … 447 447 // Remove cruft like item1.X-AB*, item1.ADR instead of ADR, and empty lines 448 448 $vcard = preg_replace(array('/^item\d*\.X-AB.*$/m', '/^item\d*\./m', "/\n+/"), array('', '', "\n"), $vcard); 449 449 450 450 // convert X-WAB-GENDER to X-GENDER 451 451 if (preg_match('/X-WAB-GENDER:(\d)/', $vcard, $matches)) { … … 459 459 return $vcard; 460 460 } 461 461 462 462 private static function x_abrelatednames_callback($matches) 463 463 { … … 498 498 private static function vcard_decode($vcard) 499 499 { 500 // Perform RFC2425 line unfolding 500 // Perform RFC2425 line unfolding and split lines 501 501 $vcard = preg_replace(array("/\r/", "/\n\s+/"), '', $vcard); 502 503 $lines = preg_split('/\r?\n/', $vcard); 504 $data = array(); 505 502 $lines = explode("\n", $vcard); 503 $data = array(); 504 506 505 for ($i=0; $i < count($lines); $i++) { 507 if (!preg_match('/^([^\\:]*):(.+)$/', $lines[$i], $line)) 508 continue; 506 if (!preg_match('/^([^:]+):(.+)$/', $lines[$i], $line)) 507 continue; 508 509 if (preg_match('/^(BEGIN|END)$/i', $line[1])) 510 continue; 509 511 510 512 // convert 2.1-style "EMAIL;internet;home:" to 3.0-style "EMAIL;TYPE=internet;TYPE=home:" … … 515 517 } 516 518 517 if ( !preg_match('/^(BEGIN|END)$/i', $line[1]) &&preg_match_all('/([^\\;]+);?/', $line[1], $regs2)) {519 if (preg_match_all('/([^\\;]+);?/', $line[1], $regs2)) { 518 520 $entry = array(); 519 521 $field = strtoupper($regs2[1][0]); … … 526 528 while ($value == 'QUOTED-PRINTABLE' && preg_match('/=$/', $lines[$i])) 527 529 $line[2] .= "\n" . $lines[++$i]; 528 530 529 531 $line[2] = self::decode_value($line[2], $value); 530 532 } … … 544 546 unset($data['VERSION']); 545 547 return $data; 546 }547 548 549 /**550 * Split quoted string551 *552 * @param string vCard string to split553 * @param string Separator char/string554 * @return array List with splitted values555 */556 private static function vcard_unquote($s, $sep = ';')557 {558 // break string into parts separated by $sep, but leave escaped $sep alone559 if (count($parts = explode($sep, strtr($s, array("\\$sep" => "\007")))) > 1) {560 foreach($parts as $s) {561 $result[] = self::vcard_unquote(strtr($s, array("\007" => "\\$sep")), $sep);562 }563 return $result;564 }565 else {566 return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\,' => ',', '\;' => ';', '\:' => ':'));567 }568 548 } 569 549 … … 649 629 } 650 630 else { 651 return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', ';' => '\;', ':' => '\:')); 631 return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', ',' => '\,', ';' => '\;')); 632 } 633 } 634 635 636 /** 637 * Split quoted string 638 * 639 * @param string vCard string to split 640 * @param string Separator char/string 641 * @return array List with splitted values 642 */ 643 private static function vcard_unquote($s, $sep = ';') 644 { 645 // break string into parts separated by $sep, but leave escaped $sep alone 646 if (count($parts = explode($sep, strtr($s, array("\\$sep" => "\007")))) > 1) { 647 foreach($parts as $s) { 648 $result[] = self::vcard_unquote(strtr($s, array("\007" => "\\$sep")), $sep); 649 } 650 return $result; 651 } 652 else { 653 return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';')); 652 654 } 653 655 } … … 701 703 702 704 } 703 704
Note: See TracChangeset
for help on using the changeset viewer.
