Bsitu has uploaded a new change for review.
https://gerrit.wikimedia.org/r/111671
Change subject: Add *_user_wiki to all the *_user_id columns
......................................................................
Add *_user_wiki to all the *_user_id columns
This is to distinguish users and ips from different wikis especially
for pages like contributions.
This still needs some more thorough testing
Change-Id: I439b102e9125c4e6aed988032a21d51b1079f93b
---
M Hooks.php
M container.php
A db_patches/patch-add-wiki.sql
M flow.sql
M includes/Data/RevisionStorage.php
M includes/Data/UserNameBatch.php
M includes/Model/AbstractRevision.php
M includes/Model/PostRevision.php
M includes/Model/Workflow.php
A maintenance/FlowUpdateUserWiki.php
10 files changed, 382 insertions(+), 28 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow
refs/changes/71/111671/1
diff --git a/Hooks.php b/Hooks.php
index b63f64f..ae43c22 100644
--- a/Hooks.php
+++ b/Hooks.php
@@ -61,6 +61,7 @@
$updater->modifyExtensionField( 'recentchanges', 'rc_source',
"$dir/db_patches/patch-rc_source.sql" );
$updater->modifyExtensionField( 'flow_revision',
'rev_change_type', "$dir/db_patches/patch-censor_to_suppress.sql" );
$updater->addExtensionField( 'flow_workflow',
'workflow_user_ip', "$dir/db_patches/patch-remove_usernames.sql" );
+ $updater->addExtensionField( 'flow_workflow',
'workflow_user_wiki', "$dir/db_patches/patch-add-wiki.sql" );
require_once
__DIR__.'/maintenance/FlowInsertDefaultDefinitions.php';
$updater->addPostDatabaseUpdateMaintenance(
'FlowInsertDefaultDefinitions' );
diff --git a/container.php b/container.php
index 3ac3c69..514c4b5 100644
--- a/container.php
+++ b/container.php
@@ -151,8 +151,7 @@
$lifecycle = array(
new Flow\Data\UserNameListener(
$c['repository.username'],
- array( 'workflow_user_id' ),
- 'workflow_wiki'
+ array( 'workflow_user_id' => 'workflow_user_wiki' )
),
// $c['storage.user_subs.user_index']
);
@@ -231,11 +230,11 @@
$c['storage.board_history.index'],
new Flow\Data\UserNameListener(
$c['repository.username'],
- array( 'rev_user_id', 'rev_mod_user_id',
'rev_edit_user_id' ),
- null,
- // @todo composite wiki id + user columns, for now this
- // works as we only display content from this wiki
- wfWikiId()
+ array(
+ 'rev_user_id' => 'rev_user_wiki',
+ 'rev_mod_user_id' => 'rev_mod_user_wiki',
+ 'rev_edit_user_id' => 'rev_edit_user_wiki'
+ )
),
);
@@ -318,11 +317,12 @@
$c['storage.board_history.index'],
new Flow\Data\UserNameListener(
$c['repository.username'],
- array( 'rev_user_id', 'rev_mod_user_id',
'rev_edit_user_id', 'tree_orig_user_id' ),
- null,
- // @todo composite wiki id + user columns, for now this
- // works as we only display content from this wiki
- wfWikiId()
+ array(
+ 'rev_user_id' => 'rev_user_wiki',
+ 'rev_mod_user_id' => 'rev_mod_user_wiki',
+ 'rev_edit_user_id' => 'rev_edit_user_wiki',
+ 'tree_orig_user_id' => 'tree_orig_user_wiki'
+ )
),
);
diff --git a/db_patches/patch-add-wiki.sql b/db_patches/patch-add-wiki.sql
new file mode 100644
index 0000000..fe8d057
--- /dev/null
+++ b/db_patches/patch-add-wiki.sql
@@ -0,0 +1,18 @@
+
+ALTER TABLE /*_*/flow_workflow ADD workflow_user_wiki varchar(32) binary not
null;
+
+ALTER TABLE /*_*/flow_subscription ADD subscription_user_wiki varchar(32)
binary not null;
+
+ALTER TABLE /*_*/flow_tree_revision ADD tree_orig_user_wiki varchar(32) binary
not null;
+
+ALTER TABLE /*_*/flow_revision ADD rev_user_wiki varchar(32) binary not null;
+
+ALTER TABLE /*_*/flow_revision ADD rev_mod_user_wiki varchar(32) binary not
null;
+
+ALTER TABLE /*_*/flow_revision ADD rev_edit_user_wiki varchar(32) binary not
null;
+
+DROP INDEX /*i*/flow_subscription_unique_user_workflow ON
/*_*/flow_subscription;
+CREATE UNIQUE INDEX /*i*/flow_subscription_unique_user_workflow ON
/*_*/flow_subscription (subscription_workflow_id, subscription_user_id,
subscription_user_wiki );
+
+DROP INDEX /*i*/flow_subscription_lookup ON /*_*/flow_subscription;
+CREATE INDEX /*i*/flow_subscription_lookup ON /*_*/flow_subscription
(subscription_user_id, subscription_user_wiki, subscription_last_updated,
subscription_workflow_id);
diff --git a/flow.sql b/flow.sql
index 77058fa..ec2d694 100644
--- a/flow.sql
+++ b/flow.sql
@@ -22,6 +22,7 @@
-- TODO: check what the new global user ids need for storage
workflow_user_id bigint unsigned not null,
workflow_user_ip varbinary(39) default null,
+ workflow_user_wiki varchar(32) binary not null,
-- TODO: is this usefull as a bitfield? may be premature optimization,
a string
-- or list of strings may be simpler and use only a little more space.
workflow_lock_state int unsigned not null,
@@ -34,12 +35,13 @@
CREATE TABLE /*_*/flow_subscription (
subscription_workflow_id int unsigned not null,
subscription_user_id bigint unsigned not null,
+ subscription_user_wiki varchar(32) binary not null,
subscription_create_timestamp varchar(14) binary not null,
subscription_last_updated varchar(14) binary not null
) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/flow_subscription_unique_user_workflow ON
/*_*/flow_subscription (subscription_workflow_id, subscription_user_id);
-CREATE INDEX /*i*/flow_subscription_lookup ON /*_*/flow_subscription
(subscription_user_id, subscription_last_updated, subscription_workflow_id);
+CREATE UNIQUE INDEX /*i*/flow_subscription_unique_user_workflow ON
/*_*/flow_subscription (subscription_workflow_id, subscription_user_id,
subscription_user_wiki );
+CREATE INDEX /*i*/flow_subscription_lookup ON /*_*/flow_subscription
(subscription_user_id, subscription_user_wiki, subscription_last_updated,
subscription_workflow_id);
-- TopicList Tables
CREATE TABLE /*_*/flow_topic_list (
@@ -61,6 +63,7 @@
tree_orig_create_time varchar(12) binary not null,
tree_orig_user_id bigint unsigned not null,
tree_orig_user_ip varbinary(39) default null,
+ tree_orig_user_wiki varchar(32) binary not null,
-- denormalize post parent as well? Prevents an extra query when
building
-- tree from closure table. unnecessary?
tree_parent_id binary(16),
@@ -102,6 +105,7 @@
-- user id creating the revision
rev_user_id bigint unsigned not null,
rev_user_ip varbinary(39) default null,
+ rev_user_wiki varchar(32) binary not null,
-- rev_id of parent or null if no previous revision
rev_parent_id binary(16),
-- comma separated set of ascii flags.
@@ -116,6 +120,7 @@
-- moderated by who?
rev_mod_user_id bigint unsigned,
rev_mod_user_ip varbinary(39) default null,
+ rev_mod_user_wiki varchar(32) binary not null,
rev_mod_timestamp varchar(14) binary,
-- moderated why? (coming soon: how?, where? and what?)
rev_mod_reason varchar(255) binary,
@@ -124,6 +129,7 @@
rev_last_edit_id binary(16) null,
rev_edit_user_id bigint unsigned,
rev_edit_user_ip varbinary(39) default null,
+ rev_edit_user_wiki varchar(32) binary not null,
PRIMARY KEY (rev_id)
) /*$wgDBTableOptions*/;
diff --git a/includes/Data/RevisionStorage.php
b/includes/Data/RevisionStorage.php
index c887e10..4ffce9a 100644
--- a/includes/Data/RevisionStorage.php
+++ b/includes/Data/RevisionStorage.php
@@ -16,6 +16,7 @@
'rev_mod_state',
'rev_mod_user_id',
'rev_mod_user_ip',
+ 'rev_mod_user_wiki',
'rev_mod_timestamp',
'rev_mod_reason',
);
diff --git a/includes/Data/UserNameBatch.php b/includes/Data/UserNameBatch.php
index 86ba77d..c34d986 100644
--- a/includes/Data/UserNameBatch.php
+++ b/includes/Data/UserNameBatch.php
@@ -20,16 +20,15 @@
/**
* @param UserNameBatch $batch
- * @param array $keys A list of keys from storage that contain user ids
+ * @param array $keys key - a list of keys from storage that contain
user ids, value - the wiki for the user id lookup, default to $wiki if null
* @param string|null $wikiKey A key from the storage row that contains
the wiki id.
* @param string|null $wiki The wikiid to use when $wikiKey is null. If
both are null wfWikiId() is used
*/
- public function __construct( UserNameBatch $batch, array $keys,
$wikiKey = null, $wiki = null ) {
+ public function __construct( UserNameBatch $batch, array $keys, $wiki =
null ) {
$this->batch = $batch;
$this->keys = $keys;
- if ( $wikiKey !== null ) {
- $this->wikiKey = $wikiKey;
- } elseif ( $wiki === null ) {
+
+ if ( $wiki === null ) {
$this->wiki = wfWikiId();
} else {
$this->wiki = $wiki;
@@ -40,16 +39,21 @@
* Load any user ids in $row into the username batch
*/
public function onAfterLoad( $object, array $row ) {
- if ( $this->wikiKey === null ) {
- $wiki = $this->wiki;
- } elseif( isset( $row[$this->wikiKey] ) ) {
- $wiki = $row[$this->wikiKey];
- } else {
- wfDebugLog( __CLASS__, __METHOD__ . ": could not detect
wiki with {$this->wikiKey}" );
- return;
- }
- foreach ( $this->keys as $key ) {
+ foreach ( $this->keys as $key => $wiki ) {
+ // check if the user id key exists in the data array
and
+ // make sure it has a non-zero value
if ( isset( $row[$key] ) && $row[$key] != 0 ) {
+ // the wiki for the user id lookup is specified,
+ // check if it exists in the data array
+ if ( $wiki ) {
+ if ( !isset( $row[$wiki] ) ) {
+ wfDebugLog( __CLASS__,
__METHOD__ . ": could not detect wiki with " . $wiki );
+ continue;
+ }
+ // no wiki lookup is specified, defalult to
$this->wiki
+ } else {
+ $wiki = $this->wiki;
+ }
$this->batch->add( $wiki, $row[$key] );
}
}
diff --git a/includes/Model/AbstractRevision.php
b/includes/Model/AbstractRevision.php
index b3af131..19eb042 100644
--- a/includes/Model/AbstractRevision.php
+++ b/includes/Model/AbstractRevision.php
@@ -53,6 +53,8 @@
*/
protected $userIp;
+ protected $userWiki;
+
/**
* Array of flags strictly related to the content. Flags are reset when
* content changes.
@@ -101,6 +103,8 @@
*/
protected $moderatedByUserIp;
+ protected $moderatedByUserWiki;
+
protected $moderatedReason;
/**
@@ -119,6 +123,8 @@
*/
protected $lastEditUserIp;
+ protected $lastEditUserWiki;
+
static public function fromStorageRow( array $row, $obj = null ) {
if ( $obj === null ) {
$obj = new static;
@@ -133,6 +139,7 @@
} elseif ( isset( $row['rev_user_text'] ) && $obj->userId === 0
) {
$obj->userIp = $row['rev_user_text'];
}
+ $obj->userWiki = $row['rev_user_wiki'];
$obj->prevRevision = UUID::create( $row['rev_parent_id'] );
$obj->changeType = $row['rev_change_type'];
$obj->flags = array_filter( explode( ',', $row['rev_flags'] ) );
@@ -149,6 +156,7 @@
} elseif ( isset( $row['rev_mod_user_text'] ) &&
$obj->moderatedByUserId === 0 ) {
$obj->moderatedByUserIp = $row['rev_mod_user_text'];
}
+ $obj->moderatedByUserWiki = $row['rev_mod_user_wiki'];
$obj->moderationTimestamp = $row['rev_mod_timestamp'];
$obj->moderatedReason = isset( $row['rev_mod_reason'] ) ?
$row['rev_mod_reason'] : null;
@@ -167,6 +175,7 @@
$obj->lastEditUserIp = $row['rev_edit_user_text'];
}
$obj->lastEditUserIp = isset( $row['rev_edit_user_ip'] ) ?
$row['rev_edit_user_ip'] : null;
+ $obj->lastEditUserWiki = $row['rev_edit_user_wiki'];
return $obj;
}
@@ -176,6 +185,7 @@
'rev_id' => $obj->revId->getBinary(),
'rev_user_id' => $obj->userId,
'rev_user_ip' => $obj->userIp,
+ 'rev_user_wiki' => $obj->userWiki,
'rev_parent_id' => $obj->prevRevision ?
$obj->prevRevision->getBinary() : null,
'rev_change_type' => $obj->changeType,
'rev_type' => $obj->getRevisionType(),
@@ -187,12 +197,14 @@
'rev_mod_state' => $obj->moderationState,
'rev_mod_user_id' => $obj->moderatedByUserId,
'rev_mod_user_ip' => $obj->moderatedByUserIp,
+ 'rev_mod_user_wiki' => $obj->moderatedByUserWiki,
'rev_mod_timestamp' => $obj->moderationTimestamp,
'rev_mod_reason' => $obj->moderatedReason,
'rev_last_edit_id' => $obj->lastEditId ?
$obj->lastEditId->getBinary() : null,
'rev_edit_user_id' => $obj->lastEditUserId,
'rev_edit_user_ip' => $obj->lastEditUserIp,
+ 'rev_edit_user_wiki' => $obj->lastEditUserWiki,
);
}
@@ -373,6 +385,10 @@
return $this->userIp;
}
+ public function getUserWiki() {
+ return $this->userWiki;
+ }
+
/**
* Should only be used for setting the initial content. To set
subsequent content
* use self::setNextContent
@@ -532,6 +548,10 @@
return $this->lastEditUserIp;
}
+ public function getLastContentEditUserWiki() {
+ return $this->lastEditUserWiki;
+ }
+
public function getModeratedByUserId() {
return $this->moderatedByUserId;
}
@@ -540,6 +560,10 @@
return $this->moderatedByUserIp;
}
+ public function getModeratedByUserWiki() {
+ return $this->moderatedByUserWiki;
+ }
+
/**
* Return a (userId, userIp) tuple for the given
* user object. userIp is null for userId != 0
diff --git a/includes/Model/PostRevision.php b/includes/Model/PostRevision.php
index 023d602..54889f9 100644
--- a/includes/Model/PostRevision.php
+++ b/includes/Model/PostRevision.php
@@ -15,6 +15,7 @@
protected $origCreateTime;
protected $origUserId;
protected $origUserIp;
+ protected $origUserWiki;
protected $replyToId;
/**
@@ -102,6 +103,7 @@
$obj->postId = $uuid;
$obj->origUserId = $obj->userId = $user->getId();
$obj->origUserIp = $obj->userIp = $user->getName();
+ $obj->origUserWiki = wfWikiId();
$obj->origCreateTime = wfTimestampNow();
$obj->setReplyToId( null ); // not a reply to anything
$obj->prevRevision = null; // no parent revision
@@ -126,6 +128,7 @@
} elseif ( isset( $row['tree_orig_user_text'] ) &&
$obj->origUserId === 0 ) {
$obj->origUserIp = $row['tree_orig_user_text'];
}
+ $obj->origUserWiki = $row['tree_orig_user_wiki'];
return $obj;
}
@@ -138,6 +141,7 @@
'tree_orig_create_time' => $rev->origCreateTime,
'tree_orig_user_id' => $rev->origUserId,
'tree_orig_user_ip' => $rev->origUserIp,
+ 'tree_orig_user_wiki' => $rev->origUserWiki,
);
}
@@ -148,6 +152,7 @@
list( $reply->userId, $reply->userIp ) = self::userFields(
$user );
$reply->origUserId = $reply->userId;
$reply->origUserIp = $reply->userIp;
+ $reply->origUserWiki = wfWikiId();
$reply->origCreateTime = wfTimestampNow();
$reply->replyToId = $this->postId;
$reply->setContent( $content );
@@ -172,6 +177,10 @@
return $this->origUserId;
}
+ public function getCreatorWiki() {
+ return $this->origUserWiki;
+ }
+
/**
* Get the user ip of the user who created this post if it
* was created by an anonymous user
diff --git a/includes/Model/Workflow.php b/includes/Model/Workflow.php
index e5cbe5e..61dc1bb 100644
--- a/includes/Model/Workflow.php
+++ b/includes/Model/Workflow.php
@@ -19,6 +19,7 @@
protected $titleText;
protected $userId;
protected $userIp;
+ protected $userWiki;
// lock state is a list of state updates, the final state
// is the active state.
protected $lockState;
@@ -46,6 +47,7 @@
} elseif ( isset( $row['workflow_user_text'] ) && $obj->userId
=== 0 ) {
$obj->userIp = $row['workflow_user_text'];
}
+ $obj->userWiki = $row['workflow_user_wiki'];
$obj->lockState = $row['workflow_lock_state'];
$obj->definitionId = UUID::create(
$row['workflow_definition_id'] );
$obj->lastModified = $row['workflow_last_update_timestamp'];
@@ -61,6 +63,7 @@
'workflow_title_text' => $obj->titleText,
'workflow_user_id' => $obj->userId,
'workflow_user_ip' => $obj->userIp,
+ 'workflow_user_wiki' => $obj->userWiki,
'workflow_lock_state' => $obj->lockState,
'workflow_definition_id' =>
$obj->definitionId->getBinary(),
'workflow_last_update_timestamp' => $obj->lastModified,
@@ -107,6 +110,7 @@
public function getDefinitionId() { return $this->definitionId; }
public function getUserId() { return $this->userId; }
public function getUserIp() { return $this->userIp; }
+ public function getUserWiki() { return $this->userWiki; }
public function getLastModified() { return $this->lastModified; }
public function getLastModifiedObj() { return new MWTimestamp(
$this->lastModified ); }
diff --git a/maintenance/FlowUpdateUserWiki.php
b/maintenance/FlowUpdateUserWiki.php
new file mode 100644
index 0000000..4779786
--- /dev/null
+++ b/maintenance/FlowUpdateUserWiki.php
@@ -0,0 +1,287 @@
+<?php
+
+use Flow\Container;
+use Flow\Model\UUID;
+use Flow\Model\Header;
+use Flow\Model\PostRevision;
+
+$IP = getenv( 'MW_INSTALL_PATH' );
+if ( $IP === false ) {
+ $IP = dirname( __FILE__ ) . '/../../..';
+}
+require_once( "$IP/maintenance/Maintenance.php" );
+
+/**
+ * Update all xxx_user_wiki field to have the correct wiki name
+ *
+ * @ingroup Maintenance
+ */
+class FlowUpdateUserWiki extends Maintenance {
+
+ /**
+ * Max number of records to process at a time
+ *
+ * @var int
+ */
+ private $batchSize = 300;
+
+ /**
+ * Use to track the number of updated count
+ */
+ private $updatedCount = 0;
+
+ public function __construct() {
+ parent::__construct();
+ $this->mDescription = "Update xxx_user_wiki field in talbes:
flow_workflow, flow_subscription, flow_tree_revision, flow_revision";
+ }
+
+ /**
+ * This is a top-to-bottom update, the process is like this:
+ * workflow -> header -> header revision -> history
+ * workflow -> topic list -> post tree revision -> post revision ->
history
+ */
+ public function execute() {
+ $id = '';
+ $count = $this->batchSize;
+ $dbw= Container::get( 'db.factory' )->getDB( DB_MASTER );
+
+ while ( $count == $this->batchSize ) {
+ $count = 0;
+ $res = $dbw->select(
+ array( 'flow_workflow', 'flow_definition' ),
+ array( 'workflow_wiki', 'workflow_id',
'definition_type' ),
+ array(
+ 'workflow_id > ' . $dbw->addQuotes( $id
),
+ 'workflow_definition_id = definition_id'
+ ),
+ __METHOD__,
+ array( 'ORDER BY' => 'workflow_id ASC', 'LIMIT'
=> $this->batchSize )
+ );
+ if ( $res ) {
+ foreach ( $res as $row ) {
+ $count++;
+ $id = $row->workflow_id;
+ $uuid = UUID::create( $row->workflow_id
);
+ $workflow = Container::get(
'storage.workflow' )->get( $uuid );
+ if ( $workflow ) {
+ // definition type 'topic' is
always under a 'discussion' and they
+ // will be handled while
processing 'discussion'
+ if ( $row->definition_type ==
'discussion' ) {
+ $this->updateHeader(
$workflow, $row->workflow_wiki );
+ $this->updateTopicList(
$workflow, $row->workflow_wiki );
+ }
+ // update workflow at last step
so this can start from over again
+ // in case there is an error in
the middle of updating others
+ $this->updateWorkflow(
$workflow, $row->workflow_wiki );
+ }
+ }
+ $this->output( "processed $count records in " .
__METHOD__ . "\n" );
+ } else {
+ throw new \MWException( 'SQL error in
maintenance script ' . __CLASS__ . '::' . __METHOD__ );
+ }
+ }
+ }
+
+ /**
+ * Update workflow
+ */
+ private function updateWorkflow( $wf, $wiki ) {
+ $storage = Container::get( 'storage.workflow' );
+ $reflection = new ReflectionClass( $wf );
+ $prop = $reflection->getProperty( 'userWiki' );
+ $prop->setAccessible( true );
+ $prop->setValue( $wf, $wiki );
+
+ $reflection = new ReflectionClass( $storage );
+ $method = $reflection->getMethod( 'update' );
+ $method->setAccessible( true );
+ $method->invoke( $storage, $wf );
+
+
+ $this->output( "processing workflow: " . $wf->getId()->getHex()
. ' in ' . __METHOD__ . "\n" );
+ $this->checkForSlave();
+ }
+
+ /**
+ * Update header
+ */
+ protected function updateHeader( $workflow, $wiki ) {
+ $id = '';
+ $count = $this->batchSize;
+ $dbw = Container::get( 'db.factory' )->getDB( DB_MASTER );
+
+ while ( $count == $this->batchSize ) {
+ $count = 0;
+ $res = $dbw->select(
+ array( 'flow_header_revision', 'flow_revision'
),
+ array( 'rev_id', 'rev_type' ),
+ array(
+ 'rev_id > ' . $dbw->addQuotes( $id ),
+ 'header_rev_id = rev_id',
+ 'header_workflow_id' =>
$workflow->getId()->getBinary()
+ ),
+ __METHOD__,
+ array( 'ORDER BY' => 'header_rev_id ASC',
'LIMIT' => $this->batchSize )
+ );
+ if ( $res ) {
+ foreach ( $res as $row ) {
+ $count++;
+ $id = $row->rev_id;
+ $revision = Container::get(
'storage.header' )->get( UUID::create( $row->rev_id ) );
+ if ( $revision ) {
+ $this->updateHistory(
$revision, $wiki, $revision );
+ $this->updateRevision(
$revision, $wiki );
+ }
+ }
+ } else {
+ throw new \MWException( 'SQL error in
maintenance script ' . __CLASS__ . '::' . __METHOD__ );
+ }
+
+ $this->output( "processed $count records in " .
__METHOD__ . "\n" );
+ }
+ }
+
+ /**
+ * Update topic list
+ */
+ protected function updateTopicList( $workflow, $wiki ) {
+ $id = '';
+ $count = $this->batchSize;
+ $dbw = Container::get( 'db.factory' )->getDB( DB_MASTER );
+
+ while ( $count == $this->batchSize ) {
+ $count = 0;
+ $res = $dbw->select(
+ array( 'flow_topic_list' ),
+ array( 'topic_id' ),
+ array( 'topic_list_id' =>
$workflow->getId()->getBinary() ),
+ __METHOD__,
+ array( 'ORDER BY' => 'topic_id ASC', 'LIMIT' =>
$this->batchSize )
+ );
+ if ( $res ) {
+ $index = 0;
+ foreach ( $res as $row ) {
+ $count++;
+ $index++;
+ $id = $row->topic_id;
+ $post = Container::get(
'loader.root_post' )->get( UUID::create( $row->topic_id ) );
+ if ( $post ) {
+ $post->setRootPost( $post );
+ $this->updatePost( $post,
$wiki, $post );
+ }
+ }
+ $this->output( "processed $index topics in " .
__METHOD__ . "\n" );
+ } else {
+ throw new \MWException( 'SQL error in
maintenance script ' . __CLASS__ . '::' . __METHOD__ );
+ }
+ $this->output( "processed $count records in " .
__METHOD__ . "\n" );
+ }
+ }
+
+ /**
+ * Update post
+ */
+ protected function updatePost( $post, $wiki, $root ) {
+ $this->updateHistory( $post, $wiki, $root );
+ $this->updateRevision( $post, $wiki );
+ foreach ( $post->getChildren() as $child ) {
+ $this->updatePost( $child, $wiki, $root );
+ }
+ }
+
+ /**
+ * Update history revision
+ */
+ protected function updateHistory( $post, $wiki, $root ) {
+ if ( $post->getPrevRevisionId() ) {
+ $parent = null;
+ if ( $post->getRevisionType() === 'header' ) {
+ $parent = Container::get( 'storage.header'
)->get( UUID::create( $post->getPrevRevisionId() ) );
+ } elseif ( $post->getRevisionType() === 'post' ) {
+ $parent = Container::get( 'storage.post'
)->get( UUID::create( $post->getPrevRevisionId() ) );
+ }
+ if ( $parent ) {
+ if ( $post->getRevisionType() === 'post' ) {
+ // DOUBLE CHECK THIS, some index like
TopicHistoryIndex::onAfterUpdate()
+ // requires a rootPost, would this
overwrite the cache with an older history?
+ $parent->setRootPost( $root );
+ }
+ $this->updateRevision( $parent, $wiki );
+ $this->updateHistory( $parent, $wiki, $root );
+ }
+ }
+ }
+
+ /**
+ * Update either header or post revision
+ */
+ protected function updateRevision( $revision, $wiki ) {
+ $type = $revision->getRevisionType();
+ if ( $type === 'post' ) {
+ $storage = Container::get( 'storage.post' );
+ } elseif ( $type === 'header' ) {
+ $storage = Container::get( 'storage.header' );
+ }
+
+ if ( !$revision ) {
+ return;
+ }
+
+ $reflection = new ReflectionClass( $revision );
+
+ $prop = $reflection->getProperty( 'userWiki' );
+ $prop->setAccessible( true );
+ $prop->setValue( $revision, $wiki );
+
+ $prop = $reflection->getProperty( 'moderatedByUserWiki' );
+ $prop->setAccessible( true );
+ $prop->setValue( $revision, $wiki );
+
+ $prop = $reflection->getProperty( 'lastEditUserWiki' );
+ $prop->setAccessible( true );
+ $prop->setValue( $revision, $wiki );
+
+ if ( $type === 'post' ) {
+ $prop = $reflection->getProperty( 'origUserWiki' );
+ $prop->setAccessible( true );
+ $prop->setValue( $revision, $wiki );
+ }
+
+ $reflection = new ReflectionClass( '\Flow\Data\RevisionStorage'
);
+ $prop = $reflection->getProperty( 'allowedUpdateColumns' );
+ $prop->setAccessible( true );
+ $prop->setValue( array(
+ 'rev_mod_state',
+ 'rev_mod_user_id',
+ 'rev_mod_user_ip',
+ 'rev_mod_user_wiki',
+ 'rev_mod_timestamp',
+ 'rev_mod_reason',
+ 'rev_user_wiki',
+ 'rev_mod_user_wiki',
+ 'rev_edit_user_wiki',
+ 'tree_orig_user_wiki'
+ )
+ );
+
+ $reflection = new ReflectionClass( $storage );
+ $method = $reflection->getMethod( 'update' );
+ $method->setAccessible( true );
+
+ $method->invoke( $storage, $revision );
+
+ $this->output( "processing $type: " .
$revision->getRevisionId()->getHex() . ' in ' . __METHOD__ . "\n" );
+ $this->checkForSlave();
+ }
+
+ private function checkForSlave() {
+ $this->updatedCount++;
+ if ( $this->updatedCount > $this->batchSize ) {
+ wfWaitForSlaves();
+ $this->updatedCount = 0;
+ }
+ }
+}
+
+$maintClass = "FlowUpdateUserWiki";
+require_once( DO_MAINTENANCE );
--
To view, visit https://gerrit.wikimedia.org/r/111671
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I439b102e9125c4e6aed988032a21d51b1079f93b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Bsitu <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits