mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-12-01 10:56:44 +00:00
3b3ed1e3bc
* In some languages like persian, the number 0 is represented as '.', we can't compare '.' with either 0 or '0' to detect the no-notification status of the badge * The markread API doesn't respect uselang param, it would return 0 instead of . in a url with uselang=fa Note: we need to provide raw and formatted count in the API since client side javascript doesn't provide fancy function like $wgLang->formatNum() bug: 54575 Change-Id: I0a49828253ec346ed27c5b9a976f8bdff4e1fa90
248 lines
7.7 KiB
PHP
248 lines
7.7 KiB
PHP
<?php
|
|
|
|
class ApiEchoNotifications extends ApiQueryBase {
|
|
public function __construct( $query, $moduleName ) {
|
|
parent::__construct( $query, $moduleName, 'not' );
|
|
}
|
|
|
|
public function execute() {
|
|
// To avoid API warning, register the parameter used to bust browser cache
|
|
$this->getMain()->getVal( '_' );
|
|
|
|
$user = $this->getUser();
|
|
if ( $user->isAnon() ) {
|
|
$this->dieUsage( 'Login is required', 'login-required' );
|
|
}
|
|
|
|
$notifUser = MWEchoNotifUser::newFromUser( $user );
|
|
|
|
$params = $this->extractRequestParams();
|
|
|
|
// @Todo - markread/markallread has been migrated to a separate new API module,
|
|
// any related code in this API should be removed in a follow-up patch so that
|
|
// anything integrated with markread will have time to switch to the new markread
|
|
// API, also to give client js code enough time to refresh
|
|
//
|
|
// There is no need to trigger markRead if all notifications are read
|
|
if ( $notifUser->getNotificationCount() > 0 ) {
|
|
if ( count( $params['markread'] ) ) {
|
|
// Make sure there is a limit to the update
|
|
$notifUser->markRead( array_slice( $params['markread'], 0, ApiBase::LIMIT_SML2 ) );
|
|
} elseif ( $params['markallread'] ) {
|
|
$notifUser->markAllRead();
|
|
}
|
|
}
|
|
|
|
$prop = $params['prop'];
|
|
|
|
$result = array();
|
|
if ( in_array( 'list', $prop ) ) {
|
|
$result['list'] = self::getNotifications( $user, $params['format'], $params['limit'] + 1, $params['continue'] );
|
|
|
|
// check if there is more elements than we request
|
|
if ( count( $result['list'] ) > $params['limit'] ) {
|
|
$lastItem = array_pop( $result['list'] );
|
|
$result['continue'] = $lastItem['timestamp']['utcunix'] . '|' . $lastItem['id'];
|
|
} else {
|
|
$result['continue'] = null;
|
|
}
|
|
$this->getResult()->setIndexedTagName( $result['list'], 'notification' );
|
|
}
|
|
|
|
if ( in_array( 'count', $prop ) ) {
|
|
$rawCount = $notifUser->getNotificationCount();
|
|
$result['rawcount'] = $rawCount;
|
|
$result['count'] = EchoNotificationController::formatNotificationCount( $rawCount );
|
|
}
|
|
|
|
if ( in_array( 'index', $prop ) ) {
|
|
$result['index'] = array();
|
|
foreach ( array_keys( $result['list'] ) as $key ) {
|
|
// Don't include the XML tag name ('_element' key)
|
|
if ( $key != '_element' ) {
|
|
$result['index'][] = $key;
|
|
}
|
|
}
|
|
$this->getResult()->setIndexedTagName( $result['index'], 'id' );
|
|
}
|
|
|
|
$this->getResult()->setIndexedTagName( $result, 'notification' );
|
|
$this->getResult()->addValue( 'query', $this->getModuleName(), $result );
|
|
}
|
|
|
|
/**
|
|
* Get a list of notifications based on the passed parameters
|
|
*
|
|
* @param $user User the user to get notifications for
|
|
* @param $format string/bool false to not format any notifications, string to a specific output format
|
|
* @param $limit int The maximum number of notifications to return
|
|
* @param $continue string Used for offset
|
|
* @return array
|
|
*/
|
|
public static function getNotifications( $user, $format = false, $limit = 20, $continue = null ) {
|
|
global $wgEchoBackend;
|
|
|
|
$output = array();
|
|
|
|
// TODO: Make 'web' based on a new API param?
|
|
$res = $wgEchoBackend->loadNotifications( $user, $limit, $continue, 'web' );
|
|
|
|
foreach ( $res as $row ) {
|
|
$event = EchoEvent::newFromRow( $row );
|
|
if ( $row->notification_bundle_base && $row->notification_bundle_display_hash ) {
|
|
$event->setBundleHash( $row->notification_bundle_display_hash );
|
|
}
|
|
|
|
$timestampMw = self::getUserLocalTime( $user, $row->notification_timestamp );
|
|
|
|
// Start creating date section header
|
|
$now = wfTimestamp();
|
|
$dateFormat = substr( $timestampMw, 0, 8 );
|
|
if ( substr( self::getUserLocalTime( $user, $now ), 0, 8 ) === $dateFormat ) {
|
|
// 'Today'
|
|
$date = wfMessage( 'echo-date-today' )->escaped();
|
|
} elseif ( substr( self::getUserLocalTime( $user, $now - 86400 ), 0, 8 ) === $dateFormat ) {
|
|
// 'Yesterday'
|
|
$date = wfMessage( 'echo-date-yesterday' )->escaped();
|
|
} else {
|
|
// 'May 10' or '10 May' (depending on user's date format preference)
|
|
$lang = RequestContext::getMain()->getLanguage();
|
|
$dateFormat = $lang->getDateFormatString( 'pretty', $user->getDatePreference() ?: 'default' );
|
|
$date = $lang->sprintfDate( $dateFormat, $timestampMw );
|
|
}
|
|
// End creating date section header
|
|
|
|
$thisEvent = array(
|
|
'id' => $event->getId(),
|
|
'type' => $event->getType(),
|
|
'category' => $event->getCategory(),
|
|
'timestamp' => array(
|
|
// UTC timestamp in UNIX format used for loading more notification
|
|
'utcunix' => wfTimestamp( TS_UNIX, $row->notification_timestamp ),
|
|
'unix' => self::getUserLocalTime( $user, $row->notification_timestamp, TS_UNIX ),
|
|
'mw' => $timestampMw,
|
|
'date' => $date
|
|
),
|
|
);
|
|
|
|
if ( $event->getVariant() ) {
|
|
$thisEvent['variant'] = $event->getVariant();
|
|
}
|
|
|
|
if ( $event->getTitle() ) {
|
|
$thisEvent['title'] = array(
|
|
'full' => $event->getTitle()->getPrefixedText(),
|
|
'namespace' => $event->getTitle()->getNSText(),
|
|
'namespace-key' => $event->getTitle()->getNamespace(),
|
|
'text' => $event->getTitle()->getText(),
|
|
);
|
|
}
|
|
|
|
if ( $event->getAgent() ) {
|
|
$thisEvent['agent'] = array(
|
|
'id' => $event->getAgent()->getId(),
|
|
'name' => $event->getAgent()->getName(),
|
|
);
|
|
}
|
|
|
|
if ( $row->notification_read_timestamp ) {
|
|
$thisEvent['read'] = $row->notification_read_timestamp;
|
|
}
|
|
|
|
if ( $format ) {
|
|
$thisEvent['*'] = EchoNotificationController::formatNotification(
|
|
$event, $user, $format );
|
|
}
|
|
|
|
$output[$event->getID()] = $thisEvent;
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Internal helper function for converting UTC timezone to a user's timezone
|
|
* @param $user User
|
|
* @param $ts string
|
|
* @param $format output format
|
|
*/
|
|
private static function getUserLocalTime( $user, $ts, $format = TS_MW ) {
|
|
$timestamp = new MWTimestamp( $ts );
|
|
$timestamp->offsetForUser( $user );
|
|
return $timestamp->getTimestamp( $format );
|
|
}
|
|
|
|
public function getAllowedParams() {
|
|
return array(
|
|
'prop' => array(
|
|
ApiBase::PARAM_ISMULTI => true,
|
|
ApiBase::PARAM_TYPE => array(
|
|
'list',
|
|
'count',
|
|
'index',
|
|
),
|
|
ApiBase::PARAM_DFLT => 'list',
|
|
),
|
|
'markread' => array(
|
|
ApiBase::PARAM_ISMULTI => true,
|
|
ApiBase::PARAM_DEPRECATED => true,
|
|
),
|
|
'markallread' => array(
|
|
ApiBase::PARAM_REQUIRED => false,
|
|
ApiBase::PARAM_TYPE => 'boolean',
|
|
ApiBase::PARAM_DEPRECATED => true,
|
|
),
|
|
'format' => array(
|
|
ApiBase::PARAM_TYPE => array(
|
|
'text',
|
|
'flyout',
|
|
'html',
|
|
),
|
|
),
|
|
'limit' => array(
|
|
ApiBase::PARAM_TYPE => 'limit',
|
|
ApiBase::PARAM_DFLT => 20,
|
|
ApiBase::PARAM_MIN => 1,
|
|
ApiBase::PARAM_MAX => ApiBase::LIMIT_SML1,
|
|
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_SML2,
|
|
),
|
|
'index' => false,
|
|
'continue' => null,
|
|
'uselang' => null
|
|
);
|
|
}
|
|
|
|
public function getParamDescription() {
|
|
return array(
|
|
'prop' => 'Details to request.',
|
|
'markread' => 'A list of notification IDs to mark as read',
|
|
'markallread' => "If set to true, marks all of a user's notifications as read",
|
|
'format' => 'If specified, notifications will be returned formatted this way.',
|
|
'index' => 'If specified, a list of notification IDs, in order, will be returned.',
|
|
'limit' => 'The maximum number of notifications to return.',
|
|
'continue' => 'When more results are available, use this to continue',
|
|
'uselang' => 'the desired language to format the output'
|
|
);
|
|
}
|
|
|
|
public function getDescription() {
|
|
return 'Get notifications waiting for the current user';
|
|
}
|
|
|
|
public function getExamples() {
|
|
return array(
|
|
'api.php?action=query&meta=notifications',
|
|
'api.php?action=query&meta=notifications¬prop=count',
|
|
'api.php?action=query&meta=notifications¬markread=8',
|
|
);
|
|
}
|
|
|
|
public function getHelpUrls() {
|
|
return 'https://www.mediawiki.org/wiki/Echo_(notifications)/API';
|
|
}
|
|
|
|
public function getVersion() {
|
|
return __CLASS__ . '-0.1';
|
|
}
|
|
}
|