Skip to content

Commit ac7221a

Browse files
committed
Merge branch 'main' into prep-1.0.1
2 parents d744ee9 + 1799091 commit ac7221a

File tree

6 files changed

+157
-144
lines changed

6 files changed

+157
-144
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,24 @@ To run this extension from the repo (and not from a pre-built package) on a loca
3333

3434
## Testing Push Notifications
3535

36-
Testing push notifications necessitates user-to-user interactions to observe the notification behavior accurately. Follow the steps outlined below to effectively test push notifications:
36+
Testing push notifications necessitates user-to-user interactions to observe the notification behavior accurately. Follow the steps outlined below to effectively test push notifications (the browser recommendations are what we have seen work in local environments):
3737

3838
1. **User Account Setup:**
39-
- Create at least two distinct user accounts for testing purposes.
40-
- In the notifications preferences for _**User Account 1**_, subscribe to receive Push Notifications (and assign web push notification types if necessary).
39+
- Create at least two distinct board user accounts for testing purposes.
40+
- Using Google Chrome, visit `UCP -> Board Preferences -> Edit notification options` for _**User Account 1**_ and enable Push Notifications (and enable all web push notification types if necessary). Your browser may ask you to allow notifications, which you should accept. Leave Chrome open and running the background.
4141

4242
2. **Message, Quote, or Reply Interaction:**
43-
- Initiate a user-to-user interaction by performing one of the following actions using _**User Account 2**_:
43+
- Initiate a user-to-user interaction by performing one of the following actions using _**User Account 2**_ in separate browser such as Firefox, Edge or Safari:
4444
- **Private Message:** Send a direct message from _**User Account 2**_ to _**User Account 1**_.
4545
- **Quote:** Quote a post or message authored by _**User Account 1**_ using _**User Account 2**_.
4646
- **Reply:** Respond to a post or message authored by _**User Account 1**_ using _**User Account 2**_.
4747

4848
3. **Observing Push Notifications:**
49-
- Once the interaction is performed from _**User Account 2**_ to engage with _**User Account 1**_, you promptly should see a notification for _**User Account 1**_.
49+
- Once the interaction is performed from _**User Account 2**_ to engage with _**User Account 1**_, you promptly should see a notification from Google Chrome for _**User Account 1**_.
5050

5151
4. **Caveats for Local Testing**
52-
- Local testing of Push Notifications only works from a `localhost` address or if your local server has a secure SSL certificate.
53-
- We have seen success on Windows using manually installed PHP, Apache and MySQL. However, for reasons not yet known we do not see success on Mac using MAMP.
52+
- Local testing of Push Notifications only works from a `http://localhost` address or if your local test server has a secure SSL certificate, e.g.: `https://local.phpbb.board`.
53+
- Depending on your local server's setup, operating system, and browsers, it is still possible that testing push notifications may not work (for example, in a local environment running on macOS, only Chrome will show notifications).
5454

5555
## License
5656

config/services.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ services:
3030
arguments:
3131
- '@config'
3232
- '@dbal.conn'
33-
- '@language'
3433
- '@log'
3534
- '@user_loader'
3635
- '@user'
@@ -49,8 +48,11 @@ services:
4948
- '@controller.helper'
5049
- '@dbal.conn'
5150
- '@phpbb.wpn.form_helper'
51+
- '@language'
52+
- '@notification_manager'
5253
- '@path_helper'
5354
- '@request'
55+
- '@user_loader'
5456
- '@user'
5557
- '@template.twig.environment'
5658
- '%tables.phpbb.wpn.notification_push%'

notification/method/webpush.php

Lines changed: 33 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use phpbb\config\config;
1515
use phpbb\controller\helper;
1616
use phpbb\db\driver\driver_interface;
17-
use phpbb\language\language;
1817
use phpbb\log\log_interface;
1918
use phpbb\notification\method\messenger_base;
2019
use phpbb\notification\type\type_interface;
@@ -36,9 +35,6 @@ class webpush extends messenger_base implements extended_method_interface
3635
/** @var driver_interface */
3736
protected $db;
3837

39-
/** @var language */
40-
protected $language;
41-
4238
/** @var log_interface */
4339
protected $log;
4440

@@ -65,7 +61,6 @@ class webpush extends messenger_base implements extended_method_interface
6561
*
6662
* @param config $config
6763
* @param driver_interface $db
68-
* @param language $language
6964
* @param log_interface $log
7065
* @param user_loader $user_loader
7166
* @param user $user
@@ -75,14 +70,13 @@ class webpush extends messenger_base implements extended_method_interface
7570
* @param string $notification_webpush_table
7671
* @param string $push_subscriptions_table
7772
*/
78-
public function __construct(config $config, driver_interface $db, language $language, log_interface $log, user_loader $user_loader, user $user, path_helper $path_helper,
73+
public function __construct(config $config, driver_interface $db, log_interface $log, user_loader $user_loader, user $user, path_helper $path_helper,
7974
string $phpbb_root_path, string $php_ext, string $notification_webpush_table, string $push_subscriptions_table)
8075
{
8176
parent::__construct($user_loader, $phpbb_root_path, $php_ext);
8277

8378
$this->config = $config;
8479
$this->db = $db;
85-
$this->language = $language;
8680
$this->log = $log;
8781
$this->user = $user;
8882
$this->path_helper = $path_helper;
@@ -145,29 +139,15 @@ public function notify()
145139
{
146140
$insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->notification_webpush_table);
147141

148-
// Load all users data we want to notify
149-
$notify_users = $this->load_recipients_data();
150-
151142
/** @var type_interface $notification */
152143
foreach ($this->queue as $notification)
153144
{
154145
$data = $notification->get_insert_array();
155-
156-
// Change notification language if needed only
157-
$recipient_data = $this->user_loader->get_user($notification->user_id);
158-
if ($this->language->get_used_language() !== $recipient_data['user_lang'])
159-
{
160-
$this->language->set_user_language($recipient_data['user_lang'], true);
161-
}
162-
163146
$data += [
164-
'push_data' => json_encode([
165-
'heading' => $this->config['sitename'],
166-
'title' => strip_tags($notification->get_title()),
167-
'text' => strip_tags($notification->get_reference()),
168-
'url' => htmlspecialchars_decode($notification->get_url()),
169-
'avatar' => $this->prepare_avatar($notification->get_avatar()),
170-
]),
147+
'push_data' => json_encode(array_merge(
148+
$data,
149+
['notification_type_name' => $notification->get_type()]
150+
)),
171151
'notification_time' => time(),
172152
'push_token' => hash('sha256', random_bytes(32))
173153
];
@@ -178,30 +158,41 @@ public function notify()
178158

179159
$insert_buffer->flush();
180160

181-
// Restore current user's language if needed only
182-
if ($this->language->get_used_language() !== $this->user->data['user_lang'])
183-
{
184-
$this->language->set_user_language($this->user->data['user_lang'], true);
185-
}
186-
187-
$this->notify_using_webpush($notify_users);
161+
$this->notify_using_webpush();
188162

189163
return false;
190164
}
191165

192166
/**
193167
* Notify using Web Push
194168
*
195-
* @param array $notify_users Array of user ids to notify
196169
* @return void
197170
*/
198-
protected function notify_using_webpush($notify_users = []): void
171+
protected function notify_using_webpush(): void
199172
{
200173
if (empty($this->queue))
201174
{
202175
return;
203176
}
204177

178+
// Load all users we want to notify
179+
$user_ids = [];
180+
foreach ($this->queue as $notification)
181+
{
182+
$user_ids[] = $notification->user_id;
183+
}
184+
185+
// Do not send push notifications to banned users
186+
if (!function_exists('phpbb_get_banned_user_ids'))
187+
{
188+
include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
189+
}
190+
$banned_users = phpbb_get_banned_user_ids($user_ids);
191+
192+
// Load all the users we need
193+
$notify_users = array_diff($user_ids, $banned_users);
194+
$this->user_loader->load_users($notify_users, [USER_IGNORE]);
195+
205196
// Get subscriptions for users
206197
$user_subscription_map = $this->get_user_subscription_map($notify_users);
207198

@@ -361,6 +352,14 @@ public static function clean_data(array $data): array
361352
return array_intersect_key($data, $row);
362353
}
363354

355+
/**
356+
* Get template data for the UCP
357+
*
358+
* @param helper $controller_helper
359+
* @param form_helper $form_helper
360+
*
361+
* @return array
362+
*/
364363
public function get_ucp_template_data(helper $controller_helper, form_helper $form_helper): array
365364
{
366365
$subscription_map = $this->get_user_subscription_map([$this->user->id()]);
@@ -461,46 +460,6 @@ protected function clean_expired_subscriptions(array $user_subscription_map, arr
461460
$this->remove_subscriptions($remove_subscriptions);
462461
}
463462

464-
/**
465-
* Takes an avatar string (usually in full html format already) and extracts the url.
466-
* If the avatar url is a relative path, it's converted to an absolute path.
467-
*
468-
* Converts:
469-
* <img class="avatar" src="./path/to/avatar=123456789.gif" width="123" height="123" alt="User avatar" />
470-
* 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" />
471-
* into https://myboard.url/path/to/avatar=123456789.gif
472-
*
473-
* @param string $avatar
474-
* @return array 'src' => Absolute path to avatar image
475-
*/
476-
protected function prepare_avatar($avatar): array
477-
{
478-
$pattern = '/src=["\']?([^"\'>]+)["\']?/';
479-
480-
preg_match_all($pattern, $avatar, $matches);
481-
482-
$path = !empty($matches[1]) ? end($matches[1]) : $avatar;
483-
484-
return ['src' => preg_replace('#^' . preg_quote($this->path_helper->get_web_root_path(), '#') . '#', $this->get_board_url(), $path, 1)];
485-
}
486-
487-
/**
488-
* Returns the board url (and caches it in the function)
489-
*
490-
* @return string the generated board url
491-
*/
492-
protected function get_board_url()
493-
{
494-
static $board_url;
495-
496-
if (empty($board_url))
497-
{
498-
$board_url = generate_board_url() . '/';
499-
}
500-
501-
return $board_url;
502-
}
503-
504463
/**
505464
* Set web push padding for endpoint
506465
*
@@ -523,31 +482,4 @@ protected function set_endpoint_padding(\Minishlink\WebPush\WebPush $web_push, s
523482
}
524483
}
525484
}
526-
527-
/**
528-
* Load all users data to send notifications
529-
*
530-
* @return array Array of user ids to notify
531-
*/
532-
protected function load_recipients_data(): array
533-
{
534-
$notify_users = $user_ids = [];
535-
foreach ($this->queue as $notification)
536-
{
537-
$user_ids[] = $notification->user_id;
538-
}
539-
540-
// Do not send push notifications to banned users
541-
if (!function_exists('phpbb_get_banned_user_ids'))
542-
{
543-
include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
544-
}
545-
$banned_users = phpbb_get_banned_user_ids($user_ids);
546-
547-
// Load all the users we need
548-
$notify_users = array_diff($user_ids, $banned_users);
549-
$this->user_loader->load_users($notify_users, [USER_IGNORE]);
550-
551-
return $notify_users;
552-
}
553485
}

tests/event/listener_test.php

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ protected function setUp(): void
108108
$this->notification_method_webpush = new \phpbb\webpushnotifications\notification\method\webpush(
109109
$this->config,
110110
$db,
111-
$this->language,
112111
new \phpbb\log\dummy(),
113112
$user_loader,
114113
$this->user,
@@ -233,6 +232,15 @@ public function test_load_template_data($user_id, $method_data, $subscriptions,
233232
{
234233
$this->config['wpn_webpush_dropdown_subscribe'] = true;
235234
$this->user->data['user_id'] = $user_id;
235+
236+
$this->set_listener();
237+
238+
$method_data['method'] = $this->notification_method_webpush;
239+
240+
$this->notifications->expects(self::once())
241+
->method('get_subscription_methods')
242+
->willReturn([$method_data['id'] => $method_data]);
243+
236244
$this->template->expects($expected ? self::once() : self::never())
237245
->method('assign_vars')
238246
->with([
@@ -243,16 +251,7 @@ public function test_load_template_data($user_id, $method_data, $subscriptions,
243251
'U_WEBPUSH_WORKER_URL' => $this->controller_helper->route('phpbb_webpushnotifications_ucp_push_worker_controller'),
244252
'SUBSCRIPTIONS' => $subscriptions,
245253
'WEBPUSH_FORM_TOKENS' => $this->form_helper->get_form_tokens(\phpbb\webpushnotifications\ucp\controller\webpush::FORM_TOKEN_UCP),
246-
]
247-
);
248-
249-
$this->set_listener();
250-
251-
$method_data['method'] = $this->notification_method_webpush;
252-
253-
$this->notifications->expects(self::once())
254-
->method('get_subscription_methods')
255-
->willReturn([$method_data['id'] => $method_data]);
254+
]);
256255

257256
$dispatcher = new \phpbb\event\dispatcher();
258257
$dispatcher->addListener('core.page_header_after', [$this->listener, 'load_template_data']);

tests/notification/notification_method_webpush_test.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ protected function setUp(): void
171171
$this->notification_method_webpush = new webpush(
172172
$phpbb_container->get('config'),
173173
$phpbb_container->get('dbal.conn'),
174-
$phpbb_container->get('language'),
175174
$phpbb_container->get('log'),
176175
$phpbb_container->get('user_loader'),
177176
$phpbb_container->get('user'),

0 commit comments

Comments
 (0)