EBernhardson (WMF) has uploaded a new change for review.
https://gerrit.wikimedia.org/r/81017
Change subject: first stab at recentchanges integration
......................................................................
first stab at recentchanges integration
Change-Id: Ie1fa4ed5511ba04c07bf16f1bbc1263b904cb8fc
---
M Flow.i18n.php
M Flow.php
M Hooks.php
M container.php
M includes/Container.php
A includes/Data/RecentChanges.php
M includes/ParsoidUtils.php
A includes/RecentChanges/ExternalChangesLines.php
8 files changed, 338 insertions(+), 1 deletion(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow
refs/changes/17/81017/1
diff --git a/Flow.i18n.php b/Flow.i18n.php
index 4cd3713..99240fb 100644
--- a/Flow.i18n.php
+++ b/Flow.i18n.php
@@ -67,6 +67,9 @@
'flow-comment-restored' => 'Restored comment',
'flow-comment-deleted' => 'Deleted comment',
+ 'flow-link-post' => 'post',
+ 'flow-link-topic' => 'topic',
+ 'flow-link-history' => 'history',
);
/** Message documentation (Message documentation)
diff --git a/Flow.php b/Flow.php
index 7ff4339..bb08362 100755
--- a/Flow.php
+++ b/Flow.php
@@ -88,6 +88,8 @@
$wgAutoloadClasses['Flow\Data\RootPostLoader'] = $dir .
'includes/Data/RootPostLoader.php';
$wgAutoloadClasses['Flow\Data\MultiDimArray'] = $dir .
'includes/Data/MultiDimArray.php';
$wgAutoloadClasses['Flow\Data\ResultDuplicator'] = $dir .
'includes/Data/MultiDimArray.php';
+$wgAutoloadClasses['Flow\Data\PostRevisionRecentChanges'] = $dir .
'includes/Data/RecentChanges.php';
+$wgAutoloadClasses['Flow\RecentChanges\ExternalChangesLines'] = $dir .
'includes/RecentChanges/ExternalChangesLines.php';
// database interaction for singular models
$wgAutoloadClasses['Flow\Data\PostRevisionStorage'] = $dir .
'includes/Data/RevisionStorage.php';
@@ -119,6 +121,8 @@
$wgHooks['LoadExtensionSchemaUpdates'][] = 'FlowHooks::getSchemaUpdates';
//$wgHooks['GetPreferences'][] = 'FlowHooks::getPreferences';
$wgHooks['UnitTestsList'][] = 'FlowHooks::getUnitTests';
+$wgHooks['OldChangesListRecentChangesLine'][] =
'FlowHooks::onOldChangesListRecentChangesLine';
+
// Extension initialization
$wgExtensionFunctions[] = 'FlowHooks::initFlowExtension';
diff --git a/Hooks.php b/Hooks.php
index ded1608..52d6eb9 100644
--- a/Hooks.php
+++ b/Hooks.php
@@ -31,4 +31,21 @@
//$files[] = "$dir/DiscussionParserTest.php";
return true;
}
+
+ public static function onOldChangesListRecentChangesLine( \ChangesList
&$changesList, &$s, \RecentChange $rc, &$classes = array() ) {
+
+ $rcType = $rc->getAttribute( 'rc_type' );
+ if ( $rcType == RC_EXTERNAL ) {
+
+ $line =
Flow\RecentChanges\ExternalChangesLines::changesLine( $changesList, $rc );
+ if ( $line === false ) {
+ return false;
+ }
+
+ $classes[] = 'flow-something';
+ $s = $line;
+ }
+
+ return true;
+ }
}
diff --git a/container.php b/container.php
index 65d6bc1..c0c8980 100644
--- a/container.php
+++ b/container.php
@@ -227,7 +227,11 @@
) )
);
- return new ObjectManager( $mapper, $storage, $indexes );
+ $handlers = array(
+ new Flow\Data\PostRevisionRecentChanges( $c['storage'],
$c['repository.tree'] ),
+ );
+
+ return new ObjectManager( $mapper, $storage, $indexes, $handlers );
} );
// Storage implementation for user subscriptions, separate from
storage.user_subs so it
// can be used in storage.user_subs.user_index as well.
diff --git a/includes/Container.php b/includes/Container.php
index a89eb49..2d10d31 100644
--- a/includes/Container.php
+++ b/includes/Container.php
@@ -3,4 +3,11 @@
namespace Flow;
class Container extends \Pimple {
+ public static function getContainer() {
+ static $container;
+ if ( $container === null ) {
+ $container = include __DIR__ . '/../container.php';
+ }
+ return $container;
+ }
}
diff --git a/includes/Data/RecentChanges.php b/includes/Data/RecentChanges.php
new file mode 100644
index 0000000..1fd65f2
--- /dev/null
+++ b/includes/Data/RecentChanges.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Flow\Data;
+
+use Flow\Model\UUID;
+use Flow\Model\Workflow;
+use Flow\Repository\TreeRepository;
+
+class PostRevisionRecentChanges implements LifecycleHandler {
+ public function __construct( ManagerGroup $storage, TreeRepository
$tree ) {
+ $this->storage = $storage;
+ $this->tree = $tree;
+ }
+
+ public function onAfterInsert( $object, array $row ) {
+ // There might be a more efficient way to get this workflow id
+ $workflowId = $this->tree->findRoot( $object->getPostId() );
+ if ( !$workflowId ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ": could not
locate root for post " . $object->getPostId()->getHex() );
+ return;
+ }
+ // These are likely already in the in-process cache
+ $workflow = $this->storage->get( 'Workflow', $workflowId );
+ if ( !$workflow ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ": could not
locate workflow $workflowId" );
+ return;
+ }
+
+ $isFirstRev = !$object->getPrevRevisionId();
+ if ( $object->isTopicTitle() ) {
+ $type = $isFirstRev ? 'new-topic' : 'edit-topic-title';
+ } elseif ( $isFirstRev && $object->getReplyToId()->equals(
$workflowId ) ) {
+ // this is the first post, which is already in recent
changes through the new-topic
+ return;
+ } elseif ( $object->getPrevRevisionId() === null ) {
+ $type = 'new-post';
+ } else {
+ // how to determine what happened and needs to be
logged?
+ // could be moderation, or content edit
+ $type = 'moderate-post';
+ }
+
+ $this->insert(
+ $type,
+ $row,
+ $workflow,
+ $object->getRevisionId(),
+ array(
+ 'post' => $object->getPostId()->getHex(),
+ 'revision' =>
$object->getRevisionId()->getHex(),
+ 'comment' => $object->getComment(),
+ )
+ );
+ }
+
+ public function onAfterUpdate( $object, array $old, array $new ) {
+
+ }
+
+ public function onAfterRemove( $object, array $old ) {
+
+ }
+
+ public function onAfterLoad( $object, array $row ) {
+ // nothingng to do
+ }
+
+ protected function insert( $type, array $row, Workflow $workflow,
$timestamp, array $changes ) {
+ if ( $timestamp instanceof UUID ) {
+ $timestamp = $timestamp->getTimestamp();
+ }
+ $title = $workflow->getTitle();
+
+ $attribs = array(
+ 'rc_namespace' => $title->getNamespace(),
+ 'rc_title' => $title->getDBkey(),
+ 'rc_user' => $row['rev_user_id'],
+ 'rc_user_text' => $row['rev_user_text'],
+ 'rc_type' => RC_EXTERNAL,
+ 'rc_minor' => 0,
+ 'rc_bot' => 0, // TODO: is revision by bot
+ 'rc_patrolled' => 0,
+ 'rc_old_len' => 0,
+ 'rc_new_len' => 0,
+ 'rc_this_oldid' => 0,
+ 'rc_last_oldid' => 0,
+ 'rc_params' => serialize( array(
+ 'flow-workflow-change' => array(
+ 'type' => $type,
+ 'workflow' =>
$workflow->getId()->getHex(),
+ 'definition' =>
$workflow->getDefinitionId()->getHex(),
+ ) + $changes,
+ ) ),
+ 'rc_cur_id' => 0, // TODO: wtf do we do with uuid's?
+ 'rc_comment' => '',
+ 'rc_timestamp' => $timestamp,
+ 'rc_cur_time' => $timestamp,
+ 'rc_log_action' => '',
+ );
+
+ $dbw = wfGetDB( DB_MASTER );
+ return $dbw->insert( 'recentchanges', $attribs, __METHOD__ );
+ }
+}
+
diff --git a/includes/ParsoidUtils.php b/includes/ParsoidUtils.php
index 3e4564c..e0ea177 100644
--- a/includes/ParsoidUtils.php
+++ b/includes/ParsoidUtils.php
@@ -6,6 +6,10 @@
public static function convertWikitextToHtml5( $wikitext, $title ) {
global $wgFlowUseParsoid;
+ if ( !$wikitext ) {
+ return '';
+ }
+
if ( $wgFlowUseParsoid ) {
global $wgFlowParsoidURL, $wgFlowParsoidPrefix,
$wgFlowParsoidTimeout;
@@ -20,6 +24,11 @@
)
);
+ if ( !$parsoidOutput ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ':
Parsoid returned no output' );
+ return false;
+ }
+
// Strip out the Parsoid boilerplate
$dom = new \DOMDocument();
$dom->loadHTML( $parsoidOutput );
diff --git a/includes/RecentChanges/ExternalChangesLines.php
b/includes/RecentChanges/ExternalChangesLines.php
new file mode 100644
index 0000000..c1db09b
--- /dev/null
+++ b/includes/RecentChanges/ExternalChangesLines.php
@@ -0,0 +1,188 @@
+<?php
+
+namespace Flow\RecentChanges;
+
+use Flow\Container;
+use ChangesList;
+use Linker;
+use RecentChange;
+use Title;
+use User;
+
+class ExternalChangesLines {
+ static public function changesLine( ChangesList $cl, RecentChange $rc )
{
+ $params = unserialize( $rc->getAttribute( 'rc_params' ) );
+ $changeData = $params['flow-workflow-change'];
+
+ if ( !is_array( $changeData ) ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ': Flow data
missing in recent changes.' );
+ return false;
+ }
+
+ if ( !array_key_exists( 'type', $changeData ) ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ': Flow change
type missing' );
+ return false;
+ }
+
+ $line = '';
+ $title = self::buildTitle( $rc, $changeData );
+ $links = self::buildActionLinks( $title, $changeData );
+ if ( $links === false ) {
+ return;
+ }
+ if ( $links ) {
+ $line .= wfMessage( 'parentheses' )->rawParams(
+ $cl->getLanguage()->pipeList( $links )
+ )->text()
+ . self::changeSeparator();
+ }
+
+ $line .= Linker::link( $title )
+ . self::getTimestamp( $cl, $rc )
+ . ' '
+ . self::changeSeparator()
+ . ' '
+ . self::userLinks( $cl, $rc->getAttribute(
'rc_user_text' ) )
+ . ' '
+ . self::getComment( $changeData );
+
+ return $line;
+ }
+
+ protected static function buildTitle( RecentChange $rc, array
$changeData ) {
+ $title = $rc->getTitle();
+ return $title;
+ }
+
+ protected static function buildActionLinks( Title $title, array
$changeData ) {
+ $links = array();
+ switch( $changeData['type'] ) {
+ case 'new-topic':
+ $links[] = self::topicLink( $title, $changeData );
+ break;
+
+ case 'new-post':
+ $links[] = self::postLink( $title, $changeData );
+ $links[] = self::topicLink( $title, $changeData );
+ break;
+
+ case 'moderate-post':
+ // TODO: this only happens when oversighting (updating
an existing
+ // revision rather than creating a new revision of the
content).
+ $links[] = self::postHistoryLink( $title, $changeData );
+ $links[] = self::topicLink( $title, $changeData );
+
+ case 'edit-topic-title':
+ break;
+
+ default:
+ wfDebugLog( __CLASS__, __FUNCTION__ . ': Invalid Flow
change type.' );
+ return false;
+ }
+
+ return $links;
+ }
+
+ protected static function changeSeparator() {
+ return ' <span class="mw-changeslist-separator">. .</span> ';
+ }
+
+ protected static function getTimestamp( $cl, $rc ) {
+ return wfMessage( 'semicolon-separator' )->text()
+ . '<span class="mw-changeslist-date">'
+ . $cl->getLanguage()->userTime(
$rc->mAttribs['rc_timestamp'], $cl->getUser() )
+ . '</span> ';
+ }
+
+ public static function postHistoryLink( Title $title, array $changeData
) {
+ return Linker::link(
+ $title,
+ wfMessage( 'flow-link-history' ),
+ array(),
+ array(
+ 'action' => 'post-history',
+ 'workflow' => $changeData['workflow'],
+ 'topic' => array(
+ 'postId' => $changeData['post'],
+ ),
+ )
+ );
+ }
+
+ public static function topicLink( Title $title, array $changeData ) {
+ return Linker::link(
+ $title,
+ wfMessage( 'flow-link-topic' ),
+ array(),
+ array(
+ 'action' => 'view',
+ 'workflow' => $changeData['workflow'],
+ )
+ );
+ }
+
+ public static function postLink( Title $title, array $changeData ) {
+ return Linker::link(
+ $title,
+ wfMessage( 'flow-link-post' ),
+ array(),
+ array(
+ 'action' => 'view',
+ 'workflow' => $changeData['workflow'],
+ 'topic' => array(
+ 'postId' => $changeData['post'],
+ ),
+ )
+ );
+ }
+
+ public static function userLinks( $cl, $userName ) {
+ if ( User::isIP( $userName ) ) {
+ $links = self::userContribsLink( $userName, $userName )
+ . wfMessage( 'word-separator' )->plain()
+ . wfMessage( 'parentheses' )->rawParams(
self::userTalkLink( $userName ) )->text();
+ } else {
+ $tools = array(
+ self::userTalkLink( $userName ),
+ self::userContribsLink( $userName )
+ );
+
+ $links = self::userLink( $userName )
+ . wfMessage( 'word-separator' )->plain()
+ . '<span class="mw-usertoollinks">'
+ . wfMessage( 'parentheses' )->rawParams(
$cl->getLanguage()->pipeList( $tools ) )->text()
+ . '</span>';
+ }
+ return $links;
+ }
+
+ protected static function userContribsLink( $userName, $text = null ) {
+ if ( $text === null ) {
+ $text = wfMessage( 'contribslink' );
+ }
+ return Linker::link( Title::newFromText(
"Contributions/$userName", NS_SPECIAL ), $text );
+ }
+
+ protected static function userTalkLink( $userName ) {
+ return Linker::link(
+ Title::newFromText( $userName, NS_USER_TALK ),
+ wfMessage( 'talkpagelinktext' )->text()
+ );
+ }
+
+ protected static function userLink( $userName ) {
+ return Linker::link(
+ Title::newFromText( $userName, NS_USER ),
+ $userName,
+ array( 'class' => 'mw-userlink' )
+ );
+ }
+
+ public static function getComment( array $changeData ) {
+ if ( isset( $changeData['comment'] ) ) {
+ return wfMessage( $changeData['comment'] );
+ } else {
+ return wfMessage( 'flow-no-comment' );
+ }
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/81017
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie1fa4ed5511ba04c07bf16f1bbc1263b904cb8fc
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: EBernhardson (WMF) <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits