使用php

时间:2015-08-13 08:01:17

标签: php html icalendar

我正在编写一个脚本,涉及到达邮件服务器,提取电子邮件,从电子邮件中解析信息,从解析的信息创建事件(ics文件),然后将事件邀请和原始电子邮件一起发送为ics文件描述。我在php中完成上述所有操作。我陷入了最后一步,即发送原始电子邮件正文(html)作为描述。

我已经明白ics文件字段描述不适合换行符(要发送我必须使用的多行描述\ n)。因此,在提取电子邮件正文后,我删除所有“\ r \ n”和我在没有换行的字符串中得到html代码。

经过研究,我发现要在一个ics文件中解析html,Outlook使用类似X-ALT-DESC.So的东西,我将DESCRIPTION和X-ALT-DESC都保存为带有html代码的字符串。但是发送电子邮件会导致Outlook忽略大部分html,并在结束时自己结束标记,而我只收到原始电子邮件的一小部分。

为了找到问题,我将相同的邮件发送到gmail,然后下载了ics文件。在检查时我发现gmail不会以任何方式改变DESC,但会自动添加某些换行符。而且我观察到outlook在第一次换行后忽略了html,并添加了自己的标签,以便在开始时完成html及其自己的Microsoft Exchange内容。

我不知道问题是在php中(用于添加换行符)或 如果在X-ALT-DESC中对ics文件有关html代码长度的限制(即在n个代码量之后添加了自动换行符或其他内容)。 感谢您的帮助,我希望在开始使用此脚本之前透露我没有PHP的经验。

用于提取消息(HTML)并将其放入一个没有线路突破的字符串的代码:

$infoxo = quoted_printable_decode(imap_fetchbody($imap,$email_id,"1"));
emailyy = str_replace(array("\r\n"),"\n",$infoxo);
$lines = explode("\n",$emailyy);
$new_lines =array();
foreach($lines as $i => $line)
{
if(!empty($line))
$new_lines[]=trim($line);
$emailzz = implode($new_lines);
}

$desc = $emailzz;

另一项功能(ICS文件代码):

$headers = 'Content-Type:text/calendar; Content-Disposition: inline;
    charset=utf-8;\r\n';
$headers .= "Content-Type: /text/plain;charset=\"utf-8\"\r\n"; 

$message = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//BLAH/BLAH
METHOD:REQUEST
BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)) . "example.com
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:".$start1."00Z
DTEND:".$end1."00Z
DESCRIPTION:".$desc."
SUMMARY:".$subject."
ORGANIZER;CN=".$organizer.":mailto:".$organizer_email."
LOCATION:".$location."
X-ALT-DESC;FMTTYPE=text/html:".$desc."
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-  
ACTION;RSVP=TRUE;CN".$participant_name_1.";X-NUM-GUESTS=0:MAILTO:".$participant_email_1."
END:VEVENT
END:VCALENDAR";
$headers .= $message;

然后我使用phpamiler()发送电子邮件

3 个答案:

答案 0 :(得分:2)

感谢arnaudq指导我正确的方向。这是适用于折叠的代码:

function abc($htmlMsg)
{
    $temp = str_replace(array("\r\n"),"\n",$htmlMsg);
    $lines = explode("\n",$temp);
    $new_lines =array();
    foreach($lines as $i => $line)
    {
        if(!empty($line))
        $new_lines[]=trim($line);
    }
    $desc = implode("\r\n ",$new_lines);
    return $desc;
}

在icalender文件中,我使用:

DESCRIPTION:".$desc."
X-ALT-DESC;FMTTYPE=text/html:".$desc."

icalender文件中的其余参数与我的问题中的参数相同。

请注意,以上内容仅在Outlook中进行了测试。它在描述中显示为干净的事件和正确的HTML格式。

答案 1 :(得分:1)

您的icalendar流不应包含超过75个字符的行。如果您的描述包含此类行,则应使用https://tools.ietf.org/html/rfc5545#section-3.1

中描述的折叠技术

然后查看您的代码,您的DESCRIPTION字段应该包含描述的纯文本版本(没有任何HTML标记)。

答案 2 :(得分:0)

我认为问题在于电子邮件中的行具有最大长度,因此phpmailer或邮件传输程序会打破长行。为避免这种情况,您可以使用base64编码:这样base64代码将被分成短行,这不会影响编码的字符串。

正如我所见,phpmailer不允许设置邮件正文编码,但您可以将ICAL作为附件发送。

$infoxo = quoted_printable_decode(imap_fetchbody($imap,$email_id,"1"));
$emailyy = str_replace(array("\r\n"),"\n",$infoxo);
$lines = explode("\n",$emailyy);
$new_lines = array();
foreach($lines as $i => $line)
{
    $line = trim($line);
    if(!empty($line))
        $new_lines[]=$line;
}

// it is enough to implode after foreach, when $new_lines is complete
$desc = implode($new_lines);

$message = "BEGIN:VCALENDAR
DESCRIPTION:".$desc."
END:VCALENDAR";

// Prepending headers to $message is useless, since phpmailer sets the headers itself.

$mail = new PHPMailer;

$mail->From = 'tzunghaor@example.com';
$mail->addAddress('joe@example.com', 'Joe User');

$mail->isHTML(false); 

$mail->Subject = 'ical';
$mail->Body    = 'ical';

$mail->addStringAttachment(
        $message, //attachment data
        'thing.ical', // attachment file name
        'base64', // encoding
        'text/calendar;charset=utf-8', // content type
        'inline' // content disposition
    );
$mail->send();