| | |
| | | */ |
| | | public function __construct($vcard = null, $charset = RCUBE_CHARSET, $detect = false, $fieldmap = array()) |
| | | { |
| | | if (!empty($fielmap)) { |
| | | if (!empty($fieldmap)) { |
| | | $this->extend_fieldmap($fieldmap); |
| | | } |
| | | |
| | |
| | | if (preg_match('/^END:VCARD$/i', $line)) { |
| | | // parse vcard |
| | | $obj = new rcube_vcard(self::cleanup($vcard_block), $charset, true, self::$fieldmap); |
| | | if (!empty($obj->displayname) || !empty($obj->email)) { |
| | | // 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)) { |
| | | $out[] = $obj; |
| | | } |
| | | |
| | |
| | | * |
| | | * @return string Cleaned vcard block |
| | | */ |
| | | private static function cleanup($vcard) |
| | | public static function cleanup($vcard) |
| | | { |
| | | // Convert special types (like Skype) to normal type='skype' classes with this simple regex ;) |
| | | $vcard = preg_replace( |
| | |
| | | $enc = null; |
| | | |
| | | foreach($regs2[1] as $attrid => $attr) { |
| | | $attr = preg_replace('/[\s\t\n\r\0\x0B]/', '', $attr); |
| | | if ((list($key, $value) = explode('=', $attr)) && $value) { |
| | | $value = trim($value); |
| | | if ($key == 'ENCODING') { |
| | | $value = strtoupper($value); |
| | | // add next line(s) to value string if QP line end detected |
| | |
| | | $value[] = $attrvalues; |
| | | } |
| | | else if (is_bool($attrvalues)) { |
| | | // true means just tag, not tag=value, as in PHOTO;BASE64:... |
| | | // true means just a tag, not tag=value, as in PHOTO;BASE64:... |
| | | if ($attrvalues) { |
| | | $attr .= strtoupper(";$attrname"); |
| | | // vCard v3 uses ENCODING=B (#1489183) |
| | | if ($attrname == 'base64') { |
| | | $attr .= ";ENCODING=B"; |
| | | } |
| | | else { |
| | | $attr .= strtoupper(";$attrname"); |
| | | } |
| | | } |
| | | } |
| | | else { |
| | |
| | | */ |
| | | private static function vcard_unquote($s, $sep = ';') |
| | | { |
| | | // break string into parts separated by $sep, but leave escaped $sep alone |
| | | if (count($parts = explode($sep, strtr($s, array("\\$sep" => "\007")))) > 1) { |
| | | foreach($parts as $s) { |
| | | $result[] = self::vcard_unquote(strtr($s, array("\007" => "\\$sep")), $sep); |
| | | // break string into parts separated by $sep |
| | | if (!empty($sep)) { |
| | | // Handle properly backslash escaping (#1488896) |
| | | $rep1 = array("\\\\" => "\010", "\\$sep" => "\007"); |
| | | $rep2 = array("\007" => "\\$sep", "\010" => "\\\\"); |
| | | |
| | | if (count($parts = explode($sep, strtr($s, $rep1))) > 1) { |
| | | foreach ($parts as $s) { |
| | | $result[] = self::vcard_unquote(strtr($s, $rep2)); |
| | | } |
| | | return $result; |
| | | } |
| | | return $result; |
| | | |
| | | $s = trim(strtr($s, $rep2)); |
| | | } |
| | | |
| | | return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';', '\:' => ':')); |
| | | // some implementations (GMail) use non-standard backslash before colon (#1489085) |
| | | // we will handle properly any backslashed character - removing dummy backslahes |
| | | // return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';')); |
| | | |
| | | $s = str_replace("\r", '', $s); |
| | | $pos = 0; |
| | | |
| | | while (($pos = strpos($s, '\\', $pos)) !== false) { |
| | | $next = substr($s, $pos + 1, 1); |
| | | if ($next == 'n' || $next == 'N') { |
| | | $s = substr_replace($s, "\n", $pos, 2); |
| | | } |
| | | else { |
| | | $s = substr_replace($s, '', $pos, 1); |
| | | } |
| | | |
| | | $pos += 1; |
| | | } |
| | | |
| | | return $s; |
| | | } |
| | | |
| | | /** |