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

Reply via email to