Esempio n. 1
0
 /**
  * Return the full rendered version of the Horde_Mime_Part object.
  *
  * URL parameters used by this function:
  *   - c: (integer) The VCARD component that contains an image.
  *   - p: (integer) The index of image inside the component to display.
  *
  * @return array  See parent::render().
  * @throws Horde_Exception
  */
 protected function _renderInline()
 {
     $vars = $GLOBALS['injector']->getInstance('Horde_Variables');
     if (!isset($vars->p)) {
         $imp_contents = $this->getConfigParam('imp_contents');
         $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_VcardImport', array('mime_id' => $this->_mimepart->getMimeId(), 'muid' => strval($imp_contents->getIndicesOb())));
         $this->_imageUrl = $this->getConfigParam('imp_contents')->urlView($this->_mimepart, 'download_render', array('params' => array('mode' => IMP_Contents::RENDER_INLINE)));
         return parent::_renderInline();
     }
     /* Send the requested photo. */
     $data = $this->_mimepart->getContents();
     $ical = new Horde_Icalendar();
     if (!$ical->parsevCalendar($data, 'VCALENDAR', $this->_mimepart->getCharset())) {
         // TODO: Error reporting
         return array();
     }
     $components = $ical->getComponents();
     if (!isset($components[$vars->c])) {
         // TODO: Error reporting
         return array();
     }
     $name = $components[$vars->c]->getAttributeDefault('FN', false);
     if ($name === false) {
         $name = $components[$vars->c]->printableName();
     }
     if (empty($name)) {
         $name = preg_replace('/\\..*?$/', '', $this->_mimepart->getName());
     }
     $photos = $components[$vars->c]->getAllAttributes('PHOTO');
     if (!isset($photos[$vars->p])) {
         // TODO: Error reporting
         return array();
     }
     $type = 'image/' . Horde_String::lower($photos[$vars->p]['params']['TYPE']);
     return array($this->_mimepart->getMimeId() => array('data' => base64_decode($photos[$vars->p]['value']), 'name' => $name . '.' . Horde_Mime_Magic::mimeToExt($type), 'type' => $type));
 }
Esempio n. 2
0
 /**
  * Returns an unsorted file list of the specified directory.
  *
  * @param string $path          The path of the directory.
  * @param string|array $filter  Regular expression(s) to filter
  *                              file/directory name on.
  * @param boolean $dotfiles     Show dotfiles?
  * @param boolean $dironly      Show only directories?
  *
  * @return array  File list.
  * @throws Horde_Vfs_Exception
  */
 protected function _listFolder($path, $filter = null, $dotfiles = true, $dironly = false)
 {
     $list = array();
     if ($path == '/') {
         try {
             $apps = $this->_registry->listApps(null, false, Horde_Perms::READ);
         } catch (Horde_Exception $e) {
             throw new Horde_Vfs_Exception($e->getMessage());
         }
         foreach ($apps as $app) {
             if ($this->_registry->hasMethod('browse', $app)) {
                 $file = array('name' => $app, 'date' => time(), 'type' => '**dir', 'size' => -1);
                 $list[] = $file;
             }
         }
         return $list;
     }
     if (substr($path, 0, 1) == '/') {
         $path = substr($path, 1);
     }
     $pieces = explode('/', $path);
     try {
         $items = $this->_registry->callByPackage($pieces[0], 'browse', array('path' => $path, 'properties' => array('name', 'browseable', 'contenttype', 'contentlength', 'modified')));
     } catch (Horde_Exception $e) {
         throw new Horde_Vfs_Exception($e->getMessage());
     }
     if (!is_array(reset($items))) {
         /* We return an object's content. */
         throw new Horde_Vfs_Exception('Unknown error');
     }
     foreach ($items as $sub_path => $i) {
         if ($dironly && !$i['browseable']) {
             continue;
         }
         $name = basename($sub_path);
         if ($this->_filterMatch($filter, $name)) {
             continue;
         }
         $type = class_exists('Horde_Mime_Magic') ? Horde_Mime_Magic::mimeToExt(empty($i['contenttype']) ? 'application/octet-stream' : $i['contenttype']) : '**none';
         $file = array('name' => $name, 'date' => empty($i['modified']) ? 0 : $i['modified'], 'type' => $i['browseable'] ? '**dir' : $type, 'size' => empty($i['contentlength']) ? 0 : $i['contentlength']);
         $list[] = $file;
     }
     return $list;
 }
Esempio n. 3
0
 /**
  * Sends the correct HTTP headers to the browser to download this image.
  *
  * @param string $view  The view to download.
  */
 public function downloadHeaders($view = 'full')
 {
     global $browser, $conf;
     $filename = $this->filename;
     if ($view != 'full') {
         if ($ext = Horde_Mime_Magic::mimeToExt('image/' . $conf['image']['type'])) {
             $filename .= '.' . $ext;
         }
     }
     $browser->downloadHeaders($filename);
 }
Esempio n. 4
0
 /**
  * Stores an object in the Kolab message store.
  *
  * TODO
  *
  * @return string  The object id, possibly updated.
  * @throws Turba_Exception
  */
 protected function _store($attributes, $object_id = null)
 {
     if (isset($attributes['__type']) && $attributes['__type'] == 'Group') {
         $this->_convertMembers($attributes);
         $data = $this->_getListData();
     } else {
         if (isset($attributes['photo']) && isset($attributes['phototype'])) {
             $filename = 'photo.' . Horde_Mime_Magic::mimeToExt($attributes['phototype']);
             $attributes['_attachments'][$filename] = array('type' => $attributes['phototype'], 'content' => Horde_Stream_Wrapper_String::getStream($attributes['photo']));
             $attributes['picture'] = $filename;
             unset($attributes['photo'], $attributes['phototype']);
         }
         // EAS sets the date fields to '' instead of null -> fix it up
         $fix_date_fields = array('birthday', 'anniversary');
         foreach ($fix_date_fields as $fix_date) {
             if (empty($attributes[$fix_date])) {
                 unset($attributes[$fix_date]);
             }
         }
         $data = $this->_getData();
     }
     if ($object_id === null) {
         $object_id = $data->create($attributes);
     } else {
         $data->modify($attributes);
     }
     /* Invalidate cache. */
     $this->_connected = false;
     return Horde_Url::uriB64Encode($object_id);
 }
Esempio n. 5
0
 /**
  * Parse a MIME message and create a new ticket.
  *
  * @param string $text       This is the full text of the MIME message.
  * @param array $info        An array of information for the new ticket.
  *                           This should include:
  *                           - 'queue'    => queue id
  *                           - 'type'     => type id
  *                           - 'state'    => state id
  *                           - 'priority' => priority id
  *                           - 'ticket'   => ticket id (prevents creation
  *                                           of new tickets)
  * @param string $auth_user  This will be the Horde user that creates the
  *                           ticket. If null, we will try to deduce from
  *                           the message's From: header. We do NOT default
  *                           to $GLOBALS['registry']->getAuth().
  *
  * @return Whups_Ticket  Ticket.
  */
 public static function processMail($text, array $info, $auth_user = null)
 {
     global $conf;
     $message = Horde_Mime_Part::parseMessage($text);
     if (preg_match("/^(.*?)\r?\n\r?\n/s", $text, $matches)) {
         $hdrText = $matches[1];
     } else {
         $hdrText = $text;
     }
     $headers = Horde_Mime_Headers::parseHeaders($hdrText);
     // If this message was generated by Whups, don't process it.
     if ($headers->getValue('X-Whups-Generated')) {
         return true;
     }
     // Try to avoid bounces, auto-replies, and mailing list responses.
     $from = $headers->getValue('from');
     if (strpos($headers->getValue('Content-Type'), 'multipart/report') !== false || stripos($from, 'mailer-daemon@') !== false || stripos($from, 'postmaster@') !== false || !is_null($headers->getValue('X-Failed-Recipients')) || !is_null($headers->getValue('X-Autoreply-Domain')) || $headers->getValue('Auto-Submitted') == 'auto-replied' || $headers->getValue('Precedence') == 'auto_reply' || $headers->getValue('X-Precedence') == 'auto_reply' || $headers->getValue('X-Auto-Response-Suppress') == 'All' || $headers->getValue('X-List-Administrivia') == 'Yes') {
         return true;
     }
     // Use the message subject as the ticket summary.
     $info['summary'] = trim($headers->getValue('subject'));
     if (empty($info['summary'])) {
         $info['summary'] = _("[No Subject]");
     }
     // Format the message into a comment.
     $comment = _("Received message:") . "\n\n";
     if (!empty($GLOBALS['conf']['mail']['include_headers'])) {
         foreach ($headers->toArray(array('nowrap' => true)) as $name => $vals) {
             if (!in_array(strtolower($name), array('subject', 'from', 'to', 'cc', 'date'))) {
                 if (is_array($vals)) {
                     foreach ($vals as $val) {
                         $comment .= $name . ': ' . $val . "\n";
                     }
                 } else {
                     $comment .= $name . ': ' . $vals . "\n";
                 }
             }
         }
         $comment .= "\n";
     }
     // Look for the body part.
     $body_id = $message->findBody();
     if ($body_id) {
         $part = $message->getPart($body_id);
         $content = Horde_String::convertCharset($part->getContents(), $part->getCharset(), 'UTF-8');
         switch ($part->getType()) {
             case 'text/plain':
                 $comment .= $content;
                 break;
             case 'text/html':
                 $comment .= Horde_Text_Filter::filter($content, array('Html2text'), array(array('width' => 0)));
                 break;
             default:
                 $comment .= _("[ Could not render body of message. ]");
                 break;
         }
     } else {
         $comment .= _("[ Could not render body of message. ]");
     }
     $info['comment'] = $comment . "\n";
     // Try to determine the Horde user for creating the ticket.
     if (empty($auth_user)) {
         $tmp = new Horde_Mail_Rfc822_Address($from);
         $auth_user = self::_findAuthUser($tmp->bare_address);
     }
     $author = $auth_user;
     if (empty($auth_user) && !empty($info['default_auth'])) {
         $auth_user = $info['default_auth'];
         if (!empty($from)) {
             $info['user_email'] = $from;
         }
     }
     if (empty($auth_user) && !empty($conf['mail']['username'])) {
         $auth_user = $conf['mail']['username'];
         if (!empty($from)) {
             $info['user_email'] = $from;
         }
     }
     // Authenticate as the correct Horde user.
     if (!empty($auth_user) && $auth_user != $GLOBALS['registry']->getAuth()) {
         $GLOBALS['registry']->setAuth($auth_user, array());
     }
     // Attach message.
     $attachments = array();
     if (!empty($GLOBALS['conf']['mail']['attach_message'])) {
         $tmp_name = Horde::getTempFile('whups');
         $fp = @fopen($tmp_name, 'wb');
         if (!$fp) {
             throw new Whups_Exception(sprintf('Cannot open file %s for writing.', $tmp_name));
         }
         fwrite($fp, $text);
         fclose($fp);
         $attachments[] = array('name' => _("Original Message") . '.eml', 'tmp_name' => $tmp_name);
     }
     // Extract attachments.
     $dl_list = array_slice(array_keys($message->contentTypeMap()), 1);
     foreach ($dl_list as $key) {
         $part = $message->getPart($key);
         if ($key == $body_id && $part->getType() == 'text/plain' || $part->getType() == 'multipart/alternative' || $part->getType() == 'multipart/mixed') {
             continue;
         }
         $tmp_name = Horde::getTempFile('whups');
         $fp = @fopen($tmp_name, 'wb');
         if (!$fp) {
             throw new Whups_Exception(sprintf('Cannot open file %s for writing.', $tmp_name));
         }
         fwrite($fp, $part->getContents());
         fclose($fp);
         $part_name = $part->getName(true);
         if (!$part_name) {
             $ptype = $part->getPrimaryType();
             switch ($ptype) {
                 case 'multipart':
                 case 'application':
                     $part_name = sprintf(_("%s part"), ucfirst($part->getSubType()));
                     break;
                 default:
                     $part_name = sprintf(_("%s part"), ucfirst($ptype));
                     break;
             }
             if ($ext = Horde_Mime_Magic::mimeToExt($part->getType())) {
                 $part_name .= '.' . $ext;
             }
         }
         $attachments[] = array('name' => $part_name, 'tmp_name' => $tmp_name);
     }
     // See if we can match this message to an existing ticket.
     if ($ticket = self::_findTicket($info)) {
         $ticket->change('comment', $info['comment']);
         $ticket->change('comment-email', $from);
         if ($attachments) {
             $ticket->change('attachments', $attachments);
         }
         $ticket->commit($author);
     } elseif (!empty($info['ticket'])) {
         // Didn't match an existing ticket though a ticket number had been
         // specified.
         throw new Whups_Exception(sprintf(_("Could not find ticket \"%s\"."), $info['ticket']));
     } else {
         if (!empty($info['guess-queue'])) {
             // Try to guess the queue name for the new ticket from the
             // message subject.
             $queues = $GLOBALS['whups_driver']->getQueues();
             foreach ($queues as $queueId => $queueName) {
                 if (preg_match('/\\b' . preg_quote($queueName, '/') . '\\b/i', $info['summary'])) {
                     $info['queue'] = $queueId;
                     break;
                 }
             }
         }
         $info['attachments'] = $attachments;
         // Create a new ticket.
         $ticket = Whups_Ticket::newTicket($info, $author);
     }
 }
Esempio n. 6
0
 /**
  * Updates the properties of this event from a Horde_Icalendar_Vevent
  * object.
  *
  * @param Horde_Icalendar_Vevent $vEvent  The iCalendar data to update
  *                                        from.
  * @param boolean $parseAttendees         Parse attendees too?
  *                                        @since Kronolith 4.2
  */
 public function fromiCalendar($vEvent, $parseAttendees = false)
 {
     // Unique ID.
     try {
         $uid = $vEvent->getAttribute('UID');
         if (!empty($uid)) {
             $this->uid = $uid;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Organizer
     try {
         $organizer = $vEvent->getAttribute('ORGANIZER');
         if (!empty($organizer)) {
             $this->organizer = str_replace(array('MAILTO:', 'mailto:'), '', $organizer);
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Sequence.
     try {
         $seq = $vEvent->getAttribute('SEQUENCE');
         if (is_int($seq)) {
             $this->sequence = $seq;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Title, tags and description.
     try {
         $title = $vEvent->getAttribute('SUMMARY');
         if (!is_array($title)) {
             $this->title = $title;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Tags
     try {
         $this->_tags = $vEvent->getAttributeValues('CATEGORIES');
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Description
     try {
         $desc = $vEvent->getAttribute('DESCRIPTION');
         if (!is_array($desc)) {
             $this->description = $desc;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Remote Url
     try {
         $url = $vEvent->getAttribute('URL');
         if (!is_array($url)) {
             $this->url = $url;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Location
     try {
         $location = $vEvent->getAttribute('LOCATION');
         if (!is_array($location)) {
             $this->location = $location;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     try {
         $geolocation = $vEvent->getAttribute('GEO');
         $this->geoLocation = array('lat' => $geolocation['latitude'], 'lon' => $geolocation['longitude']);
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Class
     try {
         $class = $vEvent->getAttribute('CLASS');
         if (!is_array($class)) {
             $class = Horde_String::upper($class);
             $this->private = $class == 'PRIVATE' || $class == 'CONFIDENTIAL';
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Status.
     try {
         $status = $vEvent->getAttribute('STATUS');
         if (!is_array($status)) {
             $status = Horde_String::upper($status);
             if ($status == 'DECLINED') {
                 $status = 'CANCELLED';
             }
             if (defined('Kronolith::STATUS_' . $status)) {
                 $this->status = constant('Kronolith::STATUS_' . $status);
             }
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Reset allday flag in case this has changed. Will be recalculated
     // next time isAllDay() is called.
     $this->allday = false;
     // Start and end date.
     $tzid = null;
     try {
         $start = $vEvent->getAttribute('DTSTART');
         $startParams = $vEvent->getAttribute('DTSTART', true);
         // We don't support different timezones for different attributes,
         // so use the DTSTART timezone for the complete event.
         if (isset($startParams[0]['TZID'])) {
             // Horde_Date supports timezone aliases, so try that first.
             $tz = $startParams[0]['TZID'];
             try {
                 // Check if the timezone name is supported by PHP natively.
                 new DateTimeZone($tz);
                 $this->timezone = $tzid = $tz;
             } catch (Exception $e) {
             }
         }
         if (!is_array($start)) {
             // Date-Time field
             $this->start = new Horde_Date($start, $tzid);
         } else {
             // Date field
             $this->start = new Horde_Date(array('year' => (int) $start['year'], 'month' => (int) $start['month'], 'mday' => (int) $start['mday']), $tzid);
         }
     } catch (Horde_Icalendar_Exception $e) {
         throw new Kronolith_Exception($e);
     } catch (Horde_Date_Exception $e) {
         throw new Kronolith_Exception($e);
     }
     try {
         $end = $vEvent->getAttribute('DTEND');
         if (!is_array($end)) {
             // Date-Time field
             $this->end = new Horde_Date($end, $tzid);
             // All day events are transferred by many device as
             // DSTART: YYYYMMDDT000000 DTEND: YYYYMMDDT2359(59|00)
             // Convert accordingly
             if (is_object($this->start) && $this->start->hour == 0 && $this->start->min == 0 && $this->start->sec == 0 && $this->end->hour == 23 && $this->end->min == 59) {
                 $this->end = new Horde_Date(array('year' => (int) $this->end->year, 'month' => (int) $this->end->month, 'mday' => (int) $this->end->mday + 1), $tzid);
             }
         } else {
             // Date field
             $this->end = new Horde_Date(array('year' => (int) $end['year'], 'month' => (int) $end['month'], 'mday' => (int) $end['mday']), $tzid);
         }
     } catch (Horde_Icalendar_Exception $e) {
         $end = null;
     }
     if (is_null($end)) {
         try {
             $duration = $vEvent->getAttribute('DURATION');
             if (!is_array($duration)) {
                 $this->end = new Horde_Date($this->start);
                 $this->end->sec += $duration;
                 $end = 1;
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
         if (is_null($end)) {
             // End date equal to start date as per RFC 2445.
             $this->end = new Horde_Date($this->start);
             if (is_array($start)) {
                 // Date field
                 $this->end->mday++;
             }
         }
     }
     // vCalendar 1.0 alarms
     try {
         $alarm = $vEvent->getAttribute('AALARM');
         if (!is_array($alarm) && intval($alarm)) {
             $this->alarm = intval(($this->start->timestamp() - $alarm) / 60);
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // vCalendar 2.0 alarms
     foreach ($vEvent->getComponents() as $alarm) {
         if (!$alarm instanceof Horde_Icalendar_Valarm) {
             continue;
         }
         try {
             if ($alarm->getAttribute('ACTION') == 'NONE') {
                 continue;
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
         try {
             // @todo consider implementing different ACTION types.
             // $action = $alarm->getAttribute('ACTION');
             $trigger = $alarm->getAttribute('TRIGGER');
             $triggerParams = $alarm->getAttribute('TRIGGER', true);
         } catch (Horde_Icalendar_Exception $e) {
             continue;
         }
         if (!is_array($triggerParams)) {
             $triggerParams = array($triggerParams);
         }
         $haveTrigger = false;
         foreach ($triggerParams as $tp) {
             if (isset($tp['VALUE']) && $tp['VALUE'] == 'DATE-TIME') {
                 if (isset($tp['RELATED']) && $tp['RELATED'] == 'END') {
                     $this->alarm = intval(($this->end->timestamp() - $trigger) / 60);
                 } else {
                     $this->alarm = intval(($this->start->timestamp() - $trigger) / 60);
                 }
                 $haveTrigger = true;
                 break;
             } elseif (isset($tp['RELATED']) && $tp['RELATED'] == 'END') {
                 $this->alarm = -intval($trigger / 60);
                 $this->alarm -= $this->durMin;
                 $haveTrigger = true;
                 break;
             }
         }
         if (!$haveTrigger) {
             $this->alarm = -intval($trigger / 60);
         }
         break;
     }
     // Alarm snoozing/dismissal
     if ($this->alarm) {
         try {
             // If X-MOZ-LASTACK is set, this event is either dismissed or
             // snoozed.
             $vEvent->getAttribute('X-MOZ-LASTACK');
             try {
                 // If X-MOZ-SNOOZE-TIME is set, this event is snoozed.
                 $snooze = $vEvent->getAttribute('X-MOZ-SNOOZE-TIME');
                 $this->_snooze = intval(($snooze - time()) / 60);
             } catch (Horde_Icalendar_Exception $e) {
                 // If X-MOZ-SNOOZE-TIME is not set, this event is dismissed.
                 $this->_snooze = -1;
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
     }
     // Attached files, we require a UID so we can attach the file in VFS.
     if ($this->uid) {
         $attach = false;
         $attach_params = array();
         try {
             $attach = $vEvent->getAttribute('ATTACH');
             $attach_params = $vEvent->getAttribute('ATTACH', true);
             if (!is_array($attach)) {
                 $attach = array($attach);
             }
             foreach ($attach as $key => $attribute) {
                 if (isset($attach_params[$key]['VALUE']) && Horde_String::lower($attach_params[$key]['VALUE']) == 'uri') {
                     // @todo
                 } elseif (Horde_String::upper($attach_params[$key]['ENCODING']) == 'BASE64') {
                     $mime_type = !empty($attach_params[$key]['FMTTYPE']) ? $attach_params[$key]['FMTTYPE'] : '';
                     // @todo We really should add stream support to VFS
                     $file_data = base64_decode($attribute);
                     $vfs = $this->vfsInit();
                     $dir = Kronolith::VFS_PATH . '/' . $this->getVfsUid();
                     // @todo - Is there a way to get a filename from a
                     // non-uri ATTACH attribute??
                     $filename = sprintf(_("File %d.%s"), $key, Horde_Mime_Magic::mimeToExt($mime_type));
                     try {
                         $vfs->writeData($dir, $filename, $file_data, true);
                     } catch (Horde_Vfs_Exception $e) {
                         Horde::log($e->getMessage(), 'ERR');
                     }
                 }
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
     }
     // Attendance.
     // Importing attendance may result in confusion: editing an imported
     // copy of an event can cause invitation updates to be sent from
     // people other than the original organizer. So we don't import by
     // default. However to allow updates by synchronization, this behavior
     // can be overriden.
     // X-ATTENDEE is there for historical reasons. @todo remove in
     // Kronolith 5.
     $attendee = $users = null;
     if ($parseAttendees) {
         try {
             $attendee = $vEvent->getAttribute('ATTENDEE');
             $params = $vEvent->getAttribute('ATTENDEE', true);
         } catch (Horde_Icalendar_Exception $e) {
             try {
                 $attendee = $vEvent->getAttribute('X-ATTENDEE');
                 $params = $vEvent->getAttribute('X-ATTENDEE', true);
             } catch (Horde_Icalendar_Exception $e) {
             }
         }
         if ($attendee && !is_array($attendee)) {
             $attendee = array($attendee);
             $params = array($params);
         }
         try {
             $users = $vEvent->getAttribute('X-HORDE-ATTENDEE');
             $userParams = $vEvent->getAttribute('X-HORDE-ATTENDEE', true);
             if (!is_array($users)) {
                 $users = array($users);
                 $userParams = array($userParams);
             }
             foreach ($userParams as &$param) {
                 $param['hordeUser'] = true;
             }
             if ($attendee) {
                 $attendee = array_merge($attendee, $users);
                 $params = array_merge($params, $userParams);
             } else {
                 $attendee = $users;
                 $params = $userParams;
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
     }
     if ($attendee) {
         // Clear the attendees since we might be editing/replacing the event
         $this->attendees = new Kronolith_Attendee_List();
         for ($i = 0; $i < count($attendee); ++$i) {
             // Default according to rfc2445:
             $attendance = Kronolith::PART_REQUIRED;
             // vCalendar 2.0 style:
             if (!empty($params[$i]['ROLE'])) {
                 switch ($params[$i]['ROLE']) {
                     case 'OPT-PARTICIPANT':
                         $attendance = Kronolith::PART_OPTIONAL;
                         break;
                     case 'NON-PARTICIPANT':
                         $attendance = Kronolith::PART_NONE;
                         break;
                 }
             }
             // vCalendar 1.0 style;
             if (!empty($params[$i]['EXPECT'])) {
                 switch ($params[$i]['EXPECT']) {
                     case 'REQUEST':
                         $attendance = Kronolith::PART_OPTIONAL;
                         break;
                     case 'FYI':
                         $attendance = Kronolith::PART_NONE;
                         break;
                 }
             }
             $response = Kronolith::RESPONSE_NONE;
             if (empty($params[$i]['PARTSTAT']) && !empty($params[$i]['STATUS'])) {
                 $params[$i]['PARTSTAT'] = $params[$i]['STATUS'];
             }
             if (!empty($params[$i]['PARTSTAT'])) {
                 switch ($params[$i]['PARTSTAT']) {
                     case 'ACCEPTED':
                         $response = Kronolith::RESPONSE_ACCEPTED;
                         break;
                     case 'DECLINED':
                         $response = Kronolith::RESPONSE_DECLINED;
                         break;
                     case 'TENTATIVE':
                         $response = Kronolith::RESPONSE_TENTATIVE;
                         break;
                 }
             }
             if (!empty($params[$i]['hordeUser'])) {
                 $this->attendees->add(new Kronolith_Attendee(array('user' => $attendee[$i], 'role' => $attendance, 'response' => $response)));
             } else {
                 $tmp = new Horde_Mail_Rfc822_Address(str_replace(array('MAILTO:', 'mailto:'), '', $attendee[$i]));
                 $email = $tmp->bare_address;
                 $name = isset($params[$i]['CN']) ? $params[$i]['CN'] : null;
                 $this->addAttendee($email, $attendance, $response, $name);
             }
         }
     }
     $this->_handlevEventRecurrence($vEvent);
     $this->initialized = true;
 }