/** * Authenticate to the POP3 server. * * @param string $method POP3 login method. * * @throws Horde_Imap_Client_Exception */ protected function _tryLogin($method) { $username = $this->getParam('username'); $password = $this->getParam('password'); switch ($method) { case 'CRAM-MD5': case 'CRAM-SHA1': case 'CRAM-SHA256': // RFC 5034: CRAM-MD5 // CRAM-SHA1 & CRAM-SHA256 supported by Courier SASL library $challenge = $this->_sendLine('AUTH ' . $method); $response = base64_encode($username . ' ' . hash_hmac(Horde_String::lower(substr($method, 5)), base64_decode(substr($challenge['resp'], 2)), $password, true)); $this->_sendLine($response, array('debug' => sprintf('[AUTH Response (username: %s)]', $username))); break; case 'DIGEST-MD5': // RFC 2831; Obsoleted by RFC 6331 $challenge = $this->_sendLine('AUTH DIGEST-MD5'); $response = base64_encode(new Horde_Imap_Client_Auth_DigestMD5($username, $password, base64_decode(substr($challenge['resp'], 2)), $this->getParam('hostspec'), 'pop3')); $sresponse = $this->_sendLine($response, array('debug' => sprintf('[AUTH Response (username: %s)]', $username))); if (stripos(base64_decode(substr($sresponse['resp'], 2)), 'rspauth=') === false) { throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Unexpected response from server when authenticating."), Horde_Imap_Client_Exception::SERVER_CONNECT); } /* POP3 doesn't use protocol's third step. */ $this->_sendLine(''); break; case 'LOGIN': // RFC 4616 (AUTH=PLAIN) & 5034 (POP3 SASL) $this->_sendLine('AUTH LOGIN'); $this->_sendLine(base64_encode($username)); $this->_sendLine(base64_encode($password), array('debug' => sprintf('[AUTH Password (username: %s)]', $username))); break; case 'PLAIN': // RFC 5034 $this->_sendLine('AUTH PLAIN ' . base64_encode(implode("", array($username, $username, $password))), array('debug' => sprintf('AUTH PLAIN [Auth Response (username: %s)]', $username))); break; case 'APOP': /* If UTF8 (+ USER) is active, and non-ASCII exists, need to apply * SASLprep to username/password. RFC 6856[2.2]. Reject if * UTF8 (+ USER) is not supported and 8-bit characters exist. */ if (Horde_Mime::is8bit($username) || Horde_Mime::is8bit($password)) { if (empty($this->_temp['utf8']) || !$this->_capability('UTF8', 'USER') || !class_exists('Horde_Stringprep')) { $error = true; } else { Horde_Stringprep::autoload(); $saslprep = new Znerol\Component\Stringprep\Profile\SASLprep(); try { $username = $saslprep->apply($username, 'UTF-8', Znerol\Compnonent\Stringprep\Profile::MODE_QUERY); $password = $saslprep->apply($password, 'UTF-8', Znerol\Compnonent\Stringprep\Profile::MODE_STORE); $error = false; } catch (Znerol\Component\Stringprep\ProfileException $e) { $error = true; } } if ($error) { throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED); } } // RFC 1939 [7] $this->_sendLine('APOP ' . $username . ' ' . hash('md5', $this->_temp['pop3timestamp'] . $password)); break; case 'USER': /* POP3 servers without UTF8 (+ USER) does not accept non-ASCII * in USER/PASS. RFC 6856[2.2] */ if ((empty($this->_temp['utf8']) || !$this->_capability('UTF8', 'USER')) && (Horde_Mime::is8bit($username) || Horde_Mime::is8bit($password))) { throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED); } // RFC 1939 [7] $this->_sendLine('USER ' . $username); $this->_sendLine('PASS ' . $password, array('debug' => 'PASS [Password]')); break; case 'SCRAM-SHA-1': $scram = new Horde_Imap_Client_Auth_Scram($username, $password, 'SHA1'); $c1 = $this->_sendLine('AUTH ' . $method . ' ' . base64_encode($scram->getClientFirstMessage())); $sr1 = base64_decode(substr($c1['resp'], 2)); if (!$scram->parseServerFirstMessage($sr1)) { throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED); } $c2 = $this->_sendLine(base64_encode($scram->getClientFinalMessage())); $sr2 = base64_decode(substr($c2['resp'], 2)); if (!$scram->parseServerFirstMessage($sr)) { throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED); /* This means authentication passed, according to the server, * but the server signature is incorrect. This indicates that * server verification has failed. Immediately disconnect from * the server, since this is a possible security issue. */ $this->logout(); throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Server failed verification check."), Horde_Imap_Client_Exception::LOGIN_SERVER_VERIFICATION_FAILED); } $this->_sendLine(''); break; default: $e = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Unknown authentication method: %s"), Horde_Imap_Client_Exception::SERVER_CONNECT); $e->messagePrintf(array($method)); throw $e; } }
/** * Constructs a new procmail recipe. * * @param array $params Array of parameters. * REQUIRED FIELDS: * 'action' * OPTIONAL FIELDS: * 'action-value' (only used if the * 'action' requires it) * 'disable' * @param array $scriptparams Array of parameters passed to * Ingo_Script_Procmail. */ public function __construct($params = array(), $scriptparams = array()) { $this->_disable = !empty($params['disable']); $this->_params = array_merge($this->_params, $scriptparams); $delivery = '| '; if (isset($this->_params['delivery_agent'])) { $delivery .= $this->_params['delivery_agent'] . ' '; } if (isset($this->_params['delivery_mailbox_prefix'])) { $delivery .= ' ' . $this->_params['delivery_mailbox_prefix']; } switch ($params['action']) { case 'Ingo_Rule_User_Keep': // Note: you may have to set the DEFAULT variable in your // backend configuration. $this->_action[] = $delivery .= '$DEFAULT'; break; case 'Ingo_Rule_User_Move': $this->_action[] = $delivery .= $this->procmailPath($params['action-value']); break; case 'Ingo_Rule_User_Discard': $this->_action[] = '/dev/null'; break; case 'Ingo_Rule_User_Redirect': $this->_action[] = '! ' . $params['action-value']; break; case 'Ingo_Rule_User_RedirectKeep': $this->_action[] = '{'; $this->_action[] = ' :0 c'; $this->_action[] = ' ! ' . $params['action-value']; if (strpos($this->_flags, 'c') === false) { $this->_action[] = ''; $this->_action[] = ' :0' . (isset($this->_params['delivery_agent']) ? ' w' : ''); $this->_action[] = ' ' . $delivery . '$DEFAULT'; } $this->_action[] = '}'; break; case 'Ingo_Rule_User_Reject': $this->_action[] = '{'; $this->_action[] = ' :0 h'; $this->_action[] = ' SUBJECT=| formail -xSubject:'; $this->_action[] = ''; $this->_action[] = ' :0 h'; $this->_action[] = ' SENDER=| formail -zxFrom:'; $this->_action[] = ''; $this->_action[] = ' :0 Wh'; $this->_action[] = ' * !^FROM_DAEMON'; $this->_action[] = ' * !^X-Loop: $SENDER'; $this->_action[] = ' | (formail -rA"X-Loop: $SENDER" \\'; $reason = $params['action-value']; if (Horde_Mime::is8bit($reason)) { $this->_action[] = ' -i"Subject: Re: $SUBJECT" \\'; $this->_action[] = ' -i"Content-Transfer-Encoding: quoted-printable" \\'; $this->_action[] = ' -i"Content-Type: text/plain; charset=UTF-8" ; \\'; $reason = Horde_Mime_QuotedPrintable::encode($reason); } else { $this->_action[] = ' -i"Subject: Re: $SUBJECT" ; \\'; } $reason = addcslashes($reason, "\\\n\r\t\"`"); $this->_action[] = ' ' . $this->_params['echo'] . ' -e "' . $reason . '" \\'; $this->_action[] = ' ) | $SENDMAIL -oi -t'; $this->_action[] = '}'; break; case 'Ingo_Rule_System_Vacation': $days = $params['action-value']['days']; $timed = !empty($params['action-value']['start']) && !empty($params['action-value']['end']); $this->_action[] = '{'; foreach ($params['action-value']['addresses'] as $address) { if (empty($address)) { continue; } $this->_action[] = ' :0'; $this->_action[] = ' * ^TO_' . $address; $this->_action[] = ' {'; $this->_action[] = ' FILEDATE=`test -f ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' && ' . $this->_params['ls'] . ' -lcn --time-style=+%s ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' | ' . 'awk \'{ print $6 + (' . $days * 86400 . ') }\'`'; $this->_action[] = ' DATE=`' . $this->_params['date'] . ' +%s`'; $this->_action[] = ' DUMMY=`test -f ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' && ' . 'test $FILEDATE -le $DATE && ' . 'rm ${VACATION_DIR:-.}/\'.vacation.' . $address . '\'`'; if ($timed) { $this->_action[] = ' START=' . $params['action-value']['start']; $this->_action[] = ' END=' . $params['action-value']['end']; } $this->_action[] = ''; $this->_action[] = ' :0 h'; $this->_action[] = ' SUBJECT=| formail -xSubject:'; $this->_action[] = ''; $this->_action[] = ' :0 Whc: ${VACATION_DIR:-.}/vacation.lock'; if ($timed) { $this->_action[] = ' * ? test $DATE -gt $START && test $END -gt $DATE'; } $this->_action[] = ' {'; $this->_action[] = ' :0 Wh'; $this->_action[] = ' * ^TO_' . $address; $this->_action[] = ' * !^X-Loop: ' . $address; $this->_action[] = ' * !^X-Spam-Flag: YES'; if (count($params['action-value']['excludes']) > 0) { foreach ($params['action-value']['excludes'] as $exclude) { if (!empty($exclude)) { $this->_action[] = ' * !^From.*' . $exclude; } } } if ($params['action-value']['ignorelist']) { $this->_action[] = ' * !^FROM_DAEMON'; } $this->_action[] = ' | formail -rD 8192 ${VACATION_DIR:-.}/.vacation.' . $address; $this->_action[] = ' :0 eh'; $this->_action[] = ' | (formail -rI"Precedence: junk" \\'; $this->_action[] = ' -a"From: <' . $address . '>" \\'; $this->_action[] = ' -A"X-Loop: ' . $address . '" \\'; $reason = Ingo_Rule_System_Vacation::vacationReason($params['action-value']['reason'], $params['action-value']['start'], $params['action-value']['end']); if (Horde_Mime::is8bit($reason)) { $this->_action[] = ' -i"Subject: ' . Horde_Mime::encode($params['action-value']['subject'] . ' (Re: $SUBJECT)') . '" \\'; $this->_action[] = ' -i"Content-Transfer-Encoding: quoted-printable" \\'; $this->_action[] = ' -i"Content-Type: text/plain; charset=UTF-8" ; \\'; $reason = Horde_Mime_QuotedPrintable::encode($reason); } else { $this->_action[] = ' -i"Subject: ' . Horde_Mime::encode($params['action-value']['subject'] . ' (Re: $SUBJECT)') . '" ; \\'; } $reason = addcslashes($reason, "\\\n\r\t\"`"); $this->_action[] = ' ' . $this->_params['echo'] . ' -e "' . $reason . '" \\'; $this->_action[] = ' ) | $SENDMAIL -f' . $address . ' -oi -t'; $this->_action[] = ' }'; $this->_action[] = ' }'; } $this->_action[] = '}'; break; case 'Ingo_Rule_System_Forward': /* Make sure that we prevent mail loops using 3 methods. * * First, we call sendmail -f to set the envelope sender to be the * same as the original sender, so bounces will go to the original * sender rather than to us. This unfortunately triggers lots of * Authentication-Warning: messages in sendmail's logs. * * Second, add an X-Loop header, to handle the case where the * address we forward to forwards back to us. * * Third, don't forward mailer daemon messages (i.e., bounces). * Method 1 above should make this redundant, unless we're sending * mail from this account and have a bad forward-to account. * * Get the from address, saving a call to formail if possible. * The procmail code for doing this is borrowed from the * Procmail Library Project, http://pm-lib.sourceforge.net/. * The Ingo project has the permission to use Procmail Library code * under Apache licence v 1.x or any later version. * Permission obtained 2006-04-04 from Author Jari Aalto. */ $this->_action[] = '{'; $this->_action[] = ' :0 '; $this->_action[] = ' *$ ! ^From *\\/[^ ]+'; $this->_action[] = ' *$ ! ^Sender: *\\/[^ ]+'; $this->_action[] = ' *$ ! ^From: *\\/[^ ]+'; $this->_action[] = ' *$ ! ^Reply-to: *\\/[^ ]+'; $this->_action[] = ' {'; $this->_action[] = ' OUTPUT = `formail -zxFrom:`'; $this->_action[] = ' }'; $this->_action[] = ' :0 E'; $this->_action[] = ' {'; $this->_action[] = ' OUTPUT = $MATCH'; $this->_action[] = ' }'; $this->_action[] = ''; /* Forward to each address on our list. */ foreach ($params['action-value'] as $address) { if (!empty($address)) { $this->_action[] = ' :0 c'; $this->_action[] = ' * !^FROM_MAILER'; $this->_action[] = ' * !^X-Loop: to-' . $address; $this->_action[] = ' | formail -A"X-Loop: to-' . $address . '" | $SENDMAIL -oi -f $OUTPUT ' . $address; } } /* In case of mail loop or bounce, store a copy locally. Note * that if we forward to more than one address, only a mail loop * on the last address will cause a local copy to be saved. TODO: * The next two lines are redundant (and create an extra copy of * the message) if "Keep a copy of messages in this account" is * checked. */ $this->_action[] = ' :0 E' . (isset($this->_params['delivery_agent']) ? 'w' : ''); $this->_action[] = ' ' . $delivery . '$DEFAULT'; $this->_action[] = ' :0 '; $this->_action[] = ' /dev/null'; $this->_action[] = '}'; break; default: $this->_valid = false; break; } }
public function readForm() { global $prefs, $session; // Event owner. $targetcalendar = Horde_Util::getFormData('targetcalendar'); if (strpos($targetcalendar, '\\')) { list(, $this->creator) = explode('\\', $targetcalendar, 2); } elseif (!isset($this->_id)) { $this->creator = $GLOBALS['registry']->getAuth(); } // Basic fields. $this->title = Horde_Util::getFormData('title', $this->title); $this->description = Horde_Util::getFormData('description', $this->description); $this->location = Horde_Util::getFormData('location', $this->location); $this->timezone = Horde_Util::getFormData('timezone', $this->timezone); $this->private = (bool) Horde_Util::getFormData('private'); // URL. $url = Horde_Util::getFormData('eventurl', $this->url); if (strlen($url)) { // Analyze and re-construct. $url = @parse_url($url); if ($url) { if (function_exists('http_build_url')) { if (empty($url['path'])) { $url['path'] = '/'; } $url = http_build_url($url); } else { $new_url = ''; if (isset($url['scheme'])) { $new_url .= $url['scheme'] . '://'; } if (isset($url['user'])) { $new_url .= $url['user']; if (isset($url['pass'])) { $new_url .= ':' . $url['pass']; } $new_url .= '@'; } if (isset($url['host'])) { // Convert IDN hosts to ASCII. if (function_exists('idn_to_ascii')) { $url['host'] = @idn_to_ascii($url['host']); } elseif (Horde_Mime::is8bit($url['host'])) { //throw new Kronolith_Exception(_("Invalid character in URL.")); $url['host'] = ''; } $new_url .= $url['host']; } if (isset($url['path'])) { $new_url .= $url['path']; } if (isset($url['query'])) { $new_url .= '?' . $url['query']; } if (isset($url['fragment'])) { $new_url .= '#' . $url['fragment']; } $url = $new_url; } } } $this->url = $url; // Status. $this->status = Horde_Util::getFormData('status', $this->status); // Attendees. $attendees = $session->get('kronolith', 'attendees', Horde_Session::TYPE_ARRAY); if (!is_null($newattendees = Horde_Util::getFormData('attendees'))) { $newattendees = Kronolith::parseAttendees(trim($newattendees)); foreach ($newattendees as $email => $attendee) { if (!isset($attendees[$email])) { $attendees[$email] = $attendee; } } foreach (array_keys($attendees) as $email) { if (!isset($newattendees[$email])) { unset($attendees[$email]); } } } $this->attendees = $attendees; // Event start. $allDay = Horde_Util::getFormData('whole_day'); if ($start_date = Horde_Util::getFormData('start_date')) { // From ajax interface. $this->start = Kronolith::parseDate($start_date . ' ' . Horde_Util::getFormData('start_time'), true, $this->timezone); if ($allDay) { $this->start->hour = $this->start->min = $this->start->sec = 0; } } else { // From traditional interface. $start = Horde_Util::getFormData('start'); $start_year = $start['year']; $start_month = $start['month']; $start_day = $start['day']; $start_hour = Horde_Util::getFormData('start_hour'); $start_min = Horde_Util::getFormData('start_min'); $am_pm = Horde_Util::getFormData('am_pm'); if (!$prefs->getValue('twentyFour')) { if ($am_pm == 'PM') { if ($start_hour != 12) { $start_hour += 12; } } elseif ($start_hour == 12) { $start_hour = 0; } } if (Horde_Util::getFormData('end_or_dur') == 1) { if ($allDay) { $start_hour = 0; $start_min = 0; $dur_day = 0; $dur_hour = 24; $dur_min = 0; } else { $dur_day = (int) Horde_Util::getFormData('dur_day'); $dur_hour = (int) Horde_Util::getFormData('dur_hour'); $dur_min = (int) Horde_Util::getFormData('dur_min'); } } $this->start = new Horde_Date(array('hour' => $start_hour, 'min' => $start_min, 'month' => $start_month, 'mday' => $start_day, 'year' => $start_year), $this->timezone); } // Event end. if ($end_date = Horde_Util::getFormData('end_date')) { // From ajax interface. $this->end = Kronolith::parseDate($end_date . ' ' . Horde_Util::getFormData('end_time'), true, $this->timezone); if ($allDay) { $this->end->hour = $this->end->min = $this->end->sec = 0; $this->end->mday++; } } elseif (Horde_Util::getFormData('end_or_dur') == 1) { // Event duration from traditional interface. $this->end = new Horde_Date(array('hour' => $start_hour + $dur_hour, 'min' => $start_min + $dur_min, 'month' => $start_month, 'mday' => $start_day + $dur_day, 'year' => $start_year)); } else { // From traditional interface. $end = Horde_Util::getFormData('end'); $end_year = $end['year']; $end_month = $end['month']; $end_day = $end['day']; $end_hour = Horde_Util::getFormData('end_hour'); $end_min = Horde_Util::getFormData('end_min'); $end_am_pm = Horde_Util::getFormData('end_am_pm'); if (!$prefs->getValue('twentyFour')) { if ($end_am_pm == 'PM') { if ($end_hour != 12) { $end_hour += 12; } } elseif ($end_hour == 12) { $end_hour = 0; } } $this->end = new Horde_Date(array('hour' => $end_hour, 'min' => $end_min, 'month' => $end_month, 'mday' => $end_day, 'year' => $end_year), $this->timezone); if ($this->end->compareDateTime($this->start) < 0) { $this->end = new Horde_Date($this->start); } } $this->allday = false; // Alarm. if (!is_null($alarm = Horde_Util::getFormData('alarm'))) { if ($alarm) { $value = Horde_Util::getFormData('alarm_value'); $unit = Horde_Util::getFormData('alarm_unit'); if ($value == 0) { $value = $unit = 1; } $this->alarm = $value * $unit; // Notification. if (Horde_Util::getFormData('alarm_change_method')) { $types = Horde_Util::getFormData('event_alarms'); $methods = array(); if (!empty($types)) { foreach ($types as $type) { $methods[$type] = array(); switch ($type) { case 'notify': $methods[$type]['sound'] = Horde_Util::getFormData('event_alarms_sound'); break; case 'mail': $methods[$type]['email'] = Horde_Util::getFormData('event_alarms_email'); break; case 'popup': break; } } } $this->methods = $methods; } else { $this->methods = array(); } } else { $this->alarm = 0; $this->methods = array(); } } // Recurrence. $this->recurrence = $this->readRecurrenceForm($this->start, $this->timezone, $this->recurrence); // Convert to local timezone. $this->setTimezone(false); // Resources $existingResources = $this->_resources; if (Horde_Util::getFormData('isajax', false)) { $resources = array(); } else { $resources = $session->get('kronolith', 'resources', Horde_Session::TYPE_ARRAY); } $newresources = Horde_Util::getFormData('resources'); if (!empty($newresources)) { foreach (explode(',', $newresources) as $id) { try { $resource = Kronolith::getDriver('Resource')->getResource($id); } catch (Kronolith_Exception $e) { $GLOBALS['notification']->push($e->getMessage(), 'horde.error'); continue; } if (!$resource instanceof Kronolith_Resource_Group || $resource->isFree($this)) { $resources[$resource->getId()] = array('attendance' => Kronolith::PART_REQUIRED, 'response' => Kronolith::RESPONSE_NONE, 'name' => $resource->get('name')); } else { $GLOBALS['notification']->push(_("No resources from this group were available"), 'horde.error'); } } } $this->_resources = $resources; // Check if we need to remove any resources $merged = $existingResources + $this->_resources; $delete = array_diff(array_keys($existingResources), array_keys($this->_resources)); foreach ($delete as $key) { // Resource might be declined, in which case it won't have the event // on it's calendar. if ($merged[$key]['response'] != Kronolith::RESPONSE_DECLINED) { try { Kronolith::getDriver('Resource')->getResource($key)->removeEvent($this); } catch (Kronolith_Exception $e) { $GLOBALS['notification']->push('foo', 'horde.error'); } } } // Tags. $this->tags = Horde_Util::getFormData('tags', $this->tags); // Geolocation if (Horde_Util::getFormData('lat') && Horde_Util::getFormData('lon')) { $this->geoLocation = array('lat' => Horde_Util::getFormData('lat'), 'lon' => Horde_Util::getFormData('lon'), 'zoom' => Horde_Util::getFormData('zoom')); } $this->initialized = true; }
/** * @see encode() */ protected function _encode($name, $val, $opts) { $curr = 0; $encode = $wrap = false; $out = array(); // 2 = '=', ';' $pre_len = strlen($name) + 2; /* Several possibilities: * - String is ASCII. Output as ASCII (duh). * - Language information has been provided. We MUST encode output * to include this information. * - String is non-ASCII, but can losslessly translate to ASCII. * Output as ASCII (most efficient). * - String is in non-ASCII, but doesn't losslessly translate to * ASCII. MUST encode output (duh). */ if (empty($opts['lang']) && !Horde_Mime::is8bit($val, 'UTF-8')) { $string = $val; } else { $cval = Horde_String::convertCharset($val, 'UTF-8', $opts['charset']); $string = Horde_String::lower($opts['charset']) . '\'' . (empty($opts['lang']) ? '' : Horde_String::lower($opts['lang'])) . '\'' . rawurlencode($cval); $encode = true; /* Account for trailing '*'. */ ++$pre_len; } if ($pre_len + strlen($string) > 75) { /* Account for continuation '*'. */ ++$pre_len; $wrap = true; while ($string) { $chunk = 75 - $pre_len - strlen($curr); $pos = min($chunk, strlen($string) - 1); /* Don't split in the middle of an encoded char. */ if ($chunk == $pos && $pos > 2) { for ($i = 0; $i <= 2; ++$i) { if ($string[$pos - $i] == '%') { $pos -= $i + 1; break; } } } $lines[] = substr($string, 0, $pos + 1); $string = substr($string, $pos + 1); ++$curr; } } else { $lines = array($string); } foreach ($lines as $i => $line) { $out[$name . ($wrap ? '*' . $i : '') . ($encode ? '*' : '')] = $line; } if (!empty($opts['broken_rfc2231']) && !isset($out[$name])) { $out = array_merge(array($name => Horde_Mime::encode($val, $opts['charset'])), $out); } /* Escape characters in params (See RFC 2045 [Appendix A]). * Must be quoted-string if one of these exists. */ return $this->_escapeParams($out); }
/** * @throws Horde_Idna_Exception */ public function __get($name) { switch ($name) { case 'bare_address': return is_null($this->host) ? $this->mailbox : $this->mailbox . '@' . $this->host; case 'bare_address_idn': $personal = $this->_personal; $this->_personal = null; $res = $this->encoded; $this->_personal = $personal; return $res; case 'eai': return is_null($this->mailbox) ? false : Horde_Mime::is8bit($this->mailbox); case 'encoded': return $this->writeAddress(true); case 'host': return $this->_host; case 'host_idn': return Horde_Idna::encode($this->_host); case 'label': return is_null($this->personal) ? $this->bare_address : $this->_personal; case 'personal': return strcasecmp($this->_personal, $this->bare_address) === 0 ? null : $this->_personal; case 'personal_encoded': return Horde_Mime::encode($this->personal); case 'valid': return (bool) strlen($this->mailbox); } }
/** * As of IMP 6, special mailboxes are stored in UTF-8, not UTF7-IMAP. */ protected function _upgradeMailboxPrefs() { global $injector, $prefs; $special_mboxes = array('drafts_folder', 'spam_folder', 'trash_folder'); foreach ($special_mboxes as $val) { if (!$prefs->isDefault($val)) { $old_pref = strval(IMP_Mailbox::getPref($val)); if (!Horde_Mime::is8bit($old_pref, 'UTF-8')) { $mbox = IMP_Mailbox::get(Horde_String::convertCharset($old_pref, 'UTF7-IMAP', 'UTF-8')); $prefs->setValue($val, $old_pref->{$mbox}->pref_to); } } } $imp_identity = $injector->getInstance('IMP_Identity'); foreach ($imp_identity->getAll('sent_mail_folder') as $key => $val) { if (!is_null($val) && !Horde_Mime::is8bit($val, 'UTF-8')) { $mbox = IMP_Mailbox::get(Horde_String::convertCharset(strval($val), 'UTF7-IMAP', 'UTF-8')); $imp_identity->setValue(IMP_Mailbox::MBOX_SENT, $mbox, $key); } } }
/** * Exports a given Turba_Object as an iCalendar vCard. * * @param Turba_Object $object Turba_Object. * @param string $version The vcard version to produce. * @param array $fields Hash of field names and * Horde_SyncMl_Property properties with the * requested fields. * @param boolean $skipEmpty Whether to skip empty fields. * * @return Horde_Icalendar_Vcard A vcard object. */ public function tovCard(Turba_Object $object, $version = '2.1', array $fields = null, $skipEmpty = false) { global $injector; $hash = $object->getAttributes(); $attributes = array_keys($this->map); $vcard = new Horde_Icalendar_Vcard($version); $formattedname = false; $charset = $version == '2.1' ? array('CHARSET' => 'UTF-8') : array(); $hooks = $injector->getInstance('Horde_Core_Hooks'); $decode_hook = $hooks->hookExists('decode_attribute', 'turba'); // Tags are stored externally to Turba, so they don't appear in the // source map. $attributes[] = '__tags'; foreach ($attributes as $key) { $val = $object->getValue($key); if ($skipEmpty && !is_array($val) && !strlen($val)) { continue; } if ($decode_hook) { try { $val = $hooks->callHook('decode_attribute', 'turba', array($key, $val, $object)); } catch (Turba_Exception $e) { } } switch ($key) { case '__uid': $vcard->setAttribute('UID', $val); break; case 'name': if ($fields && !isset($fields['FN'])) { break; } $vcard->setAttribute('FN', $val, Horde_Mime::is8bit($val) ? $charset : array()); $formattedname = true; break; case 'nickname': case 'alias': $params = Horde_Mime::is8bit($val) ? $charset : array(); if (!$fields || isset($fields['NICKNAME'])) { $vcard->setAttribute('NICKNAME', $val, $params); } if (!$fields || isset($fields['X-EPOCSECONDNAME'])) { $vcard->setAttribute('X-EPOCSECONDNAME', $val, $params); } break; case 'homeAddress': if ($fields && (!isset($fields['LABEL']) || isset($fields['LABEL']->Params['TYPE']) && !$this->_hasValEnum($fields['LABEL']->Params['TYPE']->ValEnum, 'HOME'))) { break; } if ($version == '2.1') { $vcard->setAttribute('LABEL', $val, array('HOME' => null)); } else { $vcard->setAttribute('LABEL', $val, array('TYPE' => 'HOME')); } break; case 'workAddress': if ($fields && (!isset($fields['LABEL']) || isset($fields['LABEL']->Params['TYPE']) && !$this->_hasValEnum($fields['LABEL']->Params['TYPE']->ValEnum, 'WORK'))) { break; } if ($version == '2.1') { $vcard->setAttribute('LABEL', $val, array('WORK' => null)); } else { $vcard->setAttribute('LABEL', $val, array('TYPE' => 'WORK')); } break; case 'otherAddress': if ($fields && !isset($fields['LABEL'])) { break; } $vcard->setAttribute('LABEL', $val); break; case 'phone': if ($fields && !isset($fields['TEL'])) { break; } $vcard->setAttribute('TEL', $val); break; case 'homePhone': if ($fields && (!isset($fields['TEL']) || isset($fields['TEL']->Params['TYPE']) && !$this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'HOME'))) { break; } if ($version == '2.1') { $vcard->setAttribute('TEL', $val, array('HOME' => null, 'VOICE' => null)); } else { $vcard->setAttribute('TEL', $val, array('TYPE' => array('HOME', 'VOICE'))); } break; case 'workPhone': if ($fields && (!isset($fields['TEL']) || isset($fields['TEL']->Params['TYPE']) && !$this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'WORK'))) { break; } if ($version == '2.1') { $vcard->setAttribute('TEL', $val, array('WORK' => null, 'VOICE' => null)); } else { $vcard->setAttribute('TEL', $val, array('TYPE' => array('WORK', 'VOICE'))); } break; case 'cellPhone': if ($fields && (!isset($fields['TEL']) || isset($fields['TEL']->Params['TYPE']) && !$this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'CELL'))) { break; } if ($version == '2.1') { $vcard->setAttribute('TEL', $val, array('CELL' => null, 'VOICE' => null)); } else { $vcard->setAttribute('TEL', $val, array('TYPE' => array('CELL', 'VOICE'))); } break; case 'homeCellPhone': $parameters = array(); if ($fields) { if (!isset($fields['TEL'])) { break; } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'CELL')) { if ($version == '2.1') { $parameters['CELL'] = null; $parameters['VOICE'] = null; } else { $parameters['TYPE'] = array('CELL', 'VOICE'); } } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'HOME')) { if ($version == '2.1') { $parameters['HOME'] = null; $parameters['VOICE'] = null; } else { $parameters['TYPE'] = array('HOME', 'VOICE'); } } if (empty($parameters)) { break; } } else { if ($version == '2.1') { $parameters = array('CELL' => null, 'HOME' => null, 'VOICE' => null); } else { $parameters = array('TYPE' => array('CELL', 'HOME', 'VOICE')); } } $vcard->setAttribute('TEL', $val, $parameters); break; case 'workCellPhone': $parameters = array(); if ($fields) { if (!isset($fields['TEL'])) { break; } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'CELL')) { if ($version == '2.1') { $parameters['CELL'] = null; $parameters['VOICE'] = null; } else { $parameters['TYPE'] = array('CELL', 'VOICE'); } } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'WORK')) { if ($version == '2.1') { $parameters['WORK'] = null; $parameters['VOICE'] = null; } else { $parameters['TYPE'] = array('WORK', 'VOICE'); } } if (empty($parameters)) { break; } } else { if ($version == '2.1') { $parameters = array('CELL' => null, 'WORK' => null, 'VOICE' => null); } else { $parameters = array('TYPE' => array('CELL', 'WORK', 'VOICE')); } } $vcard->setAttribute('TEL', $val, $parameters); break; case 'videoCall': if ($fields && (!isset($fields['TEL']) || isset($fields['TEL']->Params['TYPE']) && !$this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'VIDEO'))) { break; } if ($version == '2.1') { $vcard->setAttribute('TEL', $val, array('VIDEO' => null)); } else { $vcard->setAttribute('TEL', $val, array('TYPE' => 'VIDEO')); } break; case 'homeVideoCall': $parameters = array(); if ($fields) { if (!isset($fields['TEL'])) { break; } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'VIDEO')) { if ($version == '2.1') { $parameters['VIDEO'] = null; } else { $parameters['TYPE'] = 'VIDEO'; } } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'HOME')) { if ($version == '2.1') { $parameters['HOME'] = null; } else { $parameters['TYPE'] = 'HOME'; } } if (empty($parameters)) { break; } } else { if ($version == '2.1') { $parameters = array('VIDEO' => null, 'HOME' => null); } else { $parameters = array('TYPE' => array('VIDEO', 'HOME')); } } $vcard->setAttribute('TEL', $val, $parameters); break; case 'workVideoCall': $parameters = array(); if ($fields) { if (!isset($fields['TEL'])) { break; } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'VIDEO')) { if ($version == '2.1') { $parameters['VIDEO'] = null; } else { $parameters['TYPE'] = 'VIDEO'; } } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'WORK')) { if ($version == '2.1') { $parameters['WORK'] = null; } else { $parameters['TYPE'] = 'WORK'; } } if (empty($parameters)) { break; } } else { if ($version == '2.1') { $parameters = array('VIDEO' => null, 'WORK' => null); } else { $parameters = array('TYPE' => array('VIDEO', 'WORK')); } } $vcard->setAttribute('TEL', $val, $parameters); break; case 'sip': if ($fields && !isset($fields['X-SIP'])) { break; } $vcard->setAttribute('X-SIP', $val); break; case 'ptt': if ($fields && (!isset($fields['X-SIP']) || isset($fields['X-SIP']->Params['TYPE']) && !$this->_hasValEnum($fields['X-SIP']->Params['TYPE']->ValEnum, 'POC'))) { break; } if ($version == '2.1') { $vcard->setAttribute('X-SIP', $val, array('POC' => null)); } else { $vcard->setAttribute('X-SIP', $val, array('TYPE' => 'POC')); } break; case 'voip': if ($fields && (!isset($fields['X-SIP']) || isset($fields['X-SIP']->Params['TYPE']) && !$this->_hasValEnum($fields['X-SIP']->Params['TYPE']->ValEnum, 'VOIP'))) { break; } if ($version == '2.1') { $vcard->setAttribute('X-SIP', $val, array('VOIP' => null)); } else { $vcard->setAttribute('X-SIP', $val, array('TYPE' => 'VOIP')); } break; case 'shareView': if ($fields && (!isset($fields['X-SIP']) || isset($fields['X-SIP']->Params['TYPE']) && !$this->_hasValEnum($fields['X-SIP']->Params['TYPE']->ValEnum, 'SWIS'))) { break; } if ($version == '2.1') { $vcard->setAttribute('X-SIP', $val, array('SWIS' => null)); } else { $vcard->setAttribute('X-SIP', $val, array('TYPE' => 'SWIS')); } break; case 'imaddress': if ($fields && !isset($fields['X-WV-ID'])) { break; } $vcard->setAttribute('X-WV-ID', $val); break; case 'fax': if ($fields && (!isset($fields['TEL']) || isset($fields['TEL']->Params['TYPE']) && !$this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'FAX'))) { break; } if ($version == '2.1') { $vcard->setAttribute('TEL', $val, array('FAX' => null)); } else { $vcard->setAttribute('TEL', $val, array('TYPE' => 'FAX')); } break; case 'homeFax': $parameters = array(); if ($fields) { if (!isset($fields['TEL'])) { break; } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'FAX')) { if ($version == '2.1') { $parameters['FAX'] = null; } else { $parameters['TYPE'] = 'FAX'; } } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'HOME')) { if ($version == '2.1') { $parameters['HOME'] = null; } else { $parameters['TYPE'] = 'HOME'; } } if (empty($parameters)) { break; } } else { if ($version == '2.1') { $parameters = array('FAX' => null, 'HOME' => null); } else { $parameters = array('TYPE' => array('FAX', 'HOME')); } } $vcard->setAttribute('TEL', $val, $parameters); break; case 'workFax': $parameters = array(); if ($fields) { if (!isset($fields['TEL'])) { break; } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'FAX')) { if ($version == '2.1') { $parameters['FAX'] = null; } else { $parameters['TYPE'] = 'FAX'; } } if (!isset($fields['TEL']->Params['TYPE']) || $this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'WORK')) { if ($version == '2.1') { $parameters['WORK'] = null; } else { $parameters['TYPE'] = 'WORK'; } } if (empty($parameters)) { break; } } else { if ($version == '2.1') { $parameters = array('FAX' => null, 'WORK' => null); } else { $parameters = array('TYPE' => array('FAX', 'WORK')); } } $vcard->setAttribute('TEL', $val, $parameters); if ($version == '2.1') { $vcard->setAttribute('TEL', $val, array('FAX' => null, 'WORK' => null)); } else { $vcard->setAttribute('TEL', $val, array('TYPE' => array('FAX', 'WORK'))); } break; case 'pager': if ($fields && (!isset($fields['TEL']) || isset($fields['TEL']->Params['TYPE']) && !$this->_hasValEnum($fields['TEL']->Params['TYPE']->ValEnum, 'PAGER'))) { break; } if ($version == '2.1') { $vcard->setAttribute('TEL', $val, array('PAGER' => null)); } else { $vcard->setAttribute('TEL', $val, array('TYPE' => 'PAGER')); } break; case 'email': if ($fields && !isset($fields['EMAIL'])) { break; } if ($version == '2.1') { $vcard->setAttribute('EMAIL', Horde_Icalendar_Vcard::getBareEmail($val), array('INTERNET' => null)); } else { $vcard->setAttribute('EMAIL', Horde_Icalendar_Vcard::getBareEmail($val), array('TYPE' => 'INTERNET')); } break; case 'homeEmail': if ($fields && (!isset($fields['EMAIL']) || isset($fields['EMAIL']->Params['TYPE']) && !$this->_hasValEnum($fields['EMAIL']->Params['TYPE']->ValEnum, 'HOME'))) { break; } if ($version == '2.1') { $vcard->setAttribute('EMAIL', Horde_Icalendar_Vcard::getBareEmail($val), array('HOME' => null)); } else { $vcard->setAttribute('EMAIL', Horde_Icalendar_Vcard::getBareEmail($val), array('TYPE' => 'HOME')); } break; case 'workEmail': if ($fields && (!isset($fields['EMAIL']) || isset($fields['EMAIL']->Params['TYPE']) && !$this->_hasValEnum($fields['EMAIL']->Params['TYPE']->ValEnum, 'WORK'))) { break; } if ($version == '2.1') { $vcard->setAttribute('EMAIL', Horde_Icalendar_Vcard::getBareEmail($val), array('WORK' => null)); } else { $vcard->setAttribute('EMAIL', Horde_Icalendar_Vcard::getBareEmail($val), array('TYPE' => 'WORK')); } break; case 'emails': if ($fields && !isset($fields['EMAIL'])) { break; } $emails = explode(',', $val); foreach ($emails as $email) { $vcard->setAttribute('EMAIL', Horde_Icalendar_Vcard::getBareEmail($email)); } break; case 'title': if ($fields && !isset($fields['TITLE'])) { break; } $vcard->setAttribute('TITLE', $val, Horde_Mime::is8bit($val) ? $charset : array()); break; case 'role': if ($fields && !isset($fields['ROLE'])) { break; } $vcard->setAttribute('ROLE', $val, Horde_Mime::is8bit($val) ? $charset : array()); break; case 'notes': if ($fields && !isset($fields['NOTE'])) { break; } $vcard->setAttribute('NOTE', $val, Horde_Mime::is8bit($val) ? $charset : array()); break; case '__tags': $val = $injector->getInstance('Turba_Tagger')->split($val); case 'businessCategory': // No CATEGORIES in vCard 2.1 if ($version == '2.1' || $fields && !isset($fields['CATEGORIES'])) { break; } $vcard->setAttribute('CATEGORIES', null, array(), true, $val); break; case 'anniversary': if (!$fields || isset($fields['X-ANNIVERSARY'])) { $vcard->setAttribute('X-ANNIVERSARY', $val); } break; case 'spouse': if (!$fields || isset($fields['X-SPOUSE'])) { $vcard->setAttribute('X-SPOUSE', $val); } break; case 'children': if (!$fields || isset($fields['X-CHILDREN'])) { $vcard->setAttribute('X-CHILDREN', $val); } break; case 'website': if ($fields && !isset($fields['URL'])) { break; } $vcard->setAttribute('URL', $val); break; case 'homeWebsite': if ($fields && (!isset($fields['URL']) || isset($fields['URL']->Params['TYPE']) && !$this->_hasValEnum($fields['URL']->Params['TYPE']->ValEnum, 'HOME'))) { break; } if ($version == '2.1') { $vcard->setAttribute('URL', $val, array('HOME' => null)); } else { $vcard->setAttribute('URL', $val, array('TYPE' => 'HOME')); } break; case 'workWebsite': if ($fields && (!isset($fields['URL']) || isset($fields['URL']->Params['TYPE']) && !$this->_hasValEnum($fields['URL']->Params['TYPE']->ValEnum, 'WORK'))) { break; } if ($version == '2.1') { $vcard->setAttribute('URL', $val, array('WORK' => null)); } else { $vcard->setAttribute('URL', $val, array('TYPE' => 'WORK')); } break; case 'freebusyUrl': if ($version == '2.1' || $fields && !isset($fields['FBURL'])) { break; } $vcard->setAttribute('FBURL', $val); break; case 'birthday': if ($fields && !isset($fields['BDAY'])) { break; } $vcard->setAttribute('BDAY', $val); break; case 'timezone': if ($fields && !isset($fields['TZ'])) { break; } $vcard->setAttribute('TZ', $val, array('VALUE' => 'text')); break; case 'latitude': if ($fields && !isset($fields['GEO'])) { break; } if (isset($hash['longitude'])) { $vcard->setAttribute('GEO', array('latitude' => $val, 'longitude' => $hash['longitude'])); } break; case 'homeLatitude': if ($fields && (!isset($fields['GEO']) || isset($fields['GEO']->Params['TYPE']) && !$this->_hasValEnum($fields['GEO']->Params['TYPE']->ValEnum, 'HOME'))) { break; } if (isset($hash['homeLongitude'])) { if ($version == '2.1') { $vcard->setAttribute('GEO', array('latitude' => $val, 'longitude' => $hash['homeLongitude']), array('HOME' => null)); } else { $vcard->setAttribute('GEO', array('latitude' => $val, 'longitude' => $hash['homeLongitude']), array('TYPE' => 'HOME')); } } break; case 'workLatitude': if ($fields && (!isset($fields['GEO']) || isset($fields['GEO']->Params['TYPE']) && !$this->_hasValEnum($fields['GEO']->Params['TYPE']->ValEnum, 'HOME'))) { break; } if (isset($hash['workLongitude'])) { if ($version == '2.1') { $vcard->setAttribute('GEO', array('latitude' => $val, 'longitude' => $hash['workLongitude']), array('WORK' => null)); } else { $vcard->setAttribute('GEO', array('latitude' => $val, 'longitude' => $hash['workLongitude']), array('TYPE' => 'WORK')); } } break; case 'photo': case 'logo': $name = Horde_String::upper($key); $params = array(); if (strlen($hash[$key])) { $params['ENCODING'] = 'b'; } if (isset($hash[$key . 'type'])) { $params['TYPE'] = $hash[$key . 'type']; } if ($fields && (!isset($fields[$name]) || isset($params['TYPE']) && isset($fields[$name]->Params['TYPE']) && !$this->_hasValEnum($fields[$name]->Params['TYPE']->ValEnum, $params['TYPE']))) { break; } $vcard->setAttribute($name, base64_encode($hash[$key]), $params); break; } } // No explicit firstname/lastname in data source: we have to guess. if (!isset($hash['lastname']) && isset($hash['name'])) { $this->_guessName($hash); } $a = array(Horde_Icalendar_Vcard::N_FAMILY => isset($hash['lastname']) ? $hash['lastname'] : '', Horde_Icalendar_Vcard::N_GIVEN => isset($hash['firstname']) ? $hash['firstname'] : '', Horde_Icalendar_Vcard::N_ADDL => isset($hash['middlenames']) ? $hash['middlenames'] : '', Horde_Icalendar_Vcard::N_PREFIX => isset($hash['namePrefix']) ? $hash['namePrefix'] : '', Horde_Icalendar_Vcard::N_SUFFIX => isset($hash['nameSuffix']) ? $hash['nameSuffix'] : ''); $val = implode(';', $a); if (!$fields || isset($fields['N'])) { $vcard->setAttribute('N', $val, Horde_Mime::is8bit($val) ? $charset : array(), false, $a); } if (!$formattedname && (!$fields || isset($fields['FN']))) { if ($object->getValue('name')) { $val = $object->getValue('name'); } elseif (!empty($this->alternativeName) && isset($hash[$this->alternativeName])) { $val = $hash[$this->alternativeName]; } else { $val = ''; } $vcard->setAttribute('FN', $val, Horde_Mime::is8bit($val) ? $charset : array()); } $org = array(); if (!empty($hash['company']) || !$skipEmpty && array_key_exists('company', $hash)) { $org[] = $hash['company']; } if (!empty($hash['department']) || !$skipEmpty && array_key_exists('department', $hash)) { $org[] = $hash['department']; } if (count($org) && (!$fields || isset($fields['ORG']))) { $val = implode(';', $org); $vcard->setAttribute('ORG', $val, Horde_Mime::is8bit($val) ? $charset : array(), false, $org); } if ((!$fields || isset($fields['ADR'])) && (!empty($hash['commonAddress']) || !empty($hash['commonStreet']) || !empty($hash['commonPOBox']) || !empty($hash['commonExtended']) || !empty($hash['commonCity']) || !empty($hash['commonProvince']) || !empty($hash['commonPostalCode']) || !empty($hash['commonCountry']) || !$skipEmpty && (array_key_exists('commonAddress', $hash) || array_key_exists('commonStreet', $hash) || array_key_exists('commonPOBox', $hash) || array_key_exists('commonExtended', $hash) || array_key_exists('commonCity', $hash) || array_key_exists('commonProvince', $hash) || array_key_exists('commonPostalCode', $hash) || array_key_exists('commonCountry', $hash)))) { /* We can't know if this particular Turba source uses a single * address field or multiple for * street/city/province/postcode/country. Try to deal with * both. */ if (isset($hash['commonAddress']) && !isset($hash['commonStreet'])) { $hash['commonStreet'] = $hash['commonAddress']; } $a = array(Horde_Icalendar_Vcard::ADR_POB => isset($hash['commonPOBox']) ? $hash['commonPOBox'] : '', Horde_Icalendar_Vcard::ADR_EXTEND => isset($hash['commonExtended']) ? $hash['commonExtended'] : '', Horde_Icalendar_Vcard::ADR_STREET => isset($hash['commonStreet']) ? $hash['commonStreet'] : '', Horde_Icalendar_Vcard::ADR_LOCALITY => isset($hash['commonCity']) ? $hash['commonCity'] : '', Horde_Icalendar_Vcard::ADR_REGION => isset($hash['commonProvince']) ? $hash['commonProvince'] : '', Horde_Icalendar_Vcard::ADR_POSTCODE => isset($hash['commonPostalCode']) ? $hash['commonPostalCode'] : '', Horde_Icalendar_Vcard::ADR_COUNTRY => isset($hash['commonCountry']) ? Horde_Nls::getCountryISO($hash['commonCountry']) : ''); $val = implode(';', $a); if ($version == '2.1') { $params = array(); if (Horde_Mime::is8bit($val)) { $params['CHARSET'] = 'UTF-8'; } } else { $params = array('TYPE' => ''); } $vcard->setAttribute('ADR', $val, $params, true, $a); } if ((!$fields || isset($fields['ADR']) && (!isset($fields['ADR']->Params['TYPE']) || $this->_hasValEnum($fields['ADR']->Params['TYPE']->ValEnum, 'HOME'))) && (!empty($hash['homeAddress']) || !empty($hash['homeStreet']) || !empty($hash['homePOBox']) || !empty($hash['homeExtended']) || !empty($hash['homeCity']) || !empty($hash['homeProvince']) || !empty($hash['homePostalCode']) || !empty($hash['homeCountry']) || !$skipEmpty && (array_key_exists('homeAddress', $hash) || array_key_exists('homeStreet', $hash) || array_key_exists('homePOBox', $hash) || array_key_exists('homeExtended', $hash) || array_key_exists('homeCity', $hash) || array_key_exists('homeProvince', $hash) || array_key_exists('homePostalCode', $hash) || array_key_exists('homeCountry', $hash)))) { if (isset($hash['homeAddress']) && !isset($hash['homeStreet'])) { $hash['homeStreet'] = $hash['homeAddress']; } $a = array(Horde_Icalendar_Vcard::ADR_POB => isset($hash['homePOBox']) ? $hash['homePOBox'] : '', Horde_Icalendar_Vcard::ADR_EXTEND => isset($hash['homeExtended']) ? $hash['homeExtended'] : '', Horde_Icalendar_Vcard::ADR_STREET => isset($hash['homeStreet']) ? $hash['homeStreet'] : '', Horde_Icalendar_Vcard::ADR_LOCALITY => isset($hash['homeCity']) ? $hash['homeCity'] : '', Horde_Icalendar_Vcard::ADR_REGION => isset($hash['homeProvince']) ? $hash['homeProvince'] : '', Horde_Icalendar_Vcard::ADR_POSTCODE => isset($hash['homePostalCode']) ? $hash['homePostalCode'] : '', Horde_Icalendar_Vcard::ADR_COUNTRY => isset($hash['homeCountry']) ? Horde_Nls::getCountryISO($hash['homeCountry']) : ''); $val = implode(';', $a); if ($version == '2.1') { $params = array('HOME' => null); if (Horde_Mime::is8bit($val)) { $params['CHARSET'] = 'UTF-8'; } } else { $params = array('TYPE' => 'HOME'); } $vcard->setAttribute('ADR', $val, $params, true, $a); } if ((!$fields || isset($fields['ADR']) && (!isset($fields['ADR']->Params['TYPE']) || $this->_hasValEnum($fields['ADR']->Params['TYPE']->ValEnum, 'WORK'))) && (!empty($hash['workAddress']) || !empty($hash['workStreet']) || !empty($hash['workPOBox']) || !empty($hash['workExtended']) || !empty($hash['workCity']) || !empty($hash['workProvince']) || !empty($hash['workPostalCode']) || !empty($hash['workCountry']) || !$skipEmpty && (array_key_exists('workAddress', $hash) || array_key_exists('workStreet', $hash) || array_key_exists('workPOBox', $hash) || array_key_exists('workExtended', $hash) || array_key_exists('workCity', $hash) || array_key_exists('workProvince', $hash) || array_key_exists('workPostalCode', $hash) || array_key_exists('workCountry', $hash)))) { if (isset($hash['workAddress']) && !isset($hash['workStreet'])) { $hash['workStreet'] = $hash['workAddress']; } $a = array(Horde_Icalendar_Vcard::ADR_POB => isset($hash['workPOBox']) ? $hash['workPOBox'] : '', Horde_Icalendar_Vcard::ADR_EXTEND => isset($hash['workExtended']) ? $hash['workExtended'] : '', Horde_Icalendar_Vcard::ADR_STREET => isset($hash['workStreet']) ? $hash['workStreet'] : '', Horde_Icalendar_Vcard::ADR_LOCALITY => isset($hash['workCity']) ? $hash['workCity'] : '', Horde_Icalendar_Vcard::ADR_REGION => isset($hash['workProvince']) ? $hash['workProvince'] : '', Horde_Icalendar_Vcard::ADR_POSTCODE => isset($hash['workPostalCode']) ? $hash['workPostalCode'] : '', Horde_Icalendar_Vcard::ADR_COUNTRY => isset($hash['workCountry']) ? Horde_Nls::getCountryISO($hash['workCountry']) : ''); $val = implode(';', $a); if ($version == '2.1') { $params = array('WORK' => null); if (Horde_Mime::is8bit($val)) { $params['CHARSET'] = 'UTF-8'; } } else { $params = array('TYPE' => 'WORK'); } $vcard->setAttribute('ADR', $val, $params, true, $a); } return $vcard; }
/** * Reads form/post data and updates this event's properties. * * @param Kronolith_Event|null $existing If this is an exception event * this is taken as the base event. * @since 4.2.6 * */ public function readForm(Kronolith_Event $existing = null) { global $prefs, $session; // Event owner. $targetcalendar = Horde_Util::getFormData('targetcalendar'); if (strpos($targetcalendar, '\\')) { list(, $this->creator) = explode('\\', $targetcalendar, 2); } elseif (!isset($this->_id)) { $this->creator = $GLOBALS['registry']->getAuth(); } // Basic fields. $this->title = Horde_Util::getFormData('title', $this->title); $this->description = Horde_Util::getFormData('description', $this->description); $this->location = Horde_Util::getFormData('location', $this->location); $this->timezone = Horde_Util::getFormData('timezone', $this->timezone); $this->private = (bool) Horde_Util::getFormData('private'); // URL. $url = Horde_Util::getFormData('eventurl', $this->url); if (strlen($url)) { // Analyze and re-construct. $url = @parse_url($url); if ($url) { if (function_exists('http_build_url')) { if (empty($url['path'])) { $url['path'] = '/'; } $url = http_build_url($url); } else { $new_url = ''; if (isset($url['scheme'])) { $new_url .= $url['scheme'] . '://'; } if (isset($url['user'])) { $new_url .= $url['user']; if (isset($url['pass'])) { $new_url .= ':' . $url['pass']; } $new_url .= '@'; } if (isset($url['host'])) { // Convert IDN hosts to ASCII. if (function_exists('idn_to_ascii')) { $url['host'] = @idn_to_ascii($url['host']); } elseif (Horde_Mime::is8bit($url['host'])) { //throw new Kronolith_Exception(_("Invalid character in URL.")); $url['host'] = ''; } $new_url .= $url['host']; } if (isset($url['path'])) { $new_url .= $url['path']; } if (isset($url['query'])) { $new_url .= '?' . $url['query']; } if (isset($url['fragment'])) { $new_url .= '#' . $url['fragment']; } $url = $new_url; } } } $this->url = $url; // Status. $this->status = Horde_Util::getFormData('status', $this->status); // Attendees. $attendees = $session->get('kronolith', 'attendees', Horde_Session::TYPE_ARRAY); if (!is_null($newattendees = Horde_Util::getFormData('attendees'))) { $newattendees = Kronolith::parseAttendees(trim($newattendees)); foreach ($newattendees as $email => $attendee) { if (!isset($attendees[$email])) { $attendees[$email] = $attendee; } } foreach (array_keys($attendees) as $email) { if (!isset($newattendees[$email])) { unset($attendees[$email]); } } } $this->attendees = $attendees; // Event start. $allDay = Horde_Util::getFormData('whole_day'); if ($start_date = Horde_Util::getFormData('start_date')) { // From ajax interface. $this->start = Kronolith::parseDate($start_date . ' ' . Horde_Util::getFormData('start_time'), true, $this->timezone); if ($allDay) { $this->start->hour = $this->start->min = $this->start->sec = 0; } } else { // From traditional interface. $start = Horde_Util::getFormData('start'); $start_year = $start['year']; $start_month = $start['month']; $start_day = $start['day']; $start_hour = Horde_Util::getFormData('start_hour'); $start_min = Horde_Util::getFormData('start_min'); $am_pm = Horde_Util::getFormData('am_pm'); if (!$prefs->getValue('twentyFour')) { if ($am_pm == 'PM') { if ($start_hour != 12) { $start_hour += 12; } } elseif ($start_hour == 12) { $start_hour = 0; } } if (Horde_Util::getFormData('end_or_dur') == 1) { if ($allDay) { $start_hour = 0; $start_min = 0; $dur_day = 0; $dur_hour = 24; $dur_min = 0; } else { $dur_day = (int) Horde_Util::getFormData('dur_day'); $dur_hour = (int) Horde_Util::getFormData('dur_hour'); $dur_min = (int) Horde_Util::getFormData('dur_min'); } } $this->start = new Horde_Date(array('hour' => $start_hour, 'min' => $start_min, 'month' => $start_month, 'mday' => $start_day, 'year' => $start_year), $this->timezone); } // Event end. if ($end_date = Horde_Util::getFormData('end_date')) { // From ajax interface. $this->end = Kronolith::parseDate($end_date . ' ' . Horde_Util::getFormData('end_time'), true, $this->timezone); if ($allDay) { $this->end->hour = $this->end->min = $this->end->sec = 0; $this->end->mday++; } } elseif (Horde_Util::getFormData('end_or_dur') == 1) { // Event duration from traditional interface. $this->end = new Horde_Date(array('hour' => $start_hour + $dur_hour, 'min' => $start_min + $dur_min, 'month' => $start_month, 'mday' => $start_day + $dur_day, 'year' => $start_year)); } else { // From traditional interface. $end = Horde_Util::getFormData('end'); $end_year = $end['year']; $end_month = $end['month']; $end_day = $end['day']; $end_hour = Horde_Util::getFormData('end_hour'); $end_min = Horde_Util::getFormData('end_min'); $end_am_pm = Horde_Util::getFormData('end_am_pm'); if (!$prefs->getValue('twentyFour')) { if ($end_am_pm == 'PM') { if ($end_hour != 12) { $end_hour += 12; } } elseif ($end_hour == 12) { $end_hour = 0; } } $this->end = new Horde_Date(array('hour' => $end_hour, 'min' => $end_min, 'month' => $end_month, 'mday' => $end_day, 'year' => $end_year), $this->timezone); if ($this->end->compareDateTime($this->start) < 0) { $this->end = new Horde_Date($this->start); } } $this->allday = false; // Alarm. if (!is_null($alarm = Horde_Util::getFormData('alarm'))) { if ($alarm) { $value = Horde_Util::getFormData('alarm_value'); $unit = Horde_Util::getFormData('alarm_unit'); if ($value == 0) { $value = $unit = 1; } $this->alarm = $value * $unit; // Notification. if (Horde_Util::getFormData('alarm_change_method')) { $types = Horde_Util::getFormData('event_alarms'); $methods = array(); if (!empty($types)) { foreach ($types as $type) { $methods[$type] = array(); switch ($type) { case 'notify': $methods[$type]['sound'] = Horde_Util::getFormData('event_alarms_sound'); break; case 'mail': $methods[$type]['email'] = Horde_Util::getFormData('event_alarms_email'); break; case 'popup': break; } } } $this->methods = $methods; } else { $this->methods = array(); } } else { $this->alarm = 0; $this->methods = array(); } } // Recurrence. $this->recurrence = $this->readRecurrenceForm($this->start, $this->timezone, $this->recurrence); // Convert to local timezone. $this->setTimezone(false); $this->_handleResources($existing); // Tags. $this->tags = Horde_Util::getFormData('tags', $this->tags); // Geolocation if (Horde_Util::getFormData('lat') && Horde_Util::getFormData('lon')) { $this->geoLocation = array('lat' => Horde_Util::getFormData('lat'), 'lon' => Horde_Util::getFormData('lon'), 'zoom' => Horde_Util::getFormData('zoom')); } $this->initialized = true; }
/** * Scans a stream for the requested data. * * @param resource $fp A stream resource. * @param string $type Either '8bit', 'binary', or 'preg'. * @param mixed $data Any additional data needed to do the scan. * * @param boolean The result of the scan. */ protected function _scanStream($fp, $type, $data = null) { rewind($fp); while (is_resource($fp) && !feof($fp)) { $line = fread($fp, 8192); switch ($type) { case '8bit': if (Horde_Mime::is8bit($line)) { return true; } break; case 'binary': if (strpos($line, "") !== false) { return true; } break; case 'preg': if (preg_match($data, $line)) { return true; } break; } } return false; }
/** * @dataProvider is8bitProvider */ public function testIs8bit($data, $expected) { $this->assertEquals($expected, Horde_Mime::is8bit($data)); }
/** * Returns the forward text for a message. * * @param IMP_Contents $contents An IMP_Contents object. * @param array $opts Additional options: * - format: (string) Force to this format. * DEFAULT: Auto-determine. * * @return array An array with the following keys: * - body: (string) The text of the body part. * - charset: (string) The guessed charset to use for the forward. * - format: (string) The format of the body message ('html', 'text'). */ public function forwardMessageText($contents, array $opts = array()) { $h = $contents->getHeader(); $from = strval($h['from']); $msg_pre = "\n----- " . ($from ? sprintf(_("Forwarded message from %s"), $from) : _("Forwarded message")) . " -----\n" . $this->_getMsgHeaders($h) . "\n"; $msg_post = "\n\n----- " . _("End forwarded message") . " -----\n"; list($compose_html, $force_html) = $this->_msgTextFormat($opts, 'forward_format'); $msg_text = $this->_getMessageText($contents, array('html' => $compose_html)); if (!empty($msg_text) && ($msg_text['mode'] == 'html' || $force_html)) { $msg = $this->text2html($msg_pre) . ($msg_text['mode'] == 'text' ? $this->text2html($msg_text['text']) : $msg_text['text']) . $this->text2html($msg_post); $format = 'html'; } else { $msg = $msg_pre . $msg_text['text'] . $msg_post; $format = 'text'; } // Bug #10148: Message text might be us-ascii, but forward headers may // contain 8-bit characters. if ($msg_text['charset'] == 'us-ascii' && (Horde_Mime::is8bit($msg_pre) || Horde_Mime::is8bit($msg_post))) { $msg_text['charset'] = 'UTF-8'; } return array('body' => $msg, 'charset' => $msg_text['charset'], 'format' => $format); }
/** * As of IMP 6, special mailboxes are stored in UTF-8, not UTF7-IMAP. */ protected function _upgradeMailboxPrefs() { global $injector, $prefs; $special_mboxes = array('drafts_folder', 'spam_folder', 'trash_folder'); foreach ($special_mboxes as $val) { if (!$prefs->isDefault($val)) { $old_pref = strval(IMP_Mailbox::getPref($val)); if (!Horde_Mime::is8bit($old_pref)) { $mbox = IMP_Mailbox::get(new Horde_Imap_Client_Mailbox($old_pref, true)); $prefs->setValue($val, $mbox->pref_to); } } } $imp_identity = $injector->getInstance('IMP_Identity'); foreach ($imp_identity->getAll('sent_mail_folder') as $key => $val) { if (!is_null($val) && !Horde_Mime::is8bit($val)) { $mbox = IMP_Mailbox::get(new Horde_Imap_Client_Mailbox($val, true)); $imp_identity->setValue(IMP_Mailbox::MBOX_SENT, $mbox, $key); } } }