mediawiki-extensions-Discus.../includes/Notifications/SubscribedNewCommentPresentationModel.php
Bartosz Dziewoński bd27a46deb Fix revealing content of deleted revisions in notifications
If the revision from which we generated the notification has been
deleted, we shouldn't include the content snippet, nor the direct link
to the comment (because the fragment ID is generated from the content).

This matches how Echo handles mention notifications.

Change-Id: Ica939f3a4efd39d0c295511d58280d3f9d584129
2021-06-03 02:45:15 +02:00

200 lines
5.1 KiB
PHP

<?php
/**
* EchoEventPresentationModel for new comments in a subscribed section
*
* @file
* @ingroup Extensions
* @license MIT
*/
namespace MediaWiki\Extension\DiscussionTools\Notifications;
use EchoDiscussionParser;
use EchoEvent;
use EchoEventPresentationModel;
use EchoPresentationModelSection;
use Language;
use MediaWiki\MediaWikiServices;
use MediaWiki\Revision\RevisionRecord;
use Message;
use RawMessage;
use User;
class SubscribedNewCommentPresentationModel extends EchoEventPresentationModel {
/**
* @var EchoPresentationModelSection
*/
private $section;
/**
* @inheritDoc
*/
protected function __construct( EchoEvent $event, Language $language, User $user, $distributionType ) {
parent::__construct( $event, $language, $user, $distributionType );
$this->section = new EchoPresentationModelSection( $event, $user, $language );
}
/**
* @inheritDoc
*/
public function getIconType() {
return 'chat';
}
/**
* @inheritDoc
*/
public function canRender() {
return (bool)$this->event->getTitle();
}
/**
* @inheritDoc
*/
public function getPrimaryLink() {
// TODO: Handle bundles
return [
'url' => $this->getCommentLink(),
'label' => $this->msg( 'discussiontools-notification-subscribed-new-comment-view' )->text()
];
}
/**
* @inheritDoc
*/
protected function getHeaderMessageKey() {
if ( $this->isBundled() ) {
return 'discussiontools-notification-subscribed-new-comment-header-bundled';
} else {
return 'discussiontools-notification-subscribed-new-comment-header';
}
}
/**
* @inheritDoc
*/
public function getHeaderMessage() {
if ( $this->isBundled() ) {
$count = $this->getNotificationCountForOutput();
$msg = $this->msg( $this->getHeaderMessageKey() );
// Repeat is B/C until unused parameter is removed from translations
$msg->numParams( $count, $count );
$msg->plaintextParams( $this->section->getTruncatedSectionTitle() );
return $msg;
} else {
$msg = parent::getHeaderMessage();
$msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) );
$msg->plaintextParams( $this->section->getTruncatedSectionTitle() );
return $msg;
}
}
/**
* @inheritDoc
*/
public function getCompactHeaderMessage() {
$msg = $this->getMessageWithAgent( 'discussiontools-notification-subscribed-new-comment-header-compact' );
$msg->plaintextParams( $this->getContentSnippet() );
return $msg;
}
/**
* @inheritDoc
*/
public function getBodyMessage() {
if ( !$this->isBundled() ) {
return new RawMessage( '$1', [ Message::plaintextParam( $this->getContentSnippet() ) ] );
}
}
/**
* Get a link to the individual comment, if available.
*
* @return string Full URL linking to the comment
*/
protected function getCommentLink() {
$title = $this->event->getTitle();
if ( !$this->userCan( RevisionRecord::DELETED_TEXT ) ) {
return $title->getFullURL();
}
$id = $this->event->getExtraParam( 'comment-id' );
return $title->createFragmentTarget( $id )->getFullURL();
}
/**
* Get a snippet of the individual comment, if available.
*
* @return string The snippet, as plain text (may be empty)
*/
protected function getContentSnippet() {
if ( !$this->userCan( RevisionRecord::DELETED_TEXT ) ) {
return '';
}
$content = $this->event->getExtraParam( 'content' );
return $this->language->truncateForVisual( $content, EchoDiscussionParser::DEFAULT_SNIPPET_LENGTH );
}
/**
* @inheritDoc
*/
public function getSecondaryLinks() {
$title = $this->event->getTitle();
$url = $title->getLocalURL( [
'oldid' => 'prev',
'diff' => $this->event->getExtraParam( 'revid' )
] );
$viewChangesLink = [
'url' => $url,
'label' => $this->msg( 'notification-link-text-view-changes', $this->getViewingUserForGender() )->text(),
'description' => '',
'icon' => 'changes',
'prioritized' => true,
];
$links = [
$this->getAgentLink(),
$viewChangesLink,
];
$subscriptionStore = MediaWikiServices::getInstance()->getService( 'DiscussionTools.SubscriptionStore' );
$items = $subscriptionStore->getSubscriptionItemsForUser(
$this->getUser(),
[ $this->event->getExtraParam( 'subscribed-comment-name' ) ]
);
$isSubscribed = count( $items ) && !$items[0]->isMuted();
if ( $isSubscribed ) {
$commentName = $this->event->getExtraParam( 'subscribed-comment-name' );
$links[] = $this->getDynamicActionLink(
$this->event->getTitle(),
'bellOutline',
$this->msg( 'discussiontools-topicsubscription-action-unsubscribe-button' )->text(),
null,
[
'tokenType' => 'csrf',
'params' => [
'action' => 'discussiontoolssubscribe',
'page' => $this->event->getTitle(),
'commentname' => $commentName,
// 'subscribe' is unset
],
'messages' => [
'confirmation' => [
'title' => $this->msg( 'discussiontools-topicsubscription-notify-unsubscribed-title' ),
'description' => $this->msg( 'discussiontools-topicsubscription-notify-unsubscribed-body' )
]
]
],
[
'action' => 'dtunsubscribe',
'commentname' => $commentName,
]
);
}
return $links;
}
}