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 |
1 | 378 | + 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 |
1 | 175 | + 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 |
1 | 152 | + 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 |
1 | 115 | + 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 |
1 | 12 | + 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 |
1 | 30 | + 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 |
1 | 59 | + native |