+ }
+
+
+ /**
+ * Return vCard data as associative array to be unsed in Roundcube address books
+ *
+ * @return array Hash array with key-value pairs
+ */
+ public function get_assoc()
+ {
+ $out = array('name' => $this->displayname);
+ $typemap = $this->typemap;
+
+ // copy name fields to output array
+ foreach (array('firstname','surname','middlename','nickname','organization') as $col) {
+ if (strlen($this->$col))
+ $out[$col] = $this->$col;
+ }
+
+ 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(self::$fieldmap) as $tag => $col) {
+ foreach ((array)$this->raw[$tag] as $i => $raw) {
+ if (is_array($raw)) {
+ $k = -1;
+ $key = $col;
+ $subtype = '';
+
+ if (!empty($raw['type'])) {
+ $combined = join(',', self::array_filter((array)$raw['type'], 'internet,pref', true));
+ $subtype = $typemap[$combined] ? $typemap[$combined] : ($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) {
+ foreach ($raw as $k => $v) {
+ if (!is_numeric($k) && $v === true && !in_array(strtolower($k), array('pref','internet','voice','base64'))) {
+ $subtype = $typemap[$k] ? $typemap[$k] : strtolower($k);
+ break;
+ }
+ }
+ }
+
+ // force subtype if none set
+ if (!$subtype && preg_match('/^(email|phone|address|website)/', $key))
+ $subtype = 'other';
+
+ if ($subtype)
+ $key .= ':' . $subtype;
+
+ // split ADR values into assoc array
+ if ($tag == 'ADR') {
+ list(,, $value['street'], $value['locality'], $value['region'], $value['zipcode'], $value['country']) = $raw;
+ $out[$key][] = $value;
+ }
+ else
+ $out[$key][] = $raw[0];
+ }
+ else {
+ $out[$col][] = $raw;
+ }
+ }
+ }