EBernhardson has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/115532

Change subject: [WIP] Combined board history
......................................................................

[WIP] Combined board history

Change-Id: I9719b8a911b497ddb59a149d59063f8c1ce6d7e5
---
M Flow.php
M Resources.php
M container.php
M includes/Block/Header.php
M includes/Data/BoardHistoryStorage.php
A includes/Formatter/BoardHistory.php
A includes/Formatter/BoardHistoryQuery.php
A modules/history/styles/board-history.less
M templates/board-history.html.php
9 files changed, 188 insertions(+), 70 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow 
refs/changes/32/115532/1

diff --git a/Flow.php b/Flow.php
index d167d42..5234aff 100755
--- a/Flow.php
+++ b/Flow.php
@@ -140,6 +140,8 @@
 $wgAutoloadClasses['Flow\Formatter\CheckUser'] = $dir . 
'includes/Formatter/CheckUser.php';
 $wgAutoloadClasses['Flow\Formatter\ContributionsQuery'] = $dir . 
'includes/Formatter/ContributionsQuery.php';
 $wgAutoloadClasses['Flow\Formatter\Contributions'] = $dir . 
'includes/Formatter/Contributions.php';
+$wgAutoloadClasses['Flow\Formatter\BoardHistory'] = $dir . 
'includes/Formatter/BoardHistory.php';
+$wgAutoloadClasses['Flow\Formatter\BoardHistoryQuery'] = $dir . 
'includes/Formatter/BoardHistoryQuery.php';
 $wgAutoloadClasses['Flow\Formatter\RecentChanges'] = $dir . 
'includes/Formatter/RecentChanges.php';
 $wgAutoloadClasses['Flow\Data\UserNameListener'] = $dir . 
'includes/Data/UserNameBatch.php';
 $wgAutoloadClasses['Flow\Data\UserNameBatch'] = $dir . 
'includes/Data/UserNameBatch.php';
diff --git a/Resources.php b/Resources.php
index 195fb78..2fdf6f1 100644
--- a/Resources.php
+++ b/Resources.php
@@ -105,6 +105,7 @@
        ),
        'ext.flow.history' => $flowResourceTemplate + array(
                'styles' => array(
+                       'history/styles/board-history.less', // @todo should be 
independant?
                        'history/styles/history.less',
                        'history/styles/diff.less',
                ),
diff --git a/container.php b/container.php
index daa00ab..3f1d4c4 100644
--- a/container.php
+++ b/container.php
@@ -185,7 +185,8 @@
 } );
 
 $c['storage.board_history.index'] = $c->share( function( $c ) {
-       return new BoardHistoryIndex( $c['memcache.buffered'], 
$c['storage.board_history.backing'], 'flow_revision:topic_list_history',
+       return new BoardHistoryIndex( $c['memcache.buffered'], 
$c['storage.board_history.backing'],
+               'flow_revision:vXxXxX:topic_list_history',
                array( 'topic_list_id' ),
                array(
                        'limit' => 500,
@@ -483,7 +484,19 @@
                $c['templating']
        );
 } );
-
+$c['board-history.query'] = $c->share( function( $c ) {
+       return new Flow\Formatter\BoardHistoryQuery(
+               $c['storage'],
+               $c['repository.tree']
+       );
+} );
+$c['board-history.formatter'] = $c->share( function( $c ) {
+       return new Flow\Formatter\BoardHistory(
+               $c['storage'],
+               $c['flow_actions'],
+               $c['templating']
+       );
+} );
 $c['logger'] = $c->share( function( $c ) {
        return new Flow\Log\Logger(
                $c['flow_actions'],
diff --git a/includes/Block/Header.php b/includes/Block/Header.php
index 1f5a364..db15179 100644
--- a/includes/Block/Header.php
+++ b/includes/Block/Header.php
@@ -4,13 +4,9 @@
 
 use Flow\Container;
 use Flow\Model\Header;
-use Flow\Model\PostRevision;
 use Flow\RevisionActionPermissions;
-use Flow\View\History\History;
-use Flow\View\History\HistoryRenderer;
 use Flow\Templating;
 use Flow\Exception\InvalidActionException;
-use Flow\Exception\InvalidDataException;
 
 class HeaderBlock extends AbstractBlock {
 
@@ -142,19 +138,26 @@
                if ( $this->action === 'board-history' ) {
                        $templating->getOutput()->addModuleStyles( array( 
'ext.flow.history' ) );
                        $templating->getOutput()->addModules( array( 
'ext.flow.history' ) );
-                       $tplVars = array(
-                               'title' => wfMessage( 'flow-board-history', 
$this->workflow->getArticleTitle() )->escaped(),
-                               'historyExists' => false,
-                       );
+                       $title = $this->workflow->getArticleTitle();
 
-                       $history = $this->loadBoardHistory();
-                       if ( $history ) {
-                               $tplVars['historyExists'] = true;
-                               $tplVars['history'] = new History( $history );
-                               $tplVars['historyRenderer'] = new 
HistoryRenderer( $templating, $this );
+                       $lines = array();
+                       $history = Container::get( 'board-history.query' 
)->getResults( $this->workflow );
+                       $renderer = Container::get( 'board-history.formatter' );
+                       // @todo is this the right context?
+                       $ctx = \RequestContext::getMain();
+                       foreach ( $history as $row ) {
+                               $res = $renderer->format( $row, $ctx );
+                               if ( $res !== false ) {
+                                       // formatter implementations always 
return safe html
+                                       $lines[] = $res;
+                               }
                        }
 
-                       $templating->render( "flow:board-history.html.php", 
$tplVars );
+                       $templating->render( "flow:board-history.html.php", 
array(
+                               'title' => wfMessage( 'flow-board-history', 
$title )->escaped(),
+                               'lines' => $lines,
+                               'historyExists' => count( $history ) > 0,
+                       ) );
                } else {
                        $templating->getOutput()->addModuleStyles( array( 
'ext.flow.header' ) );
                        $templating->getOutput()->addModules( array( 
'ext.flow.header' ) );
@@ -192,30 +195,6 @@
                );
 
                return $output;
-       }
-
-       protected function loadBoardHistory() {
-               $history = $this->storage->find(
-                       'BoardHistoryEntry',
-                       array( 'topic_list_id' => $this->workflow->getId() ),
-                       array( 'sort' => 'rev_id', 'order' => 'DESC', 'limit' 
=> 300 )
-               );
-
-               if ( !$history ) {
-                       throw new InvalidDataException( 'Unable to load topic 
list history for ' . $this->workflow->getId()->getAlphadecimal(), 
'fail-load-history' );
-               }
-
-               // get rid of history entries user doesn't have sufficient 
permissions for
-               foreach ( $history as $i => $revision ) {
-                       /** @var PostRevision|Header $revision */
-
-                       // only check against the specific revision, ignoring 
the most recent
-                       if ( !$this->permissions->isAllowed( $revision, 
'post-history' ) ) {
-                               unset( $history[$i] );
-                       }
-               }
-
-               return $history;
        }
 
        public function getName() {
diff --git a/includes/Data/BoardHistoryStorage.php 
b/includes/Data/BoardHistoryStorage.php
index 828b7ba..d09d8c3 100644
--- a/includes/Data/BoardHistoryStorage.php
+++ b/includes/Data/BoardHistoryStorage.php
@@ -62,9 +62,13 @@
                $queries = $this->preprocessSqlArray( reset( $queries ) );
 
                $res = $this->dbFactory->getDB( DB_SLAVE )->select(
-                       array( 'flow_topic_list', 'flow_tree_revision', 
'flow_revision' ),
+                       array( 'flow_topic_list', 'flow_tree_node', 
'flow_tree_revision', 'flow_revision' ),
                        array( '*' ),
-                       array( 'tree_rev_id = rev_id', 'tree_rev_descendant_id 
= topic_id' ) + $queries,
+                       array(
+                               'topic_id = tree_ancestor_id',
+                               'tree_descendant_id = tree_rev_descendant_id',
+                               'tree_rev_id = rev_id',
+                       ) + $queries,
                        __METHOD__,
                        $options
                );
@@ -134,11 +138,11 @@
         * @param string[] $new
         */
        public function onAfterInsert( $object, array $new ) {
-               if ( $object->getRevisionType() === 'header' ) {
+               if ( $object instanceof Header ) {
                        $new['topic_list_id'] = $new['header_workflow_id'];
                        parent::onAfterInsert( $object, $new );
-               } elseif ( $object->getRevisionType() === 'post' ) {
-                       $topicListId = $this->findTopicListIdForRootPost( 
$object );
+               } elseif ( $object instanceof PostRevision ) {
+                       $topicListId = $this->findTopicListIdForRootPost( 
$object->getRootPost() );
                        if ( $topicListId ) {
                                $new['topic_list_id'] = $topicListId;
                                parent::onAfterInsert( $object, $new );
@@ -152,11 +156,11 @@
         * @param string[] $new
         */
        public function onAfterUpdate( $object, array $old, array $new ) {
-               if ( $object->getRevisionType() === 'header' ) {
+               if ( $object instanceof Header ) {
                        $new['topic_list_id'] = $old['topic_list_id'] = 
$new['header_workflow_id'];
                        parent::onAfterUpdate( $object, $old, $new );
-               } elseif ( $object->getRevisionType() === 'post' ) {
-                       $topicListId = $this->findTopicListIdForRootPost( 
$object );
+               } elseif ( $object instanceof PostRevision ) {
+                       $topicListId = $this->findTopicListIdForRootPost( 
$object->getRootPost() );
                        if ( $topicListId ) {
                                $new['topic_list_id'] = $old['topic_list_id'] = 
$topicListId;
                                parent::onAfterUpdate( $object, $old, $new );
@@ -169,11 +173,11 @@
         * @param string[] $old
         */
        public function onAfterRemove( $object, array $old ) {
-               if ( $object->getRevisionType() === 'header' ) {
+               if ( $object instanceof Header ) {
                        $old['topic_list_id'] = $old['header_workflow_id'];
                        parent::onAfterRemove( $object, $old );
-               } elseif ( $object->getRevisionType() === 'post' ) {
-                       $topicListId = $this->findTopicListIdForRootPost( 
$object );
+               } elseif ( $object instanceof PostRevision ) {
+                       $topicListId = $this->findTopicListIdForRootPost( 
$object->getRootPost() );
                        if ( $topicListId ) {
                                $old['topic_list_id'] = $topicListId;
                                parent::onAfterRemove( $object, $old );
@@ -187,14 +191,10 @@
         * @param PostRevision $object
         * @return string|boolean False when object is not root post or topic 
is not found
         */
-       protected function findTopicListIdForRootPost( $object ) {
-               if ( !$object->isTopicTitle() ) {
-                       return false;
-               }
-
+       protected function findTopicListId( PostRevision $object ) {
                $topicListEntry = Container::get( 'storage' )->find(
                        'TopicListEntry',
-                       array( 'topic_id' => $object->getPostId() )
+                       array( 'topic_id' => 
$object->getRootPost()->getPostId() )
                );
 
                if ( $topicListEntry ) {
diff --git a/includes/Formatter/BoardHistory.php 
b/includes/Formatter/BoardHistory.php
new file mode 100644
index 0000000..823dfe8
--- /dev/null
+++ b/includes/Formatter/BoardHistory.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Flow\Formatter;
+
+use Flow\Exception\FlowException;
+use Flow\Model\Header;
+use Flow\Model\PostRevision;
+use Html;
+use IContextSource;
+
+class BoardHistory extends AbstractFormatter {
+
+       /**
+        * @param \stdClass $row A result row from BoardHistoryQuery
+        * @param IContextSource $ctx
+        * @return string|false HTML string representing $row
+        */
+       public function format( $row, IContextSource $ctx ) {
+               try {
+                       return $this->formatReal( $row, $ctx );
+               } catch ( FlowException $e ) {
+                       \MWExceptionHandler::logException( $e );
+                       return false;
+               }
+       }
+
+       protected function formatReal( $row, IContextSource $ctx ) {
+               $revision = $row->revision;
+               $workflow = $row->workflow;
+               $workflowId = $workflow->getId();
+               $title = $workflow->getArticleTitle();
+
+               $user = $ctx->getUser();
+               $lang = $ctx->getLanguage();
+               $perm = $this->getPermissions( $user );
+
+               if ( !$perm->isAllowed( $revision, 'board-history' ) ) {
+                       return false;
+               }
+
+               if ( $revision instanceof PostRevision ) {
+                       if ( !$perm->isAllowed( $row->root_post, 
'board-history' ) ) {
+                               return false;
+                       }
+                       $blockType = 'header';
+               } elseif ( $revision instanceof Header ) {
+                       $blockType = 'topic';
+               } else {
+                       throw new \Exception( 'Unknown revision type' );
+               }
+
+               $description = $this->getActionDescription( $workflowId, 
$blockType, $revision );
+               $dateFormats = $this->getDateFormats( $revision, $user, $lang );
+
+               list( $href, $msg ) = $this->topicLink( $title, $workflowId );
+
+               $formattedTime = Html::element(
+                       'a',
+                       array(
+                               'href' => $href,
+                               'title' => $msg->text(),
+                       ),
+                       $dateFormats['timeAndDate']
+               );
+
+               $linksContent = ''; // @todo
+               $charDiff = $this->getCharDiff(
+                       $row->revision,
+                       $row->previous_revision
+               );
+
+
+               return $formattedTime
+                       . ' . . '
+                       . $description
+                       . ( $charDiff ? " . . $charDiff" : '' )
+                       . $linksContent;
+       }
+
+}
diff --git a/includes/Formatter/BoardHistoryQuery.php 
b/includes/Formatter/BoardHistoryQuery.php
new file mode 100644
index 0000000..39b1606
--- /dev/null
+++ b/includes/Formatter/BoardHistoryQuery.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Flow\Formatter;
+
+use Flow\Model\Workflow;
+use Flow\Exception\FlowException;
+use Flow\Exception\InvalidDataException;
+use MWExceptionHandler;
+
+class BoardHistoryQuery extends AbstractQuery {
+       public function getResults( Workflow $workflow ) {
+               // Load the history
+               $history = $this->storage->find(
+                       'BoardHistoryEntry',
+                       array( 'topic_list_id' => $workflow->getId() ),
+                       array( 'sort' => 'rev_id', 'order' => 'DESC', 'limit' 
=> 300 )
+               );
+
+               if ( !$history ) {
+                       throw new InvalidDataException( 'Unable to load topic 
list history for ' . $workflow->getId()->getAlphadecimal(), 'fail-load-history' 
);
+               }
+
+               $blockType = array(
+                       'Flow\Model\PostRevision' => 'topic',
+                       'Flow\Model\Header' => 'header',
+               );
+
+               // pre-load our workflow
+               $this->workflowCache[$workflow->getId()->getAlphadecimal()] = 
$workflow;
+               // fetch any necessary metadata
+               $this->loadMetadataBatch( $history );
+               // build rows with the extra metadata
+               $results = array();
+               foreach ( $history as $revision ) {
+                       try {
+                               $result = $this->buildResult( $revision, 
$blockType[get_class( $revision )], 'rev_id' );
+                       } catch ( FlowException $e ) {
+                               $result = false;
+                               MWExceptionHandler::logException( $e );
+                       }
+                       if ( $result ) {
+                               $results[] = $result;
+                       }
+               }
+
+               return $results;
+       }
+}
diff --git a/modules/history/styles/board-history.less 
b/modules/history/styles/board-history.less
new file mode 100644
index 0000000..a31f9a6
--- /dev/null
+++ b/modules/history/styles/board-history.less
@@ -0,0 +1,4 @@
+
+.flow-board-history-container {
+       font-size: 14px;
+}
diff --git a/templates/board-history.html.php b/templates/board-history.html.php
index 3f123d7..b66f7b0 100644
--- a/templates/board-history.html.php
+++ b/templates/board-history.html.php
@@ -2,19 +2,10 @@
 $this->getOutput()->setHtmlTitle( $title );
 $this->getOutput()->setPageTitle( $title );
 ?>
-<div class="flow-history-container">
+<div class="flow-board-history-container">
        <div class="flow-history-log">
-               <?php
-                       if ( $historyExists ) {
-                               $timespans = $historyRenderer->getTimespans( 
$history );
-                               foreach ( $timespans as $text => $timespan ) {
-                                       $timespan = $history->getTimespan( 
$timespan['from'], $timespan['to'] );
-                                       if ( $timespan->numRows() ) {
-                                               echo "<h2>$text</h2>";
-                                               echo $historyRenderer->render( 
$timespan );
-                                       }
-                               }
-                       }
-               ?>
+               <ul>
+                       <li><?php echo implode( "</li>\n<li>", $lines ) ?></li>
+               </ul>
        </div>
 </div>

-- 
To view, visit https://gerrit.wikimedia.org/r/115532
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9719b8a911b497ddb59a149d59063f8c1ce6d7e5
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to