go-mail
[ class tree: go-mail ] [ index: go-mail ] [ all elements ]

Source for file GoSwift.class.inc.php

Documentation is available at GoSwift.class.inc.php

  1. <?php
  2. /** 
  3.  * Copyright Intermesh
  4.  * 
  5.  * This file is part of Group-Office. You should have received a copy of the
  6.  * Group-Office license along with Group-Office. See the file /LICENSE.TXT
  7.  * 
  8.  * If you have questions write an e-mail to info@intermesh.nl
  9.  * 
  10.  * @copyright Copyright Intermesh
  11.  * @version $Id: GoSwift.class.inc.php 1263 2008-10-27 16:35:59Z mschering $
  12.  * @author Merijn Schering <mschering@intermesh.nl>
  13.  */
  14.  
  15. /**
  16.  * Require all mail classes that are used by this class
  17.  */
  18. require_once($GO_CONFIG->class_path."html2text.class.inc");
  19. require_once $GO_CONFIG->class_path.'mail/RFC822.class.inc';
  20. require_once $GO_CONFIG->class_path.'mail/mimeDecode.class.inc';
  21. require_once $GO_CONFIG->class_path.'mail/swift/lib/Swift.php';
  22. require_once $GO_CONFIG->class_path.'mail/swift/lib/Swift/Connection/SMTP.php';
  23. require_once $GO_CONFIG->class_path.'mail/swift/lib/Swift/Plugin/FileEmbedder.php';
  24. require_once $GO_CONFIG->class_path.'mail/swift/lib/Swift/Cache/Disk.php';
  25.  
  26. require_once $GO_CONFIG->class_path.'mail/smtp_restrict.class.inc.php';
  27.  
  28. //You change the cache class using this call...
  29. Swift_CacheFactory::setClassName("Swift_Cache_Disk");
  30.  
  31. //Then you set up the disk cache to write to a writable folder...
  32. Swift_Cache_Disk::setSavePath($GO_CONFIG->tmpdir);
  33.  
  34.  
  35. /**
  36.  * This class can be used to send an e-mail. It extends the 3rd party Swift class.
  37.  * Swift documentation can be found here:
  38.  *
  39.  * {@link http://www.swiftmailer.org/wikidocs/"target="_blank Documentation}
  40.  *
  41.  * @author Merijn Schering <mschering@intermesh.nl>
  42.  * @version $Id: GoSwift.class.inc.php 1263 2008-10-27 16:35:59Z mschering $
  43.  * @copyright Copyright Intermesh
  44.  * @license GNU General Public License
  45.  * @package go.mail
  46.  * @uses Swift
  47.  * @since Group-Office 3.0
  48.  */
  49.  
  50. class GoSwift extends Swift{
  51.  
  52.     /**
  53.      * The Swift message to send
  54.      *
  55.      * @var Swift_Message 
  56.      */
  57.     public $message;
  58.  
  59.     /**
  60.      * The Swift recipients list
  61.      *
  62.      * @var Swift_RecipientList 
  63.      */
  64.  
  65.     public $recipients;
  66.  
  67.     /**
  68.      * The raw message data to store in the sent folder or for a linked message
  69.      *
  70.      * @var String 
  71.      * @access private
  72.      */
  73.     private $data;
  74.  
  75.     /**
  76.      * When repied to a message it flags the orignal message with ANSWERED
  77.      *
  78.      * @var String 
  79.      * @access private
  80.      */
  81.     private $reply_mailbox;
  82.  
  83.     /**
  84.      * When repied to a message it flags the orignal message with ANSWERED
  85.      *
  86.      * @var String 
  87.      * @access private
  88.      */
  89.     private $reply_uid;
  90.  
  91.     /**
  92.      * The account record as an array. see table em_accounts
  93.      *
  94.      * @var array 
  95.      */
  96.     public $account;
  97.     
  98.     private $smtp_host;
  99.  
  100.  
  101.  
  102.     /**
  103.      * Constructor. This will create a Swift instance and a Swift message public property.
  104.      *
  105.      * @param String $email_to The reciepents in a comma separated string
  106.      * @param String $subject The subject of the e-mail
  107.      * @param Int $account_id The account id from the em_accounts table. Used for smtp server and sent items
  108.      * @param String $priority The priority can be 3 for normal, 1 for high or 5 for low.
  109.      */
  110.     function __construct($email_to$subject$account_id=0$priority '3'$plain_text_body=null)
  111.     {
  112.         global $GO_CONFIG$GO_MODULES;
  113.  
  114.  
  115.         if($account_id>0)
  116.         {
  117.             require_once ($GO_MODULES->modules['email']['class_path']."email.class.inc");
  118.             $email new email();
  119.  
  120.             $this->account = $email->get_account($account_id);
  121.  
  122.             $this->smtp_host=$this->account['smtp_host'];
  123.             
  124.             $smtp_connection=new Swift_Connection_SMTP($this->account['smtp_host']$this->account['smtp_port']$this->account['smtp_encryption']);
  125.             if(!empty($this->account['smtp_username']))
  126.             {
  127.                 $smtp_connection->setUsername($this->account['smtp_username']);
  128.                 $smtp_connection->setPassword($this->account['smtp_password']);
  129.             }
  130.         }else
  131.         {
  132.             $this->smtp_host=$GO_CONFIG->smtp_server;
  133.             $smtp_connection=new Swift_Connection_SMTP($GO_CONFIG->smtp_server$GO_CONFIG->smtp_port);
  134.             if(!empty($GO_CONFIG->smtp_username))
  135.             {
  136.                 $smtp_connection->setUsername($GO_CONFIG->smtp_username);
  137.                 $smtp_connection->setPassword($GO_CONFIG->smtp_password);
  138.             }
  139.         }
  140.         parent::__construct($smtp_connection);
  141.  
  142.  
  143.         $this->message =new Swift_Message($subject$plain_text_body);
  144.         $this->message->setPriority($priority);
  145.  
  146.         $this->message->headers->set("X-Mailer""Group-Office ".$GO_CONFIG->version);
  147.         $this->message->headers->set("X-MimeOLE""Produced by Group-Office ".$GO_CONFIG->version);
  148.  
  149.  
  150.         
  151.         $this->set_to($email_to);
  152.  
  153.     }
  154.     
  155.     function set_to($email_to)
  156.     {
  157.         //Start a new list
  158.         $this->recipients =new Swift_RecipientList();
  159.  
  160.         $RFC822 new RFC822();
  161.         $to_addresses $RFC822->parse_address_list($email_to);
  162.         
  163.         foreach($to_addresses as $address)
  164.         {
  165.             $this->recipients->addTo($address['email']$address['personal']);
  166.         }    
  167.     }
  168.     
  169.     function set_recipients($recipientList)
  170.     {
  171.         $this->recipients=$recipientList;
  172.     }
  173.  
  174.     /**
  175.      * Sets the message body
  176.      *
  177.      * @param String $body The message body in HTML or text
  178.      * @param String $type Can be html or text
  179.      */
  180.  
  181.     function set_body($body,$type='html')
  182.     {
  183.         global $GO_CONFIG;
  184.         
  185.         //correction for IE. It likes to add the domain name to relative url's
  186.         if($type=='html')
  187.         {
  188.             $body str_replace(substr($GO_CONFIG->full_url,0,-strlen($GO_CONFIG->host)).'cid:''cid:'$body);
  189.         }
  190.         
  191.         //add body
  192.         $this->message->attach(new Swift_Message_Part($body'text/'.$typenull'UTF-8'));
  193.  
  194.         if($type=='html')
  195.         {
  196.             //add text version of the HTML body
  197.             $htmlToText new Html2Text ($body);
  198.             $this->message->attach(new Swift_Message_Part($htmlToText->get_text()'text/plain'null'UTF-8'));
  199.         }
  200.     }
  201.  
  202.     /**
  203.      * If this message is a reply to another message then you must supply the UID and the mailbox
  204.      * of the original message. The account id must be passed to the constructor for this to work.
  205.      *
  206.      * @param String $reply_uid 
  207.      * @param String $reply_mailbox 
  208.      */
  209.  
  210.     function set_reply_to($reply_uid$reply_mailbox)
  211.     {
  212.         $this->reply_uid=$reply_uid;
  213.         $this->reply_mailbox=$reply_mailbox;
  214.     }
  215.     
  216.     
  217.     function get_mime($email_from=null$name_from=null)
  218.     {
  219.         $name_from=!empty($name_from$name_from $this->account['name'];
  220.         $email_from=!empty($email_from$email_from $this->account['email'];        
  221.         
  222.         $this->message->setFrom(new Swift_Address($email_from$name_from));
  223.         $this->message->setCc($this->recipients->getCc());
  224.         $this->message->setBcc($this->recipients->getBcc());
  225.         $this->message->setTo($this->recipients->getTo());        
  226.         
  227.         $data $this->message->build();
  228.         return $data->readFull();
  229.         
  230.     }
  231.     
  232.     function get_data($email_from=null$name_from=null)
  233.     {
  234.         $name_from=!empty($name_from$name_from $this->account['name'];
  235.         $email_from=!empty($email_from$email_from $this->account['email'];
  236.         
  237.         $this->message->setFrom(new Swift_Address($email_from$name_from));
  238.         
  239.         $this->message->setCc($this->recipients->getCc());
  240.         $this->message->setBcc($this->recipients->getBcc());
  241.         $this->message->setTo($this->recipients->getTo());
  242.         
  243.         $data $this->message->build();
  244.         return $data->readFull();
  245.  
  246.     }
  247.  
  248.     /**
  249.      * Sends the email.
  250.      *
  251.      * @param String $email_from The from e-mail address. If you don't supply this then you must supply the account_id to the constructor
  252.      * @param String $name_from The from name. If you don't supply this then you must supply the account_id to the constructor
  253.      * @param boolean $batch If you set this to true it will use the Swift batchSend method. See the swift docs.
  254.      * @throws Swift_ConnectionException If sending fails for any reason.
  255.      * @return int The number of successful recipients
  256.      */
  257.  
  258.     function sendmail($email_from=null$name_from=null$batch=false)
  259.     {
  260.         
  261.         $smtp_restrict new smtp_restrict();
  262.         
  263.         if(!$smtp_restrict->is_allowed($this->smtp_host))
  264.         {
  265.             global $lang;
  266.             $msg sprintf($lang['common']['max_emails_reached']$this->smtp_host$smtp_restrict->hosts[gethostbyname($this->smtp_host)]);
  267.             throw new Exception($msg);
  268.         }
  269.         
  270.         
  271.         $name_from=!empty($name_from$name_from $this->account['name'];
  272.         $email_from=!empty($email_from$email_from $this->account['email'];
  273.  
  274.         
  275.  
  276.         if($batch)
  277.         {
  278.             //$send_success = parent::batchSend($this->message,$this->recipients, new Swift_Address($email_from, $name_from));
  279.             
  280.             $this->batch =new Swift_BatchMailer($this);    
  281.             $this->batch->setSleepTime(10);
  282.             $this->batch->setMaxTries(2);
  283.             $this->batch->setMaxSuccessiveFailures(10);        
  284.             $this->batch->send($this->message$this->recipientsnew Swift_Address($email_from$name_from));
  285.             
  286.         }else
  287.         {
  288.             $send_success parent::send($this->message,$this->recipientsnew Swift_Address($email_from$name_from));
  289.         }
  290.  
  291.         //for appending to send and link
  292.         $this->message->setFrom(new Swift_Address($email_from$name_from));
  293.         
  294.         
  295.         $this->message->setCc($this->recipients->getCc());
  296.         $this->message->setBcc($this->recipients->getBcc());
  297.         $this->message->setTo($this->recipients->getTo());
  298.         
  299.         
  300.         
  301.         if($send_success && $this->account)
  302.         {
  303.             global $GO_CONFIG;
  304.                 
  305.             require_once ($GO_CONFIG->class_path."mail/imap.class.inc");
  306.             $imap new imap();
  307.                 
  308.                 
  309.                 
  310.             if ($imap->open(
  311.             $this->account['host'],
  312.             $this->account['type'],
  313.             $this->account['port'],
  314.             $this->account['username'],
  315.             $this->account['password'],
  316.                 'INBOX',
  317.             0,
  318.             $this->account['use_ssl'],
  319.             $this->account['novalidate_cert'])) {
  320.                     
  321.  
  322.                     
  323.                 $this->data $this->message->build();
  324.                 $this->data $this->data->readFull();
  325.  
  326.                 if ($imap->append_message($this->account['sent']$this->data,"\\Seen"))
  327.                 {
  328.                     if (!empty($this->reply_uid&& !empty($this->reply_mailbox))
  329.                     {
  330.                         $uid_arr array($this->reply_uid);
  331.                         $imap->set_message_flag($this->reply_mailbox$uid_arr"\\Answered");
  332.                     }
  333.                     $imap->close();
  334.  
  335.                 }
  336.             }
  337.         }
  338.         return $send_success;
  339.     }
  340.  
  341.     /**
  342.      * Links the message to items in Group-Office. Must be called after send()
  343.      *
  344.      * @param array $links Format Array(Array(link_id=>1, link_type=>1));
  345.      * @return void 
  346.      */
  347.     function link_to(Array $links)
  348.     {
  349.         global $GO_CONFIG$GO_LINKS;
  350.  
  351.  
  352.         $link_message['path']=$GO_CONFIG->file_storage_path.'email/'.date('mY').'/sent_'.time().'.eml';
  353.             
  354.         require_once($GO_CONFIG->class_path.'filesystem.class.inc');
  355.         $fs new filesystem();
  356.         $fs->mkdir_recursive(dirname($link_message['path']));
  357.  
  358.         if(empty($this->data))
  359.         {
  360.             $this->data $this->message->build();
  361.             $this->data $this->data->readFull();
  362.         }
  363.  
  364.  
  365.         $fp fopen($link_message['path'],"w+");
  366.         fputs ($fp$this->datastrlen($this->data));
  367.         fclose($fp);
  368.  
  369.         $email new email();
  370.  
  371.         $link_message['from']=$this->message->headers->get('from');
  372.         
  373.         $to=$this->recipients->getTo();
  374.         foreach ($to as $key => $value)
  375.     {
  376.       $to[$key$value->build();
  377.     }
  378.  
  379.         
  380.         $link_message['to']=implode(',',$to);
  381.         $link_message['subject']=$this->message->headers->get('subject');
  382.         $link_message['ctime']=$link_message['time']=time();
  383.         $link_message['link_id'$email->link_message($link_message);
  384.  
  385.         foreach($links as $link)
  386.         {
  387.             $GO_LINKS->add_link(
  388.             $link['link_id'],
  389.             $link['link_type'],
  390.             $link_message['link_id'],
  391.             9);
  392.         }
  393.     }
  394. }
  395.  
  396.  
  397. class GoSwiftImport extends GoSwift{
  398.     
  399.     var $body='';
  400.  
  401.     public function __construct($mime$add_body=true)
  402.     {
  403.         
  404.         $RFC822 new RFC822();
  405.         
  406.         
  407.         $params['include_bodies'true;
  408.         $params['decode_bodies'true;
  409.         $params['decode_headers'true;
  410.         $params['input'$mime;
  411.     
  412.     
  413.         $structure Mail_mimeDecode::decode($params);
  414.         
  415.         $from_email='';
  416.         $from_name='';
  417.     
  418.         if(isset($structure->headers['from']) )
  419.         {
  420.             $addresses=$RFC822->parse_address_list($structure->headers['from']);
  421.             if(isset($addresses[0]))
  422.             {
  423.                 $from_email=$addresses[0]['email'];
  424.                 $from_name=$addresses[0]['personal'];                
  425.             }
  426.         }
  427.         
  428.         $subject = isset($structure->headers['subject']$structure->headers['subject''';
  429.         
  430.         if(isset($structure->headers['disposition-notification-to']))
  431.         {
  432.             //$mail->ConfirmReadingTo = $structure->headers['disposition-notification-to'];
  433.         }
  434.         
  435.         $to = isset($structure->headers['to']$structure->headers['to''';
  436.         $cc = isset($structure->headers['cc']$structure->headers['cc''';
  437.         $bcc = isset($structure->headers['bcc']$structure->headers['bcc''';
  438.         
  439.         parent::__construct($to$subject);
  440.         
  441.         //TODO add cc
  442.         
  443.         $this->get_parts($structure);
  444.         
  445.         if($add_body)
  446.             $this->set_body($this->body);
  447.         
  448.     }
  449.  
  450.     private function get_parts($structure$part_number_prefix='')
  451.     {
  452.         global $GO_CONFIG$GO_MODULES;
  453.  
  454.         if (isset($structure->parts))
  455.         {
  456.             //$part_number=0;
  457.             foreach ($structure->parts as $part_number=>$part{
  458.  
  459.                 //text part and no attachment so it must be the body
  460.                 if($structure->ctype_primary=='multipart' && $structure->ctype_secondary=='alternative' &&
  461.                 $part->ctype_primary == 'text' && $part->ctype_secondary=='plain')
  462.                 {
  463.                     continue;
  464.                 }
  465.  
  466.  
  467.                 if ($part->ctype_primary == 'text' && (!isset($part->disposition|| $part->disposition != 'attachment'&& empty($part->d_parameters['filename']))
  468.                 {
  469.                     if (eregi('plain'$part->ctype_secondary))
  470.                     {
  471.                         $content_part nl2br($part->body);
  472.                     }else
  473.                     {
  474.                         $content_part $part->body;
  475.                     }
  476.                     $this->body .= $content_part;
  477.                 }elseif($part->ctype_primary=='multipart')
  478.                 {
  479.                     
  480.                 }else
  481.                 {
  482.                     //attachment 
  483.                     
  484.                     $dir=$GO_CONFIG->tmpdir.'attachments/';
  485.                     
  486.                     if(!is_dir($dir))
  487.                         mkdir($dir0755true);
  488.                         
  489.                     //unset($part->body);                        
  490.                     //var_dump($part);
  491.                     //exit();
  492.                         
  493.                     $tmp_file $dir.$part->d_parameters['filename'];                    
  494.                     file_put_contents($tmp_file$part->body);
  495.  
  496.                     $mime_type $part->ctype_primary.'/'.$part->ctype_secondary;
  497.                     
  498.                     if(isset($part->headers['content-id']))
  499.                     {
  500.                         $content_id=trim($part->headers['content-id']);
  501.                         if (strpos($content_id,'>'))
  502.                         {
  503.                             $content_id substr($part->headers['content-id']1,strlen($part->headers['content-id'])-2);
  504.                         }
  505.                         $img =new Swift_Message_Image(new Swift_File($tmp_file),utf8_basename($tmp_file)$mime_type,$content_id);
  506.                         $this->message->attach($img);                    
  507.                     }else
  508.                     {
  509.                         $file =new Swift_File($tmp_file);
  510.                         $attachment =new Swift_Message_Attachment($file,utf8_basename($tmp_file)$mime_type);
  511.                         $this->message->attach($attachment);
  512.                     }
  513.                 }
  514.  
  515.                 //$part_number++;
  516.                 if(isset($part->parts))
  517.                 {
  518.                     $this->get_parts($part$part_number_prefix.$part_number.'.');
  519.                 }
  520.  
  521.             }
  522.         }elseif(isset($structure->body))
  523.         {
  524.             //convert text to html
  525.             if (eregi('plain'$structure->ctype_secondary))
  526.             {
  527.                 $text_part nl2br($structure->body);
  528.             }else
  529.             {
  530.                 $text_part $structure->body;
  531.             }
  532.             $this->body .= $text_part;
  533.         }
  534.     }
  535. }

Documentation generated on Thu, 30 Oct 2008 14:13:30 +0100 by phpDocumentor 1.4.0