1: <?php
2: 3: 4:
5:
6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
18: class Kolab_Filter_Outlook
19: {
20:
21: 22: 23: 24: 25: 26: 27:
28: function _mimeParse(&$text)
29: {
30:
31: require_once 'Mail/mimeDecode.php';
32:
33:
34: $decode_args = array();
35: $decode_args['include_bodies'] = true;
36: $decode_args['decode_bodies'] = false;
37: $decode_args['decode_headers'] = false;
38:
39: $mimeDecode = new Mail_mimeDecode($text, MIME_PART_EOL);
40: if (!($structure = $mimeDecode->decode($decode_args))) {
41: return false;
42: }
43:
44:
45: MIME_Structure::_convertMimeDecodeData($structure);
46:
47: return array($structure->headers, $ret = &MIME_Structure::parse($structure));
48: }
49:
50: 51: 52: 53: 54: 55: 56:
57: function ($name, &$msg_headers, &$headerarray)
58: {
59: $lname = strtolower($name);
60: if (array_key_exists($lname, $headerarray)) {
61: if (is_array($headerarray[$lname])) {
62: foreach ($headerarray[$lname] as $h) {
63: $msg_headers->addHeader($name, $h);
64: }
65: } else {
66: $msg_headers->addHeader($name, $headerarray[$lname]);
67: }
68: }
69: }
70:
71: 72: 73: 74: 75: 76: 77: 78:
79: function _addOrganizer(&$icaltxt, $from)
80: {
81: global $conf;
82:
83: if (isset($conf['kolab']['filter']['email_domain'])) {
84: $email_domain = $conf['kolab']['filter']['email_domain'];
85: } else {
86: $email_domain = 'localhost';
87: }
88:
89: $iCal = new Horde_Icalendar();
90: $iCal->parsevCalendar($icaltxt);
91: $vevent =& $iCal->findComponent('VEVENT');
92: if ($vevent) {
93: $organizer = $vevent->getAttribute('ORGANIZER', true);
94: if (is_a($organizer, 'PEAR_Error')) {
95: $adrs = imap_rfc822_parse_adrlist($from, $email_domain);
96: if (count($adrs) > 0) {
97: $org_email = 'mailto:'.$adrs[0]->mailbox.'@'.$adrs[0]->host;
98: $org_name = $adrs[0]->personal;
99: if ($org_name) {
100: $vevent->setAttribute('ORGANIZER', $org_email,
101: array( 'CN' => $org_name), false);
102: } else {
103: $vevent->setAttribute('ORGANIZER', $org_email,
104: array(), false);
105: }
106: Horde::logMessage(sprintf("Adding missing organizer '%s <%s>' to iCal.",
107: $org_name, $org_email), 'DEBUG');
108: $icaltxt = $iCal->exportvCalendar();
109: }
110: }
111: }
112: }
113:
114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124:
125: function _recodeToAscii( $text ) {
126: $text = str_replace( ('æ'), 'ae', $text );
127: $text = str_replace( ('ø'), 'oe', $text );
128: $text = str_replace( ('å'), 'aa', $text );
129: $text = str_replace( ('ä'), 'ae', $text );
130: $text = str_replace( ('ö'), 'oe', $text );
131: $text = str_replace( ('ü'), 'ue', $text );
132: $text = str_replace( ('ß'), 'ss', $text );
133:
134: $text = str_replace( ('Æ'), 'Ae', $text );
135: $text = str_replace( ('Ø'), 'Oe', $text );
136: $text = str_replace( ('Å'), 'Aa', $text );
137: $text = str_replace( ('Ä'), 'Ae', $text );
138: $text = str_replace( ('Ö'), 'Oe', $text );
139: $text = str_replace( ('Ü'), 'Ue', $text );
140:
141: return $text;
142: }
143:
144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155:
156: function embedICal($fqhostname, $sender, $recipients, $origfrom, $subject,
157: $tmpfname, $transport)
158: {
159: Horde::logMessage(sprintf("Encapsulating iCal message forwarded by %s", $sender), 'DEBUG');
160:
161: $forwardtext = "This is an invitation forwarded by outlook and\n".
162: "was rectified by the Kolab server.\n".
163: "The invitation was originally sent by\n%s.\n\n".
164: "Diese Einladung wurde von Outlook weitergeleitet\n".
165: "und vom Kolab-Server in gute Form gebracht.\n".
166: "Die Einladung wurde ursprünglich von\n%s geschickt.\n";
167:
168:
169: $requestText = '';
170: $handle = @fopen($tmpfname, "r");
171: if ($handle === false) {
172: $msg = $php_errormsg;
173: return PEAR::raiseError(sprintf("Error: Could not open %s for writing: %s",
174: $tmpfname, $msg),
175: OUT_LOG | EX_IOERR);
176: }
177: while (!feof($handle)) {
178: $requestText .= fread($handle, 8192);
179: }
180: fclose($handle);
181:
182:
183: list( $headers, $mime) = Kolab_Filter_Outlook::_mimeParse($requestText);
184: $parts = $mime->contentTypeMap();
185: if (count($parts) != 1 || $parts[1] != 'text/calendar') {
186: Horde::logMessage("Message does not contain exactly one toplevel text/calendar part, passing through.", 'DEBUG');
187: return false;
188: }
189: $basepart = $mime->getBasePart();
190:
191:
192: $toppart = new MIME_Message();
193: $dorigfrom = Mail_mimeDecode::_decodeHeader($origfrom);
194: $textpart = new MIME_Part('text/plain', sprintf($forwardtext,$dorigfrom,$dorigfrom), 'UTF-8' );
195: $ical_txt = $basepart->transferDecode();
196: Kolab_Filter_Outlook::_addOrganizer($ical_txt, $dorigfrom);
197: $msgpart = new MIME_Part($basepart->getType(), Kolab_Filter_Outlook::_recodeToAscii($ical_txt),
198: $basepart->getCharset() );
199:
200: $toppart->addPart($textpart);
201: $toppart->addPart($msgpart);
202:
203:
204: $msg_headers = new MIME_Headers();
205: Kolab_Filter_Outlook::_copyHeader( 'Received', $msg_headers, $headers );
206:
207: $msg_headers->addMessageIdHeader();
208: Kolab_Filter_Outlook::_copyHeader( 'Date', $msg_headers, $headers );
209: Kolab_Filter_Outlook::_copyHeader( 'Resent-Date', $msg_headers, $headers );
210: Kolab_Filter_Outlook::_copyHeader( 'Subject', $msg_headers, $headers );
211: $msg_headers->addHeader('From', $sender);
212: $msg_headers->addHeader('To', join(', ', $recipients));
213: $msg_headers->addHeader('X-Kolab-Forwarded', 'TRUE');
214: $msg_headers->addMIMEHeaders($toppart);
215: Kolab_Filter_Outlook::_copyHeader( 'Content-Transfer-Encoding', $msg_headers, $headers );
216:
217: if (is_object($msg_headers)) {
218: $headerArray = $toppart->encode($msg_headers->toArray(), $toppart->getCharset());
219: } else {
220: $headerArray = $toppart->encode($msg_headers, $toppart->getCharset());
221: }
222:
223: return Kolab_Filter_Outlook::_inject($toppart, $recipients, $msg_headers, $sender, $transport);
224: }
225:
226: function _inject(&$toppart, $recipients, $msg_headers, $sender, $transport)
227: {
228: global $conf;
229:
230: if (isset($conf['kolab']['filter']['smtp_host'])) {
231: $host = $conf['kolab']['filter']['smtp_host'];
232: } else {
233: $host = 'localhost';
234: }
235: if (isset($conf['kolab']['filter']['smtp_port'])) {
236: $port = $conf['kolab']['filter']['smtp_port'];
237: } else {
238: $port = 10025;
239: }
240:
241: $transport = &Horde_Kolab_Filter_Transport::factory($transport,
242: array('host' => $host,
243: 'port' => $port));
244:
245: $result = $transport->start($sender, $recipients);
246: if (is_a($result, 'PEAR_Error')) {
247: return $result;
248: }
249:
250: $result = $transport->data($msg_headers->toString() . $toppart->toString());
251: if (is_a($result, 'PEAR_Error')) {
252: return $result;
253: }
254:
255: return $transport->end();
256: }
257: }
258: