Index: trunk/phase3/includes/SpecialUndelete.php |
— | — | @@ -532,8 +532,7 @@ |
533 | 533 | |
534 | 534 | if( $this->mPreview ) { |
535 | 535 | $wgOut->addHtml( "<hr />\n" ); |
536 | | - $article = new Article ( $archive->title ); # OutputPage wants an Article obj |
537 | | - $wgOut->addPrimaryWikiText( $rev->getText(), $article, false ); |
| 536 | + $wgOut->addWikiTextTitle( $rev->getText(), $archive->title, false ); |
538 | 537 | } |
539 | 538 | |
540 | 539 | $self = SpecialPage::getTitleFor( "Undelete" ); |
Index: trunk/phase3/includes/Title.php |
— | — | @@ -50,7 +50,7 @@ |
51 | 51 | var $mArticleID; # Article ID, fetched from the link cache on demand |
52 | 52 | var $mLatestID; # ID of most recent revision |
53 | 53 | var $mRestrictions; # Array of groups allowed to edit this article |
54 | | - # Only null or "sysop" are supported |
| 54 | + var $mCascadeRestrictionFlags; |
55 | 55 | var $mRestrictionsLoaded; # Boolean for initialisation on demand |
56 | 56 | var $mPrefixedText; # Text form including namespace/interwiki, initialised on demand |
57 | 57 | var $mDefaultNamespace; # Namespace index when there is no namespace |
— | — | @@ -1115,6 +1115,18 @@ |
1116 | 1116 | return false; |
1117 | 1117 | } |
1118 | 1118 | |
| 1119 | + if ( ( $this->isCascadeProtectedPage() ) || |
| 1120 | + ($this->getNamespace() == NS_IMAGE && $this->isCascadeProtectedImage() ) ) { |
| 1121 | + # We /could/ use the protection level on the source page, but it's fairly ugly |
| 1122 | + # as we have to establish a precedence hierarchy for pages included by multiple |
| 1123 | + # cascade-protected pages. So just restrict it to people with 'protect' permission, |
| 1124 | + # as they could remove the protection anyway. |
| 1125 | + if ( !$wgUser->isAllowed('protect') ) { |
| 1126 | + wfProfileOut( $fname ); |
| 1127 | + return false; |
| 1128 | + } |
| 1129 | + } |
| 1130 | + |
1119 | 1131 | foreach( $this->getRestrictions($action) as $right ) { |
1120 | 1132 | // Backwards compatibility, rewrite sysop -> protect |
1121 | 1133 | if ( $right == 'sysop' ) { |
— | — | @@ -1308,33 +1320,113 @@ |
1309 | 1321 | } |
1310 | 1322 | |
1311 | 1323 | /** |
| 1324 | + * Cascading protects: Check if the current image is protected due to a cascading restriction |
| 1325 | + * |
| 1326 | + * @return bool If the current page is protected due to a cascading restriction. |
| 1327 | + * @access public |
| 1328 | + */ |
| 1329 | + function isCascadeProtectedImage() { |
| 1330 | + global $wgEnableCascadingProtection; |
| 1331 | + if (!$wgEnableCascadingProtection) |
| 1332 | + return; |
| 1333 | + |
| 1334 | + wfProfileIn(__METHOD__); |
| 1335 | + |
| 1336 | + $dbr =& wfGetDb( DB_SLAVE ); |
| 1337 | + |
| 1338 | + $cols = array( 'il_to' ); |
| 1339 | + $tables = array ('imagelinks', 'page_restrictions'); |
| 1340 | + $where_clauses = array( 'il_to' => $this->getDBkey(), 'il_from=pr_page', 'pr_cascade' => 1 ); |
| 1341 | + |
| 1342 | + $res = $dbr->select( $tables, $cols, $where_clauses, __METHOD__); |
| 1343 | + |
| 1344 | + //die($dbr->numRows($res)); |
| 1345 | + |
| 1346 | + if ($dbr->numRows($res)) { |
| 1347 | + wfProfileOut(__METHOD__); |
| 1348 | + return true; |
| 1349 | + } else { |
| 1350 | + wfProfileOut(__METHOD__); |
| 1351 | + return false; |
| 1352 | + } |
| 1353 | + } |
| 1354 | + |
| 1355 | + /** |
| 1356 | + * Cascading protects: Check if the current page is protected due to a cascading restriction. |
| 1357 | + * |
| 1358 | + * @return bool if the current page is protected due to a cascading restriction |
| 1359 | + * @access public |
| 1360 | + */ |
| 1361 | + function isCascadeProtectedPage() { |
| 1362 | + global $wgEnableCascadingProtection; |
| 1363 | + if (!$wgEnableCascadingProtection) |
| 1364 | + return; |
| 1365 | + |
| 1366 | + wfProfileIn(__METHOD__); |
| 1367 | + |
| 1368 | + $dbr =& wfGetDb( DB_SLAVE ); |
| 1369 | + |
| 1370 | + $cols = array( 'tl_namespace', 'tl_title'/*, 'pr_level', 'pr_type'*/ ); |
| 1371 | + $tables = array ('templatelinks', 'page_restrictions'); |
| 1372 | + $where_clauses = array( 'tl_namespace' => $this->getNamespace(), 'tl_title' => $this->getDBkey(), 'tl_from=pr_page', 'pr_cascade' => 1 ); |
| 1373 | + |
| 1374 | + $res = $dbr->select( $tables, $cols, $where_clauses, __METHOD__); |
| 1375 | + |
| 1376 | + if ($dbr->numRows($res)) { |
| 1377 | + wfProfileOut(__METHOD__); |
| 1378 | + return true; |
| 1379 | + } else { |
| 1380 | + wfProfileOut(__METHOD__); |
| 1381 | + return false; |
| 1382 | + } |
| 1383 | + } |
| 1384 | + |
| 1385 | + function getRestrictionCascadingFlags() { |
| 1386 | + if (!$this->mRestrictionsLoaded) { |
| 1387 | + $this->loadRestrictions(); |
| 1388 | + } |
| 1389 | + |
| 1390 | + return $this->mCascadeRestrictionFlags; |
| 1391 | + } |
| 1392 | + |
| 1393 | + /** |
1312 | 1394 | * Loads a string into mRestrictions array |
1313 | | - * @param string $res restrictions in string format |
| 1395 | + * @param resource $res restrictions as an SQL result. |
1314 | 1396 | * @access public |
1315 | 1397 | */ |
1316 | | - function loadRestrictions( $res ) { |
1317 | | - $this->mRestrictions['edit'] = array(); |
1318 | | - $this->mRestrictions['move'] = array(); |
1319 | | - |
1320 | | - if( !$res ) { |
1321 | | - # No restrictions (page_restrictions blank) |
| 1398 | + function loadRestrictionsFromRow( $res ) { |
| 1399 | + $dbr =& wfGetDb( DB_SLAVE ); |
| 1400 | + |
| 1401 | + if (!$dbr->numRows( $res ) ) { |
| 1402 | + # No restrictions |
1322 | 1403 | $this->mRestrictionsLoaded = true; |
1323 | 1404 | return; |
1324 | 1405 | } |
1325 | | - |
1326 | | - foreach( explode( ':', trim( $res ) ) as $restrict ) { |
1327 | | - $temp = explode( '=', trim( $restrict ) ); |
1328 | | - if(count($temp) == 1) { |
1329 | | - // old format should be treated as edit/move restriction |
1330 | | - $this->mRestrictions["edit"] = explode( ',', trim( $temp[0] ) ); |
1331 | | - $this->mRestrictions["move"] = explode( ',', trim( $temp[0] ) ); |
1332 | | - } else { |
1333 | | - $this->mRestrictions[$temp[0]] = explode( ',', trim( $temp[1] ) ); |
1334 | | - } |
| 1406 | + |
| 1407 | + $this->mRestrictions['edit'] = array(); |
| 1408 | + $this->mRestrictions['move'] = array(); |
| 1409 | + |
| 1410 | + while ($row = $dbr->fetchObject( $res ) ) { |
| 1411 | + # Cycle through all the restrictions. |
| 1412 | + |
| 1413 | + $this->mRestrictions[$row->pr_type] = explode( ',', trim( $row->pr_level ) ); |
| 1414 | + |
| 1415 | + $this->mCascadeRestrictionFlags |= $row->pr_cascade; |
1335 | 1416 | } |
| 1417 | + |
1336 | 1418 | $this->mRestrictionsLoaded = true; |
1337 | 1419 | } |
1338 | 1420 | |
| 1421 | + function loadRestrictions() { |
| 1422 | + if( !$this->mRestrictionsLoaded ) { |
| 1423 | + $dbr =& wfGetDB( DB_SLAVE ); |
| 1424 | + |
| 1425 | + $res = $dbr->select( 'page_restrictions', '*', |
| 1426 | + array ( 'pr_page' => $this->getArticleId() ), __METHOD__ ); |
| 1427 | + $this->loadRestrictionsFromRow( $res ); |
| 1428 | + } |
| 1429 | + } |
| 1430 | + |
1339 | 1431 | /** |
1340 | 1432 | * Accessor/initialisation for mRestrictions |
1341 | 1433 | * |
— | — | @@ -1345,9 +1437,7 @@ |
1346 | 1438 | function getRestrictions( $action ) { |
1347 | 1439 | if( $this->exists() ) { |
1348 | 1440 | if( !$this->mRestrictionsLoaded ) { |
1349 | | - $dbr =& wfGetDB( DB_SLAVE ); |
1350 | | - $res = $dbr->selectField( 'page', 'page_restrictions', array( 'page_id' => $this->getArticleId() ) ); |
1351 | | - $this->loadRestrictions( $res ); |
| 1441 | + $this->loadRestrictions(); |
1352 | 1442 | } |
1353 | 1443 | return isset( $this->mRestrictions[$action] ) |
1354 | 1444 | ? $this->mRestrictions[$action] |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -2416,4 +2416,9 @@ |
2417 | 2417 | */ |
2418 | 2418 | $wgDisableQueryPageUpdate = false; |
2419 | 2419 | |
| 2420 | +/** |
| 2421 | + * Set this to false to disable cascading protection |
| 2422 | + */ |
| 2423 | +$wgEnableCascadingProtection = true; |
| 2424 | + |
2420 | 2425 | ?> |
Index: trunk/phase3/includes/ProtectionForm.php |
— | — | @@ -25,6 +25,7 @@ |
26 | 26 | class ProtectionForm { |
27 | 27 | var $mRestrictions = array(); |
28 | 28 | var $mReason = ''; |
| 29 | + var $mCascade = false; |
29 | 30 | |
30 | 31 | function ProtectionForm( &$article ) { |
31 | 32 | global $wgRequest, $wgUser; |
— | — | @@ -38,6 +39,7 @@ |
39 | 40 | // but the db allows multiples separated by commas. |
40 | 41 | $this->mRestrictions[$action] = implode( '', $this->mTitle->getRestrictions( $action ) ); |
41 | 42 | } |
| 43 | + $this->mCascade = $this->mTitle->getRestrictionCascadingFlags() & 1; |
42 | 44 | } |
43 | 45 | |
44 | 46 | // The form will be available in read-only to show levels. |
— | — | @@ -48,6 +50,7 @@ |
49 | 51 | |
50 | 52 | if( $wgRequest->wasPosted() ) { |
51 | 53 | $this->mReason = $wgRequest->getText( 'mwProtect-reason' ); |
| 54 | + $this->mCascade = $wgRequest->getBool( 'mwProtect-cascade' ); |
52 | 55 | foreach( $wgRestrictionTypes as $action ) { |
53 | 56 | $val = $wgRequest->getVal( "mwProtect-level-$action" ); |
54 | 57 | if( isset( $val ) && in_array( $val, $wgRestrictionLevels ) ) { |
— | — | @@ -101,7 +104,7 @@ |
102 | 105 | throw new FatalError( wfMsg( 'sessionfailure' ) ); |
103 | 106 | } |
104 | 107 | |
105 | | - $ok = $this->mArticle->updateRestrictions( $this->mRestrictions, $this->mReason ); |
| 108 | + $ok = $this->mArticle->updateRestrictions( $this->mRestrictions, $this->mReason, $this->mCascade ); |
106 | 109 | if( !$ok ) { |
107 | 110 | throw new FatalError( "Unknown error at restriction save time." ); |
108 | 111 | } |
— | — | @@ -148,6 +151,11 @@ |
149 | 152 | $out .= "</tbody>\n"; |
150 | 153 | $out .= "</table>\n"; |
151 | 154 | |
| 155 | + global $wgEnableCascadingProtection; |
| 156 | + |
| 157 | + if ($wgEnableCascadingProtection) |
| 158 | + $out .= $this->buildCascadeInput(); |
| 159 | + |
152 | 160 | if( !$this->disabled ) { |
153 | 161 | $out .= "<table>\n"; |
154 | 162 | $out .= "<tbody>\n"; |
— | — | @@ -205,6 +213,13 @@ |
206 | 214 | 'id' => $id ) ); |
207 | 215 | } |
208 | 216 | |
| 217 | + function buildCascadeInput() { |
| 218 | + $id = 'mwProtect-cascade'; |
| 219 | + $ci = wfCheckLabel( wfMsg( 'protect-cascade' ), $id, $id, $this->mCascade, array ()); |
| 220 | + |
| 221 | + return $ci; |
| 222 | + } |
| 223 | + |
209 | 224 | function buildSubmit() { |
210 | 225 | return wfElement( 'input', array( |
211 | 226 | 'type' => 'submit', |
Index: trunk/phase3/includes/Article.php |
— | — | @@ -252,7 +252,6 @@ |
253 | 253 | 'page_id', |
254 | 254 | 'page_namespace', |
255 | 255 | 'page_title', |
256 | | - 'page_restrictions', |
257 | 256 | 'page_counter', |
258 | 257 | 'page_is_redirect', |
259 | 258 | 'page_is_new', |
— | — | @@ -305,8 +304,6 @@ |
306 | 305 | $lc->addGoodLinkObj( $data->page_id, $this->mTitle ); |
307 | 306 | |
308 | 307 | $this->mTitle->mArticleID = $data->page_id; |
309 | | - $this->mTitle->loadRestrictions( $data->page_restrictions ); |
310 | | - $this->mTitle->mRestrictionsLoaded = true; |
311 | 308 | |
312 | 309 | $this->mCounter = $data->page_counter; |
313 | 310 | $this->mTouched = wfTimestamp( TS_MW, $data->page_touched ); |
— | — | @@ -795,7 +792,7 @@ |
796 | 793 | $wgOut->addParserOutputNoText( $parseout ); |
797 | 794 | } else if ( $pcache ) { |
798 | 795 | # Display content and save to parser cache |
799 | | - $wgOut->addPrimaryWikiText( $text, $this ); |
| 796 | + $this->outputWikiText( $text ); |
800 | 797 | } else { |
801 | 798 | # Display content, don't attempt to save to parser cache |
802 | 799 | # Don't show section-edit links on old revisions... this way lies madness. |
— | — | @@ -803,7 +800,7 @@ |
804 | 801 | $oldEditSectionSetting = $wgOut->parserOptions()->setEditSection( false ); |
805 | 802 | } |
806 | 803 | # Display content and don't save to parser cache |
807 | | - $wgOut->addPrimaryWikiText( $text, $this, false ); |
| 804 | + $this->outputWikiText( $text, false ); |
808 | 805 | |
809 | 806 | if( !$this->isCurrent() ) { |
810 | 807 | $wgOut->parserOptions()->setEditSection( $oldEditSectionSetting ); |
— | — | @@ -970,7 +967,6 @@ |
971 | 968 | 'page_namespace' => $this->mTitle->getNamespace(), |
972 | 969 | 'page_title' => $this->mTitle->getDBkey(), |
973 | 970 | 'page_counter' => 0, |
974 | | - 'page_restrictions' => $restrictions, |
975 | 971 | 'page_is_redirect' => 0, # Will set this shortly... |
976 | 972 | 'page_is_new' => 1, |
977 | 973 | 'page_random' => wfRandom(), |
— | — | @@ -1635,7 +1631,7 @@ |
1636 | 1632 | * @param string $reason |
1637 | 1633 | * @return bool true on success |
1638 | 1634 | */ |
1639 | | - function updateRestrictions( $limit = array(), $reason = '' ) { |
| 1635 | + function updateRestrictions( $limit = array(), $reason = '', $cascade = 0 ) { |
1640 | 1636 | global $wgUser, $wgRestrictionTypes, $wgContLang; |
1641 | 1637 | |
1642 | 1638 | $id = $this->mTitle->getArticleID(); |
— | — | @@ -1653,6 +1649,7 @@ |
1654 | 1650 | $updated = Article::flattenRestrictions( $limit ); |
1655 | 1651 | |
1656 | 1652 | $changed = ( $current != $updated ); |
| 1653 | + $changed = $changed || ($this->mTitle->getRestrictionCascadingFlags() != $cascade); |
1657 | 1654 | $protect = ( $updated != '' ); |
1658 | 1655 | |
1659 | 1656 | # If nothing's changed, do nothing |
— | — | @@ -1669,23 +1666,32 @@ |
1670 | 1667 | $comment .= " [$updated]"; |
1671 | 1668 | $nullRevision = Revision::newNullRevision( $dbw, $id, $comment, true ); |
1672 | 1669 | $nullRevId = $nullRevision->insertOn( $dbw ); |
| 1670 | + |
| 1671 | + # Update restrictions table |
| 1672 | + foreach( $limit as $action => $restrictions ) { |
| 1673 | + if ($restrictions != '' ) { |
| 1674 | + $dbw->replace( 'page_restrictions', array( 'pr_pagetype'), |
| 1675 | + array( 'pr_page' => $id, 'pr_type' => $action |
| 1676 | + , 'pr_level' => $restrictions, 'pr_cascade' => $cascade ), __METHOD__ ); |
| 1677 | + } else { |
| 1678 | + $dbw->delete( 'page_restrictions', array( 'pr_page' => $id, |
| 1679 | + 'pr_type' => $action ), __METHOD__ ); |
| 1680 | + } |
| 1681 | + } |
1673 | 1682 | |
1674 | | - # Update page record |
1675 | | - $dbw->update( 'page', |
1676 | | - array( /* SET */ |
1677 | | - 'page_touched' => $dbw->timestamp(), |
1678 | | - 'page_restrictions' => $updated, |
1679 | | - 'page_latest' => $nullRevId |
1680 | | - ), array( /* WHERE */ |
1681 | | - 'page_id' => $id |
1682 | | - ), 'Article::protect' |
1683 | | - ); |
1684 | 1683 | wfRunHooks( 'ArticleProtectComplete', array( &$this, &$wgUser, $limit, $reason ) ); |
1685 | 1684 | |
1686 | 1685 | # Update the protection log |
1687 | 1686 | $log = new LogPage( 'protect' ); |
| 1687 | + |
| 1688 | + $cascade_description = ''; |
| 1689 | + |
| 1690 | + if ($cascade) { |
| 1691 | + $cascade_description = ' ['.wfMsg('protect-summary-cascade').']'; |
| 1692 | + } |
| 1693 | + |
1688 | 1694 | if( $protect ) { |
1689 | | - $log->addEntry( 'protect', $this->mTitle, trim( $reason . " [$updated]" ) ); |
| 1695 | + $log->addEntry( 'protect', $this->mTitle, trim( $reason . " [$updated]$cascade_description" ) ); |
1690 | 1696 | } else { |
1691 | 1697 | $log->addEntry( 'unprotect', $this->mTitle, $reason ); |
1692 | 1698 | } |
— | — | @@ -2010,6 +2016,9 @@ |
2011 | 2017 | ), __METHOD__ |
2012 | 2018 | ); |
2013 | 2019 | |
| 2020 | + # Delete restrictions for it |
| 2021 | + $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ ); |
| 2022 | + |
2014 | 2023 | # Now that it's safely backed up, delete it |
2015 | 2024 | $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__); |
2016 | 2025 | |
— | — | @@ -2785,6 +2794,67 @@ |
2786 | 2795 | |
2787 | 2796 | return $summary; |
2788 | 2797 | } |
| 2798 | + |
| 2799 | + /** |
| 2800 | + * Add the primary page-view wikitext to the output buffer |
| 2801 | + * Saves the text into the parser cache if possible. |
| 2802 | + * |
| 2803 | + * @param string $text |
| 2804 | + * @param Article $article |
| 2805 | + * @param bool $cache |
| 2806 | + */ |
| 2807 | + public function outputWikiText( $text, $cache = true ) { |
| 2808 | + global $wgParser, $wgUser, $wgOut; |
| 2809 | + |
| 2810 | + $article = $this; |
| 2811 | + |
| 2812 | + $popts = $wgOut->parserOptions(); |
| 2813 | + $popts->setTidy(true); |
| 2814 | + $parserOutput = $wgParser->parse( $text, $article->mTitle, |
| 2815 | + $popts, true, true, $this->mRevisionId ); |
| 2816 | + $popts->setTidy(false); |
| 2817 | + if ( $cache && $article && $parserOutput->getCacheTime() != -1 ) { |
| 2818 | + $parserCache =& ParserCache::singleton(); |
| 2819 | + $parserCache->save( $parserOutput, $article, $wgUser ); |
| 2820 | + } |
| 2821 | + |
| 2822 | + if ( !wfReadOnly() ) { |
| 2823 | + |
| 2824 | + # Get templates from templatelinks |
| 2825 | + $tlTemplates_titles = $this->getUsedTemplates(); |
| 2826 | + |
| 2827 | + $tlTemplates = array (); |
| 2828 | + foreach( $tlTemplates_titles as $template_title) { |
| 2829 | + $tlTemplates[] = $template_title->getDBkey(); |
| 2830 | + } |
| 2831 | + |
| 2832 | + # Get templates from parser output. |
| 2833 | + $poTemplates_allns = $parserOutput->getTemplates(); |
| 2834 | + |
| 2835 | + $poTemplates = array (); |
| 2836 | + foreach ( $poTemplates_allns as $ns_templates ) { |
| 2837 | + $poTemplates = array_merge( $poTemplates, $ns_templates ); |
| 2838 | + } |
| 2839 | + |
| 2840 | + # Get the diff |
| 2841 | + $templates_diff = array_diff( $poTemplates, $tlTemplates ); |
| 2842 | + |
| 2843 | + if ( count( $templates_diff ) > 0 ) { |
| 2844 | + # Whee, link updates time. |
| 2845 | + $u = new LinksUpdate( $this->mTitle, $parserOutput ); |
| 2846 | + |
| 2847 | + $dbw =& wfGetDb( DB_MASTER ); |
| 2848 | + $dbw->begin(); |
| 2849 | + |
| 2850 | + $u->doUpdate(); |
| 2851 | + |
| 2852 | + $dbw->commit(); |
| 2853 | + } |
| 2854 | + } |
| 2855 | + |
| 2856 | + $wgOut->addParserOutput( $parserOutput ); |
| 2857 | + } |
| 2858 | + |
2789 | 2859 | } |
2790 | 2860 | |
2791 | 2861 | ?> |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -315,14 +315,26 @@ |
316 | 316 | $this->addWikiTextTitle($text, $title, $linestart); |
317 | 317 | } |
318 | 318 | |
319 | | - private function addWikiTextTitle($text, &$title, $linestart) { |
| 319 | + function addWikiTextTitleTidy($text, &$title, $linestart = true) { |
| 320 | + addWikiTextTitle( $text, $title, $linestart, true ); |
| 321 | + } |
| 322 | + |
| 323 | + public function addWikiTextTitle($text, &$title, $linestart, $tidy = false) { |
320 | 324 | global $wgParser; |
| 325 | + |
321 | 326 | $fname = 'OutputPage:addWikiTextTitle'; |
322 | 327 | wfProfileIn($fname); |
| 328 | + |
323 | 329 | wfIncrStats('pcache_not_possible'); |
324 | | - $parserOutput = $wgParser->parse( $text, $title, $this->parserOptions(), |
| 330 | + |
| 331 | + $popts = $this->parserOptions(); |
| 332 | + $popts->setTidy($tidy); |
| 333 | + |
| 334 | + $parserOutput = $wgParser->parse( $text, $title, $popts, |
325 | 335 | $linestart, true, $this->mRevisionId ); |
| 336 | + |
326 | 337 | $this->addParserOutput( $parserOutput ); |
| 338 | + |
327 | 339 | wfProfileOut($fname); |
328 | 340 | } |
329 | 341 | |
— | — | @@ -366,6 +378,7 @@ |
367 | 379 | * @param string $text |
368 | 380 | * @param Article $article |
369 | 381 | * @param bool $cache |
| 382 | + * @deprecated Use Article::outputWikitext |
370 | 383 | */ |
371 | 384 | public function addPrimaryWikiText( $text, $article, $cache = true ) { |
372 | 385 | global $wgParser, $wgUser; |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -1745,6 +1745,8 @@ |
1746 | 1746 | 'protect-default' => '(default)', |
1747 | 1747 | 'protect-level-autoconfirmed' => 'Block unregistered users', |
1748 | 1748 | 'protect-level-sysop' => 'Sysops only', |
| 1749 | +'protect-summary-cascade' => 'cascading', |
| 1750 | +'protect-cascade' => 'Cascading protection - protect any pages transcluded in this page.', |
1749 | 1751 | |
1750 | 1752 | # restrictions (nouns) |
1751 | 1753 | 'restriction-edit' => 'Edit', |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -39,6 +39,10 @@ |
40 | 40 | starts page output (http://lists.wikimedia.org/pipermail/wikitech-l/2007-January/028554.html) |
41 | 41 | * Fix SpecialVersion->formatCredits input. Version and Url parameters should be null |
42 | 42 | to be treated properly with isset. |
| 43 | +* Branch page_restrictions column out into its own table, also creating a "cascading protection" |
| 44 | + feature, which automagically disallows edits to pages transcluded into a page protected with |
| 45 | + this new option. Various other code tidiness fixes and refactoring in the log messages of |
| 46 | + branches/werdna/restrictions-separation. |
43 | 47 | |
44 | 48 | == Languages updated == |
45 | 49 | |
Index: trunk/phase3/maintenance/updaters.inc |
— | — | @@ -37,6 +37,7 @@ |
38 | 38 | array( 'filearchive', 'patch-filearchive.sql' ), |
39 | 39 | array( 'redirect', 'patch-redirect.sql' ), |
40 | 40 | array( 'querycachetwo', 'patch-querycachetwo.sql' ), |
| 41 | +# array( 'page_restrictions', 'patch-page_restrictions.sql' ), |
41 | 42 | ); |
42 | 43 | |
43 | 44 | $wgNewFields = array( |
— | — | @@ -905,6 +906,8 @@ |
906 | 907 | |
907 | 908 | do_backlinking_indices_update(); flush(); |
908 | 909 | |
| 910 | + do_restrictions_update(); flush (); |
| 911 | + |
909 | 912 | echo "Deleting old default messages..."; flush(); |
910 | 913 | deleteDefaultMessages(); |
911 | 914 | echo "Done\n"; flush(); |
— | — | @@ -925,6 +928,70 @@ |
926 | 929 | } |
927 | 930 | } |
928 | 931 | |
| 932 | +function do_restrictions_update() { |
| 933 | + # Adding page_restrictions table, obsoleting page.page_restrictions. |
| 934 | + # Migrating old restrictions to new table |
| 935 | + # -- Andrew Garrett, January 2007. |
| 936 | + |
| 937 | + global $wgDatabase; |
| 938 | + |
| 939 | + $name = 'page_restrictions'; |
| 940 | + $patch = 'patch-page_restrictions.sql'; |
| 941 | + |
| 942 | + if ( $wgDatabase->tableExists( $name ) ) { |
| 943 | + echo "...$name table already exists.\n"; |
| 944 | + } else { |
| 945 | + echo "Creating $name table..."; |
| 946 | + dbsource( archive($patch), $wgDatabase ); |
| 947 | + echo "ok\n"; |
| 948 | + |
| 949 | + echo "Migrating old restrictions to new table..."; |
| 950 | + |
| 951 | + $res = $wgDatabase->select( 'page', array( 'page_id', 'page_restrictions' ), array("page_restrictions!=''", "page_restrictions!='edit=:move='"), __METHOD__ ); |
| 952 | + |
| 953 | + $count = 0; |
| 954 | + |
| 955 | + while ($row = $wgDatabase->fetchObject($res) ) { |
| 956 | + $count = ($count + 1) % 100; |
| 957 | + |
| 958 | + if ($count == 0) { |
| 959 | + if ( function_exists( 'wfWaitForSlaves' ) ) { |
| 960 | + wfWaitForSlaves( 10 ); |
| 961 | + } else { |
| 962 | + sleep( 1 ); |
| 963 | + } |
| 964 | + } |
| 965 | + |
| 966 | + # Figure out what the restrictions are.. |
| 967 | + $id = $row->page_id; |
| 968 | + $flatterrestrictions = $row->page_restrictions; |
| 969 | + |
| 970 | + $flatrestrictions = explode( ':', $flatterrestrictions ); |
| 971 | + |
| 972 | + $restrictions = array (); |
| 973 | + |
| 974 | + foreach( $flatrestrictions as $restriction ) { |
| 975 | + $thisrestriction = explode('=', $restriction); |
| 976 | + |
| 977 | + $restriction_type = $thisrestriction[0]; |
| 978 | + $restriction_level = $thisrestriction[1]; |
| 979 | + |
| 980 | + $restrictions[$restriction_type] = $restriction_level; |
| 981 | + |
| 982 | + if ($restriction_level != '') { |
| 983 | + |
| 984 | + $wgDatabase->insert( 'page_restrictions', array ( 'pr_page' => $id, |
| 985 | + 'pr_type' => $restriction_type, |
| 986 | + 'pr_level' => $restriction_level, |
| 987 | + 'pr_cascade' => 0 ), __METHOD ); |
| 988 | + } |
| 989 | + } |
| 990 | + } |
| 991 | + print "ok\n"; |
| 992 | + } |
| 993 | + |
| 994 | +} |
| 995 | + |
929 | 996 | function do_postgres_updates() { |
930 | 997 | global $wgDatabase, $wgVersion, $wgDBmwschema; |
931 | 998 | |
Index: trunk/phase3/maintenance/tables.sql |
— | — | @@ -1075,4 +1075,27 @@ |
1076 | 1076 | |
1077 | 1077 | ) TYPE=InnoDB; |
1078 | 1078 | |
| 1079 | +--- Used for storing page restrictions (i.e. protection levels) |
| 1080 | +CREATE TABLE /*$wgDBprefix*/page_restrictions ( |
| 1081 | + -- Page to apply restrictions to (Foreign Key to page). |
| 1082 | + pr_page int(8) NOT NULL, |
| 1083 | + -- The protection type (edit, move, etc) |
| 1084 | + pr_type varchar(255) NOT NULL, |
| 1085 | + -- The protection level (Sysop, autoconfirmed, etc) |
| 1086 | + pr_level varchar(255) NOT NULL, |
| 1087 | + -- Whether or not to cascade the protection down to pages transcluded. |
| 1088 | + pr_cascade tinyint(4) NOT NULL, |
| 1089 | + -- Field for future support of per-user restriction. |
| 1090 | + pr_user int(8) NULL, |
| 1091 | + -- Field for future support of time-limited protection. |
| 1092 | + pr_expiry char(14) binary NULL, |
| 1093 | + |
| 1094 | + PRIMARY KEY (pr_page,pr_type), |
| 1095 | + |
| 1096 | + KEY pr_page (pr_page), |
| 1097 | + KEY pr_typelevel (pr_type,pr_level), |
| 1098 | + KEY pr_level (pr_level), |
| 1099 | + KEY pr_cascade (pr_cascade) |
| 1100 | +) TYPE=InnoDB; |
| 1101 | + |
1079 | 1102 | -- vim: sw=2 sts=2 et |