phpBB

Code Changes

File: includes/functions_messenger.php

  Unmodified   Added   Modified   Removed
Line 24Line 24
*/
class messenger
{

*/
class messenger
{

	var $msg, $extra_headers, $replyto, $from, $subject;

	var $msg, $replyto, $from, $subject;

	var $addresses = array();

	var $addresses = array();

 
	var $extra_headers = array();


var $mail_priority = MAIL_NORMAL_PRIORITY;
var $use_queue = true;


var $mail_priority = MAIL_NORMAL_PRIORITY;
var $use_queue = true;

Line 36Line 37
	/**
* Constructor
*/

	/**
* Constructor
*/

	function messenger($use_queue = true)

	function __construct($use_queue = true)

	{
global $config;


	{
global $config;


Line 84Line 85
			return;
}


			return;
}


		$pos = isset($this->addresses['to']) ? sizeof($this->addresses['to']) : 0;

		$pos = isset($this->addresses['to']) ? count($this->addresses['to']) : 0;


$this->addresses['to'][$pos]['email'] = trim($address);



$this->addresses['to'][$pos]['email'] = trim($address);


Line 109Line 110
			return;
}


			return;
}


		$pos = isset($this->addresses['cc']) ? sizeof($this->addresses['cc']) : 0;

		$pos = isset($this->addresses['cc']) ? count($this->addresses['cc']) : 0;

		$this->addresses['cc'][$pos]['email'] = trim($address);
$this->addresses['cc'][$pos]['name'] = trim($realname);
}

		$this->addresses['cc'][$pos]['email'] = trim($address);
$this->addresses['cc'][$pos]['name'] = trim($realname);
}

Line 124Line 125
			return;
}


			return;
}


		$pos = isset($this->addresses['bcc']) ? sizeof($this->addresses['bcc']) : 0;

		$pos = isset($this->addresses['bcc']) ? count($this->addresses['bcc']) : 0;

		$this->addresses['bcc'][$pos]['email'] = trim($address);
$this->addresses['bcc'][$pos]['name'] = trim($realname);
}

		$this->addresses['bcc'][$pos]['email'] = trim($address);
$this->addresses['bcc'][$pos]['name'] = trim($realname);
}

Line 140Line 141
			return;
}


			return;
}


		$pos = isset($this->addresses['im']) ? sizeof($this->addresses['im']) : 0;

		$pos = isset($this->addresses['im']) ? count($this->addresses['im']) : 0;

		$this->addresses['im'][$pos]['uid'] = trim($address);
$this->addresses['im'][$pos]['name'] = trim($realname);
}

		$this->addresses['im'][$pos]['uid'] = trim($address);
$this->addresses['im'][$pos]['name'] = trim($realname);
}

Line 180Line 181
	/**
* Adds X-AntiAbuse headers
*

	/**
* Adds X-AntiAbuse headers
*

	* @param array $config		Configuration array
* @param user $user A user object
*
* @return null

	* @param \phpbb\config\config	$config		Config object
* @param \phpbb\user $user User object
* @return void


	*/
function anti_abuse_headers($config, $user)
{

	*/
function anti_abuse_headers($config, $user)
{

Line 306Line 306

/**
* Send the mail out to the recipients set previously in var $this->addresses


/**
* 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)
{

	*/
function send($method = NOTIFY_EMAIL, $break = false)
{

		global $config, $user;

		global $config, $user, $phpbb_dispatcher;


// We add some standard variables we always use, no need to specify them always
$this->assign_vars(array(


// We add some standard variables we always use, no need to specify them always
$this->assign_vars(array(

Line 317Line 323
			'EMAIL_SIG'	=> str_replace('<br />', "\n", "-- \n" . htmlspecialchars_decode($config['board_email_sig'])),
'SITENAME' => htmlspecialchars_decode($config['sitename']),
));

			'EMAIL_SIG'	=> str_replace('<br />', "\n", "-- \n" . htmlspecialchars_decode($config['board_email_sig'])),
'SITENAME' => htmlspecialchars_decode($config['sitename']),
));

 

$subject = $this->subject;
$template = $this->template;
/**
* Event to modify the template before parsing
*
* @event core.modify_notification_template
* @var int method User notification method NOTIFY_EMAIL|NOTIFY_IM|NOTIFY_BOTH
* @var bool break Flag indicating if the function only formats the subject
* and the message without sending it
* @var string subject The message subject
* @var \phpbb\template\template template The (readonly) template object
* @since 3.2.4-RC1
*/
$vars = array('method', 'break', 'subject', 'template');
extract($phpbb_dispatcher->trigger_event('core.modify_notification_template', compact($vars)));


// Parse message through template


// Parse message through template

		$this->msg = trim($this->template->assign_display('body'));



















		$message = trim($this->template->assign_display('body'));

/**
* Event to modify notification message text after parsing
*
* @event core.modify_notification_message
* @var int method User notification method NOTIFY_EMAIL|NOTIFY_IM|NOTIFY_BOTH
* @var bool break Flag indicating if the function only formats the subject
* and the message without sending it
* @var string subject The message subject
* @var string message The message text
* @since 3.1.11-RC1
*/
$vars = array('method', 'break', 'subject', 'message');
extract($phpbb_dispatcher->trigger_event('core.modify_notification_message', compact($vars)));

$this->subject = $subject;
$this->msg = $message;
unset($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);


// 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);

Line 336Line 376
		else
{
$this->subject = (($this->subject != '') ? $this->subject : $user->lang['NO_EMAIL_SUBJECT']);

		else
{
$this->subject = (($this->subject != '') ? $this->subject : $user->lang['NO_EMAIL_SUBJECT']);

 
		}

if (preg_match('#^(List-Unsubscribe:(.*?))$#m', $this->msg, $match))
{
$this->extra_headers[] = $match[1];
$drop_header .= '[\r\n]*?' . preg_quote($match[1], '#');

		}

if ($drop_header)

		}

if ($drop_header)

Line 386Line 432
		switch ($type)
{
case 'EMAIL':

		switch ($type)
{
case 'EMAIL':

				$message = '<strong>EMAIL/' . (($config['smtp_delivery']) ? 'SMTP' : 'PHP/' . $config['email_function_name'] . '()') . '</strong>';

				$message = '<strong>EMAIL/' . (($config['smtp_delivery']) ? 'SMTP' : 'PHP/mail()') . '</strong>';

			break;

default:

			break;

default:

Line 473Line 519
		$vars = array('headers');
extract($phpbb_dispatcher->trigger_event('core.modify_email_headers', compact($vars)));


		$vars = array('headers');
extract($phpbb_dispatcher->trigger_event('core.modify_email_headers', compact($vars)));


		if (sizeof($this->extra_headers))

		if (count($this->extra_headers))

		{
$headers = array_merge($headers, $this->extra_headers);
}

		{
$headers = array_merge($headers, $this->extra_headers);
}

Line 486Line 532
	*/
function msg_email()
{

	*/
function msg_email()
{

		global $config;

		global $config, $phpbb_dispatcher;


if (empty($config['email_enable']))
{


if (empty($config['email_enable']))
{

Line 513Line 559

$contact_name = htmlspecialchars_decode($config['board_contact_name']);
$board_contact = (($contact_name !== '') ? '"' . mail_encode($contact_name) . '" ' : '') . '<' . $config['board_contact'] . '>';


$contact_name = htmlspecialchars_decode($config['board_contact_name']);
$board_contact = (($contact_name !== '') ? '"' . mail_encode($contact_name) . '" ' : '') . '<' . $config['board_contact'] . '>';

 

$break = false;
$addresses = $this->addresses;
$subject = $this->subject;
$msg = $this->msg;
/**
* Event to send message via external transport
*
* @event core.notification_message_email
* @var bool break Flag indicating if the function return after hook
* @var array addresses The message recipients
* @var string subject The message subject
* @var string msg The message text
* @since 3.2.4-RC1
*/
$vars = array(
'break',
'addresses',
'subject',
'msg',
);
extract($phpbb_dispatcher->trigger_event('core.notification_message_email', compact($vars)));

if ($break)
{
return true;
}


if (empty($this->replyto))
{


if (empty($this->replyto))
{

Line 618Line 691
		if (!$use_queue)
{
include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);

		if (!$use_queue)
{
include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);

			$this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']);

			$this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl'], $config['jab_verify_peer'], $config['jab_verify_peer_name'], $config['jab_allow_self_signed']);


if (!$this->jabber->connect())
{


if (!$this->jabber->connect())
{

Line 656Line 729
	*/
protected function setup_template()
{

	*/
protected function setup_template()
{

		global $phpbb_container;

		global $phpbb_container, $phpbb_dispatcher;


if ($this->template instanceof \phpbb\template\template)
{


if ($this->template instanceof \phpbb\template\template)
{

Line 671Line 744
			$phpbb_container->get('ext.manager'),
new \phpbb\template\twig\loader(
$phpbb_container->get('filesystem')

			$phpbb_container->get('ext.manager'),
new \phpbb\template\twig\loader(
$phpbb_container->get('filesystem')

			)



			),
$phpbb_dispatcher,
array()

		);
$template_environment->setLexer($phpbb_container->get('template.twig.lexer'));


		);
$template_environment->setLexer($phpbb_container->get('template.twig.lexer'));


Line 717Line 792
	/**
* constructor
*/

	/**
* constructor
*/

	function queue()

	function __construct()

	{
global $phpEx, $phpbb_root_path, $phpbb_filesystem, $phpbb_container;


	{
global $phpEx, $phpbb_root_path, $phpbb_filesystem, $phpbb_container;


Line 750Line 825
	*/
function process()
{

	*/
function process()
{

		global $config, $phpEx, $phpbb_root_path, $user;

		global $config, $phpEx, $phpbb_root_path, $user, $phpbb_dispatcher;


$lock = new \phpbb\lock\flock($this->cache_file);
$lock->acquire();


$lock = new \phpbb\lock\flock($this->cache_file);
$lock->acquire();

Line 782Line 857
			}

$package_size = $data_ary['package_size'];

			}

$package_size = $data_ary['package_size'];

			$num_items = (!$package_size || sizeof($data_ary['data']) < $package_size) ? sizeof($data_ary['data']) : $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.


/*
* This code is commented out because it causes problems on some web hosts.

Line 791Line 866
			* 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...

			* 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 (sizeof($data_ary['data']) > $package_size * 2.5)

			if (count($data_ary['data']) > $package_size * 2.5)

			{

			{

				$num_items = sizeof($data_ary['data']);

				$num_items = count($data_ary['data']);

			}
*/


			}
*/


Line 816Line 891
					}

include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);

					}

include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);

					$this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']);

					$this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl'], $config['jab_verify_peer'], $config['jab_verify_peer_name'], $config['jab_allow_self_signed']);


if (!$this->jabber->connect())
{


if (!$this->jabber->connect())
{

Line 847Line 922
				switch ($object)
{
case 'email':

				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 array addresses The message recipients
* @var string subject The message subject
* @var string msg The message text
* @since 3.2.4-RC1
*/
$vars = array(
'break',
'addresses',
'subject',
'msg',
);
extract($phpbb_dispatcher->trigger_event('core.notification_message_process', compact($vars)));

if (!$break)
{

						$err_msg = '';
$to = (!$to) ? 'undisclosed-recipients:;' : $to;


						$err_msg = '';
$to = (!$to) ? 'undisclosed-recipients:;' : $to;


Line 864Line 960
							$messenger = new messenger();
$messenger->error('EMAIL', $err_msg);
continue 2;

							$messenger = new messenger();
$messenger->error('EMAIL', $err_msg);
continue 2;

 
							}

						}
break;


						}
break;


Line 882Line 979
			}

// No more data for this object? Unset it

			}

// No more data for this object? Unset it

			if (!sizeof($this->queue_data[$object]['data']))

			if (!count($this->queue_data[$object]['data']))

			{
unset($this->queue_data[$object]);
}

			{
unset($this->queue_data[$object]);
}

Line 898Line 995
			}
}


			}
}


		if (!sizeof($this->queue_data))

		if (!count($this->queue_data))

		{
@unlink($this->cache_file);
}

		{
@unlink($this->cache_file);
}

Line 933Line 1030
	*/
function save()
{

	*/
function save()
{

		if (!sizeof($this->data))

		if (!count($this->data))

		{
return;
}

		{
return;
}

Line 947Line 1044

foreach ($this->queue_data as $object => $data_ary)
{


foreach ($this->queue_data as $object => $data_ary)
{

				if (isset($this->data[$object]) && sizeof($this->data[$object]))

				if (isset($this->data[$object]) && count($this->data[$object]))

				{
$this->data[$object]['data'] = array_merge($data_ary['data'], $this->data[$object]['data']);
}

				{
$this->data[$object]['data'] = array_merge($data_ary['data'], $this->data[$object]['data']);
}

Line 1035Line 1132
	$mail_rcpt = $mail_to = $mail_cc = array();

// Build correct addresses for RCPT TO command and the client side display (TO, CC)

	$mail_rcpt = $mail_to = $mail_cc = array();

// Build correct addresses for RCPT TO command and the client side display (TO, CC)

	if (isset($addresses['to']) && sizeof($addresses['to']))

	if (isset($addresses['to']) && count($addresses['to']))

	{
foreach ($addresses['to'] as $which_ary)
{

	{
foreach ($addresses['to'] as $which_ary)
{

Line 1044Line 1141
		}
}


		}
}


	if (isset($addresses['bcc']) && sizeof($addresses['bcc']))

	if (isset($addresses['bcc']) && count($addresses['bcc']))

	{
foreach ($addresses['bcc'] as $which_ary)
{

	{
foreach ($addresses['bcc'] as $which_ary)
{

Line 1052Line 1149
		}
}


		}
}


	if (isset($addresses['cc']) && sizeof($addresses['cc']))

	if (isset($addresses['cc']) && count($addresses['cc']))

	{
foreach ($addresses['cc'] as $which_ary)
{

	{
foreach ($addresses['cc'] as $which_ary)
{

Line 1076Line 1173
	}
$collector = new \phpbb\error_collector;
$collector->install();

	}
$collector = new \phpbb\error_collector;
$collector->install();

	$smtp->socket = fsockopen($config['smtp_host'], $config['smtp_port'], $errno, $errstr, 20);













$options = array();
$verify_peer = (bool) $config['smtp_verify_peer'];
$verify_peer_name = (bool) $config['smtp_verify_peer_name'];
$allow_self_signed = (bool) $config['smtp_allow_self_signed'];
$remote_socket = $config['smtp_host'] . ':' . $config['smtp_port'];

// Set ssl context options, see http://php.net/manual/en/context.ssl.php
$options['ssl'] = array('verify_peer' => $verify_peer, 'verify_peer_name' => $verify_peer_name, 'allow_self_signed' => $allow_self_signed);
$socket_context = stream_context_create($options);

$smtp->socket = @stream_socket_client($remote_socket, $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $socket_context);

	$collector->uninstall();
$error_contents = $collector->format_errors();


	$collector->uninstall();
$error_contents = $collector->format_errors();


Line 1220Line 1328
	var $backtrace = false;
var $backtrace_log = array();


	var $backtrace = false;
var $backtrace_log = array();


	function smtp_class()

	function __construct()

	{
// Always create a backtrace for admins to identify SMTP problems
$this->backtrace = true;

	{
// Always create a backtrace for admins to identify SMTP problems
$this->backtrace = true;

Line 1473Line 1581
	*/
protected function starttls()
{

	*/
protected function starttls()
{

 
		global $config;

// allow SMTPS (what was used by phpBB 3.0) if hostname is prefixed with tls:// or ssl://
if (strpos($config['smtp_host'], 'tls://') === 0 || strpos($config['smtp_host'], 'ssl://') === 0)
{
return true;
}


		if (!function_exists('stream_socket_enable_crypto'))
{
return false;

		if (!function_exists('stream_socket_enable_crypto'))
{
return false;

Line 1495Line 1611

if (socket_set_blocking($this->socket, 1))
{


if (socket_set_blocking($this->socket, 1))
{

			$result = stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);



			// https://secure.php.net/manual/en/function.stream-socket-enable-crypto.php#119122
$crypto = (phpbb_version_compare(PHP_VERSION, '5.6.7', '<')) ? STREAM_CRYPTO_METHOD_TLS_CLIENT : STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
$result = stream_socket_enable_crypto($this->socket, true, $crypto);

			socket_set_blocking($this->socket, (int) $stream_meta['blocked']);
}


			socket_set_blocking($this->socket, (int) $stream_meta['blocked']);
}


Line 1759Line 1877
	$array = utf8_str_split($str);
$str = '';


	$array = utf8_str_split($str);
$str = '';


	while (sizeof($array))

	while (count($array))

	{
$text = '';


	{
$text = '';


		while (sizeof($array) && intval((strlen($text . $array[0]) + 2) / 3) << 2 <= $split_length)

		while (count($array) && intval((strlen($text . $array[0]) + 2) / 3) << 2 <= $split_length)

		{
$text .= array_shift($array);
}

		{
$text .= array_shift($array);
}

Line 1781Line 1899
{
global $config, $phpbb_root_path, $phpEx;


{
global $config, $phpbb_root_path, $phpEx;


	// We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings. On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used...
// Reference: http://bugs.php.net/bug.php?id=15841








	// Convert Numeric Character References to UTF-8 chars (ie. Emojis)
$subject = utf8_decode_ncr($subject);
$msg = utf8_decode_ncr($msg);

/**
* We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings.
* On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used...
* Reference: http://bugs.php.net/bug.php?id=15841
*/

	$headers = implode($eol, $headers);

if (!class_exists('\phpbb\error_collector'))

	$headers = implode($eol, $headers);

if (!class_exists('\phpbb\error_collector'))

Line 1793Line 1918
	$collector = new \phpbb\error_collector;
$collector->install();


	$collector = new \phpbb\error_collector;
$collector->install();


	// On some PHP Versions mail() *may* fail if there are newlines within the subject.
// Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.
// Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space (Use '' as parameter to mail_encode() results in SPACE used)
$result = $config['email_function_name']($to, mail_encode($subject, ''), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers);






	/**
* On some PHP Versions mail() *may* fail if there are newlines within the subject.
* Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.
* Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space
* (Use '' as parameter to mail_encode() results in SPACE used)
*/
$additional_parameters = $config['email_force_sender'] ? '-f' . $config['board_email'] : '';

$result = mail($to, mail_encode($subject, ''), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers, $additional_parameters);


$collector->uninstall();
$err_msg = $collector->format_errors();


$collector->uninstall();
$err_msg = $collector->format_errors();