/** * EML 文件解码 * * @param string * @return string */ function decode_eml($string) { $pos = strpos($string, '=?'); if (!is_int($pos)) { return $string; } $preceding = substr($string, 0, $pos); // save any preceding text $search = substr($string, $pos + 2); // the mime header spec says this is the longest a single encoded word can be $part_1 = strpos($search, '?'); if (!is_int($part_1)) { return $string; } $charset = substr($string, $pos + 2, $part_1); // 取出字符集的定义部分 $search = substr($search, $part_1 + 1); // 字符集定义以后的部分 => $search $part_2 = strpos($search, '?'); if (!is_int($part_2)) { return $string; } $encoding = substr($search, 0, $part_2); // 两个? 之间的部分编码方式: q 或 b $search = substr($search, $part_2 + 1); $end = strpos($search, '?='); // $part_2 + 1 与 $end 之间是编码了的内容: => $endcoded_text; if (!is_int($end)) { return $string; } $encoded_text = substr($search, 0, $end); $rest = substr($string, strlen($preceding . $charset . $encoding . $encoded_text) + 6); // + 6 是前面去掉的 =????= 六个字符 switch (strtolower($encoding)) { case 'q': $decoded = quoted_printable_decode($encoded_text); if (strtolower($charset) == 'windows-1251') { $decoded = convert_cyr_string($decoded, 'w', 'k'); } break; case 'b': $decoded = base64_decode($encoded_text); if (strtolower($charset) == 'windows-1251') { $decoded = convert_cyr_string($decoded, 'w', 'k'); } break; default: $decoded = '=?' . $charset . '?' . $encoding . '?' . $encoded_text . '?='; break; } return $preceding . $decoded . decode_eml($rest); }
public function receive_email_crond() { $now = time(); $lock_time = AWS_APP::cache()->get('receive_email_locker'); if ($lock_time and $now - $lock_time <= 600) { return false; } $receiving_email_accounts = $this->get_receiving_email_config(); if (!$receiving_email_accounts) { return false; } AWS_APP::cache()->set('receive_email_locker', $now, 600); foreach ($receiving_email_accounts as $receiving_email_config) { if (!$receiving_email_config['server'] or !$receiving_email_config['protocol'] or !$receiving_email_config['username'] or !$receiving_email_config['password'] or !$receiving_email_config['uid']) { continue; } $mail_config = array('host' => $receiving_email_config['server'], 'user' => $receiving_email_config['username'], 'password' => $receiving_email_config['password']); if ($receiving_email_config['ssl'] == 1) { $mail_config['ssl'] = 'SSL'; } if ($receiving_email_config['port']) { $mail_config['port'] = $receiving_email_config['port']; } try { switch ($receiving_email_config['protocol']) { case 'pop3': $mail = new Zend_Mail_Storage_Pop3($mail_config); break; case 'imap': $mail = new Zend_Mail_Storage_Imap($mail_config); break; default: continue 2; } } catch (Exception $e) { $this->notification_of_receive_email_error($receiving_email_config['id'], $e->getMessage()); continue; } $this->notification_of_receive_email_error($receiving_email_config['id'], null); $received_email['config_id'] = $receiving_email_config['id']; $received_email['uid'] = $receiving_email_config['uid']; foreach ($mail as $num => $message) { try { if ($receiving_email_config['protocol'] == 'imap' and $message->hasFlag(Zend_Mail_Storage::FLAG_SEEN)) { continue; } $received_email['message_id'] = substr($message->messageID, 1, -1); $received_email['date'] = intval(strtotime($message->Date)); if ($now - $received_email['date'] > 604800 or $this->fetch_row('received_email', 'message_id = "' . $this->quote($received_email['message_id']) . '" AND date = ' . $received_email['date'])) { continue; } if ($message->isMultipart()) { for ($i = 1; $i <= $message->countParts(); $i++) { $part = $message->getPart($i); if (substr($part->contentType, 0, 5) == 'text/') { $encoding = $part->contentTransferEncoding; $type = $part->contentType; $received_email['content'] = $part->getContent(); break; } else { continue; } } } else { $encoding = $message->contentTransferEncoding; $type = $message->contentType; $received_email['content'] = $message->getContent(); } if (!$encoding or !$type) { continue; } preg_match('/charset\\s?=\\s?"?([a-zA-Z0-9-]+)"?$/i', $type, $matches); $charset = strtolower($matches[1]); $received_email['subject'] = decode_eml($message->Subject); preg_match('/<?([^<]+@.+(\\.[^>]+)+)>?$/i', $message->From, $matches); $received_email['from'] = strtolower($matches[1]); switch ($encoding) { case 'base64': $received_email['content'] = base64_decode($received_email['content']); break; case 'quoted-printable': $received_email['content'] = quoted_printable_decode($received_email['content']); break; } if ($charset and $charset != 'utf-8') { $received_email['subject'] = mb_convert_encoding($received_email['subject'], 'utf-8', $charset); $received_email['content'] = mb_convert_encoding($received_email['content'], 'utf-8', $charset); } $received_email['subject'] = strip_tags($received_email['subject']); $received_email['content'] = strip_tags(preg_replace(array('/<p(\\s+[^>]*)?>/i', '/<\\/p>/i', '/<br\\s*\\/?>/i'), "\n", $received_email['content'])); $now++; $received_email['access_key'] = md5($received_email['uid'] . $now); $this->insert('received_email', $received_email); if ($receiving_email_config['protocol'] == 'pop3') { $mail->removeMessage($num); } if ($receiving_email_config['protocol'] == 'imap') { $mail->setFlags($num, array(Zend_Mail_Storage::FLAG_SEEN)); } } catch (Exception $e) { continue; } } } AWS_APP::cache()->delete('receive_email_locker'); return true; }