예제 #1
0
 /**
  * Retreive an instance of the encoder as a singleton.
  * New instances are never ever needed since it's monostatic.
  * @return Message_Encoder
  */
 public static function instance()
 {
     if (self::$instance === null) {
         self::$instance = new Swift_Message_Encoder();
     }
     return self::$instance;
 }
예제 #2
0
 /**
  * Build the list of attributes for appending to the given header
  * This is RFC 2231 & 2047 compliant.
  * A HUGE thanks to Joaquim Homrighausen for heaps of help, advice
  * and testing to get this working rock solid.
  * @param string The header built without attributes
  * @param string The lowercase name of the header
  * @return string
  * @throws Swift_Message_MimeException If no such header exists or there are no attributes
  */
 function buildAttributes($header_line, $header_name)
 {
     Swift_ClassLoader::load("Swift_Message_Encoder");
     $encoder =& Swift_Message_Encoder::instance();
     $lines = explode($this->LE, $header_line);
     $used_len = strlen($lines[count($lines) - 1]);
     $lines = null;
     $ret = "";
     foreach ($this->attributes[$header_name] as $attribute => $att_value) {
         if ($att_value === null) {
             continue;
         }
         // 70 to account for LWSP, CRLF, quotes and a semi-colon
         // + length of attribute
         // + 4 for a 2 digit number and 2 asterisks
         $avail_len = 70 - (strlen($attribute) + 4);
         $encoded = $encoder->rfc2047Encode($att_value, $this->charset, $this->language, $avail_len, $this->LE);
         $lines = explode($this->LE, $encoded);
         foreach ($lines as $i => $line) {
             //Add quotes if needed (RFC 2045)
             if (preg_match("~[\\s\";,<>\\(\\)@:\\\\/\\[\\]\\?=]~", $line)) {
                 $lines[$i] = '"' . $line . '"';
             }
         }
         $encoded = implode($this->LE, $lines);
         //If we can fit this entire attribute onto the same line as the header then do it!
         if (strlen($encoded) + $used_len + strlen($attribute) + 4 < 74) {
             if (strpos($encoded, "'") !== false) {
                 $attribute .= "*";
             }
             $append = "; " . $attribute . "=" . $encoded;
             $ret .= $append;
             $used_len += strlen($append);
         } else {
             $ret .= ";";
             if (count($lines) > 1) {
                 $loop = false;
                 $add_asterisk = false;
                 foreach ($lines as $i => $line) {
                     $att_copy = $attribute;
                     //Because it's multi-line it needs asterisks with decimal indices
                     $att_copy .= "*" . $i;
                     if ($add_asterisk || strpos($encoded, "'") !== false) {
                         $att_copy .= "*";
                         //And if it's got a ' then it needs another asterisk
                         $add_asterisk = true;
                     }
                     $append = "";
                     if ($loop) {
                         $append .= ";";
                     }
                     $append .= $this->LE . " " . $att_copy . "=" . $line;
                     $ret .= $append;
                     $used_len = strlen($append) + 1;
                     $loop = true;
                 }
             } else {
                 if (strpos($encoded, "'") !== false) {
                     $attribute .= "*";
                 }
                 $append = $this->LE . " " . $attribute . "=" . $encoded;
                 $used_len = strlen($append) + 1;
                 $ret .= $append;
             }
         }
         $lines = null;
     }
     return $ret;
 }
예제 #3
0
파일: Swift.php 프로젝트: jvinet/pronto
 /**
  * Send a message to any number of recipients
  * @param Swift_Message The message to send.  This does not need to (and shouldn't really) have any of the recipient headers set.
  * @param mixed The recipients to send to.  Can be a string, Swift_Address or Swift_RecipientList. Note that all addresses apart from Bcc recipients will appear in the message headers
  * @param mixed The address to send the message from.  Can either be a string or an instance of Swift_Address.
  * @return int The number of successful recipients
  * @throws Swift_ConnectionException If sending fails for any reason.
  */
 function send(&$message, $recipients, $from)
 {
     Swift_ClassLoader::load("Swift_Message_Encoder");
     $encoder =& Swift_Message_Encoder::instance();
     if (!is_a($message, "Swift_Message")) {
         trigger_error("Swift::send expects parameter 1 to be instance of Swift_Message.");
         return;
     }
     if (is_string($recipients) && preg_match("/^" . $encoder->CHEAP_ADDRESS_RE . "\$/", $recipients)) {
         $recipients =& new Swift_Address($recipients);
     } elseif (!is_a($recipients, "Swift_AddressContainer")) {
         trigger_error("The recipients parameter must either be a valid string email address, " . "an instance of Swift_RecipientList or an instance of Swift_Address.");
         return;
     }
     if (is_string($from) && preg_match("/^" . $encoder->CHEAP_ADDRESS_RE . "\$/", $from)) {
         $from =& new Swift_Address($from);
     } elseif (!is_a($from, "Swift_Address")) {
         trigger_error("The sender parameter must either be a valid string email address or " . "an instance of Swift_Address.");
         return;
     }
     $log =& Swift_LogContainer::getLog();
     if (!$message->getEncoding() && !$this->connection->hasExtension("8BITMIME")) {
         $message->setEncoding("QP", true, true);
     }
     $list =& $recipients;
     if (is_a($recipients, "Swift_Address")) {
         $list =& new Swift_RecipientList();
         $list->addTo($recipients);
     }
     Swift_ClassLoader::load("Swift_Events_SendEvent");
     $send_event =& new Swift_Events_SendEvent($message, $list, $from, 0);
     $this->notifyListeners($send_event, "BeforeSendListener");
     $to = $cc = array();
     if (!($has_from = $message->getFrom())) {
         $message->setFrom($from);
     }
     if (!($has_return_path = $message->getReturnPath())) {
         $message->setReturnPath($from->build(true));
     }
     if (!($has_reply_to = $message->getReplyTo())) {
         $message->setReplyTo($from);
     }
     if (!($has_message_id = $message->getId())) {
         $message->generateId();
     }
     $this->command("MAIL FROM: " . $message->getReturnPath(true), 250);
     $failed = 0;
     $sent = 0;
     $tmp_sent = 0;
     $it =& $list->getIterator("to");
     while ($it->hasNext()) {
         $it->next();
         $address = $it->getValue();
         $to[] = $address->build();
         $e = null;
         Swift_Errors::expect($e, "Swift_BadResponseException");
         $this->command("RCPT TO: " . $address->build(true), 250);
         if (!$e) {
             $tmp_sent++;
             Swift_Errors::clear("Swift_BadResponseException");
         } else {
             $failed++;
             $send_event->addFailedRecipient($address->getAddress());
             if ($log->hasLevel(SWIFT_LOG_FAILURES)) {
                 $log->addfailedRecipient($address->getAddress());
             }
         }
     }
     $it =& $list->getIterator("cc");
     while ($it->hasNext()) {
         $it->next();
         $address = $it->getValue();
         $cc[] = $address->build();
         $e = null;
         Swift_Errors::expect($e, "Swift_BadResponseException");
         $this->command("RCPT TO: " . $address->build(true), 250);
         if (!$e) {
             $tmp_sent++;
             Swift_Errors::clear("Swift_BadResponseException");
         } else {
             $failed++;
             $send_event->addFailedRecipient($address->getAddress());
             if ($log->hasLevel(SWIFT_LOG_FAILURES)) {
                 $log->addfailedRecipient($address->getAddress());
             }
         }
     }
     if ($failed == count($to) + count($cc)) {
         $this->reset();
         $this->notifyListeners($send_event, "SendListener");
         return 0;
     }
     if (!($has_to = $message->getTo()) && !empty($to)) {
         $message->setTo($to);
     }
     if (!($has_cc = $message->getCc()) && !empty($cc)) {
         $message->setCc($cc);
     }
     $this->command("DATA", 354);
     $data =& $message->build();
     while (false !== ($bytes = $data->read())) {
         $this->command($bytes, -1);
     }
     if ($log->hasLevel(SWIFT_LOG_NETWORK)) {
         $log->add("<MESSAGE DATA>", SWIFT_LOG_COMMAND);
     }
     Swift_Errors::expect($e, "Swift_BadResponseException");
     $this->command("\r\n.", 250);
     if (!$e) {
         $sent += $tmp_sent;
         Swift_Errors::clear("Swift_BadResponseException");
     } else {
         $failed += $tmp_sent;
     }
     $tmp_sent = 0;
     $has_bcc = $message->getBcc();
     $it =& $list->getIterator("bcc");
     while ($it->hasNext()) {
         $it->next();
         $address = $it->getValue();
         if (!$has_bcc) {
             $message->setBcc($address->build());
         }
         $e = null;
         Swift_Errors::expect($e, "Swift_BadResponseException");
         if (!$e) {
             $this->command("MAIL FROM: " . $message->getReturnPath(true), 250);
         }
         if (!$e) {
             $this->command("RCPT TO: " . $address->build(true), 250);
         }
         if (!$e) {
             $this->command("DATA", 354);
         }
         if (!$e) {
             $data =& $message->build();
             while (false !== ($bytes = $data->read())) {
                 $this->command($bytes, -1);
             }
             if ($log->hasLevel(SWIFT_LOG_NETWORK)) {
                 $log->add("<MESSAGE DATA>", SWIFT_LOG_COMMAND);
             }
             $this->command("\r\n.", 250);
         }
         if (!$e) {
             $sent++;
             Swift_Errors::clear("Swift_BadResponseException");
         } else {
             $failed++;
             $send_event->addFailedRecipient($address->getAddress());
             if ($log->hasLevel(SWIFT_LOG_FAILURES)) {
                 $log->addfailedRecipient($address->getAddress());
             }
             $this->reset();
         }
     }
     $total = count($to) + count($cc) + count($list->getBcc());
     $send_event->setNumSent($sent);
     $this->notifyListeners($send_event, "SendListener");
     if (!$has_return_path) {
         $message->setReturnPath("");
     }
     if (!$has_from) {
         $message->setFrom("");
     }
     if (!$has_to) {
         $message->setTo("");
     }
     if (!$has_reply_to) {
         $message->setReplyTo(null);
     }
     if (!$has_cc) {
         $message->setCc(null);
     }
     if (!$has_bcc) {
         $message->setBcc(null);
     }
     if (!$has_message_id) {
         $message->setId(null);
     }
     if ($log->hasLevel(SWIFT_LOG_NETWORK)) {
         $log->add("Message sent to " . $sent . "/" . $total . " recipients", SWIFT_LOG_NORMAL);
     }
     return $sent;
 }
 /**
  * Execute needed logic prior to compilation
  */
 public function preBuild()
 {
     $data = $this->getData();
     if (!($enc = $this->getEncoding())) {
         $this->setEncoding("8bit");
     }
     if ($this->getCharset() === null && !$this->numChildren()) {
         Swift_ClassLoader::load("Swift_Message_Encoder");
         if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data)) {
             $this->setCharset("utf-8");
         } elseif (is_string($data) && Swift_Message_Encoder::instance()->is7BitAscii($data)) {
             $this->setCharset("us-ascii");
             if (!$enc) {
                 $this->setEncoding("7bit");
             }
         } else {
             $this->setCharset("iso-8859-1");
         }
     } elseif ($this->numChildren()) {
         if (!$this->getData()) {
             $this->setData($this->getMimeWarning());
             $this->setLineWrap(76);
         }
         if ($this->getCharset() !== null) {
             $this->setCharset(null);
         }
         if ($this->isFlowed()) {
             $this->setFlowed(false);
         }
         $this->setEncoding("7bit");
     }
 }
예제 #5
0
 /**
  * FUNCTION: _sendMail
  *
  * Proccesses all headers and attachments ready for sending.
  *
  * @access private
  */
 function _sendMail()
 {
     $message = new Swift_Message($this->subject);
     if (empty($this->sendto) and (empty($this->body) and empty($this->htmlbody))) {
         vlibMimeMailError::raiseError('VM_ERROR_CANNOT_SEND', FATAL);
     }
     // Attachments
     for ($index = 0; $index < sizeof($this->attachments); $index++) {
         $message->attach(new Swift_Message_Attachment(new Swift_File($this->attachments[$index]), $this->attachments[$index], $this->mimetypes[$index]));
     }
     // ReplyTo if exists
     if (!empty($this->replyToEmail)) {
         $message->setReplyTo(new Swift_Address($this->replyToEmail, $this->replyToName));
     }
     // attach body if exist
     if (!empty($this->body)) {
         if (empty($this->htmlbody) and sizeof($this->attachments) == 0) {
             $message->setData($this->body);
             Swift_ClassLoader::load('Swift_Message_Encoder');
             if (Swift_Message_Encoder::instance()->isUTF8($this->body)) {
                 $message->setCharset('utf-8');
             } else {
                 $message->setCharset('iso-8859-1');
             }
         } else {
             $message->attach(new Swift_Message_Part($this->body, 'text/plain'));
         }
     }
     // attach HTML body if exist
     if (!empty($this->htmlbody)) {
         $message->attach(new Swift_Message_Part($this->htmlbody, 'text/html'));
     }
     return $this->swift->send($message, $this->swift_recipients, new Swift_Address($this->fromEmail, $this->fromName));
 }
예제 #6
0
파일: Part.php 프로젝트: enormego/EightPHP
 /**
  * Pre-compilation logic
  */
 public function preBuild()
 {
     if (!($enc = $this->getEncoding())) {
         $this->setEncoding("8bit");
     }
     $data = $this->getData();
     if ($this->getCharset() === null && !$this->numChildren()) {
         if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data)) {
             $this->setCharset("utf-8");
         } elseif (is_string($data) && Swift_Message_Encoder::instance()->is7BitAscii($data)) {
             $this->setCharset("us-ascii");
             if (!$enc) {
                 $this->setEncoding("7bit");
             }
         } else {
             $this->setCharset("iso-8859-1");
         }
     } elseif ($this->numChildren()) {
         $this->setCharset(null);
         $this->setEncoding("7bit");
     }
 }
예제 #7
0
 /**
  * Constructor
  * @param Swift_Connection The connection to use
  * @param string The domain name of this server (not the SMTP server)
  */
 function EasySwift(&$connection, $domain = null)
 {
     if (!is_a($connection, "Swift_Connection") && !is_a($connection, "SimpleMock")) {
         trigger_error("EasySwift constructor parameter 1 must be instance of Swift_Connection.");
         return;
     }
     Swift_Errors::expect($e, "Swift_ConnectionException");
     if (!$e) {
         $this->swift =& new Swift($connection, $domain, SWIFT_ENABLE_LOGGING);
     }
     Swift_ClassLoader::load("Swift_Plugin_EasySwiftResponseTracker");
     if (!$e) {
         $this->swift->attachPlugin(new Swift_Plugin_EasySwiftResponseTracker($this), "_ResponseTracker");
     }
     if ($e) {
         $this->failed = true;
         $this->setError("The connection failed to start.  An exception was thrown:<br />" . $e->getMessage());
     }
     Swift_Errors::clear("Swift_ConnectionException");
     $this->newMessage();
     $this->newRecipientList();
     $this->encoder =& Swift_Message_Encoder::instance();
 }
예제 #8
0
 /**
  * Get the data in the format suitable for sending
  * @return Swift_Cache_OutputStream
  * @throws Swift_FileException If the file stream given cannot be read
  * @throws Swift_Message_MimeException If some required headers have been forcefully removed
  */
 public function buildData()
 {
     Swift_ClassLoader::load("Swift_Message_Encoder");
     Swift_ClassLoader::load("Swift_Cache_JointOutputStream");
     if (!empty($this->children)) {
         if ($this->boundary === null) {
             $this->boundary = self::generateBoundary();
         }
         $this->headers->setAttribute("Content-Type", "boundary", $this->boundary);
         $this->cache->clear("append");
         foreach ($this->children as $part) {
             $this->cache->write("append", $this->LE . "--" . $this->boundary . $this->LE);
             $part_stream = $part->build();
             while (false !== ($bytes = $part_stream->read())) {
                 $this->cache->write("append", $bytes);
             }
         }
         $this->cache->write("append", $this->LE . "--" . $this->boundary . "--" . $this->LE);
     }
     $joint_os = new Swift_Cache_JointOutputStream();
     //Try using a cached version to save some cycles (at the expense of memory)
     //if ($this->cache !== null) return $this->cache . $append;
     if ($this->cache->has("body")) {
         $joint_os->addStream($this->cache->getOutputStream("body"));
         $joint_os->addStream($this->cache->getOutputStream("append"));
         return $joint_os;
     }
     $is_file = $this->getData() instanceof Swift_File;
     switch ($this->getEncoding()) {
         case "quoted-printable":
             if ($is_file) {
                 $qp_os = Swift_Message_Encoder::instance()->QPEncodeFile($this->getData(), 76, $this->LE);
                 while (false !== ($bytes = $qp_os->read())) {
                     $this->cache->write("body", $bytes);
                 }
             } else {
                 $this->cache->write("body", Swift_Message_Encoder::instance()->QPEncode($this->getData(), 76, 0, false, $this->LE));
             }
             break;
         case "base64":
             if ($is_file) {
                 $b64_os = Swift_Message_Encoder::instance()->base64EncodeFile($this->getData(), 76, $this->LE);
                 while (false !== ($bytes = $b64_os->read())) {
                     $this->cache->write("body", $bytes);
                 }
             } else {
                 $this->cache->write("body", Swift_Message_Encoder::instance()->base64Encode($this->getData(), 76, 0, false, $this->LE));
             }
             break;
         case "binary":
             if ($is_file) {
                 $data = $this->getData();
                 while (false !== ($bytes = $data->read(8192))) {
                     $this->cache->write("body", $bytes);
                 }
             } else {
                 $this->cache->write("body", $this->getData());
             }
             break;
         case "7bit":
             if ($is_file) {
                 $os = Swift_Message_Encoder::instance()->encode7BitFile($this->getData(), $this->wrap, $this->LE);
                 while (false !== ($bytes = $os->read())) {
                     $this->cache->write("body", $bytes);
                 }
             } else {
                 $this->cache->write("body", Swift_Message_Encoder::instance()->encode7Bit($this->getData(), $this->wrap, $this->LE));
             }
             break;
         case "8bit":
         default:
             if ($is_file) {
                 $os = Swift_Message_Encoder::instance()->encode8BitFile($this->getData(), $this->wrap, $this->LE);
                 while (false !== ($bytes = $os->read())) {
                     $this->cache->write("body", $bytes);
                 }
             } else {
                 $this->cache->write("body", Swift_Message_Encoder::instance()->encode8Bit($this->getData(), $this->wrap, $this->LE));
             }
             break;
     }
     $joint_os->addStream($this->cache->getOutputStream("body"));
     $joint_os->addStream($this->cache->getOutputStream("append"));
     return $joint_os;
 }
예제 #9
0
 /**
  * Detecting UTF8 automatically is useful so we want to be able to do this.
  */
 public function testUTF8Detection()
 {
     $iso88591 = file_get_contents(TestConfiguration::FILES_PATH . "/encodings/iso-8859-1.txt");
     $this->assertFalse(Swift_Message_Encoder::instance()->isUTF8($iso88591));
     $utf8 = file_get_contents(TestConfiguration::FILES_PATH . "/encodings/utf-8.txt");
     $this->assertTrue(Swift_Message_Encoder::instance()->isUTF8($utf8));
 }
예제 #10
0
 /**
  * Set the encoding format to be used on the body of the document
  * @param string The encoding type used
  * @param boolean If this encoding format should be used recursively. Note, this only takes effect if no encoding is set in the children.
  * @param boolean If the encoding should only be applied when the string is not ascii.
  */
 function setEncoding($encoding, $recursive = false, $non_ascii = false)
 {
     $this->cache->clear("body");
     switch (strtolower($encoding)) {
         case "q":
         case "qp":
         case "quoted-printable":
             $encoding = "quoted-printable";
             break;
         case "b":
         case "base64":
             $encoding = "base64";
             break;
         case "7bit":
         case "8bit":
         case "binary":
             $encoding = strtolower($encoding);
             break;
     }
     $data =& $this->getData();
     if ($non_ascii && is_string($data) && !$this->_encoder->is7BitAscii($data)) {
         $this->headers->set("Content-Transfer-Encoding", $encoding);
     } elseif (!$non_ascii || !is_string($data)) {
         $this->headers->set("Content-Transfer-Encoding", $encoding);
     }
     if ($recursive) {
         foreach ($this->children as $id => $child) {
             if (!$child->getEncoding()) {
                 $this->children[$id]->setEncoding($encoding, $recursive, $non_ascii);
             }
         }
     }
 }