| | |
| | | <?php |
| | | |
| | | /* |
| | | /** |
| | | +-----------------------------------------------------------------------+ |
| | | | This file is part of the Roundcube Webmail client | |
| | | | Copyright (C) 2008-2012, The Roundcube Dev Team | |
| | |
| | | public function load($vcard, $charset = RCUBE_CHARSET, $detect = false) |
| | | { |
| | | self::$values_decoded = false; |
| | | $this->raw = self::vcard_decode($vcard); |
| | | $this->raw = self::vcard_decode(self::cleanup($vcard)); |
| | | |
| | | // resolve charset parameters |
| | | if ($charset == null) { |
| | |
| | | && $detected_charset != RCUBE_CHARSET |
| | | ) { |
| | | $this->raw = self::charset_convert($this->raw, $detected_charset); |
| | | } |
| | | |
| | | // consider FN empty if the same as the primary e-mail address |
| | | if ($this->raw['FN'][0][0] == $this->raw['EMAIL'][0][0]) { |
| | | $this->raw['FN'][0][0] = ''; |
| | | } |
| | | |
| | | // find well-known address fields |
| | |
| | | } |
| | | |
| | | while ($k < count($raw['type']) && ($subtype == 'internet' || $subtype == 'pref')) { |
| | | $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); |
| | | $subtype = $typemap[$raw['type'][++$k]] ?: strtolower($raw['type'][$k]); |
| | | } |
| | | } |
| | | |
| | |
| | | && !in_array($k, array('pref','internet','voice','base64')) |
| | | ) { |
| | | $k_uc = strtoupper($k); |
| | | $subtype = $typemap[$k_uc] ? $typemap[$k_uc] : $k; |
| | | $subtype = $typemap[$k_uc] ?: $k; |
| | | break; |
| | | } |
| | | } |
| | |
| | | $this->raw[$tag][$index] = (array)$value; |
| | | if ($type) { |
| | | $typemap = array_flip($this->typemap); |
| | | $this->raw[$tag][$index]['type'] = explode(',', ($typemap[$type_uc] ? $typemap[$type_uc] : $type)); |
| | | $this->raw[$tag][$index]['type'] = explode(',', $typemap[$type_uc] ?: $type); |
| | | } |
| | | } |
| | | else { |
| | | unset($this->raw[$tag]); |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | |
| | | * Find index with the '$type' attribute |
| | | * |
| | | * @param string Field name |
| | | * |
| | | * @return int Field index having $type set |
| | | */ |
| | | private function get_type_index($field, $type = 'pref') |
| | | private function get_type_index($field) |
| | | { |
| | | $result = 0; |
| | | if ($this->raw[$field]) { |
| | |
| | | |
| | | if (preg_match('/^END:VCARD$/i', $line)) { |
| | | // parse vcard |
| | | $obj = new rcube_vcard(self::cleanup($vcard_block), $charset, true, self::$fieldmap); |
| | | $obj = new rcube_vcard($vcard_block, $charset, true, self::$fieldmap); |
| | | // FN and N is required by vCard format (RFC 2426) |
| | | // on import we can be less restrictive, let's addressbook decide |
| | | if (!empty($obj->displayname) || !empty($obj->surname) || !empty($obj->firstname) || !empty($obj->email)) { |
| | |
| | | // Cleanup |
| | | $vcard = preg_replace(array( |
| | | // convert special types (like Skype) to normal type='skype' classes with this simple regex ;) |
| | | '/item(\d+)\.(TEL|EMAIL|URL)([^:]*?):(.*?)item\1.X-ABLabel:(?:_\$!<)?([\w-() ]*)(?:>!\$_)?./s', |
| | | '/^item\d*\.X-AB.*$/m', // remove cruft like item1.X-AB* |
| | | '/^item\d*\./m', // remove item1.ADR instead of ADR |
| | | '/item(\d+)\.(TEL|EMAIL|URL)([^:]*?):(.*?)item\1.X-ABLabel:(?:_\$!<)?([\w-() ]*)(?:>!\$_)?./si', |
| | | '/^item\d*\.X-AB.*$/mi', // remove cruft like item1.X-AB* |
| | | '/^item\d*\./mi', // remove item1.ADR instead of ADR |
| | | '/\n+/', // remove empty lines |
| | | '/^(N:[^;\R]*)$/m', // if N doesn't have any semicolons, add some |
| | | ), |
| | |
| | | // $entry['base64'] = true; |
| | | } |
| | | |
| | | $data = self::decode_value($data, $enc ? $enc : 'base64'); |
| | | $data = self::decode_value($data, $enc ?: 'base64'); |
| | | } |
| | | else if ($field == 'PHOTO') { |
| | | // vCard 4.0 data URI, "PHOTO:data:image/jpeg;base64,..." |