Ignore:
Timestamp:
Apr 22, 2011 4:03:40 AM (2 years ago)
Author:
alec
Message:
  • Fix quoting special characters, small optimizations
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/program/include/rcube_vcard.php

    r4658 r4683  
    105105    $this->organization = $this->raw['ORG'][0][0]; 
    106106    $this->business = ($this->raw['X-ABSHOWAS'][0][0] == 'COMPANY') || (join('', (array)$this->raw['N'][0]) == '' && !empty($this->organization)); 
    107      
     107 
    108108    foreach ((array)$this->raw['EMAIL'] as $i => $raw_email) 
    109109      $this->email[$i] = is_array($raw_email) ? $raw_email[0] : $raw_email; 
    110      
     110 
    111111    // make the pref e-mail address the first entry in $this->email 
    112112    $pref_index = $this->get_type_index('EMAIL', 'pref'); 
     
    135135    $out = array('name' => $this->displayname); 
    136136    $typemap = $this->typemap; 
    137      
     137 
    138138    // copy name fields to output array 
    139139    foreach (array('firstname','surname','middlename','nickname','organization') as $col) { 
     
    141141        $out[$col] = $this->$col; 
    142142    } 
    143      
     143 
    144144    if ($this->raw['N'][0][3]) 
    145145      $out['prefix'] = $this->raw['N'][0][3]; 
    146146    if ($this->raw['N'][0][4]) 
    147147      $out['suffix'] = $this->raw['N'][0][4]; 
    148      
     148 
    149149    // convert from raw vcard data into associative data for Roundcube 
    150150    foreach (array_flip($this->fieldmap) as $tag => $col) { 
     
    153153          $k = -1; 
    154154          $key = $col; 
    155            
     155 
    156156          $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); 
    157157          while ($k < count($raw['type']) && ($subtype == 'internet' || $subtype == 'pref')) 
    158158            $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); 
    159            
     159 
    160160          // read vcard 2.1 subtype 
    161161          if (!$subtype) { 
     
    171171          if (preg_match('/^(email|phone|address|website)/', $key) && !$subtype) 
    172172            $subtype = 'other'; 
    173            
     173 
    174174          if ($subtype) 
    175175            $key .= ':' . $subtype; 
     
    188188      } 
    189189    } 
    190      
     190 
    191191    // handle special IM fields as used by Apple 
    192192    foreach ($this->immap as $tag => $type) { 
     
    195195      } 
    196196    } 
    197      
     197 
    198198    // copy photo data 
    199199    if ($this->raw['PHOTO']) 
    200200      $out['photo'] = $this->raw['PHOTO'][0][0]; 
    201      
     201 
    202202    return $out; 
    203203  } 
     
    212212    return $folded ? self::rfc2425_fold($vcard) : $vcard; 
    213213  } 
    214    
    215    
     214 
     215 
    216216  /** 
    217217   * Clear the given fields in the loaded vcard data 
     
    223223    if (!$fields) 
    224224      $fields = array_merge(array_values($this->fieldmap), array_keys($this->immap), array('FN','N','ORG','NICKNAME','EMAIL','ADR','BDAY')); 
    225      
     225 
    226226    foreach ($fields as $f) 
    227227      unset($this->raw[$f]); 
     
    231231    if (!$this->raw['FN']) 
    232232      $this->raw['FN'] = array(); 
    233        
     233 
    234234    $this->email = array(); 
    235235  } 
     
    248248    $type = strtoupper($type); 
    249249    $typemap = array_flip($this->typemap); 
    250      
     250 
    251251    switch ($field) { 
    252252      case 'name': 
     
    254254        $this->raw['FN'][0][0] = $value; 
    255255        break; 
    256          
     256 
    257257      case 'surname': 
    258258        $this->raw['N'][0][0] = $value; 
    259259        break; 
    260          
     260 
    261261      case 'firstname': 
    262262        $this->raw['N'][0][1] = $value; 
    263263        break; 
    264          
     264 
    265265      case 'middlename': 
    266266        $this->raw['N'][0][2] = $value; 
    267267        break; 
    268          
     268 
    269269      case 'prefix': 
    270270        $this->raw['N'][0][3] = $value; 
    271271        break; 
    272          
     272 
    273273      case 'suffix': 
    274274        $this->raw['N'][0][4] = $value; 
    275275        break; 
    276          
     276 
    277277      case 'nickname': 
    278278        $this->raw['NICKNAME'][0][0] = $value; 
    279279        break; 
    280          
     280 
    281281      case 'organization': 
    282282        $this->raw['ORG'][0][0] = $value; 
    283283        break; 
    284          
     284 
    285285      case 'photo': 
    286286        if (strpos($value, 'http:') === 0) { 
     
    293293        } 
    294294        break; 
    295          
     295 
    296296      case 'email': 
    297297        $this->raw['EMAIL'][] = array(0 => $value, 'type' => array_filter(array('INTERNET', $type))); 
    298298        $this->email[] = $value; 
    299299        break; 
    300          
     300 
    301301      case 'im': 
    302302        // save IM subtypes into extension fields 
     
    351351      } 
    352352    } 
    353      
     353 
    354354    return $result; 
    355355  } 
    356    
    357    
     356 
     357 
    358358  /** 
    359359   * Convert a whole vcard (array) to UTF-8. 
     
    447447    // Remove cruft like item1.X-AB*, item1.ADR instead of ADR, and empty lines 
    448448    $vcard = preg_replace(array('/^item\d*\.X-AB.*$/m', '/^item\d*\./m', "/\n+/"), array('', '', "\n"), $vcard); 
    449      
     449 
    450450    // convert X-WAB-GENDER to X-GENDER 
    451451    if (preg_match('/X-WAB-GENDER:(\d)/', $vcard, $matches)) { 
     
    459459    return $vcard; 
    460460  } 
    461    
     461 
    462462  private static function x_abrelatednames_callback($matches) 
    463463  { 
     
    498498  private static function vcard_decode($vcard) 
    499499  { 
    500     // Perform RFC2425 line unfolding 
     500    // Perform RFC2425 line unfolding and split lines 
    501501    $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 
    506505    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; 
    509511 
    510512      // convert 2.1-style "EMAIL;internet;home:" to 3.0-style "EMAIL;TYPE=internet;TYPE=home:" 
     
    515517      } 
    516518 
    517       if (!preg_match('/^(BEGIN|END)$/i', $line[1]) && preg_match_all('/([^\\;]+);?/', $line[1], $regs2)) { 
     519      if (preg_match_all('/([^\\;]+);?/', $line[1], $regs2)) { 
    518520        $entry = array(); 
    519521        $field = strtoupper($regs2[1][0]); 
     
    526528              while ($value == 'QUOTED-PRINTABLE' && preg_match('/=$/', $lines[$i])) 
    527529                  $line[2] .= "\n" . $lines[++$i]; 
    528                
     530 
    529531              $line[2] = self::decode_value($line[2], $value); 
    530532            } 
     
    544546    unset($data['VERSION']); 
    545547    return $data; 
    546   } 
    547  
    548  
    549   /** 
    550    * Split quoted string 
    551    * 
    552    * @param string vCard string to split 
    553    * @param string Separator char/string 
    554    * @return array List with splitted values 
    555    */ 
    556   private static function vcard_unquote($s, $sep = ';') 
    557   { 
    558     // break string into parts separated by $sep, but leave escaped $sep alone 
    559     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     } 
    568548  } 
    569549 
     
    649629    } 
    650630    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", '\,' => ',', '\;' => ';')); 
    652654    } 
    653655  } 
     
    701703 
    702704} 
    703  
    704  
Note: See TracChangeset for help on using the changeset viewer.