WYSIJA_help_bounce

The MailPoet Newsletters WYSIJA help bounce class.

Defined (1)

The class is defined in the following location(s).

/helpers/bounce.php  
  1. class WYSIJA_help_bounce extends WYSIJA_help { 
  2.  
  3. var $report = false; 
  4. var $config; 
  5. var $mailer; 
  6. var $mailbox; 
  7. var $_message; 
  8. var $listsubClass; 
  9. var $subClass; 
  10. var $db; 
  11. var $deletedUsers = array(); 
  12. var $unsubscribedUsers = array(); 
  13. var $addtolistUsers = array(); 
  14. var $bounceMessages = array(); 
  15. var $listdetails = array(); 
  16. var $usepear = false; 
  17. var $detectEmail = '/[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@([a-z0-9\-]+\.)+[a-z0-9]{2, 8}/i'; 
  18. var $messages = array(); 
  19. var $record_ms_bounce = false; // only used in multisite scenario 
  20.  
  21. function __construct() { 
  22. $this->config = WYSIJA::get('config', 'model'); 
  23. $this->mailer = WYSIJA::get('mailer', 'helper'); 
  24. $this->rulesClass = WYSIJA::get('rules', 'helper'); 
  25. $this->mailer->report = false; 
  26. $this->subClass = WYSIJA::get('user', 'model'); //acymailing_get('class.subscriber'); 
  27. $this->listsubClass = WYSIJA::get('user_list', 'model'); //acymailing_get('class.listsub'); 
  28. $this->listsubClass->checkAccess = false; 
  29. $this->listsubClass->sendNotif = false; 
  30. $this->listsubClass->sendConf = false; 
  31. $this->historyClass = WYSIJA::get('user_history', 'model'); 
  32.  
  33. function init($config = false) { 
  34. if ($config) { 
  35. //unset($this->config->values); 
  36. foreach ($config as $key => $val) 
  37. $this->config->values[$key] = $val; 
  38. if ($this->config->getValue('bounce_connection_method') == 'pear') { 
  39. $this->usepear = true; 
  40. include_once(WYSIJA_INC . 'pear' . DS . 'pop3.php'); 
  41. return true; 
  42.  
  43. if (extension_loaded('imap') OR function_exists('imap_open')) 
  44. return true; 
  45.  
  46. $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : ''; 
  47. $EXTENSION = $prefix . 'imap.' . PHP_SHLIB_SUFFIX; 
  48.  
  49. if (function_exists('dl')) { 
  50. //We will try to load it on the fly 
  51. $fatalMessage = 'The system tried to load dynamically the ' . $EXTENSION . ' extension'; 
  52. $fatalMessage .= '<br/>If you see this message, that means the system could not load this PHP extension'; 
  53. $fatalMessage .= '<br/>Please enable the PHP Extension ' . $EXTENSION; 
  54. ob_start(); 
  55. echo $fatalMessage; 
  56. //This method could cause a fatal error, but we will still display some messages in that case. 
  57. dl($EXTENSION); 
  58. $warnings = str_replace($fatalMessage, '', ob_get_clean()); 
  59. if (extension_loaded('imap') OR function_exists('imap_open')) 
  60. return true; 
  61.  
  62. if ($this->report) { 
  63. $this->error('The extension "' . $EXTENSION . '" could not be loaded, please change your PHP configuration to enable it or use the pop3 method without imap extension', true); 
  64. if (!empty($warnings)) 
  65. $this->error($warnings, true); 
  66.  
  67. return false; 
  68.  
  69. function connect() { 
  70. if ($this->usepear) 
  71. return $this->_connectpear(); 
  72. return $this->_connectimap(); 
  73.  
  74. function _connectpear() { 
  75. ob_start(); 
  76. $this->mailbox = new Net_POP3(); 
  77.  
  78. $timeout = $this->config->getValue('bounce_timeout'); 
  79. if (!empty($timeout)) 
  80. $this->mailbox->setTimeOut($timeout); 
  81.  
  82. $port = intval($this->config->getValue('bounce_port', '')); 
  83. if (empty($port)) 
  84. $port = '110/pop3/notls'; 
  85.  
  86. $serverName = $this->config->getValue('bounce_host'); 
  87. $secure = $this->config->getValue('bounce_connection_secure', ''); 
  88. //We don't add back the ssl:// or tls:// if it's already there 
  89. if (!empty($secure) AND !strpos($serverName, '://')) 
  90. $serverName = $secure . '://' . $serverName; 
  91.  
  92. if (!$this->mailbox->connect($serverName, $port)) { 
  93. $warnings = ob_get_clean(); 
  94. if ($this->report) { 
  95. $this->error('Error connecting to the server ' . $this->config->getValue('bounce_host') . ' : ' . $port, true); 
  96. return false; 
  97. if (!empty($warnings) AND $this->report) 
  98. $this->error($warnings, true); 
  99. return false; 
  100.  
  101. $login = $this->mailbox->login(trim($this->config->getValue('bounce_login')), trim($this->config->getValue('bounce_password')), 'USER'); 
  102. if (empty($login) OR isset($login->code)) { 
  103. $warnings = ob_get_clean(); 
  104. if ($this->report) { 
  105. $this->error('Identication error ' . $this->config->getValue('bounce_login') . ':' . $this->config->getValue('bounce_password'), true); 
  106. return false; 
  107. if (!empty($warnings) AND $this->report) 
  108. $this->error($warnings, true); 
  109. return false; 
  110.  
  111. ob_clean(); 
  112.  
  113. return true; 
  114.  
  115. function _connectimap() { 
  116. ob_start(); 
  117. //First we reset the buffer or errors and warnings 
  118. $buff = imap_alerts(); 
  119. $buff = imap_errors(); 
  120.  
  121. $timeout = $this->config->getValue('bounce_timeout'); 
  122. if (!empty($timeout)) 
  123. imap_timeout(IMAP_OPENTIMEOUT, $timeout); 
  124.  
  125. $port = $this->config->getValue('bounce_port', ''); 
  126. $secure = $this->config->getValue('bounce_connection_secure', ''); 
  127. $protocol = $this->config->getValue('bounce_connection_method', ''); 
  128. $serverName = '{' . $this->config->getValue('bounce_host'); 
  129. if (empty($port)) { 
  130. if ($secure == 'ssl' && $protocol == 'imap') 
  131. $port = '993'; 
  132. elseif ($protocol == 'imap') 
  133. $port = '143'; 
  134. elseif ($protocol == 'pop3') 
  135. $port = '110'; 
  136.  
  137.  
  138. if (!empty($port)) 
  139. $serverName .= ':' . $port; 
  140. //Add the secure protocol (TLS or SSL) 
  141. if (!empty($secure)) 
  142. $serverName .= '/' . $secure; 
  143. if ($this->config->getValue('bounce_selfsigned', false)) 
  144. $serverName .= '/novalidate-cert'; 
  145. //Add the method (imap by default) ex : pop3 
  146. if (!empty($protocol)) 
  147. $serverName .='/service=' . $protocol; 
  148. $serverName .= '}'; 
  149. $this->mailbox = imap_open($serverName, trim($this->config->getValue('bounce_login')), trim($this->config->getValue('bounce_password'))); 
  150. $warnings = ob_get_clean(); 
  151.  
  152. if ($this->report) { 
  153. if (!$this->mailbox) { 
  154. $this->error('Error connecting to ' . $serverName, true); 
  155. if (!empty($warnings)) { 
  156. $this->error($warnings, true); 
  157.  
  158.  
  159. return $this->mailbox ? true : false; 
  160.  
  161. function getNBMessages() { 
  162. if ($this->usepear) { 
  163. $this->nbMessages = $this->mailbox->numMsg(); 
  164. } else { 
  165. $this->nbMessages = imap_num_msg($this->mailbox); 
  166.  
  167. return $this->nbMessages; 
  168.  
  169. function getMessage($msgNB) { 
  170. if ($this->usepear) { 
  171. $message = new \stdClass; 
  172. $message->headerString = $this->mailbox->getRawHeaders($msgNB); 
  173. if (empty($message->headerString)) 
  174. return false; 
  175. }else { 
  176. $message = imap_headerinfo($this->mailbox, $msgNB); 
  177.  
  178. return $message; 
  179.  
  180. function deleteMessage($msgNB) { 
  181. if ($this->usepear) { 
  182. $this->mailbox->deleteMsg($msgNB); 
  183. } else { 
  184. imap_delete($this->mailbox, $msgNB); 
  185. imap_expunge($this->mailbox); 
  186.  
  187. function close() { 
  188. if ($this->usepear) { 
  189. $this->mailbox->disconnect(); 
  190. } else { 
  191. imap_close($this->mailbox); 
  192.  
  193. function decodeMessage() { 
  194. if ($this->usepear) { 
  195. return $this->_decodeMessagepear(); 
  196. } else { 
  197. return $this->_decodeMessageimap(); 
  198.  
  199. function _decodeMessagepear() { 
  200. $this->_message->headerinfo = $this->mailbox->getParsedHeaders($this->_message->messageNB); 
  201.  
  202. if (empty($this->_message->headerinfo['subject'])) 
  203. return false; 
  204. $this->_message->text = ''; 
  205. $this->_message->html = $this->mailbox->getBody($this->_message->messageNB); 
  206. $this->_message->subject = $this->_decodeHeader($this->_message->headerinfo['subject']); 
  207. $this->_message->header->sender_email = (isset($this->_message->headerinfo['return-path'])) ? $this->_message->headerinfo['return-path'] : ''; 
  208. if (is_array($this->_message->header->sender_email)) 
  209. $this->_message->header->sender_email = reset($this->_message->header->sender_email); 
  210. if (preg_match($this->detectEmail, $this->_message->header->sender_email, $results)) { 
  211. $this->_message->header->sender_email = $results[0]; 
  212. $this->_message->header->sender_name = (isset($this->_message->headerinfo['from'])) ? strip_tags(@$this->_message->headerinfo['from']) : ''; 
  213. $this->_message->header->reply_to_email = $this->_message->header->sender_email; 
  214. $this->_message->header->reply_to_name = (property_exists($this->_message->header, 'sender_name')) ? $this->_message->header->sender_name : ''; 
  215. $this->_message->header->from_email = $this->_message->header->sender_email; 
  216. $this->_message->header->from_name = $this->_message->header->reply_to_name; 
  217.  
  218. return true; 
  219.  
  220. function _decodeMessageimap() { 
  221. $this->_message->structure = imap_fetchstructure($this->mailbox, $this->_message->messageNB); 
  222. if (empty($this->_message->structure)) 
  223. return false; 
  224. $this->_message->headerinfo = imap_fetchheader($this->mailbox, $this->_message->messageNB); 
  225. $this->_message->html = ''; 
  226. $this->_message->text = ''; 
  227.  
  228. //Multipart message : type == 1 
  229. if ($this->_message->structure->type == 1) { 
  230. $this->_message->contentType = 2; 
  231. $allParts = $this->_explodeBody($this->_message->structure); 
  232.  
  233. $this->_message->text = ''; 
  234. foreach ($allParts as $num => $onePart) { 
  235. $charset = $this->_getMailParam($onePart, 'charset'); 
  236. if ($onePart->subtype == 'HTML') { 
  237. $this->_message->html = $this->_decodeContent(imap_fetchbody($this->mailbox, $this->_message->messageNB, $num), $onePart); 
  238. } else { 
  239. $this->_message->text .= $this->_decodeContent(imap_fetchbody($this->mailbox, $this->_message->messageNB, $num), $onePart) . "\n\n- - -\n\n"; 
  240. } else { 
  241. $charset = $this->_getMailParam($this->_message->structure, 'charset'); 
  242. if ($this->_message->structure->subtype == 'HTML') { 
  243. $this->_message->contentType = 1; 
  244. $this->_message->html = $this->_decodeContent(imap_body($this->mailbox, $this->_message->messageNB), $this->_message->structure); 
  245. } else { 
  246. $this->_message->contentType = 0; 
  247. $this->_message->text = $this->_decodeContent(imap_body($this->mailbox, $this->_message->messageNB), $this->_message->structure); 
  248.  
  249. //Decode the subject 
  250. $this->_message->subject = $this->_decodeHeader($this->_message->subject); 
  251.  
  252. $this->_decodeAddressimap('sender'); 
  253. $this->_decodeAddressimap('from'); 
  254. $this->_decodeAddressimap('reply_to'); 
  255. $this->_decodeAddressimap('to'); 
  256. return true; 
  257.  
  258. function handleMessages() { 
  259. $model_list = WYSIJA::get('list', 'model'); 
  260.  
  261. $listdetails = $model_list->getRows(array('name', 'list_id')); 
  262.  
  263. foreach ($listdetails as $listinfo) { 
  264. $this->listdetails[$listinfo['list_id']] = $listinfo['name']; 
  265. $maxMessages = min($this->nbMessages, $this->config->getValue('bounce_max', 100)); 
  266. if (empty($maxMessages)) 
  267. $maxMessages = $this->nbMessages; 
  268.  
  269. // we need a report when we are handling the bounce manually through the settings 
  270. if ($this->report) { 
  271. // If we display informations, we directy flush so that we can display in real time! 
  272. if (!headers_sent() AND ob_get_level() > 0) { 
  273. ob_end_flush(); 
  274.  
  275. // We prepare the area where we will add informations... 
  276. $disp = '<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" />'; 
  277. $disp .= '<title>' . addslashes(__('Bounce Handling', WYSIJA)) . '</title>'; 
  278. $disp .= '<style>body{font-size:12px;font-family: Arial, Helvetica, sans-serif;} strong{color: black;}</style></head><body>'; 
  279. $disp .= "<div style='position:relative; top:3px;left:3px;'>"; 
  280. $disp .= __("Bounce Handling", WYSIJA); 
  281. $disp .= ': <span id="counter"/>0</span> / ' . $maxMessages; 
  282. $disp .= '</div>'; 
  283. $disp .= '<br/>'; 
  284. $disp .= '<script type="text/javascript" language="javascript">'; 
  285. $disp .= 'var mycounter = document.getElementById("counter");'; 
  286. $disp .= 'function setCounter(val) { mycounter.innerHTML=val;}'; 
  287. $disp .= '</script>'; 
  288. echo $disp; 
  289. if (function_exists('ob_flush')) 
  290. @ob_flush(); 
  291. @flush(); 
  292.  
  293. //We load all published the rules 
  294. $rules = $this->rulesClass->getRules(); 
  295.  
  296. $msgNB = $maxMessages; 
  297. $listClass = WYSIJA::get('list', 'model'); 
  298. $this->allLists = $listClass->getRows(); 
  299.  
  300. while (($msgNB > 0) && ($this->_message = $this->getMessage($msgNB))) { 
  301. if ($this->report) { 
  302. echo '<script type="text/javascript" language="javascript">setCounter(' . ($maxMessages - $msgNB + 1) . ')</script>'; 
  303. if (function_exists('ob_flush')) 
  304. @ob_flush(); 
  305. @flush(); 
  306. $this->_message->messageNB = $msgNB; 
  307. $this->decodeMessage(); 
  308.  
  309. $msgNB--; 
  310. if (empty($this->_message->subject)) 
  311. continue; 
  312.  
  313. $this->_message->analyseText = $this->_message->html . ' ' . $this->_message->text; 
  314. $this->_display('<strong>' . __('Subject', WYSIJA) . ' : ' . strip_tags($this->_message->subject) . '</strong>', false, $maxMessages - $this->_message->messageNB + 1); 
  315.  
  316. // Identify the user and the e-mail... there is not the same info when it is a multisite or not 
  317. $email_identifiers = array(); 
  318. if ($this->record_ms_bounce) { 
  319. preg_match('#WY([0-9]+)SI([0-9]+)JA([0-9]+)MS#i', $this->_message->analyseText, $email_identifiers); 
  320. if (!empty($email_identifiers[1])) 
  321. $this->_message->user_id = $email_identifiers[1]; 
  322. if (!empty($email_identifiers[2])) 
  323. $this->_message->email_id = $email_identifiers[2]; 
  324. if (!empty($email_identifiers[3])) 
  325. $this->_message->site_id = $email_identifiers[3]; 
  326. }else { 
  327. preg_match('#WY([0-9]+)SI([0-9]+)JA#i', $this->_message->analyseText, $email_identifiers); 
  328. if (!empty($email_identifiers[1])) 
  329. $this->_message->user_id = $email_identifiers[1]; 
  330. if (!empty($email_identifiers[2])) 
  331. $this->_message->email_id = $email_identifiers[2]; 
  332.  
  333. // if we don't have the user_id set then we need to find the user_id differently 
  334. if (empty($this->_message->user_id)) { 
  335. // We will need the e-mail itself in that case... :p 
  336. $emails_detected_in_the_email = array(); 
  337. preg_match_all($this->detectEmail, $this->_message->analyseText, $emails_detected_in_the_email); 
  338. $reply_email = $this->config->getValue('reply_email'); 
  339. $from_email = $this->config->getValue('from_email'); 
  340. $bounce_email = $this->config->getValue('bounce_email'); 
  341. $remove_emails = '#(' . str_replace(array('%'), array('@'), $this->config->getValue('bounce_login')); 
  342. if (!empty($bounce_email)) 
  343. $remove_emails .= '|' . $bounce_email; 
  344. if (!empty($from_email)) 
  345. $remove_emails .= '|' . $from_email; 
  346. if (!empty($reply_email)) 
  347. $remove_emails .= '|' . $reply_email; 
  348. $remove_emails .= ')#i'; 
  349. if (!empty($emails_detected_in_the_email[0])) { 
  350. $email_already_checked = array(); 
  351. foreach ($emails_detected_in_the_email[0] as $detected_email) { 
  352. // We will find the e-mail if it's not in the list of incorrect e-mail addresses 
  353. if (!preg_match($remove_emails, $detected_email)) { 
  354. // We will keep this one, so we make sure it's strtolower 
  355. $this->_message->subemail = strtolower($detected_email); 
  356. // We already checked this e-mail address... no need to try it a second time 
  357. if (!empty($email_already_checked[$this->_message->subemail])) 
  358. continue; 
  359. $this->subClass->getFormat = OBJECT; 
  360. $result = $this->subClass->getOne(array('user_id'), array('email' => $this->_message->subemail)); 
  361.  
  362. $this->_message->user_id = $result->user_id; 
  363. $email_already_checked[$this->_message->subemail] = true; 
  364. if (!empty($this->_message->user_id)) 
  365. break; 
  366.  
  367. // get the email_id if it is not set and the user_id has been found 
  368. if (empty($this->_message->email_id) && !empty($this->_message->user_id)) { 
  369. // We can check if we have a user and only one e-mail sent for this user, it's obviously the e-mail we just sent!! 
  370. $modelEUS = WYSIJA::get('email_user_stat', 'model'); 
  371. $emailres = $modelEUS->query('get_row', 'SELECT `email_id` FROM [wysija]' . $modelEUS->table_name . ' WHERE `user_id` = ' . (int) $this->_message->user_id . ' ORDER BY `sent_at` DESC LIMIT 1'); 
  372. $this->_message->email_id = $emailres['email_id']; 
  373. //$this->_message->email_id = $this->db->loadResult(); 
  374.  
  375. foreach ($rules as $one_rule) { 
  376. //We stop as soon as we find a good rule... 
  377. if ($this->_handleRule($one_rule)) 
  378. break; 
  379.  
  380.  
  381. if ($msgNB % 50 == 0) { 
  382. if(!$this->record_ms_bounce) $this->_sub_actions(); 
  383.  
  384. if(!$this->record_ms_bounce) $this->_sub_actions(); 
  385.  
  386. if ($this->report) { 
  387. //We need to finish the current page properly 
  388. echo '</body></html>'; 
  389.  
  390.  
  391. /** 
  392. * take action on the subscribers based on what data we gathered in the processing part earlier 
  393. */ 
  394. function _sub_actions() { 
  395.  
  396. // the action is about deleting users 
  397. if (!empty($this->deletedUsers)) { 
  398. $this->subClass->testdelete = true; 
  399. $helper_user = WYSIJA::get('user', 'helper'); 
  400. $helper_user->delete($this->deletedUsers); 
  401. $this->deletedUsers = array(); 
  402.  
  403. if (!empty($this->unsubscribedUsers)) { 
  404. //unsubscribe user 
  405. $user_helper = WYSIJA::get('user', 'helper'); 
  406. if (!is_array($this->unsubscribedUsers)) $this->unsubscribedUsers=array($this->unsubscribedUsers); 
  407.  
  408. foreach ($this->unsubscribedUsers as $unsub_user_id) { 
  409. $user_helper->unsubscribe($unsub_user_id, true); 
  410.  
  411. $this->unsubscribedUsers = array(); 
  412.  
  413. if (!empty($this->addtolistUsers)) { 
  414. //unsubscribe user 
  415. $user_helper = WYSIJA::get('user', 'helper'); 
  416. foreach ($this->addtolistUsers as $listid => $user_ids) { 
  417. $user_helper->addToList($listid, $user_ids); 
  418.  
  419. $this->addtolistUsers = array(); 
  420.  
  421. if (!empty($this->bounceMessages)) { 
  422. foreach ($this->bounceMessages as $email_id => $bouncedata) { 
  423. if (!empty($bouncedata['user_id'])) { 
  424. //flag email has bounced 
  425. $modelEUS = WYSIJA::get('email_user_stat', 'model'); 
  426. $modelEUS->update(array('status' => -1), array('user_id' => $bouncedata['user_id'], 'email_id' => (int) $email_id)); 
  427. /** $this->db->setQuery('UPDATE '.acymailing_table('userstats').' SET `bounce` = `bounce` + 1 WHERE `user_id` IN ('.implode(', ', $bouncedata['user_id']).') AND `email_id` = '.(int) $email_id); 
  428. $this->db->query(); */ 
  429. $this->bounceMessages = array(); 
  430.  
  431.  
  432.  
  433.  
  434. function _handleRule(&$one_rule) { 
  435.  
  436. $regex = $one_rule['regex']; 
  437. if (empty($regex)) 
  438. return false; 
  439.  
  440. //Do it based on the config of the rule... 
  441.  
  442. $analyse_text = ''; 
  443. if (isset($one_rule['executed_on']['senderinfo'])) 
  444. $analyse_text .= ' ' . $this->_message->header->sender_name . $this->_message->header->sender_email; 
  445. if (isset($one_rule['executed_on']['subject'])) 
  446. $analyse_text .= ' ' . $this->_message->subject; 
  447. if (isset($one_rule['executed_on']['body'])) { 
  448. if (!empty($this->_message->html)) 
  449. $analyse_text .= ' ' . $this->_message->html; 
  450. if (!empty($this->_message->text)) 
  451. $analyse_text .= ' ' . $this->_message->text; 
  452.  
  453. //regex multilines 
  454. if (!preg_match('#' . $regex . '#is', $analyse_text)) 
  455. return false; 
  456.  
  457. $message = $one_rule['name']; 
  458.  
  459. if($this->record_ms_bounce) { 
  460. // no need for user action in multisite because we'll do it per site in a second process 
  461. $message .= $this->_action_message_ms($one_rule); 
  462. }else{ 
  463. $message .= $this->_action_user($one_rule); 
  464. $message .= $this->_action_message($one_rule); 
  465.  
  466.  
  467. $this->_display($message, true); 
  468.  
  469. return true; 
  470.  
  471. function _action_user(&$one_rule) { 
  472. $message = ''; 
  473.  
  474. if (empty($this->_message->user_id)) { 
  475. $message .= 'user not identified'; 
  476. if (!empty($this->_message->subemail)) 
  477. $message .= ' ( ' . $this->_message->subemail . ' ) '; 
  478. return $message; 
  479.  
  480. if (isset($one_rule['action_user']) && in_array($one_rule['action_user'], array('unsub'))) { 
  481. if (empty($this->_message->subemail)) { 
  482. $currentUser = $this->subClass->getObject($this->_message->user_id); 
  483. if (!empty($currentUser->email)) 
  484. $this->_message->subemail = $currentUser->email; 
  485.  
  486. if (empty($this->_message->subemail)) 
  487. $this->_message->subemail = $this->_message->user_id; 
  488.  
  489. //let's handle some actions on the subscriber first 
  490. if (isset($one_rule['action_user_stats'])) { 
  491. //handle this rule in the stats 
  492. if (!empty($this->_message->email_id)) { 
  493. if (empty($this->bounceMessages[$this->_message->email_id]['nbbounces'])) { 
  494. $this->bounceMessages[$this->_message->email_id] = array(); 
  495. $this->bounceMessages[$this->_message->email_id]['nbbounces'] = 1; 
  496. } else { 
  497. $this->bounceMessages[$this->_message->email_id]['nbbounces']++; 
  498.  
  499. if (!empty($this->_message->user_id) AND ((isset($one_rule['action_user']) && $one_rule['action_user'] != 'delete') || !isset($one_rule['action_user']) )) { 
  500. //Increment the bounce number in the user stat table but only if we don't delete the subscriber 
  501. $this->bounceMessages[$this->_message->email_id]['user_id'][] = intval($this->_message->user_id); 
  502.  
  503.  
  504. //Make sure we have enough messages to really execute this 
  505. if (!empty($one_rule['action_user_min']) && $one_rule['action_user_min'] > 1) { 
  506. //Let's load the number of bounces the user has and then exit or not... 
  507. $modelEUS = WYSIJA::get('email_user_stat', 'model'); 
  508. $res = $modelEUS->query('get_row', 'SELECT COUNT(email_id) as count FROM [wysija]' . $modelEUS->table_name . ' WHERE status = -1 AND user_id = ' . $this->_message->user_id); 
  509. $nb = intval($res['count']) + 1; 
  510.  
  511. if ($nb < $one_rule['action_user_min']) { 
  512. $message .= ', ' . sprintf(__('We received %1$s messages from the user %2$s', WYSIJA), $nb, $this->_message->subemail) . ', ' . sprintf(__('Actions will be executed after %1$s messages', WYSIJA), $one_rule['action_user_min']); 
  513. return $message; 
  514.  
  515. //IN WYSIJA THERE ARE 3 POSSIBILITIES 
  516. //1-Delete user 
  517. //2-Unsubscribe user 
  518. //3-Unsubscribe and attach to list "xxx" 
  519. if (isset($one_rule['action_user'])) { 
  520. switch ($one_rule['action_user']) { 
  521. case 'delete'://1 -Delete user 
  522. $message .= ', user ' . $this->_message->subemail . ' deleted'; 
  523. $this->deletedUsers[] = intval($this->_message->user_id); 
  524.  
  525. break; 
  526. case 'unsub'://2-Unsubscribe user 
  527. //when we unsubscribe somebody automatically we set the status to -2 instead of -1 to make the difference 
  528. $message .= ', user ' . $this->_message->subemail . ' unsubscribed'; 
  529. $this->unsubscribedUsers[] = $this->_message->user_id; 
  530.  
  531. break; 
  532. default: 
  533. //3 - Unsubscribe user and add to list 
  534. if (strpos($one_rule['action_user'], 'unsub_') !== false) { 
  535. $listid = (int) str_replace('unsub_', '', $one_rule['action_user']); 
  536. $message .= ', user ' . $this->_message->subemail . ' unsubscribed'; 
  537. $this->unsubscribedUsers[] = $this->_message->user_id; 
  538. $this->addtolistUsers[$listid][] = $this->_message->user_id; 
  539. $message .= ', user ' . $this->_message->subemail . ' added to list "' . $this->listdetails[$listid] . '"'; 
  540.  
  541.  
  542.  
  543.  
  544.  
  545. return $message; 
  546.  
  547. function _action_message(&$one_rule) { 
  548.  
  549. $message = ''; 
  550.  
  551. //Handle actions on the message itself 
  552.  
  553. if (isset($one_rule['action_message']['save']) && !empty($this->_message->user_id)) { 
  554. //We have a user_id, should we save the message in the database? 
  555. $data = array(); 
  556. $data[] = 'SUBJECT::' . $this->_message->subject; 
  557.  
  558. if (!empty($this->_message->html)) 
  559. $data[] = 'HTML_VERSION::' . htmlentities($this->_message->html); 
  560. if (!empty($this->_message->text)) 
  561. $data[] = 'TEXT_VERSION::' . nl2br(htmlentities($this->_message->text)); 
  562. $this->_message->header->reply_to_name = (property_exists($this->_message->header, 'reply_to_name')) ? $this->_message->header->reply_to_name : ''; 
  563. $this->_message->header->from_name = (property_exists($this->_message->header, 'from_name')) ? $this->_message->header->from_name : ''; 
  564. $data[] = 'REPLYTO_ADDRESS::' . $this->_message->header->reply_to_name . ' ( ' . $this->_message->header->reply_to_email . ' )'; 
  565. $data[] = 'FROM_ADDRESS::' . $this->_message->header->from_name . ' ( ' . $this->_message->header->from_email . ' )'; 
  566. $data[] = print_r($this->_message->headerinfo, true); 
  567. $this->historyClass->insert($this->_message->user_id, 'bounce', $data, @$this->_message->email_id); 
  568. $message .= ', message saved (user ' . $this->_message->user_id . ')'; 
  569.  
  570. if (isset($one_rule['forward'])) { 
  571. if (isset($one_rule['action_message_forwardto']) && !empty($one_rule['action_message_forwardto']) && trim($one_rule['action_message_forwardto']) != trim($this->config->getValue('bounce_email'))) { 
  572. //Get the forward address : 
  573. $this->mailer->clearAll(); 
  574. $this->mailer->Subject = 'BOUNCE FORWARD : ' . $this->_message->subject; 
  575. $this->mailer->AddAddress($one_rule['action_message_forwardto']); 
  576. if (!empty($this->_message->html)) { 
  577. $this->mailer->IsHTML(true); 
  578. $this->mailer->Body = $this->_message->html; 
  579. if (!empty($this->_message->text)) 
  580. $this->mailer->Body .= '<br/><br/>-------<br/>' . nl2br($this->_message->text); 
  581. }else { 
  582. $this->mailer->IsHTML(false); 
  583. $this->mailer->Body = $this->_message->text; 
  584.  
  585. //We add all other extra information just in case of we could use them... 
  586. //original-rcpt-to ? http://tools.ietf.org/html/rfc5965 
  587. $this->mailer->Body .= print_r($this->_message->headerinfo, true); 
  588. $this->_message->header->reply_to_name = (property_exists($this->_message->header, 'reply_to_name')) ? $this->_message->header->reply_to_name : ''; 
  589. $this->_message->header->from_name = (property_exists($this->_message->header, 'from_name')) ? $this->_message->header->from_name : ''; 
  590. $this->mailer->AddReplyTo($this->_message->header->reply_to_email, $this->_message->header->reply_to_name); 
  591. $this->mailer->setFrom($this->_message->header->from_email, $this->_message->header->from_name); 
  592. if ($this->mailer->send()) { 
  593. $message .= ', forwarded to ' . $one_rule['action_message_forwardto']; 
  594. } else { 
  595. $message .= ', error forwarding to ' . $one_rule['action_message_forwardto']; 
  596.  
  597. } else { 
  598. //we dont delete the email if the forward email is not specified or if the bounce email is the same as the forward email 
  599. unset($one_rule['action_message']['delete']); 
  600.  
  601. if (isset($one_rule['action_message']['delete'])) { 
  602. $message .= ', message deleted'; 
  603. $this->deleteMessage($this->_message->messageNB); 
  604.  
  605. return $message; 
  606.  
  607. function _decodeAddressimap($type) { 
  608. $address = $type . 'address'; 
  609. $name = $type . '_name'; 
  610. $email = $type . '_email'; 
  611. if (empty($this->_message->$type)) 
  612. return false; 
  613.  
  614. $var = $this->_message->$type; 
  615.  
  616. if (!empty($this->_message->$address)) { 
  617. if(!isset($this->_message->header) || is_null($this->_message->header)) { 
  618. $this->_message->header = new stdClass(); 
  619. } else { 
  620. $this->_message->header->$name = $var[0]->personal; 
  621.  
  622. $this->_message->header->$email = $var[0]->mailbox . '@' . @$var[0]->host; 
  623. return true; 
  624.  
  625. /** 
  626. * If num is empty then it's a message otherwise it's a send statrus 
  627. */ 
  628. function _display($message, $status = '', $num = '') { 
  629. $this->messages[] = $message; 
  630.  
  631. if (!$this->report) 
  632. return; 
  633.  
  634. $color = $status ? 'black' : 'blue'; 
  635. if (!empty($num)) 
  636. echo '<br/>' . $num . ' : '; 
  637. else 
  638. echo '<br/>     '; 
  639.  
  640. echo '<font style="font-family: Arial;" color="' . $color . '">' . $message . '</font>'; 
  641. if (function_exists('ob_flush')) 
  642. @ob_flush(); 
  643. @flush(); 
  644.  
  645. function _decodeHeader($input) { 
  646. // Remove white space between encoded-words 
  647. $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); 
  648. $this->charset = false; 
  649.  
  650. // For each encoded-word... 
  651. while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { 
  652.  
  653. $encoded = $matches[1]; 
  654. $charset = $matches[2]; 
  655. $encoding = $matches[3]; 
  656. $text = $matches[4]; 
  657.  
  658. switch (strtolower($encoding)) { 
  659. case 'b': 
  660. $text = base64_decode($text); 
  661. break; 
  662.  
  663. case 'q': 
  664. $text = str_replace('_', ' ', $text); 
  665. preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); 
  666. foreach ($matches[1] as $value) 
  667. $text = str_replace('=' . $value, chr(hexdec($value)), $text); 
  668. break; 
  669. $this->charset = $charset; 
  670. $input = str_replace($encoded, $text, $input); 
  671.  
  672. return $input; 
  673.  
  674. function _explodeBody($struct, $path = "0", $inline = 0) { 
  675. $allParts = array(); 
  676.  
  677. if (empty($struct->parts)) 
  678. return $allParts; 
  679.  
  680. $c = 0; //counts real content 
  681. foreach ($struct->parts as $part) { 
  682. if ($part->type == 1) { 
  683. //There are more parts....: 
  684. if ($part->subtype == "MIXED") { //Mixed: 
  685. $path = $this->_incPath($path, 1); //refreshing current path 
  686. $newpath = $path . ".0"; //create a new path-id (ex.:2.0) 
  687. $allParts = array_merge($this->_explodeBody($part, $newpath), $allParts); //fetch new parts 
  688. } else { //Alternativ / rfc / signed 
  689. $newpath = $this->_incPath($path, 1); 
  690. $path = $this->_incPath($path, 1); 
  691. $allParts = array_merge($this->_explodeBody($part, $newpath, 1), $allParts); 
  692. } else { 
  693. $c++; 
  694. //creating new tree if this is part of a alternativ or rfc message: 
  695. if ($c == 1 && $inline) { 
  696. $path = $path . ".0"; 
  697. //saving content: 
  698. $path = $this->_incPath($path, 1); 
  699. //print "<br> Content ".$path."<br>"; //debug information 
  700. $allParts[$path] = $part; 
  701.  
  702. return $allParts; 
  703.  
  704. //Increases the Path to the parts: 
  705. function _incPath($path, $inc) { 
  706. $newpath = ""; 
  707. $path_elements = explode(".", $path); 
  708. $limit = count($path_elements); 
  709. for ($i = 0; $i < $limit; $i++) { 
  710. if ($i == $limit - 1) { //last element 
  711. $newpath .= $path_elements[$i] + $inc; // new Part-Number 
  712. } else { 
  713. $newpath .= $path_elements[$i] . "."; //rebuild "1.2.2"-Chronology 
  714. return $newpath; 
  715.  
  716. function _decodeContent($content, $structure) { 
  717. $encoding = $structure->encoding; 
  718.  
  719. //First we decode the content properly 
  720. if ($encoding == 2) 
  721. $content = imap_binary($content); 
  722. elseif ($encoding == 3) 
  723. $content = imap_base64($content); 
  724. elseif ($encoding == 4) 
  725. $content = imap_qprint($content); 
  726. //Other cases?? 
  727. //added for a client who had issue when message was base64 
  728. if(base64_decode($content, true)!==FALSE) 
  729. $content = base64_decode($content); 
  730.  
  731. //Now we convert into utf-8! 
  732. //$charset = $this->_getMailParam($structure, 'charset'); 
  733. // removes attachment to prevent bounce handling timeout 
  734. // 100 000 characters is plenty 
  735. return substr($content, 0, 100000); 
  736.  
  737. function _getMailParam($params, $name) { 
  738. $searchIn = array(); 
  739.  
  740. if ($params->ifparameters) 
  741. $searchIn = array_merge($searchIn, $params->parameters); 
  742. if ($params->ifdparameters) 
  743. $searchIn = array_merge($searchIn, $params->dparameters); 
  744.  
  745. if (empty($searchIn)) 
  746. return false; 
  747.  
  748. foreach ($searchIn as $num => $values) { 
  749. if (strtolower($values->attribute) == $name) { 
  750. return $values->value; 
  751.  
  752. function getErrors() { 
  753. $return = array(); 
  754. if ($this->usepear) { 
  755. //TODO : get some errors from the pear interface? 
  756. } else { 
  757. $alerts = imap_alerts(); 
  758. $errors = imap_errors(); 
  759. if (!empty($alerts)) 
  760. $return = array_merge($return, $alerts); 
  761. if (!empty($errors)) 
  762. $return = array_merge($return, $errors); 
  763.  
  764. return $return; 
  765.  
  766.  
  767.  
  768. /** 
  769. * simple function that launch a bounce process 
  770. * @return boolean 
  771. */ 
  772. function process_bounce() { 
  773.  
  774. @ini_set('max_execution_time', 0); 
  775.  
  776. $model_config = WYSIJA::get('config', 'model'); 
  777.  
  778. $this->report = true; 
  779. if (!$this->init()) { 
  780. $res['result'] = false; 
  781. return $res; 
  782. if (!$this->connect()) { 
  783. $this->error($this->getErrors()); 
  784. $res['result'] = false; 
  785. return $res; 
  786. $this->notice(sprintf(__('Successfully connected to %1$s'), $model_config->getValue('bounce_login'))); 
  787. $nbMessages = $this->getNBMessages(); 
  788.  
  789.  
  790. if (empty($nbMessages)) { 
  791. $this->error(__('There are no messages'), true); 
  792. $res['result'] = false; 
  793. return $res; 
  794. } else { 
  795. $this->notice(sprintf(__('There are %1$s messages in your mailbox'), $nbMessages)); 
  796.  
  797. $this->handleMessages(); 
  798.  
  799. $this->close(); 
  800.  
  801. $res['result'] = true; 
  802.  
  803. return $res; 
  804.  
  805.  
  806. /** 
  807. * record the bounce into the bounce table on a multisite 
  808. * @return type 
  809. */ 
  810. function record_bounce_ms() { 
  811. // make sure that the bounce recording is not already being processed on another child site 
  812. if (get_site_option('wysija_bounce_being_recorded')) 
  813. return; 
  814.  
  815. // flag the current recording 
  816. WYSIJA::update_option('wysija_bounce_being_recorded', true); 
  817.  
  818. // set the flag to indicate we are processing the bounce in a multisite manner right now 
  819. $this->record_ms_bounce = true; 
  820.  
  821. // will record the bounce in the ms table 
  822. $result = $this->process_bounce(); 
  823.  
  824. // lower the flag we can process the bounce again 
  825. WYSIJA::update_option('wysija_bounce_being_recorded', false); 
  826.  
  827. return $result; 
  828. /** 
  829. * base on the records we have in the bounce table we will take action 
  830. * @return boolean 
  831. */ 
  832. function process_bounce_ms() { 
  833.  
  834. @ini_set('max_execution_time', 0); 
  835. global $blog_id; 
  836. $main_site_prefix = $this->subClass->get_site_prefix(); 
  837. // make a query that will handle the bounce delete for all of the emails recorded in the bounce table for that site 
  838. // join the table bounce and user to make sure the ID's exist get 200 of them 
  839.  
  840. // we will delete one by one all of the data from the users that need to be removed 
  841. $tables = array( 
  842. 'user_history',  
  843. 'email_user_url',  
  844. 'email_user_stat',  
  845. 'user_list',  
  846. 'queue',  
  847. ); 
  848.  
  849. // central query to fetch the id of the bounced emails of the delete action 
  850. $query_join_bounce = 'SELECT B.user_id from '.$main_site_prefix.'bounce as A JOIN [wysija]user as B on A.email = B.email WHERE A.action_taken = "delete"'; 
  851.  
  852. try{ 
  853. foreach ($tables as $table_name) { 
  854. $query_delete = 'DELETE FROM [wysija]' . $table_name . ' WHERE user_id IN (' . $query_join_bounce . ')'; 
  855. $this->subClass->query($query_delete); 
  856. }catch(Exception $e) { 
  857. return false; 
  858.  
  859. // delete process from the user table needs to be made through a join since we cannot nest select from the same table we delete from 
  860. $query_delete_user = 'DELETE A.* FROM [wysija]user as A JOIN '.$main_site_prefix.'bounce as B on A.email = B.email WHERE B.action_taken = "delete"'; 
  861. $this->subClass->query($query_delete_user); 
  862.  
  863. // central query to fetch the id of the bounced emails of the unsubscribe action 
  864. $query_join_bounce = 'SELECT B.user_id from '.$main_site_prefix.'bounce as A JOIN [wysija]user as B on A.email = B.email WHERE A.action_taken = "unsubscribe"'; 
  865.  
  866. // query to update the status to unsubscribe 
  867. $query_update_user = 'UPDATE [wysija]user as A JOIN '.$main_site_prefix.'bounce as B on A.email = B.email SET A.`status` = -1 WHERE A.`status` != -1'; 
  868. //$query_update_user = 'UPDATE [wysija]user SET `status` = -1 WHERE user_id IN (' . $query_join_bounce . ')'; 
  869.  
  870. $query_update_user_list = 'UPDATE [wysija]user_list as A JOIN [wysija]user as B on A.user_id = B.user_id JOIN '.$main_site_prefix.'bounce as C on B.email = C.email SET A.`unsub_date` = '.time().' , A.`sub_date` = 0 WHERE B.`status` != -1'; 
  871. //$query_update_user_list = 'UPDATE [wysija]user_list SET `unsub_date` = '.time().' , `sub_date` = 0 WHERE user_id IN (' . $query_join_bounce . ')'; 
  872.  
  873. $this->subClass->getResults($query_update_user); 
  874. $this->subClass->getResults($query_update_user_list); 
  875.  
  876. // delete what's in the queue for those subscribers 
  877. $query_delete = 'DELETE FROM [wysija]queue WHERE user_id IN (' . $query_join_bounce . ')'; 
  878.  
  879. $this->subClass->getResults($query_delete); 
  880.  
  881. // query to set the boucne value in the email table 
  882. $query_update_email_user_status = 'UPDATE [wysija]email_user_stat as A JOIN '.$main_site_prefix.'bounce as C on (A.user_id = C.user_id AND A.email_id = C.email_id) SET A.`status` = -1 WHERE C.site_id='.$blog_id; 
  883. $this->subClass->getResults($query_update_email_user_status); 
  884.  
  885. $res['result'] = true; 
  886.  
  887. return $res; 
  888.  
  889. /** 
  890. * take action on the subscribers for multisites processing we don't delete or unsubscribe the users, we just record the action to be taken in the db 
  891. */ 
  892. function _sub_actions_ms() { 
  893.  
  894. // the action is about deleting users 
  895. if (!empty($this->deletedUsers)) { 
  896. $this->subClass->testdelete = true; 
  897.  
  898. $this->deletedUsers = array(); 
  899.  
  900. if (!empty($this->unsubscribedUsers)) { 
  901.  
  902. $this->unsubscribedUsers = array(); 
  903.  
  904. function _action_message_ms(&$one_rule) { 
  905.  
  906. $email_copy = $message = ''; 
  907.  
  908. //Handle actions on the message itself 
  909.  
  910. if (isset($one_rule['action_message']['save']) && !empty($this->_message->user_id)) { 
  911. //We have a user_id, should we save the message in the database? 
  912. $email_saved_as_array = array(); 
  913. $email_saved_as_array[] = 'SUBJECT::' . $this->_message->subject; 
  914.  
  915. if (!empty($this->_message->html)) 
  916. $email_saved_as_array[] = 'HTML_VERSION::' . htmlentities($this->_message->html); 
  917. if (!empty($this->_message->text)) 
  918. $email_saved_as_array[] = 'TEXT_VERSION::' . nl2br(htmlentities($this->_message->text)); 
  919. $this->_message->header->reply_to_name = (property_exists($this->_message->header, 'reply_to_name')) ? $this->_message->header->reply_to_name : ''; 
  920. $this->_message->header->from_name = (property_exists($this->_message->header, 'from_name')) ? $this->_message->header->from_name : ''; 
  921. $email_saved_as_array[] = 'REPLYTO_ADDRESS::' . $this->_message->header->reply_to_name . ' ( ' . $this->_message->header->reply_to_email . ' )'; 
  922. $email_saved_as_array[] = 'FROM_ADDRESS::' . $this->_message->header->from_name . ' ( ' . $this->_message->header->from_email . ' )'; 
  923. $email_saved_as_array[] = print_r($this->_message->headerinfo, true); 
  924. $email_copy = implode("\n", $email_saved_as_array); 
  925.  
  926. $message .= ', message saved (user ' . $this->_message->user_id . ')'; 
  927.  
  928.  
  929. if (isset($one_rule['forward'])) { 
  930. if (isset($one_rule['action_message_forwardto']) && !empty($one_rule['action_message_forwardto']) && trim($one_rule['action_message_forwardto']) != trim($this->config->getValue('bounce_email'))) { 
  931. //Get the forward address : 
  932. $this->mailer->clearAll(); 
  933. $this->mailer->Subject = 'BOUNCE FORWARD : ' . $this->_message->subject; 
  934. $this->mailer->AddAddress($one_rule['action_message_forwardto']); 
  935. if (!empty($this->_message->html)) { 
  936. $this->mailer->IsHTML(true); 
  937. $this->mailer->Body = $this->_message->html; 
  938. if (!empty($this->_message->text)) 
  939. $this->mailer->Body .= '<br/><br/>-------<br/>' . nl2br($this->_message->text); 
  940. }else { 
  941. $this->mailer->IsHTML(false); 
  942. $this->mailer->Body = $this->_message->text; 
  943.  
  944. //We add all other extra information just in case of we could use them... 
  945. //original-rcpt-to ? http://tools.ietf.org/html/rfc5965 
  946. $this->mailer->Body .= print_r($this->_message->headerinfo, true); 
  947. $this->_message->header->reply_to_name = (property_exists($this->_message->header, 'reply_to_name')) ? $this->_message->header->reply_to_name : ''; 
  948. $this->_message->header->from_name = (property_exists($this->_message->header, 'from_name')) ? $this->_message->header->from_name : ''; 
  949. $this->mailer->AddReplyTo($this->_message->header->reply_to_email, $this->_message->header->reply_to_name); 
  950. $this->mailer->setFrom($this->_message->header->from_email, $this->_message->header->from_name); 
  951. if ($this->mailer->send()) { 
  952. $message .= ', forwarded to ' . $one_rule['action_message_forwardto']; 
  953. } else { 
  954. $message .= ', error forwarding to ' . $one_rule['action_message_forwardto']; 
  955.  
  956. } else { 
  957. //we dont delete the email if the forward email is not specified or if the bounce email is the same as the forward email 
  958. unset($one_rule['action_message']['delete']); 
  959.  
  960. // insert the message or just the action taken on that message in the main bounce table 
  961.  
  962. // get the prefix of the current child site 
  963. $bounced_site_prefix = $this->subClass->get_site_prefix($this->_message->site_id); 
  964. // get the email of the bounced message based on the user_id and the site_id 
  965. $query = 'SELECT email FROM `'.$bounced_site_prefix.'user` WHERE user_id='.(int)$this->_message->user_id.' LIMIT 0 , 1'; 
  966. $result_subscriber = $this->subClass->query('get_res', $query, OBJECT); 
  967.  
  968. $this->subClass->reset(); 
  969.  
  970. if(strpos($one_rule['action_user'], 'unsub')!==false) $action_taken='unsubscribe'; 
  971. elseif($one_rule['action_user']!='') $action_taken='delete'; 
  972.  
  973. if(!empty($result_subscriber[0]->email)) { 
  974. $main_site_prefix = $this->subClass->get_site_prefix(); 
  975. $query_insert_bounce_ms = 'INSERT IGNORE INTO `'.$main_site_prefix.'bounce` (`email`, `site_id`, `user_id`, `email_id`, `action_taken`, `case`, `message`, `created_at`)'; 
  976. $query_insert_bounce_ms .= " VALUES ('".$result_subscriber[0]->email."', '".(int)$this->_message->site_id."', '".(int)$this->_message->user_id."', '".(int)$this->_message->email_id."', '".$action_taken."', '".$one_rule['key']."', '". esc_sql($email_copy)."', '".time()."')"; 
  977.  
  978. $this->subClass->query($query_insert_bounce_ms); 
  979.  
  980. if (isset($one_rule['action_message']['delete'])) { 
  981. $message .= ', message deleted'; 
  982. $this->deleteMessage($this->_message->messageNB); 
  983.  
  984. return $message; 
  985.