[ticket/17314] Parse avatars for push notifications

PHPBB3-17314

Signed-off-by: Matt Friedman <maf675@gmail.com>
This commit is contained in:
Matt Friedman 2024-05-16 19:12:34 -07:00
parent b8e66f43dc
commit de05dcf96c
No known key found for this signature in database
4 changed files with 65 additions and 4 deletions

View file

@ -253,6 +253,7 @@ services:
- '@log' - '@log'
- '@user_loader' - '@user_loader'
- '@user' - '@user'
- '@path_helper'
- '%core.root_path%' - '%core.root_path%'
- '%core.php_ext%' - '%core.php_ext%'
- '%tables.notification_push%' - '%tables.notification_push%'

View file

@ -20,6 +20,7 @@ use phpbb\db\driver\driver_interface;
use phpbb\form\form_helper; use phpbb\form\form_helper;
use phpbb\log\log_interface; use phpbb\log\log_interface;
use phpbb\notification\type\type_interface; use phpbb\notification\type\type_interface;
use phpbb\path_helper;
use phpbb\user; use phpbb\user;
use phpbb\user_loader; use phpbb\user_loader;
@ -42,6 +43,9 @@ class webpush extends messenger_base implements extended_method_interface
/** @var user */ /** @var user */
protected $user; protected $user;
/** @var path_helper */
protected $path_helper;
/** @var string Notification Web Push table */ /** @var string Notification Web Push table */
protected $notification_webpush_table; protected $notification_webpush_table;
@ -56,13 +60,14 @@ class webpush extends messenger_base implements extended_method_interface
* @param log_interface $log * @param log_interface $log
* @param user_loader $user_loader * @param user_loader $user_loader
* @param user $user * @param user $user
* @param path_helper $path_helper
* @param string $phpbb_root_path * @param string $phpbb_root_path
* @param string $php_ext * @param string $php_ext
* @param string $notification_webpush_table * @param string $notification_webpush_table
* @param string $push_subscriptions_table * @param string $push_subscriptions_table
*/ */
public function __construct(config $config, driver_interface $db, log_interface $log, user_loader $user_loader, user $user, string $phpbb_root_path, public function __construct(config $config, driver_interface $db, log_interface $log, user_loader $user_loader, user $user, path_helper $path_helper,
string $php_ext, string $notification_webpush_table, string $push_subscriptions_table) string $phpbb_root_path, string $php_ext, string $notification_webpush_table, string $push_subscriptions_table)
{ {
parent::__construct($user_loader, $phpbb_root_path, $php_ext); parent::__construct($user_loader, $phpbb_root_path, $php_ext);
@ -70,6 +75,7 @@ class webpush extends messenger_base implements extended_method_interface
$this->db = $db; $this->db = $db;
$this->log = $log; $this->log = $log;
$this->user = $user; $this->user = $user;
$this->path_helper = $path_helper;
$this->notification_webpush_table = $notification_webpush_table; $this->notification_webpush_table = $notification_webpush_table;
$this->push_subscriptions_table = $push_subscriptions_table; $this->push_subscriptions_table = $push_subscriptions_table;
} }
@ -131,7 +137,7 @@ class webpush extends messenger_base implements extended_method_interface
'title' => strip_tags($notification->get_title()), 'title' => strip_tags($notification->get_title()),
'text' => strip_tags($notification->get_reference()), 'text' => strip_tags($notification->get_reference()),
'url' => htmlspecialchars_decode($notification->get_url()), 'url' => htmlspecialchars_decode($notification->get_url()),
'avatar' => $notification->get_avatar(), 'avatar' => $this->prepare_avatar($notification->get_avatar()),
]), ]),
'notification_time' => time(), 'notification_time' => time(),
]; ];
@ -429,4 +435,44 @@ class webpush extends messenger_base implements extended_method_interface
$this->remove_subscriptions($remove_subscriptions); $this->remove_subscriptions($remove_subscriptions);
} }
/**
* Takes an avatar string (usually in full html format already) and extracts the url.
* If the avatar url is a relative path, it's converted to an absolute path.
*
* Converts:
* <img class="avatar" src="./path/to/avatar=123456789.gif" width="123" height="123" alt="User avatar" />
* or <img class="avatar" src="./styles/prosilver/theme/images/no_avatar.gif" data-src="./path/to/avatar=123456789.gif" width="123" height="123" alt="User avatar" />
* into https://myboard.url/path/to/avatar=123456789.gif
*
* @param string $avatar
* @return string Absolute path to avatar image
*/
protected function prepare_avatar(string $avatar): string
{
$pattern = '/src=["\']?([^"\'>]+)["\']?/';
preg_match_all($pattern, $avatar, $matches);
$path = !empty($matches[1]) ? end($matches[1]) : $avatar;
return preg_replace('#^' . preg_quote($this->path_helper->get_web_root_path(), '#') . '#', $this->get_board_url(), $path, 1);
}
/**
* Returns the board url (and caches it in the function)
*
* @return string the generated board url
*/
protected function get_board_url(): string
{
static $board_url;
if (empty($board_url))
{
$board_url = generate_board_url() . '/';
}
return $board_url;
}
} }

View file

@ -36,7 +36,7 @@ self.addEventListener('push', event => {
const options = { const options = {
body: responseBody, body: responseBody,
data: response, data: response,
icon: response.avatar.src, icon: response.avatar,
}; };
self.registration.showNotification(response.heading, options); self.registration.showNotification(response.heading, options);
}); });

View file

@ -122,6 +122,18 @@ class notification_method_webpush_test extends phpbb_tests_notification_base
$phpEx $phpEx
); );
$request = new \phpbb_mock_request;
$symfony_request = new \phpbb\symfony_request(
$request
);
$filesystem = new \phpbb\filesystem\filesystem();
$phpbb_path_helper = new \phpbb\path_helper(
$symfony_request,
$request,
$phpbb_root_path,
$phpEx
);
$log_table = 'phpbb_log'; $log_table = 'phpbb_log';
$this->log = new \phpbb\log\log($this->db, $user, $auth, $this->phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, $log_table); $this->log = new \phpbb\log\log($this->db, $user, $auth, $this->phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, $log_table);
@ -139,6 +151,7 @@ class notification_method_webpush_test extends phpbb_tests_notification_base
$phpbb_container->set('log', $this->log); $phpbb_container->set('log', $this->log);
$phpbb_container->set('text_formatter.utils', new \phpbb\textformatter\s9e\utils()); $phpbb_container->set('text_formatter.utils', new \phpbb\textformatter\s9e\utils());
$phpbb_container->set('dispatcher', $this->phpbb_dispatcher); $phpbb_container->set('dispatcher', $this->phpbb_dispatcher);
$phpbb_container->set('path_helper', $phpbb_path_helper);
$phpbb_container->setParameter('core.root_path', $phpbb_root_path); $phpbb_container->setParameter('core.root_path', $phpbb_root_path);
$phpbb_container->setParameter('core.php_ext', $phpEx); $phpbb_container->setParameter('core.php_ext', $phpEx);
$phpbb_container->setParameter('tables.notifications', 'phpbb_notifications'); $phpbb_container->setParameter('tables.notifications', 'phpbb_notifications');
@ -177,6 +190,7 @@ class notification_method_webpush_test extends phpbb_tests_notification_base
$phpbb_container->get('log'), $phpbb_container->get('log'),
$phpbb_container->get('user_loader'), $phpbb_container->get('user_loader'),
$phpbb_container->get('user'), $phpbb_container->get('user'),
$phpbb_container->get('path_helper'),
$phpbb_root_path, $phpbb_root_path,
$phpEx, $phpEx,
$phpbb_container->getParameter('tables.notification_push'), $phpbb_container->getParameter('tables.notification_push'),