mediawiki-extensions-Echo/includes/SeenTime.php
Matthew Flaschen 98c6cd9eab Fix seen time for new users
Until the user opens the popup the first time, everything should be
unseen, rather than nothing unseen.

Also, make the default 'everything unseen' if we forget their seen
time.

Change-Id: I99ff8d46d4fa2fab0db374ddff63727b18a68363
2016-09-09 17:46:34 -04:00

132 lines
3.4 KiB
PHP

<?php
/**
* A small wrapper around ObjectCache to manage
* storing the last time a user has seen notifications
*/
class EchoSeenTime {
/**
* Allowed notification types
* @var array
*/
private static $allowedTypes = array( 'alert', 'message' );
/**
* @var User
*/
private $user;
/**
* @param User $user A logged in user
*/
private function __construct( User $user ) {
$this->user = $user;
}
/**
* @param User $user
* @return EchoSeenTime
*/
public static function newFromUser( User $user ) {
return new self( $user );
}
/**
* Hold onto a cache for our operations. Static so it can reuse the same
* in-process cache in different instances.
*
* @return BagOStuff
*/
private static function cache() {
static $c = null;
// Use main stash for persistent storage, and
// wrap it with CachedBagOStuff for an in-process
// cache. (T144534)
if ( $c === null ) {
$c = new CachedBagOStuff(
ObjectCache::getMainStashInstance()
);
}
return $c;
}
/**
* @param string $type Type of seen time to get
* @param int $flags BagOStuff::READ_LATEST to use the master
* @param int $format Format to return time in, defaults to TS_MW
* @return string|bool Timestamp in specified format, or false if no stored time
*/
public function getTime( $type = 'all', $flags = 0, $format = TS_MW, $sourceWiki = null ) {
$sourceWiki = $sourceWiki === null ? wfWikiID() : $sourceWiki;
list( $db, $prefix ) = wfSplitWikiID( $sourceWiki );
$vals = array();
if ( $type === 'all' ) {
foreach ( self::$allowedTypes as $allowed ) {
// Use TS_MW, then convert later, so max works properly for
// all formats.
$vals[] = $this->getTime( $allowed, $flags, TS_MW, $sourceWiki );
}
return wfTimestamp( $format, min( $vals ) );
}
if ( $this->validateType( $type ) ) {
$key = wfForeignMemcKey( $db, $prefix, 'echo', 'seen', $type, 'time', $this->user->getId() );
$cas = 0; // Unused, but we have to pass something by reference
$data = self::cache()->get( $key, $cas, $flags );
if ( $data === false ) {
// Check if the user still has it set in their preferences
$data = $this->user->getOption( 'echo-seen-time', false );
}
}
if ( $data === false ) {
// There is still no time set, so set time to the UNIX epoch.
// We can't remember their real seen time, so reset everything to
// unseen.
$data = wfTimestamp( TS_MW, 1 );
$this->setTime( $data, $type, $sourceWiki );
}
return wfTimestamp( $format, $data );
}
/**
* Sets the seen time
*
* @param string $time Time, in TS_MW format
* @param string $type Type of seen time to set
* @param string $sourceWiki Source wiki to set it for, defaults to current
*/
public function setTime( $time, $type = 'all', $sourceWiki = null ) {
$sourceWiki = $sourceWiki === null ? wfWikiID() : $sourceWiki;
list( $db, $prefix ) = wfSplitWikiID( $sourceWiki );
if ( $type === 'all' ) {
foreach ( self::$allowedTypes as $allowed ) {
$this->setTime( $time, $allowed );
}
} else {
if ( $this->validateType( $type ) ) {
$key = wfForeignMemcKey( $db, $prefix, 'echo', 'seen', $type, 'time', $this->user->getId() );
return self::cache()->set( $key, $time );
}
}
}
/**
* Validate the given type, make sure it is allowed.
*
* @param string $type Given type
* @return bool Type is allowed
*/
private function validateType( $type ) {
return in_array( $type, self::$allowedTypes );
}
}