| | |
| | | 'manager' => 'X-MANAGER', |
| | | 'spouse' => 'X-SPOUSE', |
| | | 'edit' => 'X-AB-EDIT', |
| | | 'groups' => 'CATEGORIES', |
| | | ); |
| | | private $typemap = array( |
| | | 'IPHONE' => 'mobile', |
| | |
| | | */ |
| | | public function __construct($vcard = null, $charset = RCUBE_CHARSET, $detect = false, $fieldmap = array()) |
| | | { |
| | | if (!empty($fielmap)) { |
| | | if (!empty($fieldmap)) { |
| | | $this->extend_fieldmap($fieldmap); |
| | | } |
| | | |
| | |
| | | |
| | | case 'birthday': |
| | | case 'anniversary': |
| | | if (($val = rcube_utils::strtotime($value)) && ($fn = self::$fieldmap[$field])) { |
| | | $this->raw[$fn][] = array(0 => date('Y-m-d', $val), 'value' => array('date')); |
| | | if (($val = rcube_utils::anytodatetime($value)) && ($fn = self::$fieldmap[$field])) { |
| | | $this->raw[$fn][] = array(0 => $val->format('Y-m-d'), 'value' => array('date')); |
| | | } |
| | | break; |
| | | |
| | |
| | | $vcard_block = ''; |
| | | $in_vcard_block = false; |
| | | |
| | | foreach (preg_split("/[\r\n]+/", $data) as $i => $line) { |
| | | foreach (preg_split("/[\r\n]+/", $data) as $line) { |
| | | if ($in_vcard_block && !empty($line)) { |
| | | $vcard_block .= $line . "\n"; |
| | | } |
| | |
| | | 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( |
| | |
| | | $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 { |
| | |
| | | * |
| | | * @return string Joined and quoted string |
| | | */ |
| | | private static function vcard_quote($s, $sep = ';') |
| | | public static function vcard_quote($s, $sep = ';') |
| | | { |
| | | if (is_array($s)) { |
| | | foreach($s as $part) { |
| | |
| | | return(implode($sep, (array)$r)); |
| | | } |
| | | |
| | | return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', ',' => '\,', ';' => '\;')); |
| | | return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', $sep => '\\'.$sep)); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | 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 = 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; |
| | | } |
| | | |
| | | /** |