2012-04-27 15:14:24 +00:00
|
|
|
<?php
|
|
|
|
|
2017-03-30 19:35:32 +00:00
|
|
|
use MediaWiki\Logger\LoggerFactory;
|
|
|
|
|
2012-04-27 15:14:24 +00:00
|
|
|
/**
|
|
|
|
* Immutable class to represent an event.
|
|
|
|
* In Echo nomenclature, an event is a single occurrence.
|
|
|
|
*/
|
2016-03-04 19:23:02 +00:00
|
|
|
class EchoEvent extends EchoAbstractEntity implements Bundleable {
|
2014-08-14 18:46:26 +00:00
|
|
|
|
2013-03-04 20:56:42 +00:00
|
|
|
protected $type = null;
|
2012-04-27 15:14:24 +00:00
|
|
|
protected $id = null;
|
|
|
|
protected $variant = null;
|
2012-09-02 09:30:38 +00:00
|
|
|
/**
|
|
|
|
* @var User
|
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
protected $agent = null;
|
2012-05-17 00:29:37 +00:00
|
|
|
|
|
|
|
/**
|
2013-05-08 18:11:44 +00:00
|
|
|
* Loaded dynamically on request
|
|
|
|
*
|
2012-05-17 00:29:37 +00:00
|
|
|
* @var Title
|
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
protected $title = null;
|
2013-05-08 18:11:44 +00:00
|
|
|
protected $pageId = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loaded dynamically on request
|
|
|
|
*
|
|
|
|
* @var Revision
|
|
|
|
*/
|
|
|
|
protected $revision = null;
|
|
|
|
|
2016-12-05 18:51:07 +00:00
|
|
|
protected $extra = [];
|
2013-01-15 23:21:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Notification timestamp
|
|
|
|
* @var string
|
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
protected $timestamp = null;
|
|
|
|
|
2013-01-15 23:21:39 +00:00
|
|
|
/**
|
|
|
|
* A hash used to bundle a set of events, events that can be
|
|
|
|
* grouped for a user has the same bundle hash
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $bundleHash;
|
|
|
|
|
2016-03-04 19:23:02 +00:00
|
|
|
/**
|
|
|
|
* Other events bundled with this one
|
|
|
|
*
|
|
|
|
* @var EchoEvent[]
|
|
|
|
*/
|
|
|
|
protected $bundledEvents;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deletion flag
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
protected $deleted = 0;
|
|
|
|
|
2012-04-27 15:14:24 +00:00
|
|
|
/**
|
|
|
|
* You should not call the constructor.
|
|
|
|
* Instead use one of the factory functions:
|
2012-08-31 21:50:46 +00:00
|
|
|
* EchoEvent::create To create a new event
|
|
|
|
* EchoEvent::newFromRow To create an event object from a row object
|
|
|
|
* EchoEvent::newFromID To create an event object from the database given its ID
|
2012-04-27 15:14:24 +00:00
|
|
|
*/
|
2015-10-01 13:48:52 +00:00
|
|
|
protected function __construct() {
|
|
|
|
}
|
2012-04-27 15:14:24 +00:00
|
|
|
|
2013-01-15 23:21:39 +00:00
|
|
|
## Save the id and timestamp
|
2012-06-06 07:04:28 +00:00
|
|
|
function __sleep() {
|
2012-08-31 21:50:46 +00:00
|
|
|
if ( !$this->id ) {
|
2012-08-30 16:04:39 +00:00
|
|
|
throw new MWException( "Unable to serialize an uninitialized EchoEvent" );
|
2012-06-06 07:04:28 +00:00
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2016-12-05 18:51:07 +00:00
|
|
|
return [ 'id', 'timestamp' ];
|
2012-06-06 07:04:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function __wakeup() {
|
|
|
|
$this->loadFromID( $this->id );
|
|
|
|
}
|
|
|
|
|
|
|
|
function __toString() {
|
|
|
|
return "EchoEvent(id={$this->id}; type={$this->type})";
|
|
|
|
}
|
|
|
|
|
2012-04-27 15:14:24 +00:00
|
|
|
/**
|
|
|
|
* Creates an EchoEvent object
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param array $info Named arguments:
|
2012-04-27 15:14:24 +00:00
|
|
|
* type (required): The event type;
|
|
|
|
* variant: A variant of the type;
|
|
|
|
* agent: The user who caused the event;
|
|
|
|
* title: The page on which the event was triggered;
|
|
|
|
* extra: Event-specific extra information (e.g. post content)
|
|
|
|
*
|
2012-09-02 09:30:38 +00:00
|
|
|
* @throws MWException
|
2015-11-01 10:50:44 +00:00
|
|
|
* @return EchoEvent|bool false if aborted via hook or Echo DB is read-only
|
2012-04-27 15:14:24 +00:00
|
|
|
*/
|
2016-12-05 18:51:07 +00:00
|
|
|
public static function create( $info = [] ) {
|
2013-02-16 02:20:34 +00:00
|
|
|
global $wgEchoNotifications;
|
|
|
|
|
2013-05-08 21:24:47 +00:00
|
|
|
// Do not create event and notifications if write access is locked
|
2015-11-01 10:50:44 +00:00
|
|
|
if ( wfReadOnly()
|
|
|
|
|| MWEchoDbFactory::newFromDefault()->getEchoDb( DB_MASTER )->isReadOnly()
|
|
|
|
) {
|
|
|
|
return false;
|
2013-05-08 21:24:47 +00:00
|
|
|
}
|
|
|
|
|
2012-04-27 15:14:24 +00:00
|
|
|
$obj = new EchoEvent;
|
2016-12-05 18:51:07 +00:00
|
|
|
static $validFields = [ 'type', 'variant', 'agent', 'title', 'extra' ];
|
2012-04-27 15:14:24 +00:00
|
|
|
|
2012-08-01 19:53:05 +00:00
|
|
|
if ( empty( $info['type'] ) ) {
|
2012-04-27 15:14:24 +00:00
|
|
|
throw new MWException( "'type' parameter is mandatory" );
|
|
|
|
}
|
|
|
|
|
2013-02-16 02:20:34 +00:00
|
|
|
if ( !isset( $wgEchoNotifications[$info['type']] ) ) {
|
2012-08-01 18:20:21 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-04-27 15:14:24 +00:00
|
|
|
$obj->id = false;
|
2015-03-26 21:52:41 +00:00
|
|
|
if ( isset( $info['timestamp'] ) ) {
|
|
|
|
$obj->timestamp = $info['timestamp'];
|
|
|
|
} else {
|
|
|
|
$obj->timestamp = wfTimestampNow();
|
|
|
|
}
|
2012-04-27 15:14:24 +00:00
|
|
|
|
2012-08-31 21:50:46 +00:00
|
|
|
foreach ( $validFields as $field ) {
|
2012-08-30 16:04:39 +00:00
|
|
|
if ( isset( $info[$field] ) ) {
|
2012-04-27 15:14:24 +00:00
|
|
|
$obj->$field = $info[$field];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-05 18:56:11 +00:00
|
|
|
// If the extra size is more than 50000 bytes, that means there is
|
2014-02-05 22:21:48 +00:00
|
|
|
// probably a problem with the design of this notification type.
|
|
|
|
// There might be data loss if the size exceeds the DB column size of
|
|
|
|
// event_extra.
|
2014-02-05 18:56:11 +00:00
|
|
|
if ( strlen( $obj->serializeExtra() ) > 50000 ) {
|
|
|
|
wfDebugLog( __CLASS__, __FUNCTION__ . ': event extra data is too huge for ' . $info['type'] );
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2014-02-05 18:56:11 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-08 18:11:44 +00:00
|
|
|
if ( $obj->title ) {
|
|
|
|
if ( !$obj->title instanceof Title ) {
|
2017-10-03 22:39:23 +00:00
|
|
|
throw new InvalidArgumentException( 'Invalid title parameter' );
|
2013-05-08 18:11:44 +00:00
|
|
|
}
|
2013-11-30 06:20:03 +00:00
|
|
|
$obj->setTitle( $obj->title );
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
|
|
|
|
2017-10-03 22:39:23 +00:00
|
|
|
if ( $obj->agent && ! $obj->agent instanceof User ) {
|
|
|
|
throw new InvalidArgumentException( "Invalid user parameter" );
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
|
|
|
|
2016-12-05 18:51:07 +00:00
|
|
|
if ( !Hooks::run( 'BeforeEchoEventInsert', [ $obj ] ) ) {
|
2013-09-28 02:19:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-10-29 11:23:31 +00:00
|
|
|
// @Todo - Database insert logic should not be inside the model
|
2012-04-27 15:14:24 +00:00
|
|
|
$obj->insert();
|
2012-12-19 20:28:17 +00:00
|
|
|
|
2016-12-05 18:51:07 +00:00
|
|
|
Hooks::run( 'EchoEventInsertComplete', [ $obj ] );
|
2013-09-28 02:19:08 +00:00
|
|
|
|
2012-12-19 20:28:17 +00:00
|
|
|
global $wgEchoUseJobQueue;
|
|
|
|
|
2015-10-01 13:48:52 +00:00
|
|
|
EchoNotificationController::notify( $obj, $wgEchoUseJobQueue );
|
2012-04-27 15:14:24 +00:00
|
|
|
|
|
|
|
return $obj;
|
|
|
|
}
|
|
|
|
|
2014-07-18 03:58:21 +00:00
|
|
|
/**
|
|
|
|
* Convert the object's database property to array
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function toDbArray() {
|
2016-12-05 18:51:07 +00:00
|
|
|
$data = [
|
2014-07-18 03:58:21 +00:00
|
|
|
'event_type' => $this->type,
|
|
|
|
'event_variant' => $this->variant,
|
2016-03-04 19:23:02 +00:00
|
|
|
'event_deleted' => $this->deleted,
|
2014-07-18 03:58:21 +00:00
|
|
|
'event_extra' => $this->serializeExtra()
|
2016-12-05 18:51:07 +00:00
|
|
|
];
|
2014-07-18 03:58:21 +00:00
|
|
|
if ( $this->id ) {
|
|
|
|
$data['event_id'] = $this->id;
|
|
|
|
}
|
|
|
|
if ( $this->agent ) {
|
|
|
|
if ( $this->agent->isAnon() ) {
|
|
|
|
$data['event_agent_ip'] = $this->agent->getName();
|
|
|
|
} else {
|
|
|
|
$data['event_agent_id'] = $this->agent->getId();
|
|
|
|
}
|
|
|
|
}
|
2014-08-16 00:24:11 +00:00
|
|
|
|
|
|
|
if ( $this->pageId ) {
|
|
|
|
$data['event_page_id'] = $this->pageId;
|
|
|
|
} elseif ( $this->title ) {
|
2014-07-18 03:58:21 +00:00
|
|
|
$pageId = $this->title->getArticleId();
|
|
|
|
// Don't need any special handling for title with no id
|
|
|
|
// as they are already stored in extra data array
|
|
|
|
if ( $pageId ) {
|
|
|
|
$data['event_page_id'] = $pageId;
|
|
|
|
}
|
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2014-07-18 03:58:21 +00:00
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
2012-11-13 23:06:11 +00:00
|
|
|
/**
|
|
|
|
* Check whether the echo event is an enabled event
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isEnabledEvent() {
|
2013-02-16 02:20:34 +00:00
|
|
|
global $wgEchoNotifications;
|
|
|
|
if ( isset( $wgEchoNotifications[$this->getType()] ) ) {
|
2012-11-13 23:06:11 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-27 15:14:24 +00:00
|
|
|
/**
|
|
|
|
* Inserts the object into the database.
|
|
|
|
*/
|
|
|
|
protected function insert() {
|
2014-08-14 18:46:26 +00:00
|
|
|
$eventMapper = new EchoEventMapper();
|
2014-07-18 03:58:21 +00:00
|
|
|
$this->id = $eventMapper->insert( $this );
|
2016-09-07 17:38:12 +00:00
|
|
|
|
|
|
|
$targetPages = self::resolveTargetPages( $this->getExtraParam( 'target-page' ) );
|
|
|
|
if ( $targetPages ) {
|
2016-09-12 18:36:23 +00:00
|
|
|
$targetMapper = new EchoTargetPageMapper();
|
|
|
|
foreach ( $targetPages as $title ) {
|
|
|
|
$targetPage = EchoTargetPage::create( $title, $this );
|
|
|
|
if ( $targetPage ) {
|
|
|
|
$targetMapper->insert( $targetPage );
|
2016-09-07 17:38:12 +00:00
|
|
|
}
|
2016-09-12 18:36:23 +00:00
|
|
|
}
|
2016-09-07 17:38:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param int[]|int|false $targetPageIds
|
|
|
|
* @return Title[]
|
|
|
|
*/
|
|
|
|
protected static function resolveTargetPages( $targetPageIds ) {
|
|
|
|
if ( !$targetPageIds ) {
|
2016-12-05 18:51:07 +00:00
|
|
|
return [];
|
2016-09-07 17:38:12 +00:00
|
|
|
}
|
|
|
|
if ( !is_array( $targetPageIds ) ) {
|
2016-12-05 18:51:07 +00:00
|
|
|
$targetPageIds = [ $targetPageIds ];
|
2016-09-07 17:38:12 +00:00
|
|
|
}
|
2016-12-05 18:51:07 +00:00
|
|
|
$result = [];
|
2016-09-07 17:38:12 +00:00
|
|
|
foreach ( $targetPageIds as $targetPageId ) {
|
|
|
|
// Make sure the target-page id is a valid id
|
|
|
|
$title = Title::newFromID( $targetPageId );
|
|
|
|
// Try master if there is no match
|
|
|
|
if ( !$title ) {
|
|
|
|
$title = Title::newFromID( $targetPageId, Title::GAID_FOR_UPDATE );
|
|
|
|
}
|
|
|
|
if ( $title ) {
|
|
|
|
$result[] = $title;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-06-06 07:04:28 +00:00
|
|
|
* Loads data from the provided $row into this object.
|
2012-04-27 15:14:24 +00:00
|
|
|
*
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param stdClass $row row object from echo_event
|
2016-05-13 23:39:17 +00:00
|
|
|
* @return bool Whether loading was successful
|
2012-04-27 15:14:24 +00:00
|
|
|
*/
|
2012-08-30 16:04:39 +00:00
|
|
|
public function loadFromRow( $row ) {
|
2012-06-06 07:04:28 +00:00
|
|
|
$this->id = $row->event_id;
|
|
|
|
$this->type = $row->event_type;
|
2013-01-15 23:21:39 +00:00
|
|
|
|
|
|
|
// If the object is loaded from __sleep(), timestamp should be already set
|
|
|
|
if ( !$this->timestamp ) {
|
|
|
|
if ( isset( $row->notification_timestamp ) ) {
|
2013-08-22 21:51:01 +00:00
|
|
|
$this->timestamp = wfTimestamp( TS_MW, $row->notification_timestamp );
|
2013-01-15 23:21:39 +00:00
|
|
|
} else {
|
|
|
|
$this->timestamp = wfTimestampNow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-06 07:04:28 +00:00
|
|
|
$this->variant = $row->event_variant;
|
2016-05-13 23:39:17 +00:00
|
|
|
try {
|
2016-12-05 18:51:07 +00:00
|
|
|
$this->extra = $row->event_extra ? unserialize( $row->event_extra ) : [];
|
2016-05-13 23:39:17 +00:00
|
|
|
} catch ( Exception $e ) {
|
|
|
|
// T73489: unserializing can fail for old notifications
|
2017-03-01 21:02:59 +00:00
|
|
|
LoggerFactory::getInstance( 'Echo' )->warning(
|
|
|
|
'Failed to unserialize event {id}',
|
|
|
|
[
|
|
|
|
'id' => $row->event_id
|
|
|
|
]
|
|
|
|
);
|
2016-05-13 23:39:17 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-05-08 18:11:44 +00:00
|
|
|
$this->pageId = $row->event_page_id;
|
2016-03-04 19:23:02 +00:00
|
|
|
$this->deleted = $row->event_deleted;
|
2012-04-27 15:14:24 +00:00
|
|
|
|
|
|
|
if ( $row->event_agent_id ) {
|
2012-06-06 07:04:28 +00:00
|
|
|
$this->agent = User::newFromID( $row->event_agent_id );
|
2012-04-27 15:14:24 +00:00
|
|
|
} elseif ( $row->event_agent_ip ) {
|
2012-06-06 07:04:28 +00:00
|
|
|
$this->agent = User::newFromName( $row->event_agent_ip, false );
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
|
|
|
|
2014-08-16 00:24:11 +00:00
|
|
|
// Lazy load the title from getTitle() so that we can do a batch-load
|
|
|
|
if (
|
|
|
|
isset( $this->extra['page_title'], $this->extra['page_namespace'] )
|
|
|
|
&& !$row->event_page_id
|
|
|
|
) {
|
2013-05-09 18:50:05 +00:00
|
|
|
$this->title = Title::makeTitleSafe(
|
|
|
|
$this->extra['page_namespace'],
|
|
|
|
$this->extra['page_title']
|
|
|
|
);
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
2014-08-16 03:10:09 +00:00
|
|
|
if ( $row->event_page_id ) {
|
|
|
|
$titleCache = EchoTitleLocalCache::create();
|
|
|
|
$titleCache->add( $row->event_page_id );
|
|
|
|
}
|
2014-08-16 07:00:08 +00:00
|
|
|
if ( isset( $this->extra['revid'] ) && $this->extra['revid'] ) {
|
|
|
|
$revisionCache = EchoRevisionLocalCache::create();
|
|
|
|
$revisionCache->add( $this->extra['revid'] );
|
|
|
|
}
|
2016-05-13 23:39:17 +00:00
|
|
|
|
|
|
|
return true;
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-06-06 07:04:28 +00:00
|
|
|
* Loads data from the database into this object, given the event ID.
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param int $id Event ID
|
|
|
|
* @param bool $fromMaster
|
2016-05-13 23:39:17 +00:00
|
|
|
* @return bool Whether it loaded successfully
|
2012-04-27 15:14:24 +00:00
|
|
|
*/
|
2012-08-02 19:50:46 +00:00
|
|
|
public function loadFromID( $id, $fromMaster = false ) {
|
2014-08-14 18:46:26 +00:00
|
|
|
$eventMapper = new EchoEventMapper();
|
2014-07-18 03:58:21 +00:00
|
|
|
$event = $eventMapper->fetchById( $id, $fromMaster );
|
2016-05-13 23:39:17 +00:00
|
|
|
if ( !$event ) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-07-18 03:58:21 +00:00
|
|
|
|
|
|
|
// Copy over the attribute
|
|
|
|
$this->id = $event->id;
|
|
|
|
$this->type = $event->type;
|
|
|
|
$this->variant = $event->variant;
|
|
|
|
$this->extra = $event->extra;
|
|
|
|
$this->pageId = $event->pageId;
|
|
|
|
$this->agent = $event->agent;
|
|
|
|
$this->title = $event->title;
|
2016-03-04 19:23:02 +00:00
|
|
|
$this->deleted = $event->deleted;
|
2014-07-18 03:58:21 +00:00
|
|
|
// Don't overwrite timestamp if it exists already
|
|
|
|
if ( !$this->timestamp ) {
|
|
|
|
$this->timestamp = $event->timestamp;
|
|
|
|
}
|
2016-05-13 23:39:17 +00:00
|
|
|
|
|
|
|
return true;
|
2012-06-06 07:04:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an EchoEvent from a row object
|
|
|
|
*
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param stdClass $row row object from echo_event
|
2016-05-13 23:39:17 +00:00
|
|
|
* @return EchoEvent|bool
|
2012-06-06 07:04:28 +00:00
|
|
|
*/
|
2012-08-30 16:04:39 +00:00
|
|
|
public static function newFromRow( $row ) {
|
2012-06-06 07:04:28 +00:00
|
|
|
$obj = new EchoEvent();
|
2016-05-13 23:39:17 +00:00
|
|
|
return $obj->loadFromRow( $row )
|
|
|
|
? $obj
|
|
|
|
: false;
|
2012-06-06 07:04:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an EchoEvent from the database by ID
|
|
|
|
*
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param int $id Event ID
|
2016-05-13 23:39:17 +00:00
|
|
|
* @return EchoEvent|bool
|
2012-06-06 07:04:28 +00:00
|
|
|
*/
|
|
|
|
public static function newFromID( $id ) {
|
|
|
|
$obj = new EchoEvent();
|
2016-05-13 23:39:17 +00:00
|
|
|
return $obj->loadFromID( $id )
|
|
|
|
? $obj
|
|
|
|
: false;
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
|
|
|
|
2012-12-26 22:05:29 +00:00
|
|
|
/**
|
|
|
|
* Serialize the extra data for event
|
|
|
|
* @return string
|
|
|
|
*/
|
2013-01-15 23:21:39 +00:00
|
|
|
public function serializeExtra() {
|
2012-12-26 22:05:29 +00:00
|
|
|
if ( is_array( $this->extra ) || is_object( $this->extra ) ) {
|
|
|
|
$extra = serialize( $this->extra );
|
|
|
|
} elseif ( is_null( $this->extra ) ) {
|
|
|
|
$extra = null;
|
|
|
|
} else {
|
2016-12-05 18:51:07 +00:00
|
|
|
$extra = serialize( [ $this->extra ] );
|
2012-12-26 22:05:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $extra;
|
|
|
|
}
|
|
|
|
|
2013-04-02 23:47:54 +00:00
|
|
|
/**
|
|
|
|
* Check if the event is dismissable for the given distribution type
|
|
|
|
*
|
2014-05-27 18:28:37 +00:00
|
|
|
* @param string $distribution notification distribution web/email
|
2013-04-02 23:47:54 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isDismissable( $distribution ) {
|
|
|
|
global $wgEchoNotificationCategories;
|
|
|
|
|
|
|
|
$category = $this->getCategory();
|
|
|
|
if ( isset( $wgEchoNotificationCategories[$category]['no-dismiss'] ) ) {
|
|
|
|
$noDismiss = $wgEchoNotificationCategories[$category]['no-dismiss'];
|
|
|
|
} else {
|
2016-12-05 18:51:07 +00:00
|
|
|
$noDismiss = [];
|
2013-04-02 23:47:54 +00:00
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
if ( !in_array( $distribution, $noDismiss ) && !in_array( 'all', $noDismiss ) ) {
|
2013-04-02 23:47:54 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-08 18:11:44 +00:00
|
|
|
/**
|
|
|
|
* Determine if the current user is allowed to view a particular
|
|
|
|
* field of this revision, if it's marked as deleted. When no
|
|
|
|
* revision is attached always returns true.
|
|
|
|
*
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param int $field One of Revision::DELETED_TEXT,
|
2013-05-08 18:11:44 +00:00
|
|
|
* Revision::DELETED_COMMENT,
|
|
|
|
* Revision::DELETED_USER
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param User $user User object to check
|
|
|
|
* @return bool
|
2013-05-08 18:11:44 +00:00
|
|
|
*/
|
2015-11-24 00:08:17 +00:00
|
|
|
public function userCan( $field, User $user ) {
|
2013-05-08 18:11:44 +00:00
|
|
|
$revision = $this->getRevision();
|
2015-08-28 23:15:06 +00:00
|
|
|
// User is handled specially
|
|
|
|
if ( $field === Revision::DELETED_USER ) {
|
|
|
|
$agent = $this->getAgent();
|
|
|
|
if ( !$agent ) {
|
|
|
|
// No user associated, so they can see it.
|
|
|
|
return true;
|
|
|
|
} elseif ( $revision
|
|
|
|
&& $agent->getName() === $revision->getUserText( Revision::RAW )
|
|
|
|
) {
|
|
|
|
// If the agent and the revision user are the same, use rev_deleted
|
|
|
|
return $revision->userCan( $field, $user );
|
|
|
|
} else {
|
|
|
|
// Use User::isHidden()
|
|
|
|
return $user->isAllowedAny( 'viewsuppressed', 'hideuser' ) || !$agent->isHidden();
|
|
|
|
}
|
|
|
|
} elseif ( $revision ) {
|
|
|
|
// A revision is set, use rev_deleted
|
2013-05-08 18:11:44 +00:00
|
|
|
return $revision->userCan( $field, $user );
|
|
|
|
} else {
|
2015-08-28 23:15:06 +00:00
|
|
|
// Not a user, and there is no associated revision, so the user can see it
|
2013-05-08 18:11:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-27 15:14:24 +00:00
|
|
|
## Accessors
|
2013-03-04 20:56:42 +00:00
|
|
|
/**
|
|
|
|
* @return int
|
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
public function getId() {
|
|
|
|
return $this->id;
|
|
|
|
}
|
|
|
|
|
2013-03-04 20:56:42 +00:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
public function getTimestamp() {
|
|
|
|
return $this->timestamp;
|
|
|
|
}
|
|
|
|
|
2013-03-04 20:56:42 +00:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
public function getType() {
|
|
|
|
return $this->type;
|
|
|
|
}
|
|
|
|
|
2013-03-04 20:56:42 +00:00
|
|
|
/**
|
2015-08-19 19:18:27 +00:00
|
|
|
* @return string|null
|
2013-03-04 20:56:42 +00:00
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
public function getVariant() {
|
|
|
|
return $this->variant;
|
|
|
|
}
|
|
|
|
|
2013-03-04 20:56:42 +00:00
|
|
|
/**
|
|
|
|
* @return array|null
|
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
public function getExtra() {
|
|
|
|
return $this->extra;
|
|
|
|
}
|
|
|
|
|
2013-05-08 18:11:44 +00:00
|
|
|
public function getExtraParam( $key, $default = null ) {
|
|
|
|
return isset( $this->extra[$key] ) ? $this->extra[$key] : $default;
|
|
|
|
}
|
|
|
|
|
2013-03-04 20:56:42 +00:00
|
|
|
/**
|
2015-08-19 19:18:27 +00:00
|
|
|
* @return User|null
|
2013-03-04 20:56:42 +00:00
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
public function getAgent() {
|
|
|
|
return $this->agent;
|
|
|
|
}
|
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
2016-07-27 14:52:18 +00:00
|
|
|
* @param bool $fromMaster
|
|
|
|
* @return null|Title
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
2016-07-27 14:52:18 +00:00
|
|
|
public function getTitle( $fromMaster = false ) {
|
2013-05-08 18:11:44 +00:00
|
|
|
if ( $this->title ) {
|
|
|
|
return $this->title;
|
|
|
|
} elseif ( $this->pageId ) {
|
2014-08-16 03:10:09 +00:00
|
|
|
$titleCache = EchoTitleLocalCache::create();
|
|
|
|
$title = $titleCache->get( $this->pageId );
|
|
|
|
if ( $title ) {
|
|
|
|
return $this->title = $title;
|
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2016-07-27 14:52:18 +00:00
|
|
|
return $this->title = Title::newFromID( $this->pageId, $fromMaster ? Title::GAID_FOR_UPDATE : 0 );
|
2013-05-08 18:11:44 +00:00
|
|
|
} elseif ( isset( $this->extra['page_title'], $this->extra['page_namespace'] ) ) {
|
2014-03-02 08:03:38 +00:00
|
|
|
return $this->title = Title::makeTitleSafe(
|
|
|
|
$this->extra['page_namespace'],
|
|
|
|
$this->extra['page_title']
|
2013-05-08 18:11:44 +00:00
|
|
|
);
|
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2013-05-08 18:11:44 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Revision|null
|
|
|
|
*/
|
|
|
|
public function getRevision() {
|
|
|
|
if ( $this->revision ) {
|
|
|
|
return $this->revision;
|
|
|
|
} elseif ( isset( $this->extra['revid'] ) ) {
|
2014-08-16 07:00:08 +00:00
|
|
|
$revisionCache = EchoRevisionLocalCache::create();
|
|
|
|
$revision = $revisionCache->get( $this->extra['revid'] );
|
|
|
|
if ( $revision ) {
|
|
|
|
return $this->revision = $revision;
|
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2013-05-08 18:11:44 +00:00
|
|
|
return $this->revision = Revision::newFromId( $this->extra['revid'] );
|
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2013-05-08 18:11:44 +00:00
|
|
|
return null;
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
2013-03-09 00:32:28 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the category of the event type
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getCategory() {
|
2014-07-22 21:33:22 +00:00
|
|
|
$attributeManager = EchoAttributeManager::newFromGlobalVars();
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2014-07-22 21:33:22 +00:00
|
|
|
return $attributeManager->getNotificationCategory( $this->type );
|
2013-03-09 00:32:28 +00:00
|
|
|
}
|
2013-01-15 23:21:39 +00:00
|
|
|
|
2014-08-05 21:50:54 +00:00
|
|
|
/**
|
|
|
|
* Get the section of the event type
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getSection() {
|
|
|
|
$attributeManager = EchoAttributeManager::newFromGlobalVars();
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2014-08-05 21:50:54 +00:00
|
|
|
return $attributeManager->getNotificationSection( $this->type );
|
|
|
|
}
|
|
|
|
|
2014-08-27 18:39:53 +00:00
|
|
|
/**
|
2015-07-02 03:36:47 +00:00
|
|
|
* Determine whether an event can use the job queue, or should be immediate
|
2017-07-26 19:34:44 +00:00
|
|
|
* @return bool
|
2014-08-27 18:39:53 +00:00
|
|
|
*/
|
|
|
|
public function getUseJobQueue() {
|
|
|
|
global $wgEchoNotifications;
|
2015-07-02 03:36:47 +00:00
|
|
|
if ( isset( $wgEchoNotifications[$this->type]['immediate'] ) ) {
|
|
|
|
return !(bool)$wgEchoNotifications[$this->type]['immediate'];
|
2014-08-27 18:39:53 +00:00
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2015-07-02 03:36:47 +00:00
|
|
|
return true;
|
2014-08-27 18:39:53 +00:00
|
|
|
}
|
|
|
|
|
2013-11-30 06:20:03 +00:00
|
|
|
public function setType( $type ) {
|
|
|
|
$this->type = $type;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setVariant( $variant ) {
|
|
|
|
$this->variant = $variant;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setAgent( User $agent ) {
|
|
|
|
$this->agent = $agent;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setTitle( Title $title ) {
|
|
|
|
$this->title = $title;
|
2016-03-04 19:23:02 +00:00
|
|
|
$pageId = $title->getArticleID();
|
2013-11-30 06:20:03 +00:00
|
|
|
if ( $pageId ) {
|
|
|
|
$this->pageId = $pageId;
|
|
|
|
} else {
|
2016-03-04 19:23:02 +00:00
|
|
|
$this->extra['page_title'] = $title->getDBkey();
|
2013-11-30 06:20:03 +00:00
|
|
|
$this->extra['page_namespace'] = $title->getNamespace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setExtra( $name, $value ) {
|
|
|
|
$this->extra[$name] = $value;
|
|
|
|
}
|
|
|
|
|
2013-06-12 23:18:26 +00:00
|
|
|
/**
|
|
|
|
* Get the message key of the primary or secondary link for a notification type.
|
|
|
|
*
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param String $rank 'primary' or 'secondary'
|
2013-06-12 23:18:26 +00:00
|
|
|
* @return String i18n message key
|
|
|
|
*/
|
|
|
|
public function getLinkMessage( $rank ) {
|
|
|
|
global $wgEchoNotifications;
|
2014-08-16 06:41:39 +00:00
|
|
|
$type = $this->getType();
|
2015-10-01 13:48:52 +00:00
|
|
|
if ( isset( $wgEchoNotifications[$type][$rank . '-link']['message'] ) ) {
|
|
|
|
return $wgEchoNotifications[$type][$rank . '-link']['message'];
|
2013-06-12 23:18:26 +00:00
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2013-06-12 23:18:26 +00:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the link destination of the primary or secondary link for a notification type.
|
|
|
|
*
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param String $rank 'primary' or 'secondary'
|
2013-06-12 23:18:26 +00:00
|
|
|
* @return String The link destination, e.g. 'agent'
|
|
|
|
*/
|
|
|
|
public function getLinkDestination( $rank ) {
|
|
|
|
global $wgEchoNotifications;
|
2014-08-16 06:41:39 +00:00
|
|
|
$type = $this->getType();
|
2015-10-01 13:48:52 +00:00
|
|
|
if ( isset( $wgEchoNotifications[$type][$rank . '-link']['destination'] ) ) {
|
|
|
|
return $wgEchoNotifications[$type][$rank . '-link']['destination'];
|
2013-06-12 23:18:26 +00:00
|
|
|
}
|
2015-10-01 13:48:52 +00:00
|
|
|
|
2013-06-12 23:18:26 +00:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2013-01-15 23:21:39 +00:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getBundleHash() {
|
|
|
|
return $this->bundleHash;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-08-09 15:20:55 +00:00
|
|
|
* @param string $hash
|
2013-01-15 23:21:39 +00:00
|
|
|
*/
|
|
|
|
public function setBundleHash( $hash ) {
|
|
|
|
$this->bundleHash = $hash;
|
|
|
|
}
|
2016-03-04 19:23:02 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isDeleted() {
|
|
|
|
return $this->deleted === 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setBundledEvents( $events ) {
|
|
|
|
$this->bundledEvents = $events;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getBundledEvents() {
|
|
|
|
return $this->bundledEvents;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-08-09 15:20:55 +00:00
|
|
|
* @inheritDoc
|
2016-03-04 19:23:02 +00:00
|
|
|
*/
|
|
|
|
public function canBeBundled() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-08-09 15:20:55 +00:00
|
|
|
* @inheritDoc
|
2016-03-04 19:23:02 +00:00
|
|
|
*/
|
|
|
|
public function getBundlingKey() {
|
|
|
|
return $this->getBundleHash();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-08-09 15:20:55 +00:00
|
|
|
* @inheritDoc
|
2016-03-04 19:23:02 +00:00
|
|
|
*/
|
|
|
|
public function setBundledElements( $bundleables ) {
|
|
|
|
$this->setBundledEvents( $bundleables );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-08-09 15:20:55 +00:00
|
|
|
* @inheritDoc
|
2016-03-04 19:23:02 +00:00
|
|
|
*/
|
|
|
|
public function getSortingKey() {
|
|
|
|
return $this->getTimestamp();
|
|
|
|
}
|
2012-08-30 16:04:39 +00:00
|
|
|
}
|