r102139 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r102138‎ | r102139 | r102140 >
Date:01:17, 6 November 2011
Author:cryptocoryne
Status:deferred (Comments)
Tags:
Comment:
Added experimental version of new extension
Modified paths:
  • /trunk/extensions/Premoderation (added) (history)
  • /trunk/extensions/Premoderation/Premoderation.class.php (added) (history)
  • /trunk/extensions/Premoderation/Premoderation.i18n.php (added) (history)
  • /trunk/extensions/Premoderation/Premoderation.php (added) (history)
  • /trunk/extensions/Premoderation/SpecialPremoderation.php (added) (history)
  • /trunk/extensions/Premoderation/SpecialPremoderationWhiteList.php (added) (history)
  • /trunk/extensions/Premoderation/db_tables.sql (added) (history)
  • /trunk/extensions/Premoderation/install.php (added) (history)

Diff [purge]

Index: trunk/extensions/Premoderation/SpecialPremoderation.php
@@ -0,0 +1,376 @@
 2+<?php
 3+class SpecialPremoderation extends SpecialPage {
 4+ protected $mParams = false;
 5+ protected $mPosted = false;
 6+ protected $mRequest = array();
 7+ protected $mSummary = '';
 8+ public $mAllowedStatus = array( 'new', 'approved', 'declined' );
 9+
 10+ function __construct() {
 11+ global $wgRequest;
 12+ parent::__construct( 'Premoderation', 'premoderation' );
 13+
 14+ if( $wgRequest->wasPosted() ) {
 15+ $this->mPosted = true;
 16+ $this->mRequest = $wgRequest->getValues();
 17+ }
 18+ }
 19+
 20+ public function execute( $subpage ) {
 21+ global $wgUser, $wgOut;
 22+
 23+ if( !$wgUser->isAllowed( 'premoderation' ) ) {
 24+ $this->displayRestrictionError();
 25+ return;
 26+ }
 27+
 28+ $allowedActions = array( '', 'list', 'status' );
 29+
 30+ $params = array_values( explode( '/', $subpage ) );
 31+ $action = array_shift( &$params );
 32+
 33+ if( !in_array( $action, $allowedActions ) ) {
 34+ $wgOut->setPageTitle( wfMsg( 'premoderation-manager-invalidaction' ) );
 35+ $wgOut->addWikiMsg( 'premoderation-invalidaction' );
 36+ return;
 37+ }
 38+
 39+ if( $action == '' ) {
 40+ $action = 'list';
 41+ } elseif( isset( $params ) ) {
 42+ $this->mParams = Premoderation::formatParams( $params );
 43+ }
 44+
 45+ switch( $action ) {
 46+ case 'list':
 47+ $this->showList();
 48+ break;
 49+
 50+ case 'status':
 51+ ( $this->mPosted ) ? $this->performChanges() : $this->statusInterface();
 52+ break;
 53+ }
 54+ }
 55+
 56+ protected function showList() {
 57+ global $wgOut;
 58+
 59+ $wgOut->setPageTitle( wfMsg( 'premoderation-manager-mainpage' ) );
 60+ $wgOut->addWikiMsg( 'premoderation-list-intro' );
 61+
 62+ $dbr = wfGetDB( DB_SLAVE );
 63+ $res = $dbr->select(
 64+ 'pm_queue',
 65+ array( 'pmq_id', 'pmq_page_ns', 'pmq_page_title', 'pmq_user', 'pmq_user_text', 'pmq_timestamp',
 66+ 'pmq_minor', 'pmq_summary', 'pmq_len', 'pmq_status', 'pmq_updated', 'pmq_updated_user_text' ),
 67+ '', __METHOD__,
 68+ array( 'ORDER BY' => 'pmq_timestamp DESC', 'LIMIT' => 100 )
 69+ );
 70+
 71+ $result = array();
 72+ while( $row = $dbr->fetchRow( $res ) ) {
 73+ $status = $row['pmq_status'];
 74+ $result[$status][] = $row;
 75+ }
 76+
 77+ if( isset( $result['new'] ) ) {
 78+ $msg = wfMsg( 'premoderation-list-new-h2' );
 79+ $wgOut->addWikiText( '<h2>' . $msg . '</h2>' );
 80+
 81+ $output = $this->getListTableHeader( 'new' );
 82+ foreach( $result['new'] as $row ) {
 83+ $output .= $this->formatListTableRow( $row );
 84+ }
 85+ $output .= Xml::closeElement( 'table' );
 86+
 87+ $wgOut->addHTML( $output );
 88+ }
 89+
 90+ if( isset( $result['declined'] ) ) {
 91+ $msg = wfMsg( 'premoderation-list-declined-h2' );
 92+ $wgOut->addWikiText( '<h2>' . $msg . '</h2>' );
 93+
 94+ $output = $this->getListTableHeader( 'declined' );
 95+ foreach( $result['declined'] as $row ) {
 96+ $output .= $this->formatListTableRow( $row );
 97+ }
 98+ $output .= Xml::closeElement( 'table' );
 99+
 100+ $wgOut->addHTML( $output );
 101+ }
 102+ }
 103+
 104+ protected function getListTableHeader( $type ) {
 105+ return Xml::openElement( 'table', array( 'id' => 'prem-table-' . $type, 'class' => 'wikitable', 'style' => 'width: 90%' ) ) .
 106+ '<tr><th>' . wfMsg( 'premoderation-table-list-time' ) . '</th>' .
 107+ '<th>' . wfMsg( 'premoderation-table-list-user' ) . '</th>' .
 108+ '<th colspan="2">' . wfMsg( 'premoderation-table-list-title' ) . '</th>' .
 109+ '<th>' . wfMsg( 'premoderation-table-list-summary' ) . '</th>' .
 110+ '<th>' . wfMsg( 'premoderation-table-list-status' ) . '</th><tr>';
 111+ }
 112+
 113+ protected function formatListTableRow( $row ) {
 114+ global $wgLang, $wgArticlePath;
 115+
 116+ $articlePath = str_replace('$1', '', $wgArticlePath);
 117+ return '<tr><td>' . $wgLang->timeanddate( $row['pmq_timestamp'] ) . '</td>' .
 118+ '<td>' . Linker::userLink( $row['pmq_user'], $row['pmq_user_text'] ) . '</td>' .
 119+ '<td>' . Linker::link( Title::newFromText( $row['pmq_page_title'], $row['pmq_page_ns'] ) ) .
 120+ '</td><td>' . ( $row['pmq_minor'] == 0 ? '' : ' ' . wfMsg( 'minoreditletter' ) ) . '</td>' .
 121+ '<td>' . $row['pmq_summary'] . '</td><td>' . '<a href="' . $articlePath .
 122+ 'Special:Premoderation/status/id/' . $row['pmq_id'] . '">' .
 123+ wfMessage( 'premoderation-status-' . $row['pmq_status'] . ( $row['pmq_updated_user_text'] ? '-changed' : '-added' ),
 124+ array( $row['pmq_updated_user_text'] ) ) .
 125+ '</a></td></tr>';
 126+ }
 127+
 128+ protected function statusInterface() {
 129+ global $wgOut, $wgUser, $wgPremoderationStrict;
 130+
 131+ $params = $this->mParams;
 132+ if( !isset( $params['id'] ) ) {
 133+ $wgOut->setPageTitle( wfMsg( 'premoderation-manager-invalidaction' ) );
 134+ $wgOut->addWikiMsg( 'premoderation-invalidaction' );
 135+ return;
 136+ }
 137+
 138+ $id = intval( $params['id'] );
 139+ $dbr = wfGetDB( DB_SLAVE );
 140+ $res = $dbr->select(
 141+ 'pm_queue',
 142+ '*',
 143+ "pmq_id = '$id'", __METHOD__,
 144+ array( 'LIMIT' => 1 )
 145+ );
 146+ $row = $dbr->fetchRow( $res );
 147+ if( !$row ) {
 148+ $wgOut->setPageTitle( wfMsg( 'premoderation-manager-invalidaction' ) );
 149+ $wgOut->addWikiMsg( 'premoderation-notexists-id' );
 150+ return;
 151+ }
 152+
 153+ $wgOut->setPageTitle( wfMsg( 'premoderation-manager-status' ) );
 154+ $wgOut->addWikiMsg( 'premoderation-status-intro' );
 155+
 156+ $wgOut->addHTML( '<h2>' . wfMsg( 'premoderation-status-info' ) . '</h2>' .
 157+ $this->getListTableHeader( 'status' ) . $this->formatListTableRow( $row ) . Xml::closeElement( 'table' ) );
 158+
 159+ if( $wgUser->isAllowed( 'premoderation-viewip' ) ) {
 160+ $wgOut->addHTML( wfMsg( 'premoderation-private-ip' ) . ' ' . $row['pmq_ip'] );
 161+ }
 162+
 163+ $rev = Revision::newFromID( $row['pmq_page_last_id'] );
 164+ $diff = new DifferenceEngine( $rev->getTitle() );
 165+ $diff->showDiffStyle();
 166+ $formattedDiff = $diff->generateDiffBody( $rev->getText(), $row['pmq_text'] );
 167+
 168+ $wgOut->addHTML( '<h2>' . wfMsg( 'premoderation-diff-h2' ) . '</h2>' .
 169+ "<table class='mw-abusefilter-diff-multiline'><col class='diff-marker' />" .
 170+ "<col class='diff-content' /><col class='diff-marker' /><col class='diff-content' />" .
 171+ "<tbody>" . $formattedDiff . "</tbody></table>" );
 172+
 173+ if( $row['pmq_status'] == 'approved' ) {
 174+ return;
 175+ }
 176+
 177+ $externalConflicts = $this->checkExternalConflicts( $row['pmq_page_last_id'],
 178+ $row['pmq_page_ns'], $row['pmq_page_title'] );
 179+ if( $externalConflicts ) {
 180+ $wgOut->addHTML( '<h2>' . wfMsg( 'premoderation-external-conflicts-h2' ) . '</h2>' );
 181+ if( $wgPremoderationStrict ) {
 182+ $wgOut->addWikiMsg( 'premoderation-error-externals' );
 183+ return;
 184+ }
 185+ $wgOut->addWikiMsg( 'premoderation-external-edits' );
 186+ }
 187+
 188+ $this->checkInternalConflicts( $dbr, $id, $row['pmq_page_ns'], $row['pmq_page_title'] );
 189+
 190+ $final = Xml::fieldset( wfMsg( 'premoderation-status-fieldset' ) ) .
 191+ Xml::openElement( 'form', array( 'id' => 'prem-status-form', 'method' => 'post' ) ) .
 192+ $this->getStatusForm( $row['pmq_status'] ) . '<input type="hidden" name="id" value="' . $id . '" />' .
 193+ Xml::closeElement( 'form' ) . Xml::closeElement( 'fieldset' );
 194+
 195+ $wgOut->addHTML( $final );
 196+ }
 197+
 198+ protected function checkExternalConflicts( $lastId, $ns, $page ) {
 199+ global $wgOut;
 200+
 201+ $title = Title::newFromText( $page, $ns );
 202+ return $title->getLatestRevID() > $lastId;
 203+ }
 204+
 205+ protected function checkInternalConflicts( $db, $id, $ns, $page ) {
 206+ global $wgOut;
 207+
 208+ $conds = 'pmq_page_ns = ' . $db->addQuotes( $ns ) . ' AND pmq_page_title = ' .
 209+ $db->addQuotes( $page ) . ' AND pmq_id != ' . $id . ' AND pmq_status != "approved"';
 210+
 211+ $res = $db->select(
 212+ 'pm_queue', '*', $conds, __METHOD__,
 213+ array( 'ORDER BY' => 'pmq_timestamp DESC', 'LIMIT' => 20 )
 214+ );
 215+
 216+ $test = $db->fetchRow( $res );
 217+ if( $test ) {
 218+ $output = '<h2>' . wfMsg( 'premoderation-internal-conflicts-h2' ) . '</h2>' .
 219+ wfMsg( 'premoderation-internal-conflicts-intro' ) . $this->getListTableHeader( 'int-conflicts' ) .
 220+ $this->formatListTableRow( $test );
 221+
 222+ while( $row = $db->fetchRow( $res ) ) {
 223+ $output .= $this->formatListTableRow( $row );
 224+ }
 225+ $output .= Xml::closeElement( 'table' );
 226+
 227+ $wgOut->addHTML( $output );
 228+ }
 229+ }
 230+
 231+ protected function getStatusForm( $status ) {
 232+ $statusList = ( $status == 'new' ) ? array( 'approved', 'declined' ) :
 233+ array( 'new', 'approved' );
 234+
 235+ $options = '';
 236+ foreach( $statusList as $item ) {
 237+ $options .= Xml::option( wfMsg("premoderation-status-$item"), $item );
 238+ }
 239+
 240+ return "<table><tr><td><span style='white-space: nowrap'>" . Xml::tags( 'select',
 241+ array( 'id' => 'prem-status-selector', 'name' => 'statusselector' ), $options ) .
 242+ '</span></td></tr><tr><td>' . wfMsg( 'summary' ) . ' ' .
 243+ Xml::input( 'summary', 90, '', array( 'id' => 'prem-summary' ) ) . '</td></tr><tr>' .
 244+ '<td>' . Xml::submitButton( wfMsg( 'htmlform-submit' ), array( 'id' => 'prem-submit' ) ) .
 245+ '</td></tr></table>';
 246+ }
 247+
 248+ protected function performChanges() {
 249+ global $wgOut;
 250+
 251+ $data = $this->mRequest;
 252+
 253+ $newstatus = $data['statusselector'];
 254+ $id = intval( $data['id'] );
 255+ $this->mSummary = isset( $data['summary'] ) ? $data['summary'] : '';
 256+
 257+ if( !in_array( $newstatus, $this->mAllowedStatus ) || !$id ) {
 258+ $wgOut->setPageTitle( wfMsg( 'premoderation-manager-invalidaction' ) );
 259+ $wgOut->addWikiMsg( 'premoderation-bad-request' );
 260+ return;
 261+ }
 262+
 263+ if( $newstatus == 'approved' ) {
 264+ $ok = $this->approveRevision( $id );
 265+ $s = $this->changeStatus( $id, $newstatus );
 266+
 267+ if( $ok && $s ) {
 268+ $wgOut->setPageTitle( wfMsg( 'premoderation-success' ) );
 269+ $wgOut->addWikiMsg( 'premoderation-success-approved' );
 270+ }
 271+ } else {
 272+ $ok = $this->changeStatus( $id, $newstatus );
 273+
 274+ if( $ok && $this->addLogEntry( 'status', array( $id, $newstatus ) ) ) {
 275+ $wgOut->setPageTitle( wfMsg( 'premoderation-success' ) );
 276+ $wgOut->addWikiMsg( 'premoderation-success-changed-text' );
 277+ }
 278+ }
 279+ }
 280+
 281+ protected function changeStatus( $id, $status ) {
 282+ global $wgUser;
 283+
 284+ $dbw = wfGetDB( DB_MASTER );
 285+ $query = array(
 286+ 'pmq_status' => $status,
 287+ 'pmq_updated' => $dbw->timestamp( wfTimestampNow() ),
 288+ 'pmq_updated_user' => $wgUser->getID(),
 289+ 'pmq_updated_user_text' => $wgUser->getName()
 290+ );
 291+ $ok = $dbw->update( 'pm_queue', $query, array( 'pmq_id' => $id ), __METHOD__ );
 292+
 293+ return $ok;
 294+ }
 295+
 296+ protected function approveRevision( $id ) {
 297+ $dbw = wfGetDB( DB_MASTER );
 298+ $res = $dbw->fetchRow( $dbw->select( 'pm_queue', '*', "pmq_id = '$id'", __METHOD__ ) );
 299+
 300+ $title = Title::newFromText( $res['pmq_page_title'], $res['pmq_page_ns'] );
 301+ $user = User::newFromName( $res['pmq_user_text'] );
 302+
 303+ $row = array(
 304+ 'page' => 0,
 305+ 'user' => $user->getID(),
 306+ 'user_text' => $user->getName(),
 307+ 'minor_edit' => $res['pmq_minor'],
 308+ 'timestamp' => $res['pmq_timestamp'],
 309+ 'comment' => $res['pmq_summary'],
 310+ 'text' => $res['pmq_text']
 311+ );
 312+
 313+ $rev = new Revision( $row );
 314+ $revId = $rev->insertOn( $dbw );
 315+
 316+ $conflict = $this->checkExternalConflicts( $res['pmq_page_last_id'],
 317+ $res['pmq_page_ns'], $res['pmq_page_title'] );
 318+ if( !$conflict ) {
 319+ $wikipage = WikiPage::factory( $title );
 320+
 321+ if( $res['pmq_page_last_id'] == 0 ) {
 322+ $pageId = $wikipage->insertOn( $dbw );
 323+ $cond = array( 'page_id' => $pageId );
 324+ $actionType = 'create';
 325+ } else {
 326+ $wikipage->updateRevisionOn( $dbw, $rev );
 327+ $cond = array( 'page_latest' => $res['pmq_page_last_id'] );
 328+ $actionType = 'update';
 329+
 330+ $dbw->update(
 331+ 'revision', array( 'rev_page' => $title->getArticleID(), 'rev_parent_id' => $title->getLatestRevID() ),
 332+ array( 'rev_id' => $revId ), __METHOD__
 333+ );
 334+ }
 335+
 336+ $dbw->update(
 337+ 'page', array( 'page_latest' => $revId, 'page_len' => $rev->getSize() ),
 338+ $cond, __METHOD__
 339+ );
 340+ } else {
 341+ $actionType = 'updateold';
 342+
 343+ $latestRevId = intval( $title->getLatestRevID() );
 344+ $res = $dbw->fetchRow( $dbw->select( 'revision', 'rev_parent_id', "rev_id = '$latestRevId'", __METHOD__ ) );
 345+
 346+ $dbw->update(
 347+ 'revision', array( 'rev_page' => $title->getArticleID(), 'rev_parent_id' => $res['rev_parent_id'] ),
 348+ array( 'rev_id' => $revId ), __METHOD__
 349+ );
 350+ $dbw->update(
 351+ 'revision', array( 'rev_parent_id' => $revId ),
 352+ array( 'rev_id' => $latestRevId ), __METHOD__
 353+ );
 354+ }
 355+
 356+ if( isset( $pageId ) ) {
 357+ $dbw->update(
 358+ 'revision', array( 'rev_page' => $pageId ),
 359+ array( 'rev_id' => $revId ), __METHOD__
 360+ );
 361+ }
 362+
 363+ $dbw->commit();
 364+ $ok = $this->addLogEntry( $actionType, array( $title->getDBkey(), $revId ), 'public' );
 365+
 366+ return $revId && $ok;
 367+ }
 368+
 369+ protected function addLogEntry( $type, $params = array(), $visible = 'private' ) {
 370+ $log = new LogPage( 'prem-' . $visible );
 371+
 372+ $self = $this->getTitle();
 373+ $ok = $log->addEntry( $type, $self, $this->mSummary, $params );
 374+
 375+ return $ok;
 376+ }
 377+}
\ No newline at end of file
Property changes on: trunk/extensions/Premoderation/SpecialPremoderation.php
___________________________________________________________________
Added: svn:eol-style
1378 + native
Index: trunk/extensions/Premoderation/Premoderation.class.php
@@ -0,0 +1,173 @@
 2+<?php
 3+class Premoderation {
 4+ public static function initialize() {
 5+ global $wgPremoderationType, $wgPremoderationLockPages;
 6+ global $wgHooks, $wgAbuseFilterCustomActionsHandlers;
 7+
 8+ switch( $wgPremoderationType ) {
 9+ case 'all':
 10+ $wgHooks['ArticleSave'][] = 'Premoderation::processEditRequest';
 11+ break;
 12+
 13+ case 'abusefilter':
 14+ if( !class_exists( 'AbuseFilter' ) ) {
 15+ exit( 'You must install AbuseFilter extension before using option $wgPremoderationType = \'abusefilter\'.' );
 16+ }
 17+ $wgAbuseFilterAvailableActions[] = 'moderation';
 18+ $wgAbuseFilterCustomActionsHandlers['moderation'] = 'Premoderation::handleAFAction';
 19+ break;
 20+ }
 21+
 22+ if( $wgPremoderationLockPages ) {
 23+ $wgHooks['getUserPermissionsErrorsExpensive'][] = 'Premoderation::checkQueue';
 24+ }
 25+
 26+ $wgHooks['ArticleEditUpdatesDeleteFromRecentchanges'][] = 'Premoderation::deleteOldQueueEntries';
 27+
 28+ return true;
 29+ }
 30+
 31+ public static function processEditRequest( &$article, &$user, &$text, &$summary, $minor, $watchthis,
 32+ $sectionanchor, &$flags, &$status )
 33+ {
 34+ $userIP = wfGetIP();
 35+ if( $user->isAllowed( 'skipmoderation' ) || self::checkWhitelist( $userIP ) ) {
 36+ return true;
 37+ }
 38+
 39+ $title = $article->mTitle;
 40+
 41+ $dbw = wfGetDB( DB_MASTER );
 42+ $dbQuery = array(
 43+ 'pmq_id' => '',
 44+ 'pmq_page_last_id' => $title->getLatestRevID(),
 45+ 'pmq_page_ns' => $title->getNamespace(),
 46+ 'pmq_page_title' => $title->getDBkey(),
 47+ 'pmq_user' => $user->getID(),
 48+ 'pmq_user_text' => $user->getName(),
 49+ 'pmq_timestamp' => $dbw->timestamp( wfTimestampNow() ),
 50+ 'pmq_minor' => $minor,
 51+ 'pmq_summary' => $summary,
 52+ 'pmq_len' => $title->getLength(),
 53+ 'pmq_text' => $text,
 54+ 'pmq_flags' => $flags,
 55+ 'pmq_ip' => $userIP,
 56+ 'pmq_status' => 'new'
 57+ );
 58+ $dbw->insert( 'pm_queue', $dbQuery, __METHOD__ );
 59+ $dbw->commit();
 60+
 61+ throw new ErrorPageError( 'premoderation-success', 'premoderation-added-success-text' );
 62+ return true;
 63+ }
 64+
 65+ public static function handleAFAction( $action, $parameters, $title, $vars, $rule_desc ) {
 66+ global $wgUser;
 67+
 68+ $dbw = wfGetDB( DB_MASTER );
 69+ $dbQuery = array(
 70+ 'pmq_id' => '',
 71+ 'pmq_page_last_id' => $title->getLatestRevID(),
 72+ 'pmq_page_ns' => $title->getNamespace(),
 73+ 'pmq_page_title' => $title->getDBkey(),
 74+ 'pmq_user' => $wgUser->getID(),
 75+ 'pmq_user_text' => $wgUser->getName(),
 76+ 'pmq_timestamp' => $dbw->timestamp( wfTimestampNow() ),
 77+ 'pmq_minor' => $vars->getVar( 'minor_edit' )->toInt(),
 78+ 'pmq_summary' => $vars->getVar( 'summary' )->toString(),
 79+ 'pmq_len' => $title->getLength(),
 80+ 'pmq_text' => $vars->getVar( 'new_wikitext' )->toString(),
 81+ 'pmq_flags' => false,
 82+ 'pmq_ip' => wfGetIP(),
 83+ 'pmq_status' => 'new'
 84+ );
 85+ $dbw->insert( 'pm_queue', $dbQuery, __METHOD__ );
 86+ $dbw->commit();
 87+
 88+ return true;
 89+ }
 90+
 91+ public static function loadWhitelist() {
 92+ $dbr = wfGetDB( DB_SLAVE );
 93+ $res = $dbr->select( 'pm_whitelist', '*', '', array( 'LIMIT' => 500 ) );
 94+
 95+ $test = $dbr->fetchRow( $res );
 96+ if( !$test ) {
 97+ return true;
 98+ }
 99+
 100+ $returnArray = array( $test['pmw_ip'] );
 101+ while( $row = $dbr->fetchRow( $res ) ) {
 102+ $returnArray[] = $row['pmw_ip'];
 103+ }
 104+
 105+ return $returnArray;
 106+ }
 107+
 108+ public static function checkWhitelist( $ip ) {
 109+ $whitelist = self::loadWhitelist();
 110+
 111+ $memcKey = wfMemcKey( 'whitelisted', $ip );
 112+ $data = $wgMemc->get( $memcKey );
 113+
 114+ if( $data != '' ) {
 115+ return ( $data === 'ok' ) ? true : false;
 116+ }
 117+
 118+ if( is_array( $whitelist ) ) {
 119+ foreach( $whitelist as $entry ) {
 120+ if( IP::isInRange( $ip, $entry ) ) {
 121+ $wgMemc->set( $memcKey, 'ok', 86400 );
 122+ return true;
 123+ }
 124+ }
 125+ }
 126+
 127+ $wgMemc->set( $memcKey, 'not', 86400 );
 128+ return false;
 129+ }
 130+
 131+ public static function formatParams( $params ) {
 132+ $result = array();
 133+ while( count( $params ) > 1 ) {
 134+ $key = array_shift( &$params );
 135+ $value = array_shift( &$params );
 136+ $result[$key] = $value;
 137+ }
 138+
 139+ return $result;
 140+ }
 141+
 142+ public static function checkQueue( $title, $user, $action, &$result ) {
 143+ if( $action == 'edit' ) {
 144+ $dbr = wfGetDB( DB_SLAVE );
 145+
 146+ $conds = 'pmq_page_ns = ' . $dbr->addQuotes( $title->getNamespace() ) . ' AND pmq_page_title = ' .
 147+ $dbr->addQuotes( $title->getDBkey() ) . ' AND pmq_status != "approved"';
 148+ $res = $dbr->select( 'pm_queue', '*', $conds, __METHOD__ );
 149+
 150+ $test = $dbr->fetchRow( $res );
 151+
 152+ if( $test ) {
 153+ $result[] = array( 'premoderation-edit-conflict' );
 154+ return false;
 155+ }
 156+ }
 157+ return true;
 158+ }
 159+
 160+ public static function deleteOldQueueEntries() {
 161+ global $wgPremoderationDeclinedPurge, $wgPremoderationNewPurge;
 162+
 163+ if( mt_rand( 0, 49 ) == 0 ) {
 164+ $dbw = wfGetDB( DB_MASTER );
 165+
 166+ $conds = '( pmq_status = \'new\' AND pmq_timestamp < \'' . intval( $dbw->timestamp( time() -
 167+ $wgPremoderationNewPurge ) ) . '\' ) OR ( pmq_status = \'declined\' AND pmq_timestamp < \'' .
 168+ intval( $dbw->timestamp( time() - $wgPremoderationDeclinedPurge ) ) . '\' ) OR ' .
 169+ 'pmq_status = \'approved\'';
 170+ $dbw->delete( 'pm_queue', array( $conds ), __METHOD__ );
 171+ }
 172+ return true;
 173+ }
 174+}
\ No newline at end of file
Property changes on: trunk/extensions/Premoderation/Premoderation.class.php
___________________________________________________________________
Added: svn:eol-style
1175 + native
Index: trunk/extensions/Premoderation/Premoderation.i18n.php
@@ -0,0 +1,150 @@
 2+<?php
 3+/**
 4+ * @file
 5+ * @ingroup Extensions
 6+ */
 7+$messages = array();
 8+
 9+/** English
 10+ * @author Cryptocoryne
 11+ * @author Kalan
 12+ */
 13+$messages['en'] = array(
 14+ 'premoderation' => 'Premoderation',
 15+ 'premoderation-desc' => 'Allows to premoderate untrusted changes',
 16+ 'prem-public-logname' => 'Moderation log',
 17+ 'prem-public-logtext' => 'Log of revisions approving by moderators.',
 18+ 'prem-private-logname' => 'Private moderation log.',
 19+ 'prem-private-logtext' => 'Log of private actions (declining, returning to new queue) on revisions in moderation queue.',
 20+ 'prem-whitelist-logname' => 'Log of moderation whitelist',
 21+ 'prem-whitelist-logtext' => 'Log of changes in the moderation whitelist.',
 22+ 'prem-log-approve-create' => 'approved creation of page "[[$2]]"',
 23+ 'prem-log-approve-update' => 'approved revision $3 in page "[[$2]]"',
 24+ 'prem-log-approve-updateold' => 'approved old revision $3 in page "[[$2]]"',
 25+ 'prem-log-status' => 'changed status of revision $2 in moderation queue to "$3"',
 26+ 'prem-log-whitelist-add' => 'added IP address "$2" into list',
 27+ 'prem-log-whitelist-delete' => 'deleted IP address "$2" from list',
 28+ 'premoderation-diff-h2' => 'Difference between revisions',
 29+ 'premoderation-internal-conflicts-h2' => 'Conflicts with revisions in moderation queue',
 30+ 'premoderation-external-conflicts-h2' => 'Conflicts with published revisions',
 31+ 'premoderation-list-new-h2' => 'New revisions',
 32+ 'premoderation-list-declined-h2' => 'Declined revisions',
 33+ 'premoderation-manager-mainpage' => 'Moderation queue',
 34+ 'premoderation-manager-invalidaction' => 'Invalid action',
 35+ 'premoderation-manager-status' => 'Manage revision status',
 36+ 'premoderation-added-success-text' => 'Your revision has been succesfully added to the moderation queue. It will be published or declined by moderator',
 37+ 'premoderation-error-externals' => 'Cannot publish this revision: newer revisions of this page have already been published.',
 38+ 'premoderation-external-edits' => '\'\'\'Warning!\'\'\' This page has published revisions newer than this one. You can probably publish it, but not as current revision, and you must merge it with current revision manually.',
 39+ 'premoderation-invalidaction' => 'You are trying to perform an invalid action.',
 40+ 'premoderation-list-intro' => 'This special page lists new and declined revisions in the moderation queue. You can review each revision, approve and publish or decline it. Declined revisions will be completely removed from database after 3 days of last status change.',
 41+ 'premoderation-notexists-id' => 'This revision could not be found in the moderation queue. Probably it has already been published or declined and deleted from database',
 42+ 'premoderation-private-ip' => 'IP address:',
 43+ 'premoderation-success-changed-text' => 'Revision status in moderation queue has been succesfully changed',
 44+ 'premoderation-table-list-status' => 'Changing status',
 45+ 'premoderation-table-list-title' => 'Title and parameters',
 46+ 'premoderation-table-list-time' => 'Date and time',
 47+ 'premoderation-table-list-summary' => 'Summary',
 48+ 'premoderation-table-list-user' => 'User',
 49+ 'premoderation-table-list-ip' => 'IP address',
 50+ 'premoderation-table-list-delete' => 'Delete',
 51+ 'premoderation-status-fieldset' => 'Change status',
 52+ 'premoderation-status-approved' => 'Approve revision',
 53+ 'premoderation-status-declined' => 'Decline revision',
 54+ 'premoderation-status-new' => 'Return to the main moderation queue',
 55+ 'premoderation-status-approved-changed' => 'approved by moderator $1',
 56+ 'premoderation-status-declined-changed' => 'declined by moderator $1',
 57+ 'premoderation-status-new-added' => 'new revision',
 58+ 'premoderation-status-new-changed' => 'returned to the queue by moderator $1',
 59+ 'premoderation-success' => 'Success',
 60+ 'premoderation-success-approved' => 'Revision has been successfully approved and published in the wiki',
 61+ 'premoderation-status-info' => 'Revision info',
 62+ 'premoderation-status-intro' => 'On this page, you can review revisions in the moderation queue and manage them if you have sufficient rights',
 63+ 'remoderationwhitelist' => 'Moderation whitelist',
 64+ 'premoderation-whitelist-empty' => 'The whitelist is empty',
 65+ 'premoderation-whitelist-intro' => 'This page lists IP addresses and subnets that can publish revisions without moderation',
 66+ 'premoderation-wl-addip-fieldset' => 'Add IP address into list',
 67+ 'prem-whitelist-added' => 'IP address has been successfully added to the whitelist.',
 68+ 'prem-whitelist-deleted' => 'IP address has been successfully deleted from the whitelist.',
 69+ 'prem-whitelist-invalid-ip' => 'You\'ve enter invalid IP address.',
 70+ 'premoderation-edit-conflict' => 'You can\'t edit this page due to the revision in this page is already in the moderation queue.',
 71+ 'right-premoderation' => 'revision moderation',
 72+ 'right-premoderation-log' => 'view private moderation log',
 73+ 'right-premoderation-viewip' => 'view IP addresses in moderation queue',
 74+ 'right-premoderation-wlist' => 'view and edit the moderation whitelist',
 75+ 'right-skipmoderation' => 'bypass moderation',
 76+ 'abusefilter-action-moderation' => 'Moderation',
 77+ 'abusefilter-edit-action-moderation' => 'Premoderate this revision',
 78+ 'abusefilter-moderation' => 'Your revision has been succesfully added to the moderation queue. It will be published or declined by moderator',
 79+);
 80+
 81+/** Russian (Русский)
 82+ * @author Cryptocoryne
 83+ * @author Kalan
 84+ */
 85+$messages['ru'] = array(
 86+ 'premoderation' => 'Премодерация',
 87+ 'premoderation-desc' => 'Позволяет осуществлять премодерацию непроверенных правок',
 88+ 'prem-public-logname' => 'Журнал модерации',
 89+ 'prem-public-logtext' => 'Журнал подтверждения правок модераторами.',
 90+ 'prem-private-logname' => 'Закрытый журнал модерации.',
 91+ 'prem-private-logtext' => 'Журнал закрытых действий (отклонение, перемещение между очередями), совершаемых с правками в очереди модерации.',
 92+ 'prem-whitelist-logname' => 'Журнал изменений белого списка',
 93+ 'prem-whitelist-logtext' => 'Журнал изменений белого списка модерации.',
 94+ 'prem-log-approve-create' => 'подтвердил создание страницы «[[$2]]»',
 95+ 'prem-log-approve-update' => 'подтвердил правку $3 на странице «[[$2]]»',
 96+ 'prem-log-approve-updateold' => 'подтвердил старую правку $3 на странице «$2»',
 97+ 'prem-log-status' => 'изменил статус для правки $2 в очереди модерации на «$3»',
 98+ 'prem-log-whitelist-add' => 'добавил IP-адрес «$2» в список',
 99+ 'prem-log-whitelist-delete' => 'удалил IP-адрес «$2» из списка',
 100+ 'premoderation-diff-h2' => 'Разность версий',
 101+ 'premoderation-internal-conflicts-h2' => 'Конфликты с правками в очереди модерации',
 102+ 'premoderation-external-conflicts-h2' => 'Конфликты с опубликованными правками',
 103+ 'premoderation-list-new-h2' => 'Новые правки',
 104+ 'premoderation-list-declined-h2' => 'Отклонённые правки',
 105+ 'premoderation-manager-mainpage' => 'Очередь модерации',
 106+ 'premoderation-manager-invalidaction' => 'Ошибочное действие',
 107+ 'premoderation-manager-status' => 'Управление статусом правки',
 108+ 'premoderation-added-success-text' => 'Ваша правка успешно добавлена в очередь модерации. После проверки модератором правка попадёт на сайт или будет отклонена.',
 109+ 'premoderation-error-externals' => 'В статье были сделаны новые правки, опубликовать эту правку невозможно.',
 110+ 'premoderation-external-edits' => '\'\'\'Внимание!\'\'\' В статье есть опубликованные правки, внесённые после отправки этой правки на модерацию. Вы можете подтвердить её, однако она будет включена между существующими ревизиями и потребуется вручную объединить её с последней версией.',
 111+ 'premoderation-invalidaction' => 'Вы пытаетесь осуществить некорректное действие.',
 112+ 'premoderation-list-intro' => 'На этой странице перечислены правки, ожидающие подтверждения модератора. Вы можете просмотреть детали каждой правки, подтвердить её (после чего она станет доступна на сайте) или отклонить (после этого вы всё равно сможете подтвердить её или вернуть в очередь в течение 3 дней).',
 113+ 'premoderation-notexists-id' => 'Запись в очереди модерации не существует. Возможно, она уже была обработана и удалена из таблицы модерации.',
 114+ 'premoderation-private-ip' => 'IP-адрес:',
 115+ 'premoderation-success-changed-text' => 'Статус правки в очереди премодерации успешно изменён.',
 116+ 'premoderation-table-list-status' => 'Изменение статуса',
 117+ 'premoderation-table-list-title' => 'Название и параметры',
 118+ 'premoderation-table-list-time' => 'Дата и время',
 119+ 'premoderation-table-list-summary' => 'Краткое описание правки',
 120+ 'premoderation-table-list-user' => 'Участник',
 121+ 'premoderation-table-list-ip' => 'IP-адрес',
 122+ 'premoderation-table-list-delete' => 'Удалить',
 123+ 'premoderation-status-fieldset' => 'Изменить статус',
 124+ 'premoderation-status-approved' => 'Подтвердить правку',
 125+ 'premoderation-status-declined' => 'Отклонить правку',
 126+ 'premoderation-status-new' => 'Вернуть в основную очередь модерации',
 127+ 'premoderation-status-approved-changed' => 'подтверждена модератором $1',
 128+ 'premoderation-status-declined-changed' => 'отклонена модератором $1',
 129+ 'premoderation-status-new-added' => 'новая правка',
 130+ 'premoderation-status-new-changed' => 'возвращена в очередь модератором $1',
 131+ 'premoderation-success' => 'Действие выполнено',
 132+ 'premoderation-success-approved' => 'Правка успешно подтверждена и опубликована в вики',
 133+ 'premoderation-status-info' => 'Информация о правке',
 134+ 'premoderation-status-intro' => 'При помощи этой страницы вы можете просмотреть информацию о правке в очереди модерации, а также при наличии возможности совершить с ней действия.',
 135+ 'premoderation-whitelist' => 'Белый список премодерации',
 136+ 'premoderation-whitelist-empty' => 'В настоящее время белый список пуст.',
 137+ 'premoderation-whitelist-intro' => 'В этом списке перечислены IP-адреса и подсети, правки которых публикуются на сайте без прохождения премодерации.',
 138+ 'premoderation-wl-addip-fieldset' => 'Добавить IP-адрес в список',
 139+ 'prem-whitelist-added' => 'IP-адрес был успешно добавлен в белый список.',
 140+ 'prem-whitelist-deleted' => 'IP-адрес был успешно удалён из белого списка.',
 141+ 'prem-whitelist-invalid-ip' => 'Вы ввели некорректный IP-адрес.',
 142+ 'premoderation-edit-conflict' => 'Вы не можете редактировать эту страницу, так как связанная с ней правка уже есть в очереди модерации.',
 143+ 'right-premoderation' => 'модерация правок',
 144+ 'right-premoderation-log' => 'просмотр закрытого журнала модерации',
 145+ 'right-premoderation-viewip' => 'просмотр IP-адресов в очереди модерации',
 146+ 'right-premoderation-wlist' => 'просмотр и изменение белого списка модерации',
 147+ 'right-skipmoderation' => 'внесение правок без премодерации',
 148+ 'abusefilter-action-moderation' => 'Модерация',
 149+ 'abusefilter-edit-action-moderation' => 'Отправить правку на премодерацию',
 150+ 'abusefilter-moderation' => 'Ваша правка успешно добавлена в очередь модерации. После проверки модератором правка попадёт на сайт или будет отклонена.',
 151+);
\ No newline at end of file
Property changes on: trunk/extensions/Premoderation/Premoderation.i18n.php
___________________________________________________________________
Added: svn:eol-style
1152 + native
Index: trunk/extensions/Premoderation/SpecialPremoderationWhiteList.php
@@ -0,0 +1,113 @@
 2+<?php
 3+class SpecialPremoderationWhiteList extends SpecialPage {
 4+ protected $mParams = false;
 5+ protected $mPosted = false;
 6+ protected $mRequest = array();
 7+
 8+ function __construct() {
 9+ global $wgRequest;
 10+ parent::__construct( 'PremoderationWhiteList', 'premoderation-wlist' );
 11+
 12+ if( $wgRequest->wasPosted() ) {
 13+ $this->mPosted = true;
 14+ $this->mRequest = $wgRequest->getValues();
 15+ }
 16+ }
 17+
 18+ public function execute( $subpage ) {
 19+ global $wgUser, $wgOut;
 20+
 21+ if( !$wgUser->isAllowed( 'premoderation-wlist' ) ) {
 22+ $this->displayRestrictionError();
 23+ return;
 24+ }
 25+
 26+ $wgOut->setPageTitle( wfMsg( 'premoderationwhitelist' ) );
 27+ $wgOut->addWikiMsg( 'premoderation-whitelist-intro' );
 28+
 29+ $params = array_values( explode( '/', $subpage ) );
 30+ $action = array_shift( &$params );
 31+
 32+ if( $action == '' ) {
 33+ $action = 'list';
 34+ } elseif( $action == 'list' && isset( $params ) ) {
 35+ $this->mParams = Premoderation::formatParams( $params );
 36+ } else {
 37+ $wgOut->setPageTitle( wfMsg( 'premoderation-manager-invalidaction' ) );
 38+ $wgOut->addWikiMsg( 'premoderation-invalidaction' );
 39+ return;
 40+ }
 41+
 42+ if( $this->mPosted ) {
 43+ $msg = $this->updateList();
 44+ $wgOut->addHTML( '<p class="error">' . wfMsg( $msg ) . '</p>' );
 45+ }
 46+
 47+ $wgOut->addHTML( $this->getAddForm() );
 48+
 49+ $whiteList = Premoderation::loadWhitelist();
 50+ if( is_array( $whiteList ) ) {
 51+ $output = '<table class="wikitable"><tr><th>' . wfMsg( 'premoderation-table-list-ip' ) .
 52+ '</th><th>' . wfMsg( 'premoderation-table-list-delete' ) . '</th></tr>';
 53+ foreach( $whiteList as $ip ) {
 54+ $output .= '<tr><td>' . $ip . '</td><td>' . $this->getDeletionButton( $ip ) . '</td></tr>';
 55+ }
 56+ $output .= '</table>';
 57+ $wgOut->addHTML( $output );
 58+ } else {
 59+ $wgOut->addWikiMsg( 'premoderation-whitelist-empty' );
 60+ }
 61+ }
 62+
 63+ protected function getAddForm() {
 64+ return Xml::fieldset( wfMsg( 'premoderation-wl-addip-fieldset' ) ) .
 65+ Xml::openElement( 'form', array( 'id' => 'prem-wl-form', 'method' => 'post' ) ) . '<table><tr><td>' .
 66+ wfMsg( 'premoderation-private-ip' ) . '</td><td>' . Xml::input( 'ip', 50, '', array( 'id' => 'prem-whitelist-addip' ) ) .
 67+ '</td></tr><tr><td>' . wfMsg( 'summary' ) . '</td><td>' . Xml::input( 'summary', 50, '',
 68+ array( 'id' => 'prem-summary' ) ) . '</td></tr><tr>' . '<td>' . Xml::submitButton( wfMsg( 'htmlform-submit' ),
 69+ array( 'id' => 'prem-wl-submit' ) ) . '<input type="hidden" name="action" value="add" />' .
 70+ '</td></tr></table>' . Xml::closeElement( 'form' ) . Xml::closeElement( 'fieldset' );
 71+ }
 72+
 73+ protected function getDeletionButton( $ip ) {
 74+ return Xml::openElement( 'form', array( 'id' => 'prem-wl-delete' . $ip, 'method' => 'post' ) ) .
 75+ Xml::submitButton( wfMsg( 'premoderation-table-list-delete' ) ) .
 76+ '<input type="hidden" name="action" value="delete" /><input type="hidden" name="ip" value="' . $ip . '" />' .
 77+ Xml::closeElement( 'form' );
 78+ }
 79+
 80+ protected function updateList() {
 81+ $ip = $this->mRequest['ip'];
 82+
 83+ switch( $this->mRequest['action'] ) {
 84+ case 'add':
 85+ if( !IP::isIPAddress( $ip ) ) {
 86+ return 'prem-whitelist-invalid-ip';
 87+ }
 88+ $dbw = wfGetDB( DB_MASTER );
 89+ $dbw->insert( 'pm_whitelist', array( 'pmw_ip' => $ip ), __METHOD__ );
 90+ $this->addLogEntry( $this->mRequest['action'], array( $ip ) );
 91+ return 'prem-whitelist-added';
 92+
 93+ case 'delete':
 94+ if( !IP::isIPAddress( $ip ) ) {
 95+ return 'prem-whitelist-invalid-ip';
 96+ }
 97+ $dbw = wfGetDB( DB_MASTER );
 98+ $dbw->delete( 'pm_whitelist', array( 'pmw_ip' => $ip ), __METHOD__ );
 99+ $this->addLogEntry( $this->mRequest['action'], array( $ip ) );
 100+ return 'prem-whitelist-deleted';
 101+
 102+ default:
 103+ return 'prem-whitelist-error-action';
 104+ }
 105+ }
 106+
 107+ protected function addLogEntry( $action, $params ) {
 108+ $log = new LogPage( 'prem-whitelist' );
 109+
 110+ $self = $this->getTitle();
 111+ $summary = isset( $this->mRequest['summary'] ) ? strval( $this->mRequest['summary'] ) : '';
 112+ $log->addEntry( $action, $self, $summary, $params );
 113+ }
 114+}
\ No newline at end of file
Property changes on: trunk/extensions/Premoderation/SpecialPremoderationWhiteList.php
___________________________________________________________________
Added: svn:eol-style
1115 + native
Index: trunk/extensions/Premoderation/install.php
@@ -0,0 +1,10 @@
 2+<?php
 3+/*
 4+ * Script for creating new database tables
 5+ */
 6+
 7+$dir = dirname( __FILE__ );
 8+require_once ( $dir . '/../../maintenance/commandLine.inc' );
 9+
 10+$dbw = wfGetDB( DB_MASTER );
 11+$dbw->sourceFile( $dir . '/db_tables.sql' );
\ No newline at end of file
Property changes on: trunk/extensions/Premoderation/install.php
___________________________________________________________________
Added: svn:eol-style
112 + native
Index: trunk/extensions/Premoderation/db_tables.sql
@@ -0,0 +1,28 @@
 2+CREATE TABLE /*$wgDBprefix*/pm_queue (
 3+ pmq_id BIGINT unsigned NOT NULL AUTO_INCREMENT,
 4+ pmq_page_last_id INT unsigned NOT NULL,
 5+ pmq_page_ns INT NOT NULL,
 6+ pmq_page_title VARCHAR(255) BINARY NOT NULL,
 7+ pmq_user INT unsigned NOT NULL DEFAULT 0,
 8+ pmq_user_text VARCHAR(255) BINARY NOT NULL DEFAULT '',
 9+ pmq_timestamp BINARY(14) NOT NULL DEFAULT '',
 10+ pmq_minor TINYINT unsigned NOT NULL DEFAULT 0,
 11+ pmq_summary TINYBLOB NOT NULL,
 12+ pmq_len INT unsigned,
 13+ pmq_text MEDIUMBLOB NOT NULL,
 14+ pmq_flags tinyblob NOT NULL,
 15+ pmq_ip VARBINARY(40) NOT NULL DEFAULT '',
 16+ pmq_updated BINARY(14) DEFAULT NULL,
 17+ pmq_updated_user INT unsigned DEFAULT NULL,
 18+ pmq_updated_user_text VARCHAR(255) BINARY DEFAULT NULL,
 19+ pmq_status VARBINARY(40) NOT NULL DEFAULT '',
 20+
 21+ PRIMARY KEY (pmq_id),
 22+ KEY (pmq_user)
 23+) /*$wgDBTableOptions*/;
 24+
 25+CREATE TABLE /*$wgDBprefix*/pm_whitelist (
 26+ pmw_ip VARBINARY(40) NOT NULL DEFAULT '',
 27+
 28+ PRIMARY KEY (pmw_ip)
 29+) /*$wgDBTableOptions*/;
\ No newline at end of file
Property changes on: trunk/extensions/Premoderation/db_tables.sql
___________________________________________________________________
Added: svn:eol-style
130 + native
Index: trunk/extensions/Premoderation/Premoderation.php
@@ -0,0 +1,57 @@
 2+<?php
 3+if ( !defined( 'MEDIAWIKI' ) ) {
 4+ die();
 5+}
 6+
 7+$wgExtensionCredits['antispam'][] = array(
 8+ 'path' => __FILE__,
 9+ 'name' => 'Premoderation',
 10+ 'author' => array( 'Cryptocoryne' ),
 11+ 'descriptionmsg' => 'premoderation-desc',
 12+ 'version' => '1.0beta',
 13+ 'url' => 'http://www.mediawiki.org/wiki/Extension:Premoderation',
 14+);
 15+
 16+$dir = dirname( __FILE__ );
 17+$wgExtensionMessagesFiles['Premoderation'] = "$dir/Premoderation.i18n.php";
 18+$wgAutoloadClasses['Premoderation'] = "$dir/Premoderation.class.php";
 19+$wgAutoloadClasses['SpecialPremoderation'] = "$dir/SpecialPremoderation.php";
 20+$wgAutoloadClasses['SpecialPremoderationWhiteList'] = "$dir/SpecialPremoderationWhiteList.php";
 21+
 22+$wgSpecialPages['Premoderation'] = 'SpecialPremoderation';
 23+$wgSpecialPages['PremoderationWhiteList'] = 'SpecialPremoderationWhiteList';
 24+$wgSpecialPageGroups['Premoderation'] = 'wiki';
 25+$wgSpecialPageGroups['PremoderationWhiteList'] = 'wiki';
 26+
 27+$wgAvailableRights[] = 'premoderation';
 28+$wgAvailableRights[] = 'premoderation-log';
 29+$wgAvailableRights[] = 'premoderation-viewip';
 30+$wgAvailableRights[] = 'premoderation-wlist';
 31+$wgAvailableRights[] = 'skipmoderation';
 32+
 33+$wgLogTypes[] = 'prem-public';
 34+$wgLogTypes[] = 'prem-private';
 35+$wgLogTypes[] = 'prem-whitelist';
 36+$wgLogNames['prem-public'] = 'prem-public-logname';
 37+$wgLogNames['prem-private'] = 'prem-private-logname';
 38+$wgLogNames['prem-whitelist'] = 'prem-whitelist-logname';
 39+$wgLogHeaders['prem-public'] = 'prem-public-logtext';
 40+$wgLogHeaders['prem-private'] = 'prem-private-logtext';
 41+$wgLogHeaders['prem-whitelist'] = 'prem-whitelist-logtext';
 42+$wgLogActions['prem-public/create'] = 'prem-log-approve-create';
 43+$wgLogActions['prem-public/update'] = 'prem-log-approve-update';
 44+$wgLogActions['prem-public/updateold'] = 'prem-log-approve-updateold';
 45+$wgLogActions['prem-private/status'] = 'prem-log-status';
 46+$wgLogActions['prem-whitelist/add'] = 'prem-log-whitelist-add';
 47+$wgLogActions['prem-whitelist/delete'] = 'prem-log-whitelist-delete';
 48+$wgLogRestrictions['prem-private'] = 'premoderation-log';
 49+$wgLogRestrictions['prem-whitelist'] = 'premoderation-wlist';
 50+
 51+// 'all' or 'abusefilter'
 52+$wgPremoderationType = 'all';
 53+$wgPremoderationStrict = false;
 54+$wgPremoderationLockPages = false;
 55+$wgPremoderationDeclinedPurge = 86400 * 3;
 56+$wgPremoderationNewPurge = 86400 * 14;
 57+
 58+$wgExtensionFunctions[] = 'Premoderation::initialize';
\ No newline at end of file
Property changes on: trunk/extensions/Premoderation/Premoderation.php
___________________________________________________________________
Added: svn:eol-style
159 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r102153Followup r102139: fix some critical errorcryptocoryne04:46, 6 November 2011
r102199Followup r102139 -- some improves and fixes according to ashley's reviewcryptocoryne21:38, 6 November 2011

Comments

#Comment by Jack Phoenix (talk | contribs)   13:23, 6 November 2011
+	protected $mParams = false;
+	protected $mPosted = false;
+	protected $mRequest = array();
+	protected $mSummary = '';
+	public $mAllowedStatus = array( 'new', 'approved', 'declined' );

Prefixing class member variables with m is so 1999.

+		if( !$wgUser->isAllowed( 'premoderation' ) ) {
+			$this->displayRestrictionError();
+			return;
+		}

Should you also perform checks for read-only mode and if the user trying to perform the action is blocked?

+		$res = $dbr->select(
+			'pm_queue',
+			array( 'pmq_id', 'pmq_page_ns', 'pmq_page_title', 'pmq_user', 'pmq_user_text', 'pmq_timestamp',
+				'pmq_minor', 'pmq_summary', 'pmq_len', 'pmq_status', 'pmq_updated', 'pmq_updated_user_text' ),

Please break lines at 80 characters.

+		if( $wgUser->isAllowed( 'premoderation-viewip' ) ) {
+			$wgOut->addHTML( wfMsg( 'premoderation-private-ip' ) . ' ' . $row['pmq_ip'] );
+		}

I believe that you should pass the $row['pmq_ip'] variable to the message for better international compatibility.

$output .= Xml::closeElement( 'table' );

Personally I'd write </table>, even though the recommended way is to use the Html class.

+	protected function checkInternalConflicts( $db, $id, $ns, $page ) {
+		global $wgOut;
+		
+		$conds = 'pmq_page_ns = ' . $db->addQuotes( $ns ) . ' AND pmq_page_title = ' .
+			$db->addQuotes( $page ) . ' AND pmq_id != ' . $id . ' AND pmq_status != "approved"';
+		
+		$res = $db->select(
+			'pm_queue', '*', $conds, __METHOD__,
+			array( 'ORDER BY' => 'pmq_timestamp DESC', 'LIMIT' => 20 )
+		);

I'd suggest swapping the MySQL-specific != operator to the standard SQL NOT operator <> and writing the query like this:

		$res = $db->select(
			'pm_queue',
			'*',
			array(
				'pmq_page_ns' => $ns,
				'pmq_page_title' => $page,
				"pmq_id <> $id",
				'pmq_status <> "approved"'
			),
			__METHOD__,
			array( 'ORDER BY' => 'pmq_timestamp DESC', 'LIMIT' => 20 )
		);

I'd suggest removing install.php script altogether and writing a function that hooks into the LoadExtensionSchemaUpdates hook; that way the database tables will be created by update.php whenever the user runs it (usually after installing the extension) and you don't need to have a separate installer script. Many social tools, such as Extension:LinkFilter, handle schema changes this way.

+CREATE TABLE /*$wgDBprefix*/pm_queue (
+	pmq_id BIGINT unsigned NOT NULL AUTO_INCREMENT,
[snip]
+	PRIMARY KEY (pmq_id),
+	KEY (pmq_user)
+) /*$wgDBTableOptions*/;

This is not SQLite-compatible. To make it SQLite compatible:

CREATE TABLE /*_*/pm_queue (
	pmq_id BIGINT unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
[snip]
) /*$wgDBTableOptions*/;
CREATE INDEX /*i*/pmq_user ON /*_*/pm_queue (pmq_user);

Likewise, to make the pm_whitelist table SQLite-compatible, you will need to move the PRIMARY KEY declaration.

Premoderation.php has exactly one comment. It really could use some comments for the configuration variables. Also, you don't need to use array() in $wgExtensionCredits when there is only one author.

#Comment by Cryptocoryne (talk | contribs)   21:39, 6 November 2011

See r102199.

Status & tagging log