mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-24 07:54:13 +00:00
Merge "Add push notifier"
This commit is contained in:
commit
a9391e1035
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use EchoPush\NotificationServiceClient;
|
||||
use EchoPush\SubscriptionManager;
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
@ -7,6 +8,16 @@ use MediaWiki\Storage\NameTableStore;
|
|||
|
||||
return [
|
||||
|
||||
'EchoPushNotificationServiceClient' => function ( MediaWikiServices $services ):
|
||||
NotificationServiceClient {
|
||||
$echoConfig = $services->getConfigFactory()->makeConfig( 'Echo' );
|
||||
$httpRequestFactory = $services->getHttpRequestFactory();
|
||||
$url = $echoConfig->get( 'EchoPushServiceUrl' );
|
||||
$client = new NotificationServiceClient( $httpRequestFactory, $url );
|
||||
$client->setLogger( LoggerFactory::getInstance( 'Echo' ) );
|
||||
return $client;
|
||||
},
|
||||
|
||||
'EchoPushSubscriptionManager' => function ( MediaWikiServices $services ): SubscriptionManager {
|
||||
$echoConfig = $services->getConfigFactory()->makeConfig( 'Echo' );
|
||||
// Use shared DB/cluster for push subscriptions
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
],
|
||||
"JobClasses": {
|
||||
"EchoNotificationJob": "EchoNotificationJob",
|
||||
"EchoNotificationDeleteJob": "EchoNotificationDeleteJob"
|
||||
"EchoNotificationDeleteJob": "EchoNotificationDeleteJob",
|
||||
"EchoPushNotificationRequest": "EchoPush\\NotificationRequestJob"
|
||||
},
|
||||
"SpecialPages": {
|
||||
"Notifications": "SpecialNotifications",
|
||||
|
@ -988,6 +989,10 @@
|
|||
"EchoEnablePush": {
|
||||
"value": false,
|
||||
"description": "Whether to enable push notifications"
|
||||
},
|
||||
"EchoPushServiceUrl": {
|
||||
"value": false,
|
||||
"description": "Request endpoint URL for the push notification service"
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
"echo-pref-email-format": "Email format:",
|
||||
"echo-pref-web": "Web",
|
||||
"echo-pref-email": "Email",
|
||||
"echo-pref-push": "Push (apps only)",
|
||||
"echo-pref-email-frequency-never": "Do not send me any email notifications",
|
||||
"echo-pref-email-frequency-immediately": "Individual notifications as they come in",
|
||||
"echo-pref-email-frequency-daily": "A daily summary of notifications",
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
"echo-pref-email-format": "Label for individual email notification format, the label will be updated once HTML email is ready for email digest.\n\nUsed as label for the select box which has the following options:\n* {{msg-mw|Echo-pref-email-format-html}}\n* {{msg-mw|Echo-pref-email-format-plain-text}}",
|
||||
"echo-pref-web": "Label for list of notifications which are delivered on the web. In other words, on the wiki itself rather by email or another method. This should be kept very short.",
|
||||
"echo-pref-email": "Label for list of notifications which are delivered via email. This should be kept very short.\n{{Identical|E-mail}}",
|
||||
"echo-pref-push": "Label for the notification preferences column controlling which notifications should be delivered by push notification. The '(apps only)' expression indicates that push notifications are currently only supported for the Wikipedia mobile apps.",
|
||||
"echo-pref-email-frequency-never": "Option for users who don't want to receive any email notifications\n\nSee also:\n* {{msg-mw|Echo-pref-email-frequency-immediately}}\n* {{msg-mw|Echo-pref-email-frequency-daily}}\n* {{msg-mw|Echo-pref-email-frequency-weekly}}",
|
||||
"echo-pref-email-frequency-immediately": "Option for users who want to receive email for each notification as it occurs",
|
||||
"echo-pref-email-frequency-daily": "Option for users who want to receive a daily digest of email notifications",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use EchoPush\NotificationServiceClient;
|
||||
use EchoPush\SubscriptionManager;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
|
@ -13,11 +14,24 @@ class EchoServices {
|
|||
return new self( MediaWikiServices::getInstance() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MediaWikiServices $services
|
||||
* @return EchoServices
|
||||
*/
|
||||
public static function wrap( MediaWikiServices $services ): EchoServices {
|
||||
return new self( $services );
|
||||
}
|
||||
|
||||
/** @param MediaWikiServices $services */
|
||||
public function __construct( MediaWikiServices $services ) {
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/** @return NotificationServiceClient */
|
||||
public function getPushNotificationServiceClient(): NotificationServiceClient {
|
||||
return $this->services->getService( 'EchoPushNotificationServiceClient' );
|
||||
}
|
||||
|
||||
/** @return SubscriptionManager */
|
||||
public function getPushSubscriptionManager(): SubscriptionManager {
|
||||
return $this->services->getService( 'EchoPushSubscriptionManager' );
|
||||
|
|
23
includes/Push/NotificationRequestJob.php
Normal file
23
includes/Push/NotificationRequestJob.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace EchoPush;
|
||||
|
||||
use EchoServices;
|
||||
use Job;
|
||||
|
||||
class NotificationRequestJob extends Job {
|
||||
|
||||
/**
|
||||
* @return bool success
|
||||
*/
|
||||
public function run(): bool {
|
||||
$centralId = $this->params['centralId'];
|
||||
$echoServices = EchoServices::getInstance();
|
||||
$subscriptionManager = $echoServices->getPushSubscriptionManager();
|
||||
$subscriptions = $subscriptionManager->getSubscriptionsForUser( $centralId );
|
||||
$serviceClient = $echoServices->getPushNotificationServiceClient();
|
||||
$serviceClient->sendCheckEchoRequest( $subscriptions );
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
45
includes/Push/NotificationServiceClient.php
Normal file
45
includes/Push/NotificationServiceClient.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace EchoPush;
|
||||
|
||||
use MediaWiki\Http\HttpRequestFactory;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
|
||||
class NotificationServiceClient implements LoggerAwareInterface {
|
||||
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/** @var HttpRequestFactory */
|
||||
private $httpRequestFactory;
|
||||
|
||||
/** @var string */
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @param HttpRequestFactory $httpRequestFactory
|
||||
* @param string $url push service notification request endpoint URL
|
||||
*/
|
||||
public function __construct( HttpRequestFactory $httpRequestFactory, string $url ) {
|
||||
$this->httpRequestFactory = $httpRequestFactory;
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a CHECK_ECHO notification request to the push service.
|
||||
* @param array $subscriptions Subscriptions for which to send the message
|
||||
*/
|
||||
public function sendCheckEchoRequest( array $subscriptions ): void {
|
||||
$this->sendRequest( $subscriptions, [ 'message' => 'CHECK_ECHO' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $subscriptions Subscriptions for which to send the message
|
||||
* @param array $payload message payload
|
||||
*/
|
||||
private function sendRequest( array $subscriptions, array $payload ): void {
|
||||
// TODO: Implement this when the push notification service's request API exists
|
||||
$this->logger->debug( 'Sending push notification request' );
|
||||
}
|
||||
|
||||
}
|
32
includes/Push/PushNotifier.php
Normal file
32
includes/Push/PushNotifier.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace EchoPush;
|
||||
|
||||
use CentralIdLookup;
|
||||
use EchoEvent;
|
||||
use JobQueueGroup;
|
||||
use User;
|
||||
|
||||
class PushNotifier {
|
||||
|
||||
/**
|
||||
* Submits a notification derived from an Echo event to each push notifications service
|
||||
* subscription found for a user, via a configured service handler implementation
|
||||
* @param User $user
|
||||
* @param EchoEvent $event
|
||||
*/
|
||||
public static function notifyWithPush( User $user, EchoEvent $event ): void {
|
||||
JobQueueGroup::singleton()->push( self::createJobForUser( $user ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return NotificationRequestJob
|
||||
*/
|
||||
private static function createJobForUser( User $user ): NotificationRequestJob {
|
||||
$centralId = CentralIdLookup::factory()->centralIdFromLocalUser( $user );
|
||||
$params = [ 'centralId' => $centralId ];
|
||||
return new NotificationRequestJob( 'EchoPushNotificationRequest', $params );
|
||||
}
|
||||
|
||||
}
|
|
@ -63,15 +63,15 @@ class SubscriptionManager extends EchoAbstractMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get all registered subscriptions for a user.
|
||||
* @param User $user
|
||||
* Get all registered subscriptions for a user (by central ID).
|
||||
* @param int $centralId
|
||||
* @return array array of Subscription objects
|
||||
*/
|
||||
public function getSubscriptionsForUser( User $user ) {
|
||||
public function getSubscriptionsForUser( int $centralId ) {
|
||||
$res = $this->dbr->select(
|
||||
'echo_push_subscription',
|
||||
'*',
|
||||
[ 'eps_user' => $this->getCentralId( $user ) ]
|
||||
[ 'eps_user' => $centralId ]
|
||||
);
|
||||
$result = [];
|
||||
foreach ( $res as $row ) {
|
||||
|
|
|
@ -1,12 +1,32 @@
|
|||
<?php
|
||||
|
||||
use EchoPush\NotificationServiceClient;
|
||||
use EchoPush\SubscriptionManager;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
/** @covers EchoServices */
|
||||
class EchoServicesTest extends MediaWikiIntegrationTestCase {
|
||||
|
||||
public function testGetSubscriptionManager(): void {
|
||||
$subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager();
|
||||
/** @var EchoServices */
|
||||
private $echoServices;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->echoServices = EchoServices::getInstance();
|
||||
}
|
||||
|
||||
public function testWrap(): void {
|
||||
$services = EchoServices::wrap( MediaWikiServices::getInstance() );
|
||||
$this->assertInstanceOf( EchoServices::class, $services );
|
||||
}
|
||||
|
||||
public function testGetPushNotificationServiceClient(): void {
|
||||
$serviceClient = $this->echoServices->getPushNotificationServiceClient();
|
||||
$this->assertInstanceOf( NotificationServiceClient::class, $serviceClient );
|
||||
}
|
||||
|
||||
public function testGetPushSubscriptionManager(): void {
|
||||
$subscriptionManager = $this->echoServices->getPushSubscriptionManager();
|
||||
$this->assertInstanceOf( SubscriptionManager::class, $subscriptionManager );
|
||||
}
|
||||
|
||||
|
|
20
tests/phpunit/integration/Push/PushNotifierTest.php
Normal file
20
tests/phpunit/integration/Push/PushNotifierTest.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
use EchoPush\NotificationRequestJob;
|
||||
use EchoPush\PushNotifier;
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
/** @covers \EchoPush\PushNotifier */
|
||||
class PushNotifierTest extends MediaWikiIntegrationTestCase {
|
||||
|
||||
public function testCreateJobForUser(): void {
|
||||
$notifier = TestingAccessWrapper::newFromClass( PushNotifier::class );
|
||||
$user = $this->getTestUser()->getUser();
|
||||
$centralId = CentralIdLookup::factory()->centralIdFromLocalUser( $user );
|
||||
$job = $notifier->createJobForUser( $user );
|
||||
$this->assertInstanceOf( NotificationRequestJob::class, $job );
|
||||
$this->assertSame( 'EchoPushNotificationRequest', $job->getType() );
|
||||
$this->assertSame( $centralId, $job->getParams()['centralId'] );
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* @group Database
|
||||
* @covers \EchoPush\SubscriptionManager
|
||||
*/
|
||||
class PushSubscriptionManagerTest extends MediaWikiIntegrationTestCase {
|
||||
class SubscriptionManagerTest extends MediaWikiIntegrationTestCase {
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
@ -15,11 +15,12 @@ class PushSubscriptionManagerTest extends MediaWikiIntegrationTestCase {
|
|||
public function testManagePushSubscriptions(): void {
|
||||
$subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager();
|
||||
$user = $this->getTestUser()->getUser();
|
||||
$centralId = CentralIdLookup::factory()->centralIdFromLocalUser( $user );
|
||||
$subscriptionManager->create( $user, 'test', 'ABC123' );
|
||||
$subscriptions = $subscriptionManager->getSubscriptionsForUser( $user );
|
||||
$subscriptions = $subscriptionManager->getSubscriptionsForUser( $centralId );
|
||||
$this->assertCount( 1, $subscriptions );
|
||||
$subscriptionManager->delete( $user, 'ABC123' );
|
||||
$subscriptions = $subscriptionManager->getSubscriptionsForUser( $user );
|
||||
$subscriptions = $subscriptionManager->getSubscriptionsForUser( $centralId );
|
||||
$this->assertCount( 0, $subscriptions );
|
||||
}
|
||||
|
Loading…
Reference in a new issue