mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-08 04:18:52 +00:00
[ticket/17135] Refactor messenger code to services [ci skip]
PHPBB3-17135
This commit is contained in:
parent
1869b2a99e
commit
df5b7fd66e
5 changed files with 1213 additions and 65 deletions
|
@ -19,6 +19,7 @@ imports:
|
||||||
- { resource: services_http.yml }
|
- { resource: services_http.yml }
|
||||||
- { resource: services_language.yml }
|
- { resource: services_language.yml }
|
||||||
- { resource: services_mention.yml }
|
- { resource: services_mention.yml }
|
||||||
|
- { resource: services_messenger.yml }
|
||||||
- { resource: services_migrator.yml }
|
- { resource: services_migrator.yml }
|
||||||
- { resource: services_mimetype_guesser.yml }
|
- { resource: services_mimetype_guesser.yml }
|
||||||
- { resource: services_module.yml }
|
- { resource: services_module.yml }
|
||||||
|
|
46
phpBB/config/default/container/services_messenger.yml
Normal file
46
phpBB/config/default/container/services_messenger.yml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
parameters:
|
||||||
|
core.messenger_queue_file: '%core.cache_dir%queue.%core.php_ext%'
|
||||||
|
|
||||||
|
services:
|
||||||
|
messenger.method_collection:
|
||||||
|
class: phpbb\di\service_collection
|
||||||
|
arguments:
|
||||||
|
- '@service_container'
|
||||||
|
tags:
|
||||||
|
- { name: service_collection, tag: messenger.method, class_name_aware: true }
|
||||||
|
|
||||||
|
messenger.method_base:
|
||||||
|
class: phpbb\messenger\method\base
|
||||||
|
shared: false
|
||||||
|
arguments:
|
||||||
|
- '@config'
|
||||||
|
- '@dispatcher'
|
||||||
|
- '@language'
|
||||||
|
- '@log'
|
||||||
|
- '@request'
|
||||||
|
- '@user'
|
||||||
|
- '@messenger.queue'
|
||||||
|
|
||||||
|
messenger.method_email:
|
||||||
|
class: phpbb\messenger\method\email
|
||||||
|
shared: false
|
||||||
|
parent: messenger.method_base
|
||||||
|
calls:
|
||||||
|
- [init, []]
|
||||||
|
- [set_transport, []]
|
||||||
|
|
||||||
|
messenger.method_jabber:
|
||||||
|
class: phpbb\messenger\method\jabber
|
||||||
|
shared: false
|
||||||
|
parent: messenger.method_base
|
||||||
|
calls:
|
||||||
|
- [init, []]
|
||||||
|
|
||||||
|
messenger.queue:
|
||||||
|
class: phpbb\messenger\queue
|
||||||
|
shared: false
|
||||||
|
arguments:
|
||||||
|
- '@config'
|
||||||
|
- '@dispatcher'
|
||||||
|
- '@messenger.method_collection'
|
||||||
|
- '%core.messenger_queue_file%'
|
408
phpBB/phpbb/messenger/method/base.php
Normal file
408
phpBB/phpbb/messenger/method/base.php
Normal file
|
@ -0,0 +1,408 @@
|
||||||
|
<?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\event\dispatcher;
|
||||||
|
use phpbb\language\language;
|
||||||
|
use phpbb\log\log_interface;
|
||||||
|
use phpbb\request\request;
|
||||||
|
use phpbb\messenger\queue;
|
||||||
|
use phpbb\template\template;
|
||||||
|
use phpbb\user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Messenger base class
|
||||||
|
*/
|
||||||
|
class base
|
||||||
|
{
|
||||||
|
/** @var array */
|
||||||
|
protected $additional_headers = [];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $addresses = [];
|
||||||
|
|
||||||
|
/** @var config */
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/** @var dispatcher */
|
||||||
|
protected $dispatcher;
|
||||||
|
|
||||||
|
/** @var language */
|
||||||
|
protected $language;
|
||||||
|
|
||||||
|
/** @var log_interface */
|
||||||
|
protected $log;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $msg = '';
|
||||||
|
|
||||||
|
/** @var queue */
|
||||||
|
protected $queue;
|
||||||
|
|
||||||
|
/** @var request */
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $subject = '';
|
||||||
|
|
||||||
|
/** @var template */
|
||||||
|
protected $template;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
protected $use_queue = true;
|
||||||
|
|
||||||
|
/** @var user */
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Messenger base class constructor
|
||||||
|
*
|
||||||
|
* @param config $config
|
||||||
|
* @param dispatcher $dispatcher
|
||||||
|
* @param language $language
|
||||||
|
* @param log_interface $log
|
||||||
|
* @param request $request
|
||||||
|
* @param user $user
|
||||||
|
* @param queue $queue
|
||||||
|
*/
|
||||||
|
function __construct(config $config, dispatcher $dispatcher, language $language, log_interface $log, request $request, user $user, queue $queue)
|
||||||
|
{
|
||||||
|
$this->config = $config;
|
||||||
|
$this->dispatcher = $dispatcher;
|
||||||
|
$this->language = $language;
|
||||||
|
$this->log = $log;
|
||||||
|
$this->request = $request;
|
||||||
|
$this->user = $user;
|
||||||
|
$this->queue = $queue;
|
||||||
|
|
||||||
|
$this->set_use_queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the use of messenger queue flag
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_use_queue($use_queue = true)
|
||||||
|
{
|
||||||
|
$this->use_queue = $use_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all the data (address, template file, etc etc) to default
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->addresses = [];
|
||||||
|
$this->msg = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set addresses for to/im as available
|
||||||
|
*
|
||||||
|
* @param array $user User row
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_addresses($user)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up subject for mail
|
||||||
|
*
|
||||||
|
* @param string $subject Email subject
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function subject($subject = '')
|
||||||
|
{
|
||||||
|
$this->subject = $subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 bool
|
||||||
|
*/
|
||||||
|
public 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 = [
|
||||||
|
[
|
||||||
|
'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',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign variables to email template
|
||||||
|
*
|
||||||
|
* @param array $vars Array of VAR => VALUE to assign to email template
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function assign_vars($vars)
|
||||||
|
{
|
||||||
|
$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($blockname, $vars)
|
||||||
|
{
|
||||||
|
$this->setup_template();
|
||||||
|
|
||||||
|
$this->template->assign_block_vars($blockname, $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare message before sending out to the recipients
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function prepare_message()
|
||||||
|
{
|
||||||
|
// 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->email->getSubject();
|
||||||
|
$template = $this->template;
|
||||||
|
/**
|
||||||
|
* Event to modify the template before parsing
|
||||||
|
*
|
||||||
|
* @event core.modify_notification_template
|
||||||
|
* @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. 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add error message to log
|
||||||
|
*
|
||||||
|
* @param string $type Error type: EMAIL / etc
|
||||||
|
* @param string $msg Error message text
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public 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('PHP_SELF'), ENT_COMPAT);
|
||||||
|
$message = '<strong>' . $type . '</strong><br><em>' . htmlspecialchars($calling_page, ENT_COMPAT) . '</em><br><br>' . $msg . '<br>';
|
||||||
|
$this->log->add('critical', $this->user->data['user_id'], $this->user->ip, 'LOG_ERROR_' . $type, false, [$message]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save message data to the messemger file queue
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function save_queue()
|
||||||
|
{
|
||||||
|
$this->queue->save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup template engine
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function setup_template()
|
||||||
|
{
|
||||||
|
if ($this->template instanceof \phpbb\template\template)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_environment = new \phpbb\template\twig\environment(
|
||||||
|
$this->config,
|
||||||
|
$this->phpbb_container->get('filesystem'),
|
||||||
|
$this->phpbb_container->get('path_helper'),
|
||||||
|
$this->phpbb_container->getParameter('core.template.cache_path'),
|
||||||
|
$this->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
|
||||||
|
*
|
||||||
|
* @param string $path_name Email template path name
|
||||||
|
* @param string $paths Email template paths
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function set_template_paths($path_name, $paths)
|
||||||
|
{
|
||||||
|
$this->setup_template();
|
||||||
|
|
||||||
|
$this->template->set_custom_style($path_name, $paths);
|
||||||
|
}
|
||||||
|
}
|
576
phpBB/phpbb/messenger/method/email.php
Normal file
576
phpBB/phpbb/messenger/method/email.php
Normal file
|
@ -0,0 +1,576 @@
|
||||||
|
<?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 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Messenger class
|
||||||
|
*/
|
||||||
|
class email extends base
|
||||||
|
{
|
||||||
|
/** @var array */
|
||||||
|
private const PRIORITY_MAP = [
|
||||||
|
Email::PRIORITY_HIGHEST => 'Highest',
|
||||||
|
Email::PRIORITY_HIGH => 'High',
|
||||||
|
Email::PRIORITY_NORMAL => 'Normal',
|
||||||
|
Email::PRIORITY_LOW => 'Low',
|
||||||
|
Email::PRIORITY_LOWEST => 'Lowest',
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
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 string
|
||||||
|
*
|
||||||
|
* Symfony Mailer transport DSN
|
||||||
|
*/
|
||||||
|
protected $dsn = '';
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $from;
|
||||||
|
|
||||||
|
/** @var Symfony\Component\Mime\Header\Headers */
|
||||||
|
protected $headers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*
|
||||||
|
* Possible values are:
|
||||||
|
* Email::PRIORITY_HIGHEST
|
||||||
|
* Email::PRIORITY_HIGH
|
||||||
|
* Email::PRIORITY_NORMAL
|
||||||
|
* Email::PRIORITY_LOW
|
||||||
|
* Email::PRIORITY_LOWEST
|
||||||
|
*/
|
||||||
|
protected $mail_priority = Email::PRIORITY_NORMAL;
|
||||||
|
|
||||||
|
/** @var queue */
|
||||||
|
protected $queue;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $replyto = '';
|
||||||
|
|
||||||
|
/** @var Symfony\Component\Mailer\Transport */
|
||||||
|
protected $transport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the messenger method is enabled
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function is_enabled()
|
||||||
|
{
|
||||||
|
return (bool) $this->config['email_enable'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inits/resets the data to default
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->email = new Email();
|
||||||
|
$this->headers = $this->email->getHeaders();
|
||||||
|
$this->msg = $this->replyto = $this->from = '';
|
||||||
|
$this->mail_priority = Email::PRIORITY_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the use of messenger queue flag
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_use_queue($use_queue = true)
|
||||||
|
{
|
||||||
|
$this->use_queue = !$this->config['email_package_size'] ? false : $use_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set address as available
|
||||||
|
*
|
||||||
|
* @param array $user User row
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_addresses($user)
|
||||||
|
{
|
||||||
|
if (isset($user['user_email']) && $user['user_email'])
|
||||||
|
{
|
||||||
|
$this->to($user['user_email'], $user['username'] ?: '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets email address to send to
|
||||||
|
*
|
||||||
|
* @param string $address Email "To" recipient address
|
||||||
|
* @param string $realname Email "To" recipient name
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function to($address, $realname = '')
|
||||||
|
{
|
||||||
|
if (!$address = 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($address, $windows_empty_sendmail_path ? '' : trim($realname));
|
||||||
|
$this->email->getTo() ? $this->email->addTo($to) : $this->email->to($to);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets cc address to send to
|
||||||
|
*
|
||||||
|
* @param string $address Email carbon copy recipient address
|
||||||
|
* @param string $realname Email carbon copy recipient name
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function cc($address, $realname = '')
|
||||||
|
{
|
||||||
|
if (!$address = trim($address))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cc = new Address($address, trim($realname));
|
||||||
|
$this->email->getCc() ? $this->email->addCc($to) : $this->email->cc($to);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets bcc address to send to
|
||||||
|
*
|
||||||
|
* @param string $address Email black carbon copy recipient address
|
||||||
|
* @param string $realname Email black carbon copy recipient name
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function bcc($address, $realname = '')
|
||||||
|
{
|
||||||
|
if (!$address = trim($address))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bcc = new Address($address, trim($realname));
|
||||||
|
$this->email->getBcc() ? $this->email->addBcc($to) : $this->email->bcc($to);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the reply to address
|
||||||
|
*
|
||||||
|
* @param string $address Email "Reply to" address
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public 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
|
||||||
|
*
|
||||||
|
* @param string $address Email "from" address
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public 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
|
||||||
|
*
|
||||||
|
* @param string $subject Email subject
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function subject($subject = '')
|
||||||
|
{
|
||||||
|
parent::subject(trim($subject));
|
||||||
|
$this->email->subject($this->subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up extra mail headers
|
||||||
|
*
|
||||||
|
* @param string $header_name Email header name
|
||||||
|
* @param string $header_value Email header body
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function header($header_name, $header_value)
|
||||||
|
{
|
||||||
|
$header_name = trim($header_name);
|
||||||
|
$header_value = trim($header_value);
|
||||||
|
|
||||||
|
// addMailboxListHeader() requires value to be array
|
||||||
|
if ($this->get_header_method($header_name) == 'addMailboxListHeader')
|
||||||
|
{
|
||||||
|
$header_value = [$header_value];
|
||||||
|
}
|
||||||
|
$this->headers->addHeader($header_name, $header_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds X-AntiAbuse headers
|
||||||
|
*
|
||||||
|
* @param \phpbb\config\config $config Config object
|
||||||
|
* @param \phpbb\user $user User object
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function anti_abuse_headers($config, $user)
|
||||||
|
{
|
||||||
|
$this->header('X-AntiAbuse', 'Board servername - ' . $config['server_name']);
|
||||||
|
$this->header('X-AntiAbuse', 'User_id - ' . $user->data['user_id']);
|
||||||
|
$this->header('X-AntiAbuse', 'Username - ' . $user->data['username']);
|
||||||
|
$this->header('X-AntiAbuse', 'User IP - ' . $user->ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the email priority
|
||||||
|
*
|
||||||
|
* Possible values are:
|
||||||
|
* Email::PRIORITY_HIGHEST = 1
|
||||||
|
* Email::PRIORITY_HIGH = 2
|
||||||
|
* Email::PRIORITY_NORMAL = 3
|
||||||
|
* Email::PRIORITY_LOW = 4
|
||||||
|
* Email::PRIORITY_LOWEST = 5
|
||||||
|
*
|
||||||
|
* @param int $priority Email priority level
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_mail_priority($priority = Email::PRIORITY_NORMAL)
|
||||||
|
{
|
||||||
|
$this->email->priority($priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add error message to log
|
||||||
|
*
|
||||||
|
* @param string $msg Error message text
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function error($msg)
|
||||||
|
{
|
||||||
|
$type = 'EMAIL/' . ($this->config['smtp_delivery']) ? 'SMTP' : 'PHP/mail()';
|
||||||
|
parent::error($type, $msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save message data to the messenger file queue
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function save_queue()
|
||||||
|
{
|
||||||
|
if ($this->config['email_package_size'] && $this->use_queue && !empty($this->queue))
|
||||||
|
{
|
||||||
|
$this->queue->save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect proper Header class method to add header
|
||||||
|
*
|
||||||
|
* @param string $name Email header name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected 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
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected 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 = ['headers'];
|
||||||
|
extract($this->dispatcher->trigger_event('core.modify_email_headers', compact($vars)));
|
||||||
|
|
||||||
|
foreach ($headers as $header => $value)
|
||||||
|
{
|
||||||
|
$this->header($header, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates valid DSN for Symfony Mailer transport
|
||||||
|
*
|
||||||
|
* @param string $dsn Symfony Mailer transport DSN
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_dsn($dsn = '')
|
||||||
|
{
|
||||||
|
if (!empty($dsn))
|
||||||
|
{
|
||||||
|
$this->dsn = $dsn;
|
||||||
|
}
|
||||||
|
else if ($this->config['smtp_delivery'])
|
||||||
|
{
|
||||||
|
if (empty($this->config['smtp_host']))
|
||||||
|
{
|
||||||
|
$this->dsn = 'null://null';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$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'];
|
||||||
|
|
||||||
|
$this->dsn = "smtp://$user:$password@$smtp_host:$smtp_port";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->dsn = 'sendmail://default';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Symfony Mailer transport DSN
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function get_dsn()
|
||||||
|
{
|
||||||
|
return $this->dsn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a valid transport to send email
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_transport()
|
||||||
|
{
|
||||||
|
if (empty($this->dsn))
|
||||||
|
{
|
||||||
|
$this->set_dsn();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->transport = Transport::fromDsn($this->dsn);
|
||||||
|
|
||||||
|
if ($this->config['smtp_delivery'] && !in_array($this->dsn, ['null://null', 'sendmail://default']))
|
||||||
|
{
|
||||||
|
// Set ssl context options, see http://php.net/manual/en/context.ssl.php
|
||||||
|
$options['ssl'] = [
|
||||||
|
'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'],
|
||||||
|
];
|
||||||
|
$this->transport->getStream()->setStreamOptions($options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get mailer transport object
|
||||||
|
*
|
||||||
|
* @return Symfony\Component\Mailer\Transport Symfony Mailer transport object
|
||||||
|
*/
|
||||||
|
public function get_transport()
|
||||||
|
{
|
||||||
|
return $this->transport;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send out emails
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function send()
|
||||||
|
{
|
||||||
|
$this->prepare_message();
|
||||||
|
|
||||||
|
$contact_name = html_entity_decode($this->config['board_contact_name'], ENT_COMPAT);
|
||||||
|
$board_contact = trim($this->config['board_contact']);
|
||||||
|
|
||||||
|
$this->email->subject($this->subject);
|
||||||
|
$this->email->text($this->msg);
|
||||||
|
|
||||||
|
$subject = $this->subject;
|
||||||
|
$msg = $this->msg;
|
||||||
|
$email = $this->email;
|
||||||
|
/**
|
||||||
|
* Event to send message via external transport
|
||||||
|
*
|
||||||
|
* @event core.notification_message_email
|
||||||
|
* @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, break
|
||||||
|
*/
|
||||||
|
$vars = [
|
||||||
|
'subject',
|
||||||
|
'msg',
|
||||||
|
'email',
|
||||||
|
];
|
||||||
|
extract($this->dispatcher->trigger_event('core.notification_message_email', compact($vars)));
|
||||||
|
|
||||||
|
if (empty($this->email->getReplyto()))
|
||||||
|
{
|
||||||
|
$this->replyto($board_contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->email->getFrom()))
|
||||||
|
{
|
||||||
|
$this->from($board_contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build headers
|
||||||
|
foreach ($this->additional_headers as $header_name => $header_value)
|
||||||
|
{
|
||||||
|
$this->header($header_name, $header_value);
|
||||||
|
}
|
||||||
|
$this->build_header();
|
||||||
|
|
||||||
|
// Send message ...
|
||||||
|
if (!$this->use_queue)
|
||||||
|
{
|
||||||
|
$mailer = new Mailer($this->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($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->init('email', $this->config['email_package_size']);
|
||||||
|
$this->queue->put('email', [
|
||||||
|
'email' => $this->email,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,25 +11,20 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
namespace phpbb\messenger\method;
|
||||||
* @ignore
|
|
||||||
*/
|
|
||||||
if (!defined('IN_PHPBB'))
|
|
||||||
{
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Jabber class from Flyspray project
|
* Based on Jabber class from Flyspray project
|
||||||
*
|
*
|
||||||
* @version class.jabber2.php 1595 2008-09-19 (0.9.9)
|
* @version class.jabber2.php 1595 2008-09-19 (0.9.9)
|
||||||
* @copyright 2006 Flyspray.org
|
* @copyright 2006 Flyspray.org
|
||||||
* @author Florian Schmitz (floele)
|
* @author Florian Schmitz (floele)
|
||||||
*
|
*
|
||||||
* Only slightly modified by Acyd Burn
|
* Slightly modified by Acyd Burn (2006)
|
||||||
|
* Refactored to a service (2023)
|
||||||
*/
|
*/
|
||||||
class jabber
|
class jabber extends base
|
||||||
{
|
{
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $connect_server;
|
protected $connect_server;
|
||||||
|
@ -70,6 +65,9 @@ class jabber
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $timeout = 10;
|
protected $timeout = 10;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $to = [];
|
||||||
|
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
protected $use_ssl = false;
|
protected $use_ssl = false;
|
||||||
|
|
||||||
|
@ -80,13 +78,12 @@ class jabber
|
||||||
private const STREAM_CLOSE_HANDSHAKE = '</stream:stream>';
|
private const STREAM_CLOSE_HANDSHAKE = '</stream:stream>';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jabber class constructor
|
* Set initial parameter values
|
||||||
|
* To init correctly, username() call should go before server()
|
||||||
|
* and ssl() call should go before port() and stream_options() calls.
|
||||||
*
|
*
|
||||||
* Use (username() call should go before server()
|
* Example:
|
||||||
* and ssl() call should go before port() and stream_options()):
|
* $this->username($username)
|
||||||
*
|
|
||||||
* new jabber()
|
|
||||||
* -> username($username)
|
|
||||||
* ->password($password)
|
* ->password($password)
|
||||||
* ->ssl($use_ssl)
|
* ->ssl($use_ssl)
|
||||||
* ->server($server)
|
* ->server($server)
|
||||||
|
@ -96,9 +93,34 @@ class jabber
|
||||||
* 'verify_peer_name' => true,
|
* 'verify_peer_name' => true,
|
||||||
* 'allow_self_signed' => false,
|
* 'allow_self_signed' => false,
|
||||||
* );
|
* );
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function __construct()
|
public function init()
|
||||||
{
|
{
|
||||||
|
$this->username($this->config['jab_username'])
|
||||||
|
->password($this->config['jab_password'])
|
||||||
|
->ssl((bool) $this->config['jab_use_ssl'])
|
||||||
|
->server($this->config['jab_host'])
|
||||||
|
->port($this->config['jab_port'])
|
||||||
|
->stream_options['ssl'] = [
|
||||||
|
'verify_peer' => $this->config['jab_verify_peer'],
|
||||||
|
'verify_peer_name' => $this->config['jab_verify_peer_name'],
|
||||||
|
'allow_self_signed' => $this->config['jab_allow_self_signed'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the messenger method is enabled
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function is_enabled()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
empty($this->config['jab_enable']) ||
|
||||||
|
empty($this->config['jab_host']) ||
|
||||||
|
empty($this->config['jab_username']) ||
|
||||||
|
empty($this->config['jab_password']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,12 +134,8 @@ class jabber
|
||||||
{
|
{
|
||||||
if ($this->use_ssl)
|
if ($this->use_ssl)
|
||||||
{
|
{
|
||||||
// Set default stream options and change it if needed
|
// Change default stream options if needed
|
||||||
$this->stream_options['ssl'] = array_merge([
|
$this->stream_options['ssl'] = array_merge($this->stream_options['ssl'], $options);
|
||||||
'verify_peer' => true,
|
|
||||||
'verify_peer_name' => true,
|
|
||||||
'allow_self_signed' => false,
|
|
||||||
], $options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -131,7 +149,7 @@ class jabber
|
||||||
*/
|
*/
|
||||||
public function password($password = '')
|
public function password($password = '')
|
||||||
{
|
{
|
||||||
$this->password = $password;
|
$this->password = html_entity_decode($password, ENT_COMPAT);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -263,8 +281,8 @@ class jabber
|
||||||
|
|
||||||
if ($this->open_socket($this->connect_server, $this->port))
|
if ($this->open_socket($this->connect_server, $this->port))
|
||||||
{
|
{
|
||||||
$this->send("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
|
$this->send_xml("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
|
||||||
$this->send("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
$this->send_xml("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -331,6 +349,105 @@ class jabber
|
||||||
return $this->response($this->features);
|
return $this->response($this->features);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set address as available
|
||||||
|
*
|
||||||
|
* @param array $user User row
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_addresses($user)
|
||||||
|
{
|
||||||
|
if (isset($user['user_jabber']) && $user['user_jabber'])
|
||||||
|
{
|
||||||
|
$this->to($user['user_jabber'], (isset($user['username']) ? $user['username'] : ''));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets jabber contact to send message to
|
||||||
|
*
|
||||||
|
* @param string $address Jabber "To" recipient address
|
||||||
|
* @param string $realname Jabber "To" recipient name
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function to($address, $realname = '')
|
||||||
|
{
|
||||||
|
// IM-Addresses could be empty
|
||||||
|
if (!trim($address))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pos = !empty($this->to) ? count($this->to) : 0;
|
||||||
|
$this->to[$pos]['uid'] = trim($address);
|
||||||
|
$this->to[$pos]['name'] = trim($realname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the use of messenger queue flag
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set_use_queue($use_queue = true)
|
||||||
|
{
|
||||||
|
$this->use_queue = !$this->config['jab_package_size'] ? false : $use_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send jabber message out
|
||||||
|
*/
|
||||||
|
public function send()
|
||||||
|
{
|
||||||
|
$this->prepare_message();
|
||||||
|
|
||||||
|
if (empty($this->to))
|
||||||
|
{
|
||||||
|
$this->add_to_log('Error: Could not send, recepient addresses undefined.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$addresses = [];
|
||||||
|
foreach ($this->to as $uid_ary)
|
||||||
|
{
|
||||||
|
$addresses[] = $uid_ary['uid'];
|
||||||
|
}
|
||||||
|
$addresses = array_unique($addresses);
|
||||||
|
|
||||||
|
if (!$this->use_queue)
|
||||||
|
{
|
||||||
|
if (!$this->connect())
|
||||||
|
{
|
||||||
|
$this->error('JABBER', $this->user->lang['ERR_JAB_CONNECT'] . '<br />' . $this->get_log());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->login())
|
||||||
|
{
|
||||||
|
$this->error('JABBER', $this->user->lang['ERR_JAB_AUTH'] . '<br />' . $this->get_log());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($addresses as $address)
|
||||||
|
{
|
||||||
|
$this->send_message($address, $this->msg, $this->subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->disconnect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->queue->init('jabber', $this->config['jab_package_size']);
|
||||||
|
$this->queue->put('jabber', array(
|
||||||
|
'addresses' => $addresses,
|
||||||
|
'subject' => $this->subject,
|
||||||
|
'msg' => $this->msg)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
unset($addresses);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send data to the Jabber server
|
* Send data to the Jabber server
|
||||||
*
|
*
|
||||||
|
@ -338,7 +455,7 @@ class jabber
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function send($xml)
|
public function send_xml($xml)
|
||||||
{
|
{
|
||||||
if ($this->connected())
|
if ($this->connected())
|
||||||
{
|
{
|
||||||
|
@ -459,7 +576,7 @@ class jabber
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->send("<iq type='get' id='reg_1'><query xmlns='jabber:iq:register'/></iq>");
|
$this->send_xml("<iq type='get' id='reg_1'><query xmlns='jabber:iq:register'/></iq>");
|
||||||
return $this->response($this->listen());
|
return $this->response($this->listen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +605,7 @@ class jabber
|
||||||
|
|
||||||
$this->session['sent_presence'] = !$unavailable;
|
$this->session['sent_presence'] = !$unavailable;
|
||||||
|
|
||||||
return $this->send("<presence$unavailable>" . $type . $message . '</presence>');
|
return $this->send_xml("<presence$unavailable>" . $type . $message . '</presence>');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -567,7 +684,7 @@ class jabber
|
||||||
// session required?
|
// session required?
|
||||||
$this->session['sess_required'] = isset($xml['stream:features'][0]['#']['session']);
|
$this->session['sess_required'] = isset($xml['stream:features'][0]['#']['session']);
|
||||||
|
|
||||||
$this->send("<iq type='set' id='bind_1'>
|
$this->send_xml("<iq type='set' id='bind_1'>
|
||||||
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
|
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
|
||||||
<resource>" . utf8_htmlspecialchars($this->resource) . '</resource>
|
<resource>" . utf8_htmlspecialchars($this->resource) . '</resource>
|
||||||
</bind>
|
</bind>
|
||||||
|
@ -579,7 +696,7 @@ class jabber
|
||||||
if (!$this->session['ssl'] && self::can_use_tls() && self::can_use_ssl() && isset($xml['stream:features'][0]['#']['starttls']))
|
if (!$this->session['ssl'] && self::can_use_tls() && self::can_use_ssl() && isset($xml['stream:features'][0]['#']['starttls']))
|
||||||
{
|
{
|
||||||
$this->add_to_log('Switching to TLS.');
|
$this->add_to_log('Switching to TLS.');
|
||||||
$this->send("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n");
|
$this->send_xml("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n");
|
||||||
return $this->response($this->listen());
|
return $this->response($this->listen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,18 +722,18 @@ class jabber
|
||||||
|
|
||||||
if (in_array('DIGEST-MD5', $methods))
|
if (in_array('DIGEST-MD5', $methods))
|
||||||
{
|
{
|
||||||
$this->send("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>");
|
$this->send_xml("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>");
|
||||||
}
|
}
|
||||||
else if (in_array('PLAIN', $methods) && ($this->session['ssl'] || !empty($this->session['tls'])))
|
else if (in_array('PLAIN', $methods) && ($this->session['ssl'] || !empty($this->session['tls'])))
|
||||||
{
|
{
|
||||||
// http://www.ietf.org/rfc/rfc4616.txt (PLAIN SASL Mechanism)
|
// http://www.ietf.org/rfc/rfc4616.txt (PLAIN SASL Mechanism)
|
||||||
$this->send("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>"
|
$this->send_xml("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>"
|
||||||
. base64_encode($this->username . '@' . $this->server . chr(0) . $this->username . chr(0) . $this->password) .
|
. base64_encode($this->username . '@' . $this->server . chr(0) . $this->username . chr(0) . $this->password) .
|
||||||
'</auth>');
|
'</auth>');
|
||||||
}
|
}
|
||||||
else if (in_array('ANONYMOUS', $methods))
|
else if (in_array('ANONYMOUS', $methods))
|
||||||
{
|
{
|
||||||
$this->send("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>");
|
$this->send_xml("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -653,7 +770,7 @@ class jabber
|
||||||
// second challenge?
|
// second challenge?
|
||||||
if (isset($decoded['rspauth']))
|
if (isset($decoded['rspauth']))
|
||||||
{
|
{
|
||||||
$this->send("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>");
|
$this->send_xml("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -680,7 +797,7 @@ class jabber
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->send("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" . base64_encode($this->implode_data($response)) . '</response>');
|
$this->send_xml("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" . base64_encode($this->implode_data($response)) . '</response>');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->response($this->listen());
|
return $this->response($this->listen());
|
||||||
|
@ -707,15 +824,15 @@ class jabber
|
||||||
$this->session['tls'] = true;
|
$this->session['tls'] = true;
|
||||||
|
|
||||||
// new stream
|
// new stream
|
||||||
$this->send("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
|
$this->send_xml("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
|
||||||
$this->send("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
$this->send_xml("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
||||||
|
|
||||||
return $this->response($this->listen());
|
return $this->response($this->listen());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'success':
|
case 'success':
|
||||||
// Yay, authentication successful.
|
// Yay, authentication successful.
|
||||||
$this->send("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
$this->send_xml("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
||||||
$this->session['authenticated'] = true;
|
$this->session['authenticated'] = true;
|
||||||
|
|
||||||
// we have to wait for another response
|
// we have to wait for another response
|
||||||
|
@ -738,7 +855,7 @@ class jabber
|
||||||
// and (maybe) yet another request to be able to send messages *finally*
|
// and (maybe) yet another request to be able to send messages *finally*
|
||||||
if ($this->session['sess_required'])
|
if ($this->session['sess_required'])
|
||||||
{
|
{
|
||||||
$this->send("<iq to='{$this->server}' type='set' id='sess_1'>
|
$this->send_xml("<iq to='{$this->server}' type='set' id='sess_1'>
|
||||||
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
|
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
|
||||||
</iq>");
|
</iq>");
|
||||||
return $this->response($this->listen());
|
return $this->response($this->listen());
|
||||||
|
@ -752,7 +869,7 @@ class jabber
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'reg_1':
|
case 'reg_1':
|
||||||
$this->send("<iq type='set' id='reg_2'>
|
$this->send_xml("<iq type='set' id='reg_2'>
|
||||||
<query xmlns='jabber:iq:register'>
|
<query xmlns='jabber:iq:register'>
|
||||||
<username>" . utf8_htmlspecialchars($this->username) . "</username>
|
<username>" . utf8_htmlspecialchars($this->username) . "</username>
|
||||||
<password>" . utf8_htmlspecialchars($this->password) . "</password>
|
<password>" . utf8_htmlspecialchars($this->password) . "</password>
|
||||||
|
@ -829,7 +946,7 @@ class jabber
|
||||||
$type = 'normal';
|
$type = 'normal';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->send("<message from='" . utf8_htmlspecialchars($this->session['jid']) . "' to='" . utf8_htmlspecialchars($to) . "' type='$type' id='" . uniqid('msg') . "'>
|
return $this->send_xml("<message from='" . utf8_htmlspecialchars($this->session['jid']) . "' to='" . utf8_htmlspecialchars($to) . "' type='$type' id='" . uniqid('msg') . "'>
|
||||||
<subject>" . utf8_htmlspecialchars($subject) . "</subject>
|
<subject>" . utf8_htmlspecialchars($subject) . "</subject>
|
||||||
<body>" . utf8_htmlspecialchars($text) . "</body>
|
<body>" . utf8_htmlspecialchars($text) . "</body>
|
||||||
</message>"
|
</message>"
|
Loading…
Add table
Reference in a new issue