1<?php
2/**
3 * SwiftMailer plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <andi@splitbrain.org>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
13require_once(DOKU_PLUGIN.'action.php');
14
15class action_plugin_swiftmail extends DokuWiki_Action_Plugin {
16
17    /**
18     * register the eventhandlers
19     *
20     * @author Andreas Gohr <andi@splitbrain.org>
21     */
22    function register(Doku_Event_Handler $controller){
23        $controller->register_hook('MAIL_MESSAGE_SEND',
24                                   'BEFORE',
25                                   $this,
26                                   'handle_message_send',
27                                   array());
28    }
29
30    /**
31     * Handle the message send event and use SwiftMailer to mail
32     */
33    function handle_message_send(&$event, $param){
34        require_once dirname(__FILE__).'/Swift.php';
35        require_once dirname(__FILE__).'/Swift/Connection/SMTP.php';
36        $ok = false;
37        if($this->getConf('debug')){
38            $log =& Swift_LogContainer::getLog();
39            $log->setLogLevel(Swift_Log::LOG_EVERYTHING);
40        }
41
42        try {
43            // initialize the connection
44            $smtp =& new Swift_Connection_SMTP(
45                        $this->getConf('smtp_host'),
46                        $this->getConf('smtp_port'),
47                        $this->getConf('smtp_ssl')
48                     );
49
50            // use Pop-before-SMTP
51            if($this->getConf('pop3_host')) {
52                require_once dirname(__FILE__).'/Swift/Authenticator/@PopB4Smtp.php';
53                $smtp->attachAuthenticator(new Swift_Authenticator_PopB4Smtp($this->getConf('pop3_host')));
54            }
55
56            // use SMTP auth?
57            if($this->getConf('auth_user')) $smtp->setUsername($this->getConf('auth_user'));
58            if($this->getConf('auth_pass')) $smtp->setPassword($this->getConf('auth_pass'));
59
60            // start Swift
61            $swift =& new Swift($smtp,$this->getConf('localdomain'));
62
63            // did we get an Adora Belle Mailer object?
64            if(isset($event->data['mail']) && is_a($event->data['mail'],'Mailer')){
65                // we'd need to call cleanHeaders() here, but it's protected in Adora Belle.
66                // instead we call the dump() method which will call cleanHeaders for us
67                if(is_callable(array($event->data['mail'],'cleanHeaders()'))){
68                    $event->data['mail']->cleanHeaders();
69                }else{
70                    $event->data['mail']->dump();
71                }
72            }
73
74            // prepare message (Swift autodetects UTF-8)
75            $message =& new Swift_Message($event->data['subject'], $event->data['body']);
76
77            // handle the recipients (duplicates some code from mail_encode_address)
78            $reci =& new Swift_RecipientList();
79            $from = null;
80            $num  = 0;
81            foreach(array('to','cc','bcc','from') as $hdr){
82                $parts = explode(',',$event->data[$hdr]);
83                foreach ($parts as $part){
84                    $part = trim($part);
85
86                    // parse address
87                    if(preg_match('#(.*?)<(.*?)>#',$part,$matches)){
88                        $text = trim($matches[1]);
89                        $addr = $matches[2];
90                    }else{
91                        $addr = $part;
92                    }
93
94                    // skip empty ones
95                    if(empty($addr)) continue;
96
97                    // add
98                    if($hdr == 'from'){
99                        $from =& new Swift_Address($addr,$text);
100                    }else{
101                        if($hdr == 'to' || $hdr == 'cc') $num++;
102                        if($hdr == 'bcc' && $num == 0){
103                            // no to and cc - add bcc as to and send as batch later
104                            $reci->add($addr,$text,'to');
105                        }else{
106                            $reci->add($addr,$text,$hdr);
107                        }
108                    }
109                }
110            }
111
112            // now finally send the mail
113            if($num){
114                $ok = $swift->send($message, $reci, $from);
115            }else{
116                $ok = $swift->batchSend($message, $reci, $from);
117            }
118        } catch (Swift_ConnectionException $e) {
119            msg('There was a problem communicating with SMTP: '.$e->getMessage(),-1);
120        } catch (Swift_Message_MimeException $e) {
121            msg('There was an unexpected problem building the email: '.$e->getMessage(),-1);
122        } catch(Exception $e){
123            msg('There was an unexpected problem with sending the email: '.$e->getMessage(),-1);
124        }
125
126        if(!$ok && $this->getConf('debug')){
127            $dbglog = $log->dump(true);
128            $dbglog = preg_replace('/(AUTH \w+ ).*$/m','\\1 ***',$dbglog); //filter out passwords
129            $dbglog = preg_replace('/(PASS ).*$/m','\\1 ***',$dbglog); //filter out passwords
130            msg('SwiftMailer log:<br /><pre>'.hsc($dbglog).'</pre>',-1);
131        }
132
133        $event->preventDefault();
134        $event->stopPropagation();
135        $event->result = $ok;
136        $event->data['success'] = $ok;
137    }
138}
139
140