mediawiki-extensions-Echo/api/ApiEchoNotifications.php
kaldari 0fd7915801 Switching to short date headers based on user prefs (and timezone)
This change will allow people to switch between 'May 10' and
'10 May' as requested in bug 47211. It also now corrects for the
user's timezone settings.

Bug: 47211

Change-Id: I7c5eae52857fac2d82ff1cb0b10864a1e1b30b6a
2013-06-12 17:45:40 -07:00

233 lines
6.9 KiB
PHP

<?php
class ApiEchoNotifications extends ApiQueryBase {
public function __construct( $query, $moduleName ) {
parent::__construct( $query, $moduleName, 'not' );
}
public function execute() {
$user = $this->getUser();
if ( $user->isAnon() ) {
$this->dieUsage( 'Login is required', 'login-required' );
}
$notifUser = MWEchoNotifUser::newFromUser( $user );
$params = $this->extractRequestParams();
// 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']['unix'] . '|' . $lastItem['id'];
} else {
$result['continue'] = null;
}
$this->getResult()->setIndexedTagName( $result['list'], 'notification' );
}
if ( in_array( 'count', $prop ) ) {
$result['count'] = $notifUser->getFormattedNotificationCount();
}
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 );
}
$timestamp = new MWTimestamp( $row->notification_timestamp );
// Adjust for the user's timezone
$timestamp->offsetForUser( $user );
$timestampUnix = $timestamp->getTimestamp( TS_UNIX );
$timestampMw = $timestamp->getTimestamp( TS_MW );
// Start creating date section header
$today = wfTimestamp( TS_MW );
$yesterday = wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $today ) - 24 * 3600 );
if ( substr( $today, 0, 8 ) === substr( $timestampMw, 0, 8 ) ) {
// 'Today'
$date = wfMessage( 'echo-date-today' )->escaped();
} elseif ( substr( $yesterday, 0, 8 ) === substr( $timestampMw, 0, 8 ) ) {
// '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(
'unix' => $timestampUnix,
'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;
}
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,
),
'markallread' => array(
ApiBase::PARAM_REQUIRED => false,
ApiBase::PARAM_TYPE => 'boolean'
),
'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,
'offset' => array(
ApiBase::PARAM_TYPE => 'integer',
),
'timestamp' => array(
ApiBase::PARAM_TYPE => 'integer',
),
'continue' => 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.',
'offset' => 'Notification event id to start from (requires timestamp param to be passed as well)',
'timestamp' => 'Timestamp to start from',
'continue' => 'When more results are available, use this to continue',
);
}
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&notprop=count',
'api.php?action=query&meta=notifications&notmarkread=8',
);
}
public function getHelpUrls() {
return 'https://www.mediawiki.org/wiki/Echo_(notifications)/API';
}
public function getVersion() {
return __CLASS__ . '-0.1';
}
}