【问题标题】:Html in ics file description with php用php在ics文件描述中的html
【发布时间】:2019-03-15 14:42:31
【问题描述】:

我正在编写一个脚本,该脚本涉及到达邮件服务器、获取电子邮件、从电子邮件中解析信息、从解析的信息中创建一个事件(ics 文件),然后将事件邀请与原始电子邮件一起作为 ics 文件的描述发送。我正在用 php.ini 完成以上所有工作。我被困在最后一步,即发送原始电子邮件正文(html)作为描述。

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

经过研究,我发现要解析 ics 文件中的 html,Outlook 使用 X-ALT-DESC 之类的东西。所以,我将DESCRIPTION 和 X-ALT-DESC 作为带有 h​​tml 代码的字符串。但是发送电子邮件会导致 Outlook 忽略大部分 html,并在最后结束自己的标签,我只收到原始电子邮件的一小部分。

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

我不知道问题是在 php 中(用于添加换行符)还是 如果 ics 文件在 X-ALT-DESC 中存在关于 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() 发送电子邮件

【问题讨论】:

  • 你能给我们展示一个最小的工作源代码吗?
  • 您应该考虑使用库来生成 iCalendar 文件。
  • @tzunghaor 我已经添加了代码。

标签: php html icalendar


【解决方案1】:

感谢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 格式。

【讨论】:

    【解决方案2】:

    您的 icalendar 流不应包含超过 75 个字符的行。如果你的描述中包含这样的行,你应该使用https://www.rfc-editor.org/rfc/rfc5545#section-3.1中描述的折叠技术

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

    【讨论】:

    • 这正是我认为的问题。我可以使用纯文本没问题。但是,您能否指导我参阅有关“折叠技术”的指南。我无法按照 ietf 网站上的措辞折叠线条。平原应该是类似于 aaaCRLF abc 的东西,它会打印出 aaa abc 对不起,我在这里是个“菜鸟”。
    • 没有。 aaaCRLF abc 将展开为 aaaabc。 CRLF 后面的空格表示新行是第一行的延续,因此在展开时应删除。当然,您可能有超过 2 行(例如“abcCRLF defCRLF ghi”)。
    【解决方案3】:

    我认为问题在于电子邮件中的行有最大长度,因此 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();
    

    【讨论】:

      猜你喜欢
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 2011-07-24
      • 2013-07-13
      • 1970-01-01
      相关资源
      最近更新 更多