forked from e107inc/e107
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpop_bounce_handler.php
301 lines (264 loc) · 7.41 KB
/
pop_bounce_handler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
<?php
/*
* e107 website system
*
* Copyright (C) 2008-2009 e107 Inc (e107.org)
* Released under the terms and conditions of the
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
*
* Bounce handler for cron or manual triggering
*
* $Source: /cvs_backup/e107_0.8/e107_handlers/pop_bounce_handler.php,v $
* $Revision$
* $Date$
* $Author$
*/
/*
This handler is intended for use with a cron job, or with manual triggering, to get bounce notifications from a POP3 or IMAP account.
It extends the receiveMail class (pop3_class.php) to provide some higher level methods.
Can be used for getting mail from any POP3 mail account.
Some parts used from/based on the receiveMail class, by Mitul Koradia (Email: [email protected], Cell : +91 9879697592)
Notes:
1. Requires that the IMAP extension is installed
2. Mailbox names that contain international characters besides those in the printable ASCII space have to be encoded width imap_utf7_encode().
*/
/**
*
*/
class pop3BounceHandler
{
protected $e107;
protected $server=''; // String to connect to server
protected $username='';
protected $password='';
protected $email=''; // Email address receiving bounces
protected $delBounce = FALSE; // TRUE to delete emails after reading
protected $mailResource = ''; // Resource identifier for IMAP
protected $mailManager = FALSE;
/**
* @param $override
*/
public function __construct($override = FALSE)
{
global $pref;
$this->e107 = e107::getInstance();
if (($override === FALSE) || !is_array($override))
{ // Set up from prefs
$override['mail_bounce_user'] = $pref['mail_bounce_user'];
$override['mail_bounce_pass'] = $pref['mail_bounce_pass'];
$override['mail_bounce_email'] = $pref['mail_bounce_email'];
$override['mail_bounce_pop3'] = $pref['mail_bounce_pop3'];
$override['mail_bounce_type'] = varset($pref['mail_bounce_type'],'pop3');
}
if($override['mail_bounce_type']=='imap')
{
$port = varset($override['mail_bounce_port'], '143');
$strConnect='{'.$override['mail_bounce_pop3'].':'.$port. '}INBOX';
}
else
{
$port = varset($override['mail_bounce_port'], '110'); // POP3 port
$servertype = '/'.varset($override['mail_bounce_type'], 'pop3');
$strConnect='{'.$override['mail_bounce_pop3'].':'.$port. $servertype.'}INBOX';
}
$this->server = $strConnect;
$this->username = $override['mail_bounce_user'];
$this->password = $override['mail_bounce_pass'];
$this->email = $override['mail_bounce_email'];
$this->delBounce = ($pref['mail_bounce_delete']) ? true : false;
}
/**
* @return void
*/
function connect() //Connect To the Mail Box
{
$this->mailResource=imap_open($this->server,$this->username,$this->password);
}
/**
* @return int
*/
function getTotalMails() //Get Total Number off Unread Email In Mailbox
{
$headers=imap_headers($this->mailResource);
return count($headers);
}
/**
* @param $mid
* @return array
*/
function getHeaders($mid) // Get Header info
{
$mail_header=imap_header($this->mailResource,$mid);
$sender=$mail_header->from[0];
$sender_replyto=$mail_header->reply_to[0];
$stat = !(strtolower($sender->mailbox) != 'mailer-daemon' && strtolower($sender->mailbox) != 'postmaster');
if(strpos($mail_header->subject,"delayed"))
{
$stat = FALSE;
}
$mail_details=array(
'from'=>strtolower($sender->mailbox).'@'.$sender->host,
'fromName'=>$sender->personal,
'toOth'=>strtolower($sender_replyto->mailbox).'@'.$sender_replyto->host,
'toNameOth'=>$sender_replyto->personal,
'subject'=>$mail_header->subject,
'to'=>strtolower($mail_header->toaddress),
'bounce'=>$stat,
'date'=>$mail_header->date
);
return $mail_details;
}
/**
* @param $structure
* @return string
*/
protected function get_mime_type(&$structure) //Get Mime type Internal Private Use
{
$primary_mime_type = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
if($structure->subtype)
{
return $primary_mime_type[(int) $structure->type] . '/' . $structure->subtype;
}
return "TEXT/PLAIN";
}
/**
* @param $stream
* @param $msg_number
* @param $mime_type
* @param $structure
* @param $part_number
* @return false|string
*/
protected function get_part($stream, $msg_number, $mime_type, $structure = false, $part_number = false) //Get Part Of Message Internal Private Use
{
if(!$structure)
{
$structure = imap_fetchstructure($stream, $msg_number);
}
if($structure)
{
if($mime_type == $this->get_mime_type($structure))
{
if(!$part_number)
{
$part_number = '1';
}
$text = imap_fetchbody($stream, $msg_number, $part_number);
if($structure->encoding == 3)
{
return imap_base64($text);
}
else if($structure->encoding == 4)
{
return imap_qprint($text);
}
else
{
return $text;
}
}
if($structure->type == 1) /* multipart */
{
foreach($structure->parts as $index => $sub_structure)
{
if($part_number)
{
$prefix = $part_number . '.';
}
$data = $this->get_part($stream, $msg_number, $mime_type, $sub_structure, $prefix . ($index + 1));
if($data)
{
return $data;
}
}
}
}
return false;
}
/**
* @param $mid
* @param $mode
* @return false|string
*/
function getBody($mid, $mode='') // Get Message Body
{
if($mode != 'plain')
{
$body = $this->get_part($this->mailResource, $mid, 'TEXT/HTML');
}
if (($body == '') || $mode == 'plain')
{
$body = $this->get_part($this->mailResource, $mid, 'TEXT/PLAIN');
}
if ($body == '')
{
return '';
}
return $body;
}
/**
* @param $mid
* @return void
*/
function deleteMails($mid) // Delete That Mail
{
imap_delete($this->mailResource,$mid);
}
/**
* @return void
*/
function close_mailbox() //Close Mail Box
{
imap_close($this->mailResource,CL_EXPUNGE);
}
/**
* Loop reading all emails from the bounces mailbox. If an email address and/or e107 header are
* identified, process the bounce.
* Delete all emails after processing, if $pref flag is set.
*
* @return void
*/
public function processBounces()
{
$identifier = deftrue('MAIL_IDENTIFIER', 'X-e107-id');
$this->connect();
$tot = $this->getTotalMails(); // Get all the emails
for ($i = 1; $i <= $tot; $i++)
{
$head = $this->getHeaders($i); // Get the headers
if ($head['bounce'])
{
//print_a($head);
$body = $this->getBody($i);
$e107Header = '';
if (preg_match('#.*'.$identifier.':(.*?)[\n\r]#',$body, $result))
{
$e107Header = varset($result[1],'');
}
$emailAddress = '';
if (preg_match("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i",$body,$result))
{
$emailAddress = varset($result[0],'');
if ($emailAddress == $this->email)
{
$emailAddress = ''; // Email address found is that of the bounce email account
}
}
// Call the bounce handler here
if ($this->mailManager === FALSE)
{
require_once(e_HANDLER.'mail_manager_class.php');
$this->mailManager = new e107MailManager();
}
echo "Email: {$emailAddress}<br />Header: {$e107Header}<br />";
$this->mailManager->markBounce($e107Header, $emailAddress);
}
// Now delete the email, if option set (do it regardless of whether a bounce email)
if ($this->delBounce)
{
$this->deleteMails($i); // Not actually deleted until we close the mailbox
}
}
$this->close_mailbox();
}
}