* @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ use Symfony\Component\Mailer\Transport; use Symfony\Component\Mailer\Mailer; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; use Symfony\Component\Mime\Header\Headers; /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } /** * Messenger */ class messenger { private const PRIORITY_MAP = [ Email::PRIORITY_HIGHEST => 'Highest', Email::PRIORITY_HIGH => 'High', Email::PRIORITY_NORMAL => 'Normal', Email::PRIORITY_LOW => 'Low', Email::PRIORITY_LOWEST => 'Lowest', ]; private const HEADER_CLASS_MAP = [ 'date' => DateHeader::class, 'from' => MailboxListHeader::class, 'sender' => MailboxHeader::class, 'reply-to' => MailboxListHeader::class, 'to' => MailboxListHeader::class, 'cc' => MailboxListHeader::class, 'bcc' => MailboxListHeader::class, 'message-id' => IdentificationHeader::class, 'in-reply-to' => UnstructuredHeader::class, 'references' => UnstructuredHeader::class, 'return-path' => PathHeader::class, ]; var $msg, $replyto, $from, $subject; var $addresses = []; var $extra_headers = []; /** * Possible values are: * Email::PRIORITY_HIGHEST * Email::PRIORITY_HIGH * Email::PRIORITY_NORMAL * Email::PRIORITY_LOW * Email::PRIORITY_LOWEST */ var $mail_priority = Email::PRIORITY_NORMAL; var $use_queue = true; /** @var \phpbb\template\template */ protected $template; /** * Constructor */ function __construct($use_queue = true) { global $phpbb_container, $phpbb_root_path, $phpEx; $this->phpbb_container = $phpbb_container; $this->config = $this->phpbb_container->get('config'); $this->dispatcher = $this->phpbb_container->get('dispatcher'); $this->language = $this->phpbb_container->get('language'); $this->log = $this->phpbb_container->get('log'); $this->request = $this->phpbb_container->get('request'); $this->user = $this->phpbb_container->get('user'); $this->email = new Email(); $this->headers = $this->email->getHeaders(); $this->use_queue = (!$this->config['email_package_size']) ? false : $use_queue; $this->subject = ''; $this->root_path = $phpbb_root_path; $this->php_ext = $phpEx; } /** * Resets all the data (address, template file, etc etc) to default */ function reset() { $this->addresses = $this->extra_headers = []; $this->msg = $this->replyto = $this->from = ''; $this->mail_priority = Email::PRIORITY_NORMAL; } /** * Set addresses for to/im as available * * @param array $user User row */ function set_addresses($user) { if (isset($user['user_email']) && $user['user_email']) { $this->email->to(new Address($user['user_email'], $user['username'] ?: '')); } if (isset($user['user_jabber']) && $user['user_jabber']) { $this->im($user['user_jabber'], $user['username'] ?: ''); } } /** * Sets an email address to send to */ function to($address, $realname = '') { if (!trim($address)) { return; } // If empty sendmail_path on windows, PHP changes the to line $windows_empty_sendmail_path = !$this->config['smtp_delivery'] && DIRECTORY_SEPARATOR == '\\'; $to = new Address(trim($address), $windows_empty_sendmail_path ? '' : trim($realname)); $this->email->getTo() ? $this->email->addTo($to) : $this->email->to($to); } /** * Sets an cc address to send to */ function cc($address, $realname = '') { if (!trim($address)) { return; } $cc = new Address(trim($address), trim($realname)); $this->email->getCc() ? $this->email->addCc($to) : $this->email->cc($to); } /** * Sets an bcc address to send to */ function bcc($address, $realname = '') { if (!trim($address)) { return; } $bcc = new Address(trim($address), trim($realname)); $this->email->getBcc() ? $this->email->addBcc($to) : $this->email->bcc($to); } /** * Sets a im contact to send to */ function im($address, $realname = '') { // IM-Addresses could be empty if (!trim($address)) { return; } $pos = isset($this->addresses['im']) ? count($this->addresses['im']) : 0; $this->addresses['im'][$pos]['uid'] = trim($address); $this->addresses['im'][$pos]['name'] = trim($realname); } /** * Set the reply to address */ function replyto($address) { $this->replyto = new Address(trim($address)); $this->email->getReplyTo() ? $this->email->addReplyTo($this->replyto) : $this->email->replyTo($this->replyto); } /** * Set the from address */ function from($address) { $this->from = new Address(trim($address)); $this->email->getFrom() ? $this->email->addFrom($this->from) : $this->email->from($this->from); } /** * set up subject for mail */ function subject($subject = '') { $this->email->subject(trim($subject)); } /** * set up extra mail headers */ function headers($header_name, $header_value) { $this->headers->addTextHeader(trim($header_name), trim($header_value)); } /** * Adds X-AntiAbuse headers * * @param \phpbb\config\config $config Config object * @param \phpbb\user $user User object * @return void */ function anti_abuse_headers($config, $user) { $this->headers->addTextHeader('X-AntiAbuse', 'Board servername - ' . $config['server_name']); $this->headers->addTextHeader('X-AntiAbuse', 'User_id - ' . $user->data['user_id']); $this->headers->addTextHeader('X-AntiAbuse', 'Username - ' . $user->data['username']); $this->headers->addTextHeader('X-AntiAbuse', 'User IP - ' . $user->ip); } /** * Set the email priority * Possible values are: * Email::PRIORITY_HIGHEST * Email::PRIORITY_HIGH * Email::PRIORITY_NORMAL * Email::PRIORITY_LOW * Email::PRIORITY_LOWEST */ function set_mail_priority($priority = Email::PRIORITY_NORMAL) { $this->email->priority($priority); } /** * Set email template to use */ function template($template_file, $template_lang = '', $template_path = '', $template_dir_prefix = '') { $template_dir_prefix = (!$template_dir_prefix || $template_dir_prefix[0] === '/') ? $template_dir_prefix : '/' . $template_dir_prefix; $this->setup_template(); if (!trim($template_file)) { trigger_error('No template file for emailing set.', E_USER_ERROR); } if (!trim($template_lang)) { // fall back to board default language if the user's language is // missing $template_file. If this does not exist either, // $this->template->set_filenames will do a trigger_error $template_lang = basename($this->config['default_lang']); } $ext_template_paths = array( array( 'name' => $template_lang . '_email', 'ext_path' => 'language/' . $template_lang . '/email' . $template_dir_prefix, ), ); if ($template_path) { $template_paths = array( $template_path . $template_dir_prefix, ); } else { $template_path = (!empty($this->user->lang_path)) ? $this->user->lang_path : $this->root_path . 'language/'; $template_path .= $template_lang . '/email'; $template_paths = array( $template_path . $template_dir_prefix, ); $board_language = basename($this->config['default_lang']); // we can only specify default language fallback when the path is not a custom one for which we // do not know the default language alternative if ($template_lang !== $board_language) { $fallback_template_path = (!empty($this->user->lang_path)) ? $this->user->lang_path : $this->root_path . 'language/'; $fallback_template_path .= $board_language . '/email'; $template_paths[] = $fallback_template_path . $template_dir_prefix; $ext_template_paths[] = array( 'name' => $board_language . '_email', 'ext_path' => 'language/' . $board_language . '/email' . $template_dir_prefix, ); } // If everything fails just fall back to en template if ($template_lang !== 'en' && $board_language !== 'en') { $fallback_template_path = (!empty($this->user->lang_path)) ? $this->user->lang_path : $this->root_path . 'language/'; $fallback_template_path .= 'en/email'; $template_paths[] = $fallback_template_path . $template_dir_prefix; $ext_template_paths[] = array( 'name' => 'en_email', 'ext_path' => 'language/en/email' . $template_dir_prefix, ); } } $this->set_template_paths($ext_template_paths, $template_paths); $this->template->set_filenames(array( 'body' => $template_file . '.txt', )); return true; } /** * assign variables to email template */ function assign_vars($vars) { $this->setup_template(); $this->template->assign_vars($vars); } function assign_block_vars($blockname, $vars) { $this->setup_template(); $this->template->assign_block_vars($blockname, $vars); } /** * Send the mail out to the recipients set previously in var $this->addresses * * @param int $method User notification method NOTIFY_EMAIL|NOTIFY_IM|NOTIFY_BOTH * @param bool $break Flag indicating if the function only formats the subject * and the message without sending it * * @return bool */ function send($method = NOTIFY_EMAIL, $break = false) { // We add some standard variables we always use, no need to specify them always $this->assign_vars([ 'U_BOARD' => generate_board_url(), 'EMAIL_SIG' => str_replace('
', "\n", "-- \n" . html_entity_decode($this->config['board_email_sig'], ENT_COMPAT)), 'SITENAME' => html_entity_decode($this->config['sitename'], ENT_COMPAT), ]); $email = $this->email; $subject = $this->email->getSubject(); $template = $this->template; /** * Event to modify the template before parsing * * @event core.modify_notification_template * @var bool break Flag indicating if the function only formats the subject * and the message without sending it * @var Symfony\Component\Mime\Email email The Symfony Email object * @var int method User notification method NOTIFY_EMAIL|NOTIFY_IM|NOTIFY_BOTH * @var string subject The message subject * @var \phpbb\template\template template The (readonly) template object * @since 3.2.4-RC1 * @changed 4.0.0-a1 Added vars: email. */ $vars = ['break', 'email', 'method', 'subject', 'template']; extract($this->dispatcher->trigger_event('core.modify_notification_template', compact($vars))); // Parse message through template $message = trim($this->template->assign_display('body')); /** * Event to modify notification message text after parsing * * @event core.modify_notification_message * @var bool break Flag indicating if the function only formats the subject * and the message without sending it * @var Symfony\Component\Mime\Email email The Symfony Email object * @var string message The message text * @var int method User notification method NOTIFY_EMAIL|NOTIFY_IM|NOTIFY_BOTH * @var string subject The message subject * @since 3.1.11-RC1 * @changed 4.0.0-a1 Added vars: email. */ $vars = ['break', 'email', 'message', 'method', 'subject']; extract($this->dispatcher->trigger_event('core.modify_notification_message', compact($vars))); $this->email = $email; $this->subject = $subject; $this->msg = $message; unset($email, $subject, $message, $template); // Because we use \n for newlines in the body message we need to fix line encoding errors for those admins who uploaded email template files in the wrong encoding $this->msg = str_replace("\r\n", "\n", $this->msg); // We now try and pull a subject from the email body ... if it exists, // do this here because the subject may contain a variable $drop_header = ''; $match = array(); if (preg_match('#^(Subject:(.*?))$#m', $this->msg, $match)) { $this->subject = (trim($match[2]) != '') ? trim($match[2]) : (($this->subject != '') ? $this->subject : $this->user->lang['NO_EMAIL_SUBJECT']); $drop_header .= '[\r\n]*?' . preg_quote($match[1], '#'); } else { $this->subject = (($this->subject != '') ? $this->subject : $this->user->lang['NO_EMAIL_SUBJECT']); } if (preg_match('#^(List-Unsubscribe:(.*?))$#m', $this->msg, $match)) { $this->headers->addTextHeader('List-Unsubscribe', trim($match[2])); $drop_header .= '[\r\n]*?' . preg_quote($match[1], '#'); } if ($drop_header) { $this->msg = trim(preg_replace('#' . $drop_header . '#s', '', $this->msg)); } $this->email->subject($this->subject); $this->email->text($this->msg); if ($break) { return true; } switch ($method) { case NOTIFY_EMAIL: $result = $this->msg_email(); break; case NOTIFY_IM: $result = $this->msg_jabber(); break; case NOTIFY_BOTH: $result = $this->msg_email(); $this->msg_jabber(); break; } $this->reset(); return $result; } /** * Add error message to log */ function error($type, $msg) { // Session doesn't exist, create it if (!isset($this->user->session_id) || $this->user->session_id === '') { $this->user->session_begin(); } $calling_page = html_entity_decode($this->request->server('REQUEST_URI'), ENT_COMPAT); switch ($type) { case 'EMAIL': $message = 'EMAIL/' . (($this->config['smtp_delivery']) ? 'SMTP' : 'PHP/mail()') . ''; break; default: $message = "$type"; break; } $message .= '
' . htmlspecialchars($calling_page, ENT_COMPAT) . '

' . $msg . '
'; $this->log->add('critical', $this->user->data['user_id'], $this->user->ip, 'LOG_ERROR_' . $type, false, [$message]); } /** * Save to queue */ function save_queue() { if ($this->config['email_package_size'] && $this->use_queue && !empty($this->queue)) { $this->queue->save(); return; } } /** * Detect proper method to add header * * @return string */ public function get_header_method(string $name) { $parts = explode('\\', self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class); $method = 'add'.ucfirst(array_pop($parts)); if ('addUnstructuredHeader' === $method) { $method = 'addTextHeader'; } else if ('addIdentificationHeader' === $method) { $method = 'addIdHeader'; } return $method; } /** * Set email headers */ function build_header() { $headers = []; $board_contact = $this->config['board_contact']; if (empty($this->email->getReplyTo())) { $this->replyto = $board_contact; $headers['Reply-To'] = $this->replyto; } if (empty($this->email->getFrom())) { $this->from = $board_contact; $headers['From'] = $this->from; } $headers['Return-Path'] = new Address($this->config['board_email']); $headers['Sender'] = new Address($this->config['board_email']); $headers['X-Priority'] = sprintf('%d (%s)', $this->mail_priority, self::PRIORITY_MAP[$this->mail_priority]); $headers['X-MSMail-Priority'] = self::PRIORITY_MAP[$this->mail_priority]; $headers['X-Mailer'] = 'phpBB3'; $headers['X-MimeOLE'] = 'phpBB3'; $headers['X-phpBB-Origin'] = 'phpbb://' . str_replace(['http://', 'https://'], ['', ''], generate_board_url()); /** * Event to modify email header entries * * @event core.modify_email_headers * @var array headers Array containing email header entries * @since 3.1.11-RC1 */ $vars = array('headers'); extract($this->dispatcher->trigger_event('core.modify_email_headers', compact($vars))); foreach ($headers as $header => $value) { // addMailboxListHeader() requires value to be array if ($this->get_header_method($header) == 'addMailboxListHeader') { $value = [$value]; } $this->headers->addHeader($header, $value); } return true; } /** * Generates a valid transport to send email * * @param bool $dummy Flag to disable mail delivery * @return Symfony\Component\Mailer\Transport Symfony Transport object */ function get_transport($dummy = false) { if ($dummy) { $dsn = 'null://null'; } else if ($this->config['smtp_delivery']) { $user = urlencode($this->config['smtp_username']); $password = urlencode($this->config['smtp_password']); $smtp_host = urlencode($this->config['smtp_host']); $smtp_port = $this->config['smtp_port']; $dsn = "smtp://$user:$password@$smtp_host:$smtp_port"; } else { $dsn = 'sendmail://default'; } $transport = Transport::fromDsn($dsn); if ($this->config['smtp_delivery']) { // Set ssl context options, see http://php.net/manual/en/context.ssl.php $verify_peer = (bool) $this->config['smtp_verify_peer']; $verify_peer_name = (bool) $this->config['smtp_verify_peer_name']; $allow_self_signed = (bool) $this->config['smtp_allow_self_signed']; $options = [ 'ssl' => [ 'verify_peer' => $verify_peer, 'verify_peer_name' => $verify_peer_name, 'allow_self_signed' => $allow_self_signed, ] ]; $transport->getStream()->setStreamOptions($options); } return $transport; } /** * Send out emails */ function msg_email() { if (empty($this->config['email_enable'])) { return false; } // Addresses to send to? if (empty($this->email->getTo())) { // Send was successful. ;) return true; } $use_queue = false; if ($this->config['email_package_size'] && $this->use_queue) { if (empty($this->queue)) { $this->queue = new queue(); $this->queue->init('email', $this->config['email_package_size']); } $use_queue = true; } $contact_name = html_entity_decode($this->config['board_contact_name'], ENT_COMPAT); $board_contact = $this->config['board_contact']; $break = false; $subject = $this->subject; $msg = $this->msg; $email = $this->email; /** * Event to send message via external transport * * @event core.notification_message_email * @var bool break Flag indicating if the function return after hook * @var string subject The message subject * @var string msg The message text * @var Symfony\Component\Mime\Email email The Symfony Email object * @since 3.2.4-RC1 * @changed 4.0.0-a1 Added vars: email. Removed vars: addresses */ $vars = array( 'break', 'subject', 'msg', 'email', ); extract($this->dispatcher->trigger_event('core.notification_message_email', compact($vars))); $this->addresses = $addresses; $this->subject = $subject; $this->msg = $msg; unset($addresses, $subject, $msg); if ($break) { return true; } if (empty($this->email->getReplyto())) { $this->email->replyTo(new Address($board_contact)); } if (empty($this->email->getFrom())) { $this->email->from(new Address($board_contact)); } // Build header $this->build_header(); // Send message ... if (!$use_queue) { $transport = $this->get_transport(); $mailer = new Mailer($transport); $subject = $this->subject; $msg = $this->msg; $headers = $this->headers; $email = $this->email; /** * Modify data before sending out emails with PHP's mail function * * @event core.phpbb_mail_before * @var Symfony\Component\Mime\Email email The Symfony Email object * @var string subject The message subject * @var string msg The message text * @var string headers The email headers * @since 3.3.6-RC1 * @changed 4.0.0-a1 Added vars: email. Removed vars: to, eol, additional_parameters. */ $vars = [ 'email', 'subject', 'msg', 'headers', ]; extract($this->dispatcher->trigger_event('core.phpbb_mail_before', compact($vars))); $this->subject = $subject; $this->msg = $msg; $this->headers = $headers; $this->email = $email; try { $mailer->send($this->email); } catch (TransportExceptionInterface $e) { $this->error('EMAIL', $e->getDebug()); return false; } /** * Execute code after sending out emails with PHP's mail function * * @event core.phpbb_mail_after * @var Symfony\Component\Mime\Email email The Symfony Email object * @var string subject The message subject * @var string msg The message text * @var string headers The email headers * @since 3.3.6-RC1 * @changed 4.0.0-a1 Added vars: email. Removed vars: to, eol, additional_parameters, $result. */ $vars = [ 'email', 'subject', 'msg', 'headers', ]; extract($this->dispatcher->trigger_event('core.phpbb_mail_after', compact($vars))); } else { $this->queue->put('email', [ 'email' => $this->email, ]); } return true; } /** * Send jabber message out */ function msg_jabber() { if (empty($this->config['jab_enable']) || empty($this->config['jab_host']) || empty($this->config['jab_username']) || empty($this->config['jab_password'])) { return false; } if (empty($this->addresses['im'])) { // Send was successful. ;) return true; } $use_queue = false; if ($this->config['jab_package_size'] && $this->use_queue) { if (empty($this->queue)) { $this->queue = new queue(); $this->queue->init('jabber', $this->config['jab_package_size']); } $use_queue = true; } $addresses = array(); foreach ($this->addresses['im'] as $type => $uid_ary) { $addresses[] = $uid_ary['uid']; } $addresses = array_unique($addresses); if (!$use_queue) { include_once($this->root_path . 'includes/functions_jabber.' . $this->php_ext); $this->jabber = new jabber($this->config['jab_host'], $this->config['jab_port'], $this->config['jab_username'], html_entity_decode($this->config['jab_password'], ENT_COMPAT), $this->config['jab_use_ssl'], $this->config['jab_verify_peer'], $this->config['jab_verify_peer_name'], $this->config['jab_allow_self_signed']); if (!$this->jabber->connect()) { $this->error('JABBER', $this->user->lang['ERR_JAB_CONNECT'] . '
' . $this->jabber->get_log()); return false; } if (!$this->jabber->login()) { $this->error('JABBER', $this->user->lang['ERR_JAB_AUTH'] . '
' . $this->jabber->get_log()); return false; } foreach ($addresses as $address) { $this->jabber->send_message($address, $this->msg, $this->subject); } $this->jabber->disconnect(); } else { $this->queue->put('jabber', array( 'addresses' => $addresses, 'subject' => $this->subject, 'msg' => $this->msg) ); } unset($addresses); return true; } /** * Setup template engine */ protected function setup_template() { if ($this->template instanceof \phpbb\template\template) { return; } $template_environment = new \phpbb\template\twig\environment( $phpbb_container->get('assets.bag'), $phpbb_container->get('config'), $phpbb_container->get('filesystem'), $phpbb_container->get('path_helper'), $phpbb_container->getParameter('core.template.cache_path'), $phpbb_container->get('ext.manager'), new \phpbb\template\twig\loader(), $this->dispatcher, [] ); $template_environment->setLexer($this->phpbb_container->get('template.twig.lexer')); $this->template = new \phpbb\template\twig\twig( $this->phpbb_container->get('path_helper'), $this->config, new \phpbb\template\context(), $template_environment, $this->phpbb_container->getParameter('core.template.cache_path'), $this->user, $this->phpbb_container->get('template.twig.extensions.collection'), $this->phpbb_container->get('ext.manager') ); } /** * Set template paths to load */ protected function set_template_paths($path_name, $paths) { $this->setup_template(); $this->template->set_custom_style($path_name, $paths); } } /** * handling email and jabber queue */ class queue { var $data = []; var $queue_data = []; var $package_size = 0; var $cache_file = ''; var $eol = "\n"; /** * @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; /** * constructor */ function __construct() { global $phpbb_container; $this->phpbb_container = $phpbb_container; $this->php_ext = $this->phpbb_container->getParameter('core.php_ext'); $this->root_path = $this->phpbb_container->getParameter('core.root_path'); $this->cache_file = $this->phpbb_container->getParameter('core.cache_dir') . "queue.{$this->php_ext}"; $this->filesystem = $this->phpbb_container->get('filesystem'); $this->config = $this->phpbb_container->get('config'); $this->dispatcher = $this->phpbb_container->get('dispatcher'); } /** * Init a queue object */ function init($object, $package_size) { $this->data[$object] = array(); $this->data[$object]['package_size'] = $package_size; $this->data[$object]['data'] = array(); } /** * Put object in queue */ function put($object, $scope) { $this->data[$object]['data'][] = $scope; } /** * Process queue * Using lock file */ function process() { $lock = new \phpbb\lock\flock($this->cache_file); $lock->acquire(); // avoid races, check file existence once $have_cache_file = file_exists($this->cache_file); if (!$have_cache_file || $this->config['last_queue_run'] > time() - $this->config['queue_interval']) { if (!$have_cache_file) { $this->config->set('last_queue_run', time(), false); } $lock->release(); return; } $this->config->set('last_queue_run', time(), false); include($this->cache_file); foreach ($this->queue_data as $object => $data_ary) { @set_time_limit(0); if (!isset($data_ary['package_size'])) { $data_ary['package_size'] = 0; } $package_size = $data_ary['package_size']; $num_items = (!$package_size || count($data_ary['data']) < $package_size) ? count($data_ary['data']) : $package_size; /* * This code is commented out because it causes problems on some web hosts. * The core problem is rather restrictive email sending limits. * This code is nly useful if you have no such restrictions from the * web host and the package size setting is wrong. // If the amount of emails to be sent is way more than package_size than we need to increase it to prevent backlogs... if (count($data_ary['data']) > $package_size * 2.5) { $num_items = count($data_ary['data']); } */ switch ($object) { case 'email': // Delete the email queued objects if mailing is disabled if (!$this->config['email_enable']) { unset($this->queue_data['email']); continue 2; } break; case 'jabber': if (!$this->config['jab_enable']) { unset($this->queue_data['jabber']); continue 2; } include_once($this->root_path . 'includes/functions_jabber.' . $this->php_ext); $this->jabber = new jabber($this->config['jab_host'], $this->config['jab_port'], $this->config['jab_username'], html_entity_decode($this->config['jab_password'], ENT_COMPAT), $this->config['jab_use_ssl'], $this->config['jab_verify_peer'], $this->config['jab_verify_peer_name'], $this->config['jab_allow_self_signed']); if (!$this->jabber->connect()) { $messenger = new messenger(); $messenger->error('JABBER', $this->user->lang['ERR_JAB_CONNECT']); continue 2; } if (!$this->jabber->login()) { $messenger = new messenger(); $messenger->error('JABBER', $this->user->lang['ERR_JAB_AUTH']); continue 2; } break; default: $lock->release(); return; } for ($i = 0; $i < $num_items; $i++) { // Make variables available... extract(array_shift($this->queue_data[$object]['data'])); switch ($object) { case 'email': $break = false; /** * Event to send message via external transport * * @event core.notification_message_process * @var bool break Flag indicating if the function return after hook * @var Symfony\Component\Mime\Email email The Symfony Email object * @since 3.2.4-RC1 * @changed 4.0.0-a1 Added vars: email. Removed vars: addresses, subject, msg. */ $vars = [ 'break', 'email', ]; extract($this->dispatcher->trigger_event('core.notification_message_process', compact($vars))); if (!$break) { $messenger = new messenger(); $transport = $messenger->get_transport(); $mailer = new Mailer($transport); try { $mailer->send($email); } catch (TransportExceptionInterface $e) { $messenger->error('EMAIL', $e->getDebug()); continue 2; } } break; case 'jabber': foreach ($addresses as $address) { if ($this->jabber->send_message($address, $msg, $subject) === false) { $messenger = new messenger(); $messenger->error('JABBER', $this->jabber->get_log()); continue 3; } } break; } } // No more data for this object? Unset it if (!count($this->queue_data[$object]['data'])) { unset($this->queue_data[$object]); } // Post-object processing switch ($object) { case 'jabber': // Hang about a couple of secs to ensure the messages are // handled, then disconnect $this->jabber->disconnect(); break; } } if (!count($this->queue_data)) { @unlink($this->cache_file); } else { if ($fp = @fopen($this->cache_file, 'wb')) { fwrite($fp, "queue_data = unserialize(" . var_export(serialize($this->queue_data), true) . ");\n\n?>"); fclose($fp); if (function_exists('opcache_invalidate')) { @opcache_invalidate($this->cache_file); } try { $this->filesystem->phpbb_chmod($this->cache_file, \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE); } catch (\phpbb\filesystem\exception\filesystem_exception $e) { // Do nothing } } } $lock->release(); } /** * Save queue */ function save() { if (!count($this->data)) { return; } $lock = new \phpbb\lock\flock($this->cache_file); $lock->acquire(); if (file_exists($this->cache_file)) { include($this->cache_file); foreach ($this->queue_data as $object => $data_ary) { if (isset($this->data[$object]) && count($this->data[$object])) { $this->data[$object]['data'] = array_merge($data_ary['data'], $this->data[$object]['data']); } else { $this->data[$object]['data'] = $data_ary['data']; } } } if ($fp = @fopen($this->cache_file, 'w')) { fwrite($fp, "queue_data = unserialize(" . var_export(serialize($this->data), true) . ");\n\n?>"); fclose($fp); if (function_exists('opcache_invalidate')) { @opcache_invalidate($this->cache_file); } try { $this->filesystem->phpbb_chmod($this->cache_file, \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE); } catch (\phpbb\filesystem\exception\filesystem_exception $e) { // Do nothing } $this->data = array(); } $lock->release(); } }