Matthias Mullie has uploaded a new change for review.
https://gerrit.wikimedia.org/r/92903
Change subject: Update RecentChanges to use history i18n
......................................................................
Update RecentChanges to use history i18n
Change-Id: I34705cce7b5de062439a1d18d945a908e8db632a
---
M Flow.php
M FlowActions.php
M Hooks.php
M container.php
M includes/Block/Header.php
M includes/Data/RecentChanges.php
M includes/Model/Workflow.php
M includes/RecentChanges/Formatter.php
M includes/WorkflowLoader.php
M maintenance/FlowInsertDefaultDefinitions.php
A maintenance/FlowUpdateRecentChanges.php
11 files changed, 344 insertions(+), 62 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow
refs/changes/03/92903/1
diff --git a/Flow.php b/Flow.php
index a298602..72ebe6c 100755
--- a/Flow.php
+++ b/Flow.php
@@ -231,7 +231,7 @@
$wgFlowOccupyPages = array();
// Namespaces to occupy is an array of NS_* constants, e.g. array(
NS_USER_TALK ).
-$wgFlowOccupyNamespaces = array( NS_TALK );
+$wgFlowOccupyNamespaces = array();
// Action details config file
require $dir . 'FlowActions.php';
diff --git a/FlowActions.php b/FlowActions.php
index 2cd070c..5aae369 100644
--- a/FlowActions.php
+++ b/FlowActions.php
@@ -1,6 +1,7 @@
<?php
use Flow\Model\PostRevision;
+use Flow\Model\Header;
use Flow\PostActionPermissions;
use Flow\Log\Logger;
use Flow\UrlGenerator;
diff --git a/Hooks.php b/Hooks.php
index ff7a683..503cc67 100644
--- a/Hooks.php
+++ b/Hooks.php
@@ -47,6 +47,9 @@
require_once
__DIR__.'/maintenance/FlowInsertDefaultDefinitions.php';
$updater->addPostDatabaseUpdateMaintenance(
'FlowInsertDefaultDefinitions' );
+ require_once __DIR__.'/maintenance/FlowUpdateRecentChanges.php';
+ $updater->addPostDatabaseUpdateMaintenance(
'FlowUpdateRecentChanges' );
+
return true;
}
diff --git a/container.php b/container.php
index 5a6ccb0..e78548d 100644
--- a/container.php
+++ b/container.php
@@ -376,6 +376,9 @@
$c['recentchanges.formatter'] = $c->share( function( $c ) {
global $wgLang;
return new Flow\RecentChanges\Formatter(
+ $c['storage'],
+ $c['factory.loader.workflow'],
+ $c['flow_actions'],
$c['url_generator'],
$wgLang
);
diff --git a/includes/Block/Header.php b/includes/Block/Header.php
index 61e4345..a90fd6c 100644
--- a/includes/Block/Header.php
+++ b/includes/Block/Header.php
@@ -24,6 +24,7 @@
$this->needCreate = true;
return;
}
+
// Get the latest revision attached to this workflow
$found = $this->storage->find(
'Header',
@@ -53,7 +54,7 @@
$this->errors['prev_revision'] = wfMessage(
'flow-prev-revision-mismatch' )->params( $this->submitted['prev_revision'],
$this->header->getRevisionId()->getHex() );
}
// this isnt really part of validate, but we want the
error-rendering template to see the users edited header
- $this->header = $this->header->newNextRevision(
$this->user, $this->submitted['content'], 'flow-edit-header' );
+ $this->header = $this->header->newNextRevision(
$this->user, $this->submitted['content'], 'edit-header' );
} else {
if ( empty( $this->submitted['prev_revision'] ) ) {
// this isnt really part of validate either,
should validate be renamed or should this logic be redone?
diff --git a/includes/Data/RecentChanges.php b/includes/Data/RecentChanges.php
index 381851f..63cf3bd 100644
--- a/includes/Data/RecentChanges.php
+++ b/includes/Data/RecentChanges.php
@@ -32,7 +32,7 @@
// nothing to do
}
- protected function insert( $type, array $row, Workflow $workflow,
$timestamp, array $changes ) {
+ protected function insert( $action, $block, $revisionType, $revisionId,
array $row, Workflow $workflow, $timestamp, array $changes ) {
if ( $timestamp instanceof UUID ) {
$timestamp = $timestamp->getTimestamp();
}
@@ -54,7 +54,10 @@
'rc_last_oldid' => 0,
'rc_params' => serialize( array(
'flow-workflow-change' => array(
- 'type' => $type, // @todo: need a
maintenance script that retroactively fixes these
+ 'action' => $action,
+ 'block' => $block,
+ 'revision_type' => $revisionType,
+ 'revision' => $revisionId,
'workflow' =>
$workflow->getId()->getHex(),
'definition' =>
$workflow->getDefinitionId()->getHex(),
) + $changes,
@@ -86,11 +89,13 @@
$this->insert(
$object->getChangeType(),
+ 'header',
+ 'Header',
+ $object->getRevisionId()->getHex(),
$row,
$workflow,
$object->getRevisionId(),
array(
- 'revision' =>
$object->getRevisionId()->getHex(),
'content' => $this->contLang->truncate(
$object->getContent(), self::TRUNCATE_LENGTH ),
)
);
@@ -120,12 +125,14 @@
$this->insert(
$object->getChangeType(),
+ 'topic',
+ 'PostRevision',
+ $object->getRevisionId()->getHex(),
$row,
$workflow,
$object->getRevisionId(),
array(
'post' => $object->getPostId()->getHex(),
- 'revision' =>
$object->getRevisionId()->getHex(),
'topic' => $this->getTopicTitle( $object ),
)
);
diff --git a/includes/Model/Workflow.php b/includes/Model/Workflow.php
index f7b4767..bd4eb20 100644
--- a/includes/Model/Workflow.php
+++ b/includes/Model/Workflow.php
@@ -26,7 +26,7 @@
if ( $obj === null ) {
$obj = new self;
} elseif ( !$obj instanceof self ) {
- throw new \Exception( 'Wrong obj type: ' . get_class(
$obj ) );
+ throw new \MWException( 'Wrong obj type: ' . get_class(
$obj ) );
}
$obj->id = UUID::create( $row['workflow_id'] );
$obj->isNew = false;
@@ -64,7 +64,7 @@
$wiki = $title->getTransWikiID();
}
if ( $definition->getWiki() !== $wiki ) {
- throw new \Exception( 'Title and Definition are
from separate wikis' );
+ throw new \MWException( 'Title and Definition
are from separate wikis' );
}
$obj = new self;
@@ -123,11 +123,11 @@
// these are exceptions currently to make debugging easier
// it should return false later on to allow wider use.
public function matchesTitle( Title $title ) {
- if ( $title->getNamespace() !== $this->namespace ) {
- throw new \Exception( 'namespace' );
+ if ( $title->getNamespace() != $this->namespace ) {
+ throw new \MWException( 'namespace' );
}
if ( $title->getDBkey() !== $this->titleText ) {
- throw new \Exception( 'title' );
+ throw new \MWException( 'title' );
}
if ( $title->isLocal() ) {
return $this->wiki === wfWikiId();
diff --git a/includes/RecentChanges/Formatter.php
b/includes/RecentChanges/Formatter.php
index 0b9f54e..5289a82 100644
--- a/includes/RecentChanges/Formatter.php
+++ b/includes/RecentChanges/Formatter.php
@@ -3,8 +3,12 @@
namespace Flow\RecentChanges;
use Flow\Container;
+use Flow\Data\ManagerGroup;
+use Flow\FlowActions;
+use Flow\Model\UUID;
use Flow\UrlGenerator;
use ChangesList;
+use Flow\WorkflowLoaderFactory;
use Language;
use Linker;
use Html;
@@ -13,7 +17,35 @@
use User;
class Formatter {
- public function __construct( UrlGenerator $urlGenerator, Language $lang
) {
+ /**
+ * @var ManagerGroup
+ */
+ protected $storage;
+
+ /**
+ * @var WorkflowLoaderFactory
+ */
+ protected $workflowLoaderFactory;
+
+ /**
+ * @var FlowActions
+ */
+ protected $actions;
+
+ /**
+ * @var UrlGenerator
+ */
+ protected $urlGenerator;
+
+ /**
+ * @var Language
+ */
+ protected $lang;
+
+ public function __construct( ManagerGroup $storage,
WorkflowLoaderFactory $workflowLoaderFactory, FlowActions $actions,
UrlGenerator $urlGenerator, Language $lang ) {
+ $this->actions = $actions;
+ $this->storage = $storage;
+ $this->workflowLoaderFactory = $workflowLoaderFactory;
$this->urlGenerator = $urlGenerator;
$this->lang = $lang;
}
@@ -28,15 +60,15 @@
}
// used in $this->buildActionLinks()
- if ( !array_key_exists( 'type', $changeData ) ) {
- wfWarn( __METHOD__ . ': Flow change type missing' );
+ if ( !array_key_exists( 'action', $changeData ) ) {
+ wfWarn( __METHOD__ . ': Flow action missing' );
return false;
}
$line = '';
$title = $rc->getTitle();
$links = $this->buildActionLinks( $title, $changeData );
-
+
if ( $links ) {
$linksContent = $cl->getLanguage()->pipeList( $links );
$line .= wfMessage( 'parentheses' )->rawParams(
$linksContent )->text()
@@ -51,47 +83,47 @@
. ' '
. $this->userLinks( $cl, $rc->getAttribute(
'rc_user_id' ), $rc->getAttribute( 'rc_user_text' ) )
. ' '
- . $this->getActionDescription( $changeData );
+ . $this->getActionDescription( $changeData, $cl, $rc );
return $line;
}
protected function buildActionLinks( Title $title, array $changeData ) {
$links = array();
- switch( $changeData['type'] ) {
- case 'flow-rev-message-reply':
- $links[] = $this->topicLink( $title, $changeData );
- break;
+ switch( $changeData['action'] ) {
+ case 'reply':
+ $links[] = $this->topicLink( $title,
$changeData );
+ break;
- case 'flow-rev-message-new-post': // fall through
- case 'flow-rev-message-edit-post':
- $links[] = $this->topicLink( $title, $changeData );
- $links[] = $this->postLink( $title, $changeData );
- break;
+ case 'new-post': // fall through
+ case 'edit-post':
+ $links[] = $this->topicLink( $title,
$changeData );
+ $links[] = $this->postLink( $title, $changeData
);
+ break;
- case 'flow-rev-message-hid-comment':
- $links[] = $this->topicLink( $title, $changeData );
- $links[] = $this->postHistoryLink( $title, $changeData
);
- break;
+ case 'hide-post':
+ $links[] = $this->topicLink( $title,
$changeData );
+ $links[] = $this->postHistoryLink( $title,
$changeData );
+ break;
- case 'flow-rev-message-edit-title':
- $links[] = $this->topicLink( $title, $changeData );
- // This links to the history of the topic title
- $links[] = $this->postHistoryLink( $title, $changeData
);
- break;
+ case 'edit-title':
+ $links[] = $this->topicLink( $title,
$changeData );
+ // This links to the history of the topic title
+ $links[] = $this->postHistoryLink( $title,
$changeData );
+ break;
- case 'flow-rev-message-create-header': // fall through
- case 'flow-rev-message-edit-header':
- //$links[] = $this->workflowLink( $title, $changeData );
- break;
+ case 'create-header': // fall through
+ case 'edit-header':
+ //$links[] = $this->workflowLink( $title,
$changeData );
+ break;
- case null:
- wfWarn( __METHOD__ . ': Flow change has null change
type' );
- return false;
+ case null:
+ wfWarn( __METHOD__ . ': Flow change has null
change type' );
+ return false;
- default:
- wfWarn( __METHOD__ . ': Unknown Flow change type: ' .
$changeData['type'] );
- return false;
+ default:
+ wfWarn( __METHOD__ . ': Unknown Flow action: '
. $changeData['action'] );
+ return false;
}
return $links;
@@ -172,13 +204,68 @@
);
}
- public function getActionDescription( array $changeData ) {
- $msg = wfMessage( $changeData['type'] )->text();
-
- if ( isset( $changeData['topic'] ) ) {
- $msg .= ' ' . wfMessage( 'parentheses' )->rawParams(
$changeData['topic'] );
+ public function getActionDescription( array $changeData, ChangesList
$cl, RecentChange $rc ) {
+ // Fetch Block object
+ $title = Title::newFromText( $rc->getAttribute( 'rc_title' ),
(int) $rc->getAttribute( 'rc_namespace' ) );
+ $block = $this->loadBlock( $title, $changeData['workflow'],
$changeData['block'] );
+ if ( !$block ) {
+ return '';
}
- return $msg;
+ // Fetch requested Revision
+ $storage = Container::get( 'storage' );
+ $revision = $storage->get( $changeData['revision_type'],
UUID::create( $changeData['revision'] ) );
+ if ( !$revision ) {
+ return '';
+ }
+
+ // Build description message, piggybacking on history i18n
+ $msg = $this->actions->getValue( $changeData['action'],
'history', 'i18n-message' );
+ $params = $this->actions->getValue( $changeData['action'],
'history', 'i18n-params' );
+ return $this->buildMessage( $msg, (array) $params, array(
+ $revision,
+ $this->urlGenerator,
+ $cl->getUser(),
+ $block
+ ) )->parse();
+ }
+
+ /**
+ * @param Title $title
+ * @param string $definitionId
+ * @param string $workflowId
+ * @param string $name Block name
+ * @return AbstractBlock|false Requested block or false on failure
+ */
+ protected function loadBlock( Title $title, $workflowId, $name ) {
+ $loader = $this->workflowLoaderFactory
+ ->createWorkflowLoader( $title, UUID::create(
$workflowId ) );
+ $blocks = $loader->createBlocks();
+ return isset( $blocks[$name] ) ? $blocks[$name] : false;
+ }
+
+ /**
+ * Returns i18n message for $msg; piggybacking on History i18n.
+ *
+ * Complex parameters can be injected in the i18n messages. Anything in
+ * $params will be call_user_func'ed, with these given $arguments.
+ * Those results will be used as message parameters.
+ *
+ * Note: return array( 'raw' => $value ) or array( 'num' => $value ) for
+ * raw or numeric parameter input.
+ *
+ * @param string $msg i18n key
+ * @param array[optional] $params Callbacks for parameters
+ * @param array[optional] $arguments Arguments for the callbacks
+ * @return Message
+ */
+ protected function buildMessage( $msg, array $params = array(), array
$arguments = array() ) {
+ foreach ( $params as &$param ) {
+ $param = call_user_func_array( $param, $arguments );
+ }
+var_dump($msg);
+var_dump($params);
+
+ return wfMessage( $msg, $params );
}
}
diff --git a/includes/WorkflowLoader.php b/includes/WorkflowLoader.php
index e4489cc..36b84fc 100644
--- a/includes/WorkflowLoader.php
+++ b/includes/WorkflowLoader.php
@@ -130,19 +130,28 @@
public function createBlocks( ) {
switch( $this->definition->getType() ) {
case 'discussion':
- return array(
- 'header' => new HeaderBlock( $this->workflow,
$this->storage, $this->notificationController ),
- 'topics' => new TopicListBlock(
$this->workflow, $this->storage, $this->notificationController,
$this->rootPostLoader ),
+ $blocks = array(
+ new HeaderBlock( $this->workflow,
$this->storage, $this->notificationController ),
+ new TopicListBlock( $this->workflow,
$this->storage, $this->notificationController, $this->rootPostLoader ),
);
+ break;
case 'topic':
- return array(
- 'topic' => new TopicBlock( $this->workflow,
$this->storage, $this->notificationController, $this->rootPostLoader ),
+ $blocks = array(
+ new TopicBlock( $this->workflow,
$this->storage, $this->notificationController, $this->rootPostLoader ),
);
+ break;
default:
throw new \MWException( 'Not Implemented' );
}
+
+ $return = array();
+ foreach ( $blocks as $block ) {
+ $return[$block->getName()] = $block;
+ }
+
+ return $return;
}
public function handleSubmit( $action, array $blocks, $user,
\WebRequest $request ) {
diff --git a/maintenance/FlowInsertDefaultDefinitions.php
b/maintenance/FlowInsertDefaultDefinitions.php
index 55cab08..5376a3e 100644
--- a/maintenance/FlowInsertDefaultDefinitions.php
+++ b/maintenance/FlowInsertDefaultDefinitions.php
@@ -3,17 +3,12 @@
use Flow\Container;
use Flow\Model\UUID;
-/**
- * Remove invalid events from echo_event and echo_notification
- *
- * @ingroup Maintenance
- */
require_once ( getenv( 'MW_INSTALL_PATH' ) !== false
? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php'
: dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php' );
/**
- * Maintenance script that removes invalid notifications
+ * Inserts Flow's default definitions
*
* @ingroup Maintenance
*/
@@ -21,7 +16,7 @@
protected function doDBUpdates() {
$container = Container::getContainer();
- $dbw = $container[ 'db.factory']->getDB( DB_MASTER );
+ $dbw = $container['db.factory']->getDB( DB_MASTER );
$res = $dbw->select(
/* table */'flow_definition',
diff --git a/maintenance/FlowUpdateRecentChanges.php
b/maintenance/FlowUpdateRecentChanges.php
new file mode 100644
index 0000000..6f30bb0
--- /dev/null
+++ b/maintenance/FlowUpdateRecentChanges.php
@@ -0,0 +1,176 @@
+<?php
+
+use Flow\Container;
+use Flow\Model\UUID;
+
+require_once ( getenv( 'MW_INSTALL_PATH' ) !== false
+ ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php'
+ : dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php' );
+
+/**
+ * Updates recentchanges entries to contain information to build the
+ * AbstractBlock objects.
+ *
+ * @ingroup Maintenance
+ */
+class FlowUpdateRecentChanges extends LoggedUpdateMaintenance {
+ /**
+ * The number of entries completed
+ *
+ * @var int
+ */
+ private $completeCount = 0;
+
+ /**
+ * Max number of records to process at a time
+ *
+ * @var int
+ */
+ protected $batchSize = 300;
+
+ protected function doDBUpdates() {
+ $container = Container::getContainer();
+ $dbw = $container['db.factory']->getDB( DB_MASTER );
+
+ $continue = 0;
+
+ while ( $continue !== null ) {
+ $continue = $this->refreshBatch( $dbw, $continue );
+ wfWaitForSlaves();
+ }
+
+ return true;
+ }
+
+ /**
+ * Refreshes a batch of recentchanges entries
+ *
+ * @param DatabaseBase $dbw
+ * @param int[optional] $continue The next batch starting at rc_id
+ * @return int Start id for the next batch
+ */
+ public function refreshBatch( DatabaseBase $dbw, $continue = null ) {
+ $rows = $dbw->select(
+ /* table */'recentchanges',
+ /* select */array( 'rc_id', 'rc_params' ),
+ /* conds */array( "rc_id > $continue", 'rc_type' =>
RC_FLOW ),
+ __METHOD__,
+ /* options */array( 'LIMIT' => $this->mBatchSize,
'ORDER BY' => 'rc_id' )
+ );
+
+ $continue = null;
+
+ foreach ( $rows as $row ) {
+ $continue = $row->rc_id;
+
+ // build params
+ $params = @unserialize( $row->rc_params );
+ if ( !$params ) {
+ $params = array();
+ }
+
+ // Don't fix entries that have been dealt with already
+ if ( !isset( $params['flow-workflow-change']['type'] )
) {
+ continue;
+ }
+
+ // Set action, based on older 'type' values
+ switch ( $params['flow-workflow-change']['type'] ) {
+ case 'flow-rev-message-edit-title':
+ case 'flow-edit-title':
+
$params['flow-workflow-change']['action'] = 'edit-title';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-new-post':
+ case 'flow-new-post':
+
$params['flow-workflow-change']['action'] = 'new-post';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-edit-post':
+ case 'flow-edit-post':
+
$params['flow-workflow-change']['action'] = 'edit-post';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-reply':
+ case 'flow-reply':
+
$params['flow-workflow-change']['action'] = 'reply';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-restored-post':
+ case 'flow-post-restored':
+
$params['flow-workflow-change']['action'] = 'restore-post';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-hid-post':
+ case 'flow-post-hidden':
+
$params['flow-workflow-change']['action'] = 'hide-post';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-deleted-post':
+ case 'flow-post-deleted':
+
$params['flow-workflow-change']['action'] = 'delete-post';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-censored-post':
+ case 'flow-post-censored':
+
$params['flow-workflow-change']['action'] = 'censor-post';
+
$params['flow-workflow-change']['block'] = 'topic';
+
$params['flow-workflow-change']['revision_type'] = 'PostRevision';
+ break;
+
+ case 'flow-rev-message-edit-header':
+ case 'flow-edit-summary':
+
$params['flow-workflow-change']['action'] = 'edit-header';
+
$params['flow-workflow-change']['block'] = 'header';
+
$params['flow-workflow-change']['revision_type'] = 'Header';
+ break;
+
+ case 'flow-rev-message-create-header':
+ case 'flow-create-summary':
+
$params['flow-workflow-change']['action'] = 'create-header';
+
$params['flow-workflow-change']['block'] = 'header';
+
$params['flow-workflow-change']['revision_type'] = 'Header';
+ break;
+ }
+
+ unset( $params['flow-workflow-change']['type'] );
+
+ // update log entry
+ $dbw->update(
+ 'recentchanges',
+ array( 'rc_params' => serialize( $params ) ),
+ array( 'rc_id' => $row->rc_id )
+ );
+
+ $this->completeCount++;
+ }
+
+ return $continue;
+ }
+
+ /**
+ * Get the update key name to go in the update log table
+ *
+ * @return string
+ */
+ protected function getUpdateKey() {
+ return 'FlowUpdateRecentChanges';
+ }
+}
+
+$maintClass = 'FlowUpdateRecentChanges'; // Tells it to run the class
+require_once( RUN_MAINTENANCE_IF_MAIN );
--
To view, visit https://gerrit.wikimedia.org/r/92903
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I34705cce7b5de062439a1d18d945a908e8db632a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Matthias Mullie <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits