| | |
| | | 'notes' => 'NOTE', |
| | | 'email' => 'EMAIL', |
| | | 'address' => 'ADR', |
| | | 'jobtitle' => 'TITLE', |
| | | 'gender' => 'X-GENDER', |
| | | 'maidenname' => 'X-MAIDENNAME', |
| | | 'anniversary' => 'X-ANNIVERSARY', |
| | |
| | | $typemap = $this->typemap; |
| | | |
| | | // copy name fields to output array |
| | | foreach (array('firstname','surname','middlename','nickname','organization') as $col) |
| | | $out[$col] = $this->$col; |
| | | foreach (array('firstname','surname','middlename','nickname','organization') as $col) { |
| | | if (strlen($this->$col)) |
| | | $out[$col] = $this->$col; |
| | | } |
| | | |
| | | $out['prefix'] = $this->raw['N'][0][3]; |
| | | $out['suffix'] = $this->raw['N'][0][4]; |
| | | if ($this->raw['N'][0][3]) |
| | | $out['prefix'] = $this->raw['N'][0][3]; |
| | | if ($this->raw['N'][0][4]) |
| | | $out['suffix'] = $this->raw['N'][0][4]; |
| | | |
| | | // convert from raw vcard data into associative data for Roundcube |
| | | foreach (array_flip($this->fieldmap) as $tag => $col) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | // force subtype if none set |
| | | if (preg_match('/^(email|phone|address|website)/', $key) && !$subtype) |
| | | $subtype = 'other'; |
| | | |
| | | if ($subtype) |
| | | $key .= ':' . $subtype; |
| | |
| | | break; |
| | | |
| | | case 'photo': |
| | | $encoded = !preg_match('![^a-z0-9/=+-]!i', $value); |
| | | $this->raw['PHOTO'][0] = array(0 => $encoded ? $value : base64_encode($value), 'BASE64' => true); |
| | | if (strpos($value, 'http:') === 0) { |
| | | // TODO: fetch file from URL and save it locally? |
| | | $this->raw['PHOTO'][0] = array(0 => $value, 'URL' => true); |
| | | } |
| | | else { |
| | | $encoded = !preg_match('![^a-z0-9/=+-]!i', $value); |
| | | $this->raw['PHOTO'][0] = array(0 => $encoded ? $value : base64_encode($value), 'BASE64' => true); |
| | | } |
| | | break; |
| | | |
| | | case 'email': |
| | |
| | | { |
| | | // Convert special types (like Skype) to normal type='skype' classes with this simple regex ;) |
| | | $vcard = preg_replace( |
| | | '/item(\d+)\.(TEL|URL)([^:]*?):(.*?)item\1.X-ABLabel:(?:_\$!<)?([\w-() ]*)(?:>!\$_)?./s', |
| | | '/item(\d+)\.(TEL|EMAIL|URL)([^:]*?):(.*?)item\1.X-ABLabel:(?:_\$!<)?([\w-() ]*)(?:>!\$_)?./s', |
| | | '\2;type=\5\3:\4', |
| | | $vcard); |
| | | |
| | | // convert Apple X-ABRELATEDNAMES into X-* fields for better compatibility |
| | | $vcard = preg_replace_callback( |
| | | '/item(\d+)\.(X-ABRELATEDNAMES)([^:]*?):(.*?)item\1.X-ABLabel:(?:_\$!<)?([\w-() ]*)(?:>!\$_)?./s', |
| | | array('self', 'x_abrelatednames_callback'), |
| | | $vcard); |
| | | |
| | | // Remove cruft like item1.X-AB*, item1.ADR instead of ADR, and empty lines |
| | |
| | | |
| | | return $vcard; |
| | | } |
| | | |
| | | private static function x_abrelatednames_callback($matches) |
| | | { |
| | | return 'X-' . strtoupper($matches[5]) . $matches[3] . ':'. $matches[4]; |
| | | } |
| | | |
| | | private static function rfc2425_fold_callback($matches) |
| | | { |
| | | return ":\n ".rtrim(chunk_split($matches[1], 72, "\n ")); |
| | | // use mb string function if available |
| | | if (function_exists('mb_ereg_replace')) { |
| | | return ":\n " . mb_ereg_replace('(.{70})', "\\1\n ", $matches[1]); |
| | | } |
| | | |
| | | // chunk_split string and avoid lines breaking multibyte characters |
| | | $c = 66; |
| | | $out = ":\n " . substr($matches[1], 0, $c); |
| | | for ($n = $c; $c < strlen($matches[1]); $c++) { |
| | | // break if length > 70 or mutlibyte character starts after position 66 |
| | | if ($n > 70 || ($n > 66 && ord($matches[1][$c]) >> 6 == 3)) { |
| | | $out .= "\n "; |
| | | $n = 0; |
| | | } |
| | | $out .= $matches[1][$c]; |
| | | $n++; |
| | | } |
| | | |
| | | return $out; |
| | | } |
| | | |
| | | private static function rfc2425_fold($val) |
| | |
| | | if (substr($string, 0, 2) == "\xFF\xFE") return 'UTF-16LE'; // Little Endian |
| | | if (substr($string, 0, 3) == "\xEF\xBB\xBF") return 'UTF-8'; |
| | | |
| | | // heuristics |
| | | if ($string[0] == "\0" && $string[1] == "\0" && $string[2] == "\0" && $string[3] != "\0") return 'UTF-32BE'; |
| | | if ($string[0] != "\0" && $string[1] == "\0" && $string[2] == "\0" && $string[3] == "\0") return 'UTF-32LE'; |
| | | if ($string[0] == "\0" && $string[1] != "\0" && $string[2] == "\0" && $string[3] != "\0") return 'UTF-16BE'; |
| | | if ($string[0] != "\0" && $string[1] == "\0" && $string[2] != "\0" && $string[3] == "\0") return 'UTF-16LE'; |
| | | |
| | | // use mb_detect_encoding() |
| | | $encodings = array('UTF-8', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', |
| | | 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', |