summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CommentStreams/includes/CommentStreamsHooks.php')
-rw-r--r--CommentStreams/includes/CommentStreamsHooks.php334
1 files changed, 115 insertions, 219 deletions
diff --git a/CommentStreams/includes/CommentStreamsHooks.php b/CommentStreams/includes/CommentStreamsHooks.php
index 897ce9c8..5dcf727e 100644
--- a/CommentStreams/includes/CommentStreamsHooks.php
+++ b/CommentStreams/includes/CommentStreamsHooks.php
@@ -26,14 +26,14 @@ namespace MediaWiki\Extension\CommentStreams;
use Article;
use DatabaseUpdater;
use MediaWiki;
+use MediaWiki\MediaWikiServices;
+use MWException;
use OutputPage;
+use PageProps;
use Parser;
use PPFrame;
use SearchResult;
use Skin;
-use SMW\DIWikiPage;
-use SMW\DIProperty;
-use SMW\PropertyRegistry;
use SpecialSearch;
use Status;
use Title;
@@ -42,7 +42,6 @@ use WebRequest;
use WikiPage;
class CommentStreamsHooks {
-
/**
* Implements LoadExtensionSchemaUpdates hook.
* See https://www.mediawiki.org/wiki/Manual:Hooks/LoadExtensionSchemaUpdates
@@ -51,9 +50,8 @@ class CommentStreamsHooks {
* @param DatabaseUpdater $updater database updater
* @return bool continue checking hooks
*/
- public static function addCommentTableToDatabase( DatabaseUpdater $updater ) {
- $dir = $GLOBALS['wgExtensionDirectory'] . DIRECTORY_SEPARATOR .
- 'CommentStreams' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR;
+ public static function addCommentTableToDatabase( DatabaseUpdater $updater ) : bool {
+ $dir = __DIR__ . '/../sql/';
$updater->addExtensionTable( 'cs_comment_data', $dir . 'commentData.sql' );
$updater->addExtensionTable( 'cs_votes', $dir . 'votes.sql' );
$updater->addExtensionTable( 'cs_watchlist', $dir . 'watch.sql' );
@@ -63,6 +61,8 @@ class CommentStreamsHooks {
$dir . 'dropForeignKey1.sql' );
$updater->dropExtensionIndex( 'cs_comment_data', 'cst_assoc_page_id',
$dir . 'dropForeignKey2.sql' );
+ $updater->addExtensionField( 'cs_comment_data', 'cst_id',
+ $dir . 'addCommentId.sql' );
return true;
}
@@ -75,7 +75,7 @@ class CommentStreamsHooks {
* corresponding canonical names
* @return bool continue checking hooks
*/
- public static function addCommentStreamsNamespaces( array &$namespaces ) {
+ public static function addCommentStreamsNamespaces( array &$namespaces ) : bool {
$namespaces[NS_COMMENTSTREAMS] = 'CommentStreams';
$namespaces[NS_COMMENTSTREAMS_TALK] = 'CommentStreams_Talk';
return true;
@@ -94,10 +94,17 @@ class CommentStreamsHooks {
* @param WebRequest $request WebRequest object
* @param MediaWiki $wiki MediaWiki object
* @return bool continue checking hooks
+ * @noinspection PhpUnusedParameterInspection
+ * @throws MWException
*/
- public static function onMediaWikiPerformAction( OutputPage $output,
- Article $article, Title $title, User $user, WebRequest $request,
- MediaWiki $wiki ) {
+ public static function onMediaWikiPerformAction(
+ OutputPage $output,
+ Article $article,
+ Title $title,
+ User $user,
+ WebRequest $request,
+ MediaWiki $wiki
+ ) : bool {
if ( $title->getNamespace() !== NS_COMMENTSTREAMS ) {
return true;
}
@@ -108,10 +115,14 @@ class CommentStreamsHooks {
if ( $action !== 'view' ) {
$message =
wfMessage( 'commentstreams-error-prohibitedaction', $action )->text();
- $output->addHTML( '<p class="error">' . $message . '</p>' );
+ $output->addHTML( '<p class="error">' . htmlentities( $message ) . '</p>' );
}
+
+ $commentStreamsFactory =
+ MediaWikiServices::getInstance()->getService( 'CommentStreamsFactory' );
+
$wikipage = new WikiPage( $title );
- $comment = Comment::newFromWikiPage( $wikipage );
+ $comment = $commentStreamsFactory->newFromWikiPage( $wikipage );
if ( $comment !== null ) {
$commentTitle = $comment->getCommentTitle();
if ( $commentTitle !== null ) {
@@ -119,29 +130,25 @@ class CommentStreamsHooks {
}
$associatedTitle = Title::newFromId( $comment->getAssociatedId() );
if ( $associatedTitle !== null ) {
- $values = [];
- if ( class_exists( 'PageProps' ) ) {
- $values = \PageProps::getInstance()->getProperties( $associatedTitle,
- 'displaytitle' );
- }
+ $values = PageProps::getInstance()->getProperties( $associatedTitle,
+ 'displaytitle' );
if ( array_key_exists( $comment->getAssociatedId(), $values ) ) {
$displaytitle = $values[$comment->getAssociatedId()];
} else {
$displaytitle = $associatedTitle->getPrefixedText();
}
+ $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
$output->setSubtitle(
- CommentStreamsUtils::link( $associatedTitle, '< ' . $displaytitle )
- );
+ $linkRenderer->makeLink( $associatedTitle, '< ' . $displaytitle ) );
} else {
$message =
wfMessage( 'commentstreams-error-comment-on-deleted-page' )->text();
- $output->addHTML( '<p class="error">' . $message . '</p>' );
- }
- if ( method_exists( 'OutputPage', 'addWikiTextAsInterface' ) ) {
- $output->addWikiTextAsInterface( $comment->getHTML() );
- } else {
- $output->addWikiText( $comment->getHTML() );
+ $output->addHTML( '<p class="error">' . htmlentities( $message ) . '</p>' );
}
+ CommentStreamsUtils::addWikiTextToOutputPage(
+ $comment->getHTML( $output->getContext() ),
+ $output
+ );
}
return false;
}
@@ -156,8 +163,11 @@ class CommentStreamsHooks {
* @param Status $status Status object to pass error messages to
* @return bool continue checking hooks
*/
- public static function onMovePageIsValidMove( Title $oldTitle,
- Title $newTitle, Status $status ) {
+ public static function onMovePageIsValidMove(
+ Title $oldTitle,
+ Title $newTitle,
+ Status $status
+ ) : bool {
if ( $oldTitle->getNamespace() === NS_COMMENTSTREAMS ||
$newTitle->getNamespace() === NS_COMMENTSTREAMS ) {
$status->fatal( wfMessage( 'commentstreams-error-prohibitedaction',
@@ -172,15 +182,19 @@ class CommentStreamsHooks {
* See https://www.mediawiki.org/wiki/Manual:Hooks/userCan
* Ensures that only the original author can edit a comment
*
- * @param Title &$title the title object in question
- * @param User &$user the user performing the action
+ * @param Title $title the title object in question
+ * @param User $user the user performing the action
* @param string $action the action being performed
* @param bool &$result true means the user is allowed, false means the
* user is not allowed, untouched means this hook has no opinion
* @return bool continue checking hooks
*/
- public static function userCan( Title &$title, User &$user, $action,
- &$result ) {
+ public static function userCan(
+ Title $title,
+ User $user,
+ string $action,
+ bool &$result
+ ) : bool {
if ( $title->getNamespace() !== NS_COMMENTSTREAMS ) {
return true;
}
@@ -191,22 +205,9 @@ class CommentStreamsHooks {
return true;
}
- if ( $user->isBlocked() ) {
- $result = false;
- return false;
- }
-
if ( $action === 'cs-comment' ) {
- if ( $user->getId() === $wikipage->getOldestRevision()->getUser() ) {
- $result = true;
- } else {
- $result = false;
- }
- return false;
- }
-
- if ( $action === 'cs-moderator-edit' ) {
- if ( in_array( 'cs-moderator-edit', $user->getRights() ) ) {
+ if ( CommentStreamsUtils::userHasRight( $user, $action ) &&
+ $user->getId() === CommentStreamsUtils::getAuthor( $title )->getId() ) {
$result = true;
} else {
$result = false;
@@ -214,12 +215,8 @@ class CommentStreamsHooks {
return false;
}
- if ( $action === 'cs-moderator-delete' ) {
- if ( in_array( 'cs-moderator-delete', $user->getRights() ) ) {
- $result = true;
- } else {
- $result = false;
- }
+ if ( in_array( $action, [ 'cs-moderator-edit', 'cs-moderator-delete' ] ) ) {
+ $result = CommentStreamsUtils::userHasRight( $user, $action );
return false;
}
@@ -234,8 +231,9 @@ class CommentStreamsHooks {
*
* @param Parser $parser the parser
* @return bool continue checking hooks
+ * @throws MWException
*/
- public static function onParserSetup( Parser $parser ) {
+ public static function onParserSetup( Parser $parser ) : bool {
$parser->setHook( 'comment-streams',
'MediaWiki\Extension\CommentStreams\CommentStreamsHooks::enableCommentStreams' );
$parser->setHook( 'no-comment-streams',
@@ -249,22 +247,30 @@ class CommentStreamsHooks {
* Implements tag function, <comment-streams/>, which enables
* CommentStreams on a page.
*
- * @param string $input input between the tags (ignored)
+ * @param ?string $input input between the tags (ignored)
* @param array $args tag arguments
* @param Parser $parser the parser
* @param PPFrame $frame the parent frame
* @return string to replace tag with
+ * @noinspection PhpUnusedParameterInspection
*/
- public static function enableCommentStreams( $input, array $args,
- Parser $parser, PPFrame $frame ) {
+ public static function enableCommentStreams(
+ ?string $input,
+ array $args,
+ Parser $parser,
+ PPFrame $frame
+ ) : string {
$parser->getOutput()->updateCacheExpiry( 0 );
- $cs = CommentStreams::singleton();
+ $cs = MediaWikiServices::getInstance()->getService( 'CommentStreamsHandler' );
$cs->enableCommentsOnPage();
- if ( isset( $args['location'] ) && $args['location'] === 'footer' ) {
+ if ( isset( $args['id'] ) ) {
+ $ret = '<div class="cs-comments" id="csc_' . md5( $args['id'] ) . '"></div>';
+ } elseif ( isset( $args['location'] ) && $args['location'] === 'footer' ) {
$ret = '';
} else {
- $ret = '<div id="cs-comments"></div>';
+ $ret = '<div class="cs-comments" id="cs-comments"></div>';
}
+ // @phan-suppress-next-line SecurityCheck-XSS
return $ret;
}
@@ -272,34 +278,44 @@ class CommentStreamsHooks {
* Implements tag function, <no-comment-streams/>, which disables
* CommentStreams on a page.
*
- * @param string $input input between the tags (ignored)
+ * @param ?string $input input between the tags (ignored)
* @param array $args tag arguments
* @param Parser $parser the parser
* @param PPFrame $frame the parent frame
* @return string to replace tag with
+ * @noinspection PhpUnusedParameterInspection
*/
- public static function disableCommentStreams( $input, array $args,
- Parser $parser, PPFrame $frame ) {
+ public static function disableCommentStreams(
+ ?string $input,
+ array $args,
+ Parser $parser,
+ PPFrame $frame
+ ) : string {
$parser->getOutput()->updateCacheExpiry( 0 );
- $cs = CommentStreams::singleton();
+ $cs = MediaWikiServices::getInstance()->getService( 'CommentStreamsHandler' );
$cs->disableCommentsOnPage();
- return "";
+ return '';
}
/**
* Implements tag function, <comment-streams-initially-collapsed/>, which
* makes CommentStreams on a page start as collapsed when the page is viewed.
*
- * @param string $input input between the tags (ignored)
+ * @param ?string $input input between the tags (ignored)
* @param array $args tag arguments
* @param Parser $parser the parser
* @param PPFrame $frame the parent frame
* @return string to replace tag with
+ * @noinspection PhpUnusedParameterInspection
*/
- public static function initiallyCollapseCommentStreams( $input, array $args,
- Parser $parser, PPFrame $frame ) {
+ public static function initiallyCollapseCommentStreams(
+ ?string $input,
+ array $args,
+ Parser $parser,
+ PPFrame $frame
+ ) : string {
$parser->getOutput()->updateCacheExpiry( 0 );
- $cs = CommentStreams::singleton();
+ $cs = MediaWikiServices::getInstance()->getService( 'CommentStreamsHandler' );
$cs->initiallyCollapseCommentsOnPage();
return "";
}
@@ -309,13 +325,16 @@ class CommentStreamsHooks {
* See https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
* Gets comments for page and initializes variables to be passed to JavaScript.
*
- * @param OutputPage &$output OutputPage object
- * @param Skin &$skin Skin object that will be used to generate the page
+ * @param OutputPage $output OutputPage object
+ * @param Skin $skin Skin object that will be used to generate the page
* @return bool continue checking hooks
+ * @noinspection PhpUnusedParameterInspection
*/
- public static function addCommentsAndInitializeJS( OutputPage &$output,
- Skin &$skin ) {
- $cs = CommentStreams::singleton();
+ public static function addCommentsAndInitializeJS(
+ OutputPage $output,
+ Skin $skin
+ ) : bool {
+ $cs = MediaWikiServices::getInstance()->getService( 'CommentStreamsHandler' );
$cs->init( $output );
return true;
}
@@ -327,15 +346,27 @@ class CommentStreamsHooks {
* associated content page instead.
*
* @param Title &$title title to link to
- * @param string &$text text to use for the link
+ * @param ?string &$text text to use for the link
* @param SearchResult $result the search result
* @param array $terms the search terms entered
* @param SpecialSearch $page the SpecialSearch object
* @return bool continue checking hooks
+ * @noinspection PhpUnusedParameterInspection
*/
- public static function showSearchHitTitle( Title &$title, &$text,
- SearchResult $result, array $terms, SpecialSearch $page ) {
- $comment = Comment::newFromWikiPage( WikiPage::factory( $title ) );
+ public static function showSearchHitTitle(
+ Title &$title,
+ ?string &$text,
+ SearchResult $result,
+ array $terms,
+ SpecialSearch $page
+ ) : bool {
+ if ( $title->getNamespace() !== NS_COMMENTSTREAMS ) {
+ return true;
+ }
+ $commentStreamsFactory =
+ MediaWikiServices::getInstance()->getService( 'CommentStreamsFactory' );
+ $comment = $commentStreamsFactory->newFromWikiPage(
+ CommentStreamsUtils::newWikiPageFromId( $title->getArticleID() ) );
if ( $comment !== null ) {
$t = Title::newFromId( $comment->getAssociatedId() );
if ( $t !== null ) {
@@ -346,28 +377,16 @@ class CommentStreamsHooks {
}
/**
- * Implements SMW::Settings::BeforeInitializationComplete callback.
- * See https://github.com/SemanticMediaWiki/SemanticMediaWiki/blob/master/docs/technical/hooks/hook.settings.beforeinitializationcomplete.md
- * Defines CommentStreams namespace constants.
- *
- * @param array &$configuration An array of the configuration options
- */
- public static function onSMWInitialization( array &$configuration ) {
- $namespace = $GLOBALS['wgCommentStreamsNamespaceIndex'];
- $configuration['smwgNamespacesWithSemanticLinks'][$namespace] = true;
- }
-
- /**
* Implements extension registration callback.
* See https://www.mediawiki.org/wiki/Manual:Extension_registration#Customizing_registration
* Sets configuration constants.
- *
*/
public static function onRegistration() {
define( 'NS_COMMENTSTREAMS', $GLOBALS['wgCommentStreamsNamespaceIndex'] );
- define( 'NS_COMMENTSTREAMS_TALK',
- $GLOBALS['wgCommentStreamsNamespaceIndex'] + 1 );
- $GLOBALS['wgNamespacesToBeSearchedDefault'][NS_COMMENTSTREAMS] = true;
+ define( 'NS_COMMENTSTREAMS_TALK', $GLOBALS['wgCommentStreamsNamespaceIndex'] + 1 );
+ if ( $GLOBALS['wgCommentStreamsEnableSearch'] ) {
+ $GLOBALS['wgNamespacesToBeSearchedDefault'][NS_COMMENTSTREAMS] = true;
+ }
$found = false;
foreach ( $GLOBALS['wgGroupPermissions'] as $groupperms ) {
if ( isset( $groupperms['cs-comment'] ) ) {
@@ -383,13 +402,11 @@ class CommentStreamsHooks {
}
}
}
- if ( !isset( $GLOBALS['wgGroupPermissions']['csmoderator']
- ['cs-moderator-delete'] ) ) {
+ if ( !isset( $GLOBALS['wgGroupPermissions']['csmoderator']['cs-moderator-delete'] ) ) {
$GLOBALS['wgGroupPermissions']['csmoderator']['cs-moderator-delete'] =
true;
}
- if ( !isset( $GLOBALS['wgGroupPermissions']['csmoderator']
- ['cs-moderator-edit'] ) ) {
+ if ( !isset( $GLOBALS['wgGroupPermissions']['csmoderator']['cs-moderator-edit'] ) ) {
$GLOBALS['wgGroupPermissions']['csmoderator']['cs-moderator-edit'] =
false;
}
@@ -399,125 +416,4 @@ class CommentStreamsHooks {
$GLOBALS['wgLogTypes'][] = 'commentstreams';
$GLOBALS['wgLogActionsHandlers']['commentstreams/*'] = 'LogFormatter';
}
-
- /**
- * Initialize extra Semantic MediaWiki properties.
- * This won't get called unless Semantic MediaWiki is installed.
- */
- public static function initProperties() {
- $pr = PropertyRegistry::getInstance();
- $pr->registerProperty( '___CS_ASSOCPG', '_wpg', 'Comment on' );
- $pr->registerProperty( '___CS_REPLYTO', '_wpg', 'Reply to' );
- $pr->registerProperty( '___CS_TITLE', '_txt', 'Comment title of' );
- $pr->registerProperty( '___CS_UPVOTES', '_num', 'Comment up votes' );
- $pr->registerProperty( '___CS_DOWNVOTES', '_num', 'Comment down votes' );
- $pr->registerProperty( '___CS_VOTEDIFF', '_num', 'Comment vote diff' );
- }
-
- /**
- * Implements Semantic MediaWiki SMWStore::updateDataBefore callback.
- * This won't get called unless Semantic MediaWiki is installed.
- * If the comment has not been added to the database yet, which is indicated
- * by a null associated page id, this function will return early, but it
- * will be invoked again by an update job.
- *
- * @param SMW\Store $store semantic data store
- * @param SMW\SemanticData $semanticData semantic data for page
- * @return bool true to continue
- */
- public static function updateData( $store, $semanticData ) {
- $subject = $semanticData->getSubject();
- if ( $subject !== null && $subject->getTitle() !== null &&
- $subject->getTitle()->getNamespace() === NS_COMMENTSTREAMS ) {
- $page_id = $subject->getTitle()->getArticleID( Title::GAID_FOR_UPDATE );
- $wikipage = WikiPage::newFromId( $page_id );
- $comment = Comment::newFromWikiPage( $wikipage );
-
- if ( $comment === null ) {
- return true;
- }
-
- $assoc_page_id = $comment->getAssociatedId();
- if ( $assoc_page_id !== null ) {
- $assoc_wikipage = WikiPage::newFromId( $assoc_page_id );
- if ( $assoc_wikipage !== null ) {
- $propertyDI = new DIProperty( '___CS_ASSOCPG' );
- $dataItem =
- DIWikiPage::newFromTitle( $assoc_wikipage->getTitle() );
- $semanticData->addPropertyObjectValue( $propertyDI, $dataItem );
- }
- }
-
- $parent_page_id = $comment->getParentId();
- if ( $parent_page_id !== null ) {
- $parent_wikipage = WikiPage::newFromId( $parent_page_id );
- if ( $parent_wikipage !== null ) {
- $propertyDI = new DIProperty( '___CS_REPLYTO' );
- $dataItem =
- DIWikiPage::newFromTitle( $parent_wikipage->getTitle() );
- $semanticData->addPropertyObjectValue( $propertyDI, $dataItem );
- }
- }
-
- $commentTitle = $comment->getCommentTitle();
- if ( $commentTitle !== null ) {
- $propertyDI = new DIProperty( '___CS_TITLE' );
- $dataItem = new SMWDIBlob( $comment->getCommentTitle() );
- $semanticData->addPropertyObjectValue( $propertyDI, $dataItem );
- }
-
- if ( $GLOBALS['wgCommentStreamsEnableVoting'] === true ) {
- $upvotes = $comment->getNumUpVotes();
- $propertyDI = new DIProperty( '___CS_UPVOTES' );
- $dataItem = new SMWDINumber( $upvotes );
- $semanticData->addPropertyObjectValue( $propertyDI, $dataItem );
- $downvotes = $comment->getNumDownVotes();
- $propertyDI = new DIProperty( '___CS_DOWNVOTES' );
- $dataItem = new SMWDINumber( $downvotes );
- $semanticData->addPropertyObjectValue( $propertyDI, $dataItem );
- $votediff = $upvotes - $downvotes;
- $propertyDI = new DIProperty( '___CS_VOTEDIFF' );
- $dataItem = new SMWDINumber( $votediff );
- $semanticData->addPropertyObjectValue( $propertyDI, $dataItem );
- }
- }
- return true;
- }
-
- /**
- * @param array &$notifications notifications
- * @param array &$notificationCategories notification categories
- * @param array &$icons notification icons
- */
- public static function onBeforeCreateEchoEvent( &$notifications,
- &$notificationCategories, &$icons ) {
- $notificationCategories['commentstreams-notification-category'] = [
- 'priority' => 3
- ];
-
- $notifications['commentstreams-comment-on-watched-page'] = [
- 'category' => 'commentstreams-notification-category',
- 'group' => 'positive',
- 'section' => 'alert',
- 'presentation-model' => EchoCSPresentationModel::class,
- 'user-locators' => [ 'EchoUserLocator::locateUsersWatchingTitle' ]
- ];
-
- $notifications['commentstreams-reply-on-watched-page'] = [
- 'category' => 'commentstreams-notification-category',
- 'group' => 'positive',
- 'section' => 'alert',
- 'presentation-model' => EchoCSPresentationModel::class,
- 'user-locators' => [ 'EchoUserLocator::locateUsersWatchingTitle' ],
- 'user-filters' => [ 'Comment::locateUsersWatchingComment' ]
- ];
-
- $notifications['commentstreams-reply-to-watched-comment'] = [
- 'category' => 'commentstreams-notification-category',
- 'group' => 'positive',
- 'section' => 'alert',
- 'presentation-model' => EchoCSPresentationModel::class,
- 'user-locators' => [ 'Comment::locateUsersWatchingComment' ]
- ];
- }
}