diff --git a/Hooks.php b/Hooks.php index a8d3e2f7d..b3bd91005 100644 --- a/Hooks.php +++ b/Hooks.php @@ -37,7 +37,7 @@ class EchoHooks { */ public static function initEchoExtension() { global $wgEchoNotifications, $wgEchoNotificationCategories, $wgEchoNotificationIcons, - $wgEchoEventLoggingSchemas, $wgEchoMentionStatusNotifications, $wgAllowArticleReminderNotification; + $wgEchoEventLoggingSchemas, $wgEchoMentionStatusNotifications, $wgAllowArticleReminderNotification, $wgAPIModules; // allow extensions to define their own event Hooks::run( 'BeforeCreateEchoEvent', [ &$wgEchoNotifications, &$wgEchoNotificationCategories, &$wgEchoNotificationIcons ] ); @@ -51,6 +51,7 @@ class EchoHooks { // Only allow article reminder notifications when enabled if ( !$wgAllowArticleReminderNotification ) { unset( $wgEchoNotificationCategories['article-reminder'] ); + unset( $wgAPIModules['echoarticlereminder'] ); } // turn schema off if eventLogging is not enabled @@ -661,28 +662,12 @@ class EchoHooks { * @return bool */ public static function onLocalUserCreated( $user, $autocreated ) { - global $wgAllowArticleReminderNotification; - if ( !$autocreated ) { $overrides = self::getNewUserPreferenceOverrides(); foreach ( $overrides as $prefKey => $value ) { $user->setOption( $prefKey, $value ); } - $user->saveSettings(); - - // Temporarily here, just for the POC - if ( $wgAllowArticleReminderNotification ) { - EchoEvent::create( [ - 'type' => 'article-reminder', - 'agent' => $user, - 'title' => Title::newMainPage(), - 'extra' => [ - 'notifyAgent' => true - ] - ] ); - } - EchoEvent::create( [ 'type' => 'welcome', 'agent' => $user, diff --git a/extension.json b/extension.json index fe2a1ca91..39606dbcf 100644 --- a/extension.json +++ b/extension.json @@ -23,7 +23,8 @@ }, "APIModules": { "echomarkread": "ApiEchoMarkRead", - "echomarkseen": "ApiEchoMarkSeen" + "echomarkseen": "ApiEchoMarkSeen", + "echoarticlereminder": "ApiEchoArticleReminder" }, "DefaultUserOptions": { "echo-show-alert": true, @@ -902,6 +903,7 @@ "manifest_version": 2, "AutoloadClasses": { "ApiCrossWikiBase": "includes/api/ApiCrossWikiBase.php", + "ApiEchoArticleReminder": "includes/api/ApiEchoArticleReminder.php", "ApiEchoMarkRead": "includes/api/ApiEchoMarkRead.php", "ApiEchoMarkReadTest": "tests/phpunit/api/ApiEchoMarkReadTest.php", "ApiEchoMarkSeen": "includes/api/ApiEchoMarkSeen.php", diff --git a/i18n/api/en.json b/i18n/api/en.json index 76676b020..4ca9fb1c5 100644 --- a/i18n/api/en.json +++ b/i18n/api/en.json @@ -52,7 +52,15 @@ "apihelp-query+unreadnotificationpages-param-limit": "The maximum number of pages to return.", "apihelp-query+unreadnotificationpages-param-wikis": "List of wikis to fetch pages with unread notifications from (defaults to only current wiki).", "apihelp-query+unreadnotificationpages-example-1": "List pages with (their amount of) unread notifications", + "apihelp-echoarticlereminder-summary": "Request a future reminder about the specified article", + "apihelp-echoarticlereminder-param-pageid": "ID of article to remind the user about", + "apihelp-echoarticlereminder-param-title": "Title of article to remind the user about", + "apihelp-echoarticlereminder-param-timestamp": "On which timestamp to remind the user", + "apihelp-echoarticlereminder-param-comment": "Optional user comment to include in the reminder", + "apihelp-echoarticlereminder-example-1" : "Create an article reminder notification for tomorrow with comment", + "apihelp-echoarticlereminder-example-2" : "Create an article reminder notification for tomorrow without comment", "apiwarn-echo-deprecation-timestampformat": "The MW timestamp output format is deprecated here. In the future, ISO 8601 will always be used for the output timestamp format. Adjust your client and set timestampFormat to ISO_8601.", "apiwarn-echo-deprecation-flyout": "notformat=flyout has been deprecated and will be removed soon. Use notformat=model to get the raw data or notformat=special for pre-rendered HTML.", - "apiwarn-echo-deprecation-html": "notformat=html has been deprecated and will be removed soon. Use notformat=special instead." + "apiwarn-echo-deprecation-html": "notformat=html has been deprecated and will be removed soon. Use notformat=special instead.", + "apierror-echo-event-creation-failed": "Could not create Echo event" } diff --git a/i18n/api/qqq.json b/i18n/api/qqq.json index 2e3785679..33e4a943a 100644 --- a/i18n/api/qqq.json +++ b/i18n/api/qqq.json @@ -48,6 +48,13 @@ "apihelp-query+notifications-param-bundle": "{{doc-apihelp-param|query+notifications|bundle}}", "apihelp-query+notifications-example-1": "{{doc-apihelp-example|query+notifications}}", "apihelp-query+notifications-example-2": "{{doc-apihelp-example|query+notifications}}", + "apihelp-echoarticlereminder-summary": "{{doc-apihelp-summary|echoarticlereminder}}", + "apihelp-echoarticlereminder-param-pageid": "{{doc-apihelp-param|echoarticlereminder|pageid}}", + "apihelp-echoarticlereminder-param-title": "{{doc-apihelp-param|echoarticlereminder|title}}", + "apihelp-echoarticlereminder-param-timestamp": "{{doc-apihelp-param|echoarticlereminder|timestamp}}", + "apihelp-echoarticlereminder-param-comment": "{{doc-apihelp-param|echoarticlereminder|comment}}", + "apihelp-echoarticlereminder-example-1" : "{{doc-apihelp-example|echoarticlereminder}}", + "apihelp-echoarticlereminder-example-2" : "{{doc-apihelp-example|echoarticlereminder}}", "apihelp-query+unreadnotificationpages-description": "{{doc-apihelp-description|query+unreadnotificationpages}}", "apihelp-query+unreadnotificationpages-summary": "{{doc-apihelp-summary|query+unreadnotificationpages}}", "apihelp-query+unreadnotificationpages-param-grouppages": "{{doc-apihelp-param|query+unreadnotificationpages|grouppages}}", @@ -56,5 +63,6 @@ "apihelp-query+unreadnotificationpages-example-1": "{{doc-apihelp-example|query+unreadnotificationpages}}", "apiwarn-echo-deprecation-timestampformat": "{{doc-apierror}}", "apiwarn-echo-deprecation-flyout": "{{doc-apierror}}", - "apiwarn-echo-deprecation-html": "{{doc-apierror}}" + "apiwarn-echo-deprecation-html": "{{doc-apierror}}", + "apierror-echo-event-creation-failed": "{{doc-apierror}}" } diff --git a/includes/api/ApiEchoArticleReminder.php b/includes/api/ApiEchoArticleReminder.php new file mode 100644 index 000000000..5ed267948 --- /dev/null +++ b/includes/api/ApiEchoArticleReminder.php @@ -0,0 +1,112 @@ +getMain()->setCacheMode( 'private' ); + $user = $this->getUser(); + if ( $user->isAnon() ) { + $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); + } + + $params = $this->extractRequestParams(); + $result = []; + $userTimestamp = new MWTimestamp( $params['timestamp'] ); + $nowTimestamp = new MWTimestamp(); + // We need $params['timestamp'] to be a future timestamp: + // $userTimestamp < $nowTimestamp = invert 0 + // $userTimestamp > $nowTimestamp = invert 1 + if ( $userTimestamp->diff( $nowTimestamp )->invert === 0 ) { + $this->dieWithError( [ 'apierror-badparameter', 'timestamp' ], 'timestamp-not-in-future', null, 400 ); + } + + $eventCreation = EchoEvent::create( [ + 'type' => 'article-reminder', + 'agent' => $user, + 'title' => $this->getTitleFromTitleOrPageId( $params ), + 'extra' => [ + 'notifyAgent' => true, + 'comment' => $params['comment'], + ], + ] ); + + if ( !$eventCreation ) { + $this->dieWithError( 'apierror-echo-event-creation-failed', null, null, 500 ); + } + + /* Temp - removing the delay just for now: + $job = new JobSpecification( + 'articleReminder', + [ + 'userId' => $user->getId(), + 'timestamp' => $params['timestamp'], + 'comment' => $params['comment'], + ], + [ 'removeDuplicates' => true ], + Title::newFromID( $params['pageid'] ) + ); + JobQueueGroup::singleton()->push( $job );*/ + $result += [ + 'result' => 'success' + ]; + $this->getResult()->addValue( 'query', $this->getModuleName(), $result ); + } + + public function getAllowedParams() { + return [ + 'pageid' => [ + ApiBase::PARAM_TYPE => 'integer', + ], + 'title' => [ + ApiBase::PARAM_TYPE => 'string', + ], + 'comment' => [ + ApiBase::PARAM_TYPE => 'string', + ], + 'timestamp' => [ + ApiBase::PARAM_REQUIRED => true, + ApiBase::PARAM_TYPE => 'timestamp', + ], + 'token' => [ + ApiBase::PARAM_REQUIRED => true, + ], + ]; + } + + public function needsToken() { + return 'csrf'; + } + + public function getTokenSalt() { + return ''; + } + + public function mustBePosted() { + return true; + } + + public function isWriteMode() { + return true; + } + + /** + * @see ApiBase::getExamplesMessages() + */ + protected function getExamplesMessages() { + $todayDate = new DateTime(); + $oneDay = new DateInterval( 'P1D' ); + $tomorrowDate = $todayDate->add( $oneDay ); + $tomorrowDateTimestamp = new MWTimestamp( $tomorrowDate ); + $tomorrowTimestampStr = $tomorrowDateTimestamp->getTimestamp( TS_ISO_8601 ); + return [ + "action=echoarticlereminder&pageid=1×tamp=$tomorrowTimestampStr&comment=example" + => 'apihelp-echoarticlereminder-example-1', + "action=echoarticlereminder&title=Main_Page×tamp=$tomorrowTimestampStr" + => 'apihelp-echoarticlereminder-example-2', + ]; + } + + public function getHelpUrls() { + return 'https://www.mediawiki.org/wiki/Echo_(Notifications)/API'; + } +}