mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-07 20:08:53 +00:00
Also use union types consistently instead of question marks. Fixed with php-cs-fixer. PHPBB-17496
484 lines
12 KiB
PHP
484 lines
12 KiB
PHP
<?php
|
|
/**
|
|
*
|
|
* This file is part of the phpBB Forum Software package.
|
|
*
|
|
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
|
* @license GNU General Public License, version 2 (GPL-2.0)
|
|
*
|
|
* For full copyright and license information, please see
|
|
* the docs/CREDITS.txt file.
|
|
*
|
|
*/
|
|
|
|
namespace phpbb\messenger\method;
|
|
|
|
use phpbb\config\config;
|
|
use phpbb\di\service_collection;
|
|
use phpbb\event\dispatcher;
|
|
use phpbb\extension\manager;
|
|
use phpbb\language\language;
|
|
use phpbb\log\log_interface;
|
|
use phpbb\path_helper;
|
|
use phpbb\request\request;
|
|
use phpbb\messenger\queue;
|
|
use phpbb\template\assets_bag;
|
|
use phpbb\template\twig\lexer;
|
|
use phpbb\user;
|
|
|
|
/**
|
|
* Messenger base class
|
|
*/
|
|
abstract class base implements messenger_interface
|
|
{
|
|
/** @var array */
|
|
protected $additional_headers = [];
|
|
|
|
/** @var assets_bag */
|
|
protected $assets_bag;
|
|
|
|
/** @var config */
|
|
protected $config;
|
|
|
|
/** @var dispatcher */
|
|
protected $dispatcher;
|
|
|
|
/** @var manager */
|
|
protected $ext_manager;
|
|
|
|
/** @var language */
|
|
protected $language;
|
|
|
|
/** @var log_interface */
|
|
protected $log;
|
|
|
|
/** @var string */
|
|
protected $msg = '';
|
|
|
|
/** @var queue */
|
|
protected $queue;
|
|
|
|
/** @var path_helper */
|
|
protected $path_helper;
|
|
|
|
/** @var request */
|
|
protected $request;
|
|
|
|
/** @var string */
|
|
protected $root_path;
|
|
|
|
/** @var string */
|
|
protected $subject = '';
|
|
|
|
/** @var \phpbb\template\template */
|
|
protected $template;
|
|
|
|
/** @var string */
|
|
protected $template_cache_path;
|
|
|
|
/** @var service_collection */
|
|
protected $twig_extensions_collection;
|
|
|
|
/** @var lexer */
|
|
protected $twig_lexer;
|
|
|
|
/** @var bool */
|
|
protected $use_queue = true;
|
|
|
|
/** @var user */
|
|
protected $user;
|
|
|
|
/**
|
|
* Messenger base class constructor
|
|
*
|
|
* @param assets_bag $assets_bag
|
|
* @param config $config
|
|
* @param dispatcher $dispatcher
|
|
* @param language $language
|
|
* @param queue $queue
|
|
* @param path_helper $path_helper
|
|
* @param request $request
|
|
* @param service_collection $twig_extensions_collection
|
|
* @param lexer $twig_lexer
|
|
* @param user $user
|
|
* @param string $phpbb_root_path
|
|
* @param string $template_cache_path
|
|
* @param manager $ext_manager
|
|
* @param log_interface $log
|
|
*/
|
|
public function __construct(
|
|
assets_bag $assets_bag,
|
|
config $config,
|
|
dispatcher $dispatcher,
|
|
language $language,
|
|
queue $queue,
|
|
path_helper $path_helper,
|
|
request $request,
|
|
service_collection $twig_extensions_collection,
|
|
lexer $twig_lexer,
|
|
user $user,
|
|
string $phpbb_root_path,
|
|
string $template_cache_path,
|
|
manager|null $ext_manager = null,
|
|
log_interface|null $log = null
|
|
)
|
|
{
|
|
$this->assets_bag = $assets_bag;
|
|
$this->config = $config;
|
|
$this->dispatcher = $dispatcher;
|
|
$this->ext_manager = $ext_manager;
|
|
$this->language = $language;
|
|
$this->log = $log;
|
|
$this->queue = $queue;
|
|
$this->path_helper = $path_helper;
|
|
$this->request = $request;
|
|
$this->twig_extensions_collection = $twig_extensions_collection;
|
|
$this->twig_lexer = $twig_lexer;
|
|
$this->user = $user;
|
|
$this->root_path = $phpbb_root_path;
|
|
$this->template_cache_path = $template_cache_path;
|
|
|
|
$this->set_use_queue();
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
abstract public function is_enabled(): bool;
|
|
|
|
/**
|
|
* Sets the use of messenger queue flag
|
|
*
|
|
* @param bool $use_queue Flag indicating if cached queue to be used
|
|
*
|
|
* @return void
|
|
*/
|
|
public function set_use_queue(bool $use_queue = true): void
|
|
{
|
|
$this->use_queue = $use_queue;
|
|
}
|
|
|
|
/**
|
|
* Initializes all the data (address, template file, etc) or resets to default
|
|
*
|
|
* @return void
|
|
*/
|
|
abstract public function init(): void;
|
|
|
|
/**
|
|
* Set addresses for to/im as available
|
|
*
|
|
* @param array $user_row User row
|
|
*
|
|
* @return void
|
|
*/
|
|
abstract public function set_addresses(array $user_row): void;
|
|
|
|
/**
|
|
* Get messenger method fie queue object name
|
|
*
|
|
* @return string
|
|
*/
|
|
abstract public function get_queue_object_name(): string;
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function subject(string $subject = ''): void
|
|
{
|
|
$this->subject = $subject;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
abstract public function send(): bool;
|
|
|
|
/**
|
|
* Send messages from the queue
|
|
*
|
|
* @param array $queue_data Queue data array
|
|
*
|
|
* @return void
|
|
*/
|
|
abstract public function process_queue(array &$queue_data): void;
|
|
|
|
/**
|
|
* Set email template to use
|
|
*
|
|
* @param string $template_file Email template file name
|
|
* @param string $template_lang Email template language
|
|
* @param string $template_path Email template path
|
|
* @param string $template_dir_prefix Email template directory prefix
|
|
*
|
|
* @return void
|
|
*/
|
|
public function template(string $template_file, string $template_lang = '', string $template_path = '', string $template_dir_prefix = ''): void
|
|
{
|
|
$template_dir_prefix = (!$template_dir_prefix || $template_dir_prefix[0] === '/') ? $template_dir_prefix : '/' . $template_dir_prefix;
|
|
|
|
$this->setup_template();
|
|
|
|
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 = [
|
|
[
|
|
'name' => $template_lang . '_email',
|
|
'ext_path' => 'language/' . $template_lang . '/email' . $template_dir_prefix,
|
|
],
|
|
];
|
|
|
|
if ($template_path)
|
|
{
|
|
$template_paths = [
|
|
$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 = [
|
|
$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[] = [
|
|
'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[] = [
|
|
'name' => 'en_email',
|
|
'ext_path' => 'language/en/email' . $template_dir_prefix,
|
|
];
|
|
}
|
|
}
|
|
|
|
$this->set_template_paths($ext_template_paths, $template_paths);
|
|
|
|
$this->template->set_filenames([
|
|
'body' => $template_file . '.txt',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Assign variables to email template
|
|
*
|
|
* @param array $vars Array of VAR => VALUE to assign to email template
|
|
*
|
|
* @return void
|
|
*/
|
|
public function assign_vars(array $vars): void
|
|
{
|
|
$this->setup_template();
|
|
$this->template->assign_vars($vars);
|
|
}
|
|
|
|
/**
|
|
* Assign block of variables to email template
|
|
*
|
|
* @param string $blockname Template block name
|
|
* @param array $vars Array of VAR => VALUE to assign to email template block
|
|
*
|
|
* @return void
|
|
*/
|
|
public function assign_block_vars(string $blockname, array $vars): void
|
|
{
|
|
$this->setup_template();
|
|
|
|
$this->template->assign_block_vars($blockname, $vars);
|
|
}
|
|
|
|
/**
|
|
* Prepare message before sending out to the recipients
|
|
*
|
|
* @return void
|
|
*/
|
|
public function prepare_message(): void
|
|
{
|
|
// 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('<br />', "\n", "-- \n" . html_entity_decode($this->config['board_email_sig'], ENT_COMPAT)),
|
|
'SITENAME' => html_entity_decode($this->config['sitename'], ENT_COMPAT),
|
|
]);
|
|
|
|
$subject = $this->subject;
|
|
$template = $this->template;
|
|
/**
|
|
* Event to modify the template before parsing
|
|
*
|
|
* @event core.modify_notification_template
|
|
* @var string subject The message subject
|
|
* @var string template The (readonly) template object
|
|
* @since 3.2.4-RC1
|
|
* @changed 4.0.0-a1 Removed vars: method, break.
|
|
*/
|
|
$vars = ['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 string message The message text
|
|
* @var string subject The message subject
|
|
* @since 3.1.11-RC1
|
|
* @changed 4.0.0-a1 Removed vars: method, break.
|
|
*/
|
|
$vars = ['message', 'subject'];
|
|
extract($this->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);
|
|
|
|
// 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 = [];
|
|
if (preg_match('#^(Subject):(.*?)$#m', $this->msg, $match))
|
|
{
|
|
$this->subject = (trim($match[2]) != '') ? trim($match[2]) : (($this->subject != '') ? $this->subject : $this->language->lang('NO_EMAIL_SUBJECT'));
|
|
$drop_header .= '[\r\n]*?' . preg_quote($match[0], '#');
|
|
}
|
|
else
|
|
{
|
|
$this->subject = (($this->subject != '') ? $this->subject : $this->language->lang('NO_EMAIL_SUBJECT'));
|
|
}
|
|
|
|
if (preg_match('#^(List-Unsubscribe):(.*?)$#m', $this->msg, $match))
|
|
{
|
|
$drop_header .= '[\r\n]*?' . preg_quote($match[0], '#');
|
|
$this->additional_headers[$match[1]] = trim($match[2]);
|
|
}
|
|
|
|
if ($drop_header)
|
|
{
|
|
$this->msg = trim(preg_replace('#' . $drop_header . '#s', '', $this->msg));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function error(string $msg): void
|
|
{
|
|
// Session doesn't exist, create it
|
|
if (!isset($this->user->session_id) || $this->user->session_id === '')
|
|
{
|
|
$this->user->session_begin();
|
|
}
|
|
|
|
$type = strtoupper($this->get_queue_object_name());
|
|
$calling_page = html_entity_decode($this->request->server('PHP_SELF'), ENT_COMPAT);
|
|
$message = '<strong>' . $type . '</strong><br><em>' . htmlspecialchars($calling_page, ENT_COMPAT) . '</em><br><br>' . $msg . '<br>';
|
|
if ($this->log)
|
|
{
|
|
$this->log->add('critical', $this->user->data['user_id'], $this->user->ip, 'LOG_ERROR_' . $type, false, [$message]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save message data to the messenger file queue
|
|
*
|
|
* @return void
|
|
*/
|
|
public function save_queue(): void
|
|
{
|
|
if ($this->use_queue)
|
|
{
|
|
$this->queue->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup template engine
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function setup_template(): void
|
|
{
|
|
if (isset($this->template) && $this->template instanceof \phpbb\template\template)
|
|
{
|
|
return;
|
|
}
|
|
|
|
$template_environment = new \phpbb\template\twig\environment(
|
|
$this->assets_bag,
|
|
$this->config,
|
|
new \phpbb\filesystem\filesystem(),
|
|
$this->path_helper,
|
|
$this->template_cache_path,
|
|
$this->ext_manager,
|
|
new \phpbb\template\twig\loader(),
|
|
$this->dispatcher,
|
|
[]
|
|
);
|
|
$template_environment->setLexer($this->twig_lexer);
|
|
|
|
$this->template = new \phpbb\template\twig\twig(
|
|
$this->path_helper,
|
|
$this->config,
|
|
new \phpbb\template\context(),
|
|
$template_environment,
|
|
$this->template_cache_path,
|
|
$this->user,
|
|
$this->twig_extensions_collection,
|
|
$this->ext_manager
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Set template paths to load
|
|
*
|
|
* @param string|array $path_name Email template path name
|
|
* @param string|array $paths Email template paths
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function set_template_paths(array|string $path_name, array|string $paths): void
|
|
{
|
|
$this->setup_template();
|
|
$this->template->set_custom_style($path_name, $paths);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function header(string $header_name, mixed $header_value): void
|
|
{
|
|
}
|
|
}
|