| | |
| | | 'FN' => array(), |
| | | 'N' => array(array('','','','','')), |
| | | ); |
| | | private $fieldmap = array( |
| | | private static $fieldmap = array( |
| | | 'phone' => 'TEL', |
| | | 'birthday' => 'BDAY', |
| | | 'website' => 'URL', |
| | |
| | | 'email' => 'EMAIL', |
| | | 'address' => 'ADR', |
| | | 'jobtitle' => 'TITLE', |
| | | 'department' => 'X-DEPARTMENT', |
| | | 'gender' => 'X-GENDER', |
| | | 'maidenname' => 'X-MAIDENNAME', |
| | | 'anniversary' => 'X-ANNIVERSARY', |
| | | 'assistant' => 'X-ASSISTANT', |
| | | 'manager' => 'X-MANAGER', |
| | | 'spouse' => 'X-SPOUSE', |
| | | 'edit' => 'X-AB-EDIT', |
| | | ); |
| | | private $typemap = array('iPhone' => 'mobile', 'CELL' => 'mobile'); |
| | | private $phonetypemap = array('HOME1' => 'HOME', 'BUSINESS1' => 'WORK', 'BUSINESS2' => 'WORK2', 'BUSINESSFAX' => 'WORKFAX'); |
| | |
| | | public $notes; |
| | | public $email = array(); |
| | | |
| | | public static $eol = "\r\n"; |
| | | |
| | | /** |
| | | * Constructor |
| | | */ |
| | | public function __construct($vcard = null, $charset = RCMAIL_CHARSET, $detect = false) |
| | | public function __construct($vcard = null, $charset = RCMAIL_CHARSET, $detect = false, $fieldmap = array()) |
| | | { |
| | | if (!empty($fielmap)) |
| | | $this->extend_fieldmap($fieldmap); |
| | | |
| | | if (!empty($vcard)) |
| | | $this->load($vcard, $charset, $detect); |
| | | } |
| | |
| | | $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) { |
| | | foreach (array_flip(self::$fieldmap) as $tag => $col) { |
| | | foreach ((array)$this->raw[$tag] as $i => $raw) { |
| | | if (is_array($raw)) { |
| | | $k = -1; |
| | | $key = $col; |
| | | $subtype = ''; |
| | | |
| | | $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); |
| | | while ($k < count($raw['type']) && ($subtype == 'internet' || $subtype == 'pref')) |
| | | if (!empty($raw['type'])) { |
| | | $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); |
| | | while ($k < count($raw['type']) && ($subtype == 'internet' || $subtype == 'pref')) |
| | | $subtype = $typemap[$raw['type'][++$k]] ? $typemap[$raw['type'][$k]] : strtolower($raw['type'][$k]); |
| | | } |
| | | |
| | | // read vcard 2.1 subtype |
| | | if (!$subtype) { |
| | |
| | | } |
| | | |
| | | // force subtype if none set |
| | | if (preg_match('/^(email|phone|address|website)/', $key) && !$subtype) |
| | | if (!$subtype && preg_match('/^(email|phone|address|website)/', $key)) |
| | | $subtype = 'other'; |
| | | |
| | | if ($subtype) |
| | |
| | | public function reset($fields = null) |
| | | { |
| | | if (!$fields) |
| | | $fields = array_merge(array_values($this->fieldmap), array_keys($this->immap), array('FN','N','ORG','NICKNAME','EMAIL','ADR','BDAY')); |
| | | $fields = array_merge(array_values(self::$fieldmap), array_keys($this->immap), array('FN','N','ORG','NICKNAME','EMAIL','ADR','BDAY')); |
| | | |
| | | foreach ($fields as $f) |
| | | unset($this->raw[$f]); |
| | |
| | | if ($field == 'phone' && $this->phonetypemap[$type]) |
| | | $type = $this->phonetypemap[$type]; |
| | | |
| | | if (($tag = $this->fieldmap[$field]) && (is_array($value) || strlen($value))) { |
| | | if (($tag = self::$fieldmap[$field]) && (is_array($value) || strlen($value))) { |
| | | $index = count($this->raw[$tag]); |
| | | $this->raw[$tag][$index] = (array)$value; |
| | | if ($type) |
| | |
| | | |
| | | |
| | | /** |
| | | * Extends fieldmap definition |
| | | */ |
| | | public function extend_fieldmap($map) |
| | | { |
| | | if (is_array($map)) |
| | | self::$fieldmap = array_merge($map, self::$fieldmap); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Factory method to import a vcard file |
| | | * |
| | | * @param string vCard file content |
| | |
| | | |
| | | if (preg_match('/^END:VCARD$/i', $line)) { |
| | | // parse vcard |
| | | $obj = new rcube_vcard(self::cleanup($vcard_block), $charset, true); |
| | | $obj = new rcube_vcard(self::cleanup($vcard_block), $charset, true, self::$fieldmap); |
| | | if (!empty($obj->displayname) || !empty($obj->email)) |
| | | $out[] = $obj; |
| | | |
| | |
| | | $value = $entry; |
| | | } |
| | | |
| | | $vcard .= self::vcard_quote($type) . $attr . ':' . self::vcard_quote($value) . "\n"; |
| | | // skip empty entries |
| | | if (self::is_empty($value)) |
| | | continue; |
| | | |
| | | $vcard .= self::vcard_quote($type) . $attr . ':' . self::vcard_quote($value) . self::$eol; |
| | | } |
| | | } |
| | | |
| | | return "BEGIN:VCARD\nVERSION:3.0\n{$vcard}END:VCARD"; |
| | | return 'BEGIN:VCARD' . self::$eol . 'VERSION:3.0' . self::$eol . $vcard . 'END:VCARD'; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Check if vCard entry is empty: empty string or an array with |
| | | * all entries empty. |
| | | * |
| | | * @param mixed $value Attribute value (string or array) |
| | | * |
| | | * @return bool True if the value is empty, False otherwise |
| | | */ |
| | | private static function is_empty($value) |
| | | { |
| | | foreach ((array)$value as $v) { |
| | | if (((string)$v) !== '') { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Returns UNICODE type based on BOM (Byte Order Mark) |
| | | * |
| | | * @param string Input string to test |