Index: trunk/extensions/ApprovedRevs/ApprovedRevs_body.php |
— | — | @@ -0,0 +1,136 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +if (!defined('MEDIAWIKI')) die(); |
| 5 | + |
| 6 | +/** |
| 7 | + * Main class for the Approved Revs extension. |
| 8 | + * |
| 9 | + * @file |
| 10 | + * @ingroup Extensions |
| 11 | + * |
| 12 | + * @author Yaron Koren |
| 13 | + */ |
| 14 | + |
| 15 | +class ApprovedRevs { |
| 16 | + |
| 17 | + /** |
| 18 | + * Gets the approved revision ID for this page, or null if there isn't |
| 19 | + * one. |
| 20 | + */ |
| 21 | + public static function getApprovedRevID( $title ) { |
| 22 | + $dbr = wfGetDB( DB_SLAVE ); |
| 23 | + $page_id = $title->getArticleId(); |
| 24 | + $rev_id = $dbr->selectField( 'approved_revs', 'rev_id', array( 'page_id' => $page_id ) ); |
| 25 | + return $rev_id; |
| 26 | + } |
| 27 | + |
| 28 | + /** |
| 29 | + * Returns whether or not this page has a revision ID. |
| 30 | + */ |
| 31 | + public static function hasApprovedRevision( $title ) { |
| 32 | + $revision_id = self::getApprovedRevID( $title ); |
| 33 | + return ( ! empty( $revision_id ) ); |
| 34 | + } |
| 35 | + |
| 36 | + /** |
| 37 | + * Returns the content of the approved revision of this page, or null |
| 38 | + * if there isn't one. |
| 39 | + */ |
| 40 | + public static function getApprovedContent( $title ) { |
| 41 | + $revision_id = ApprovedRevs::getApprovedRevID( $title ); |
| 42 | + if ( empty( $revision_id ) ) { |
| 43 | + return null; |
| 44 | + } |
| 45 | + $article = new Article( $title, $revision_id ); |
| 46 | + return( $article->getContent() ); |
| 47 | + } |
| 48 | + |
| 49 | + /** |
| 50 | + * Returns whether this page is in a namespace that the Approved Revs |
| 51 | + * extension doesn't support. |
| 52 | + */ |
| 53 | + public static function hasUnsupportedNamespace( $title ) { |
| 54 | + global $egApprovedRevsUnsupportedNamespaces; |
| 55 | + $unsupported_namespaces = $egApprovedRevsUnsupportedNamespaces; |
| 56 | + $unsupported_namespaces[] = NS_FILE; |
| 57 | + $unsupported_namespaces[] = NS_CATEGORY; |
| 58 | + return( in_array( $title->getNamespace(), $unsupported_namespaces ) ); |
| 59 | + } |
| 60 | + |
| 61 | + /** |
| 62 | + * Sets a certain revision as the approved one for this page in the |
| 63 | + * approved_revs DB table; calls a "links update" on this revision |
| 64 | + * so that category information can be stored correctly, as well as |
| 65 | + * info for extensions such as Semantic MediaWiki; and logs the action. |
| 66 | + */ |
| 67 | + public static function setApprovedRevID( $title, $rev_id ) { |
| 68 | + $dbr = wfGetDB( DB_MASTER ); |
| 69 | + $page_id = $title->getArticleId(); |
| 70 | + $old_rev_id = $dbr->selectField( 'approved_revs', 'rev_id', array( 'page_id' => $page_id ) ); |
| 71 | + if ( $old_rev_id ) { |
| 72 | + $dbr->update( 'approved_revs', array( 'rev_id' => $rev_id ), array( 'page_id' => $page_id ) ); |
| 73 | + } else { |
| 74 | + $dbr->insert( 'approved_revs', array( 'page_id' => $page_id, 'rev_id' => $rev_id ) ); |
| 75 | + } |
| 76 | + |
| 77 | + $parser = new Parser(); |
| 78 | + $parser->setTitle( $title ); |
| 79 | + $article = new Article( $title, $rev_id ); |
| 80 | + $text = $article->getContent(); |
| 81 | + $options = new ParserOptions(); |
| 82 | + $parser->parse( $text, $title, $options, true, true, $rev_id); |
| 83 | + $u = new LinksUpdate( $title, $parser->getOutput() ); |
| 84 | + $u->doUpdate(); |
| 85 | + |
| 86 | + $log = new LogPage( 'approval' ); |
| 87 | + $rev_url = $title->getFullURL( array( 'old_id' => $rev_id ) ); |
| 88 | + $rev_link = Xml::element( |
| 89 | + 'a', |
| 90 | + array( 'href' => $rev_url ), |
| 91 | + $rev_id |
| 92 | + ); |
| 93 | + $logParams = array( $rev_link ); |
| 94 | + $log->addEntry( |
| 95 | + 'approve', |
| 96 | + $title, |
| 97 | + '', |
| 98 | + $logParams |
| 99 | + ); |
| 100 | + |
| 101 | + wfRunHooks( 'ApprovedRevsRevisionApproved', array( $parser, $title, $rev_id ) ); |
| 102 | + } |
| 103 | + |
| 104 | + public static function deleteRevisionApproval( $title ) { |
| 105 | + $dbr = wfGetDB( DB_MASTER ); |
| 106 | + $page_id = $title->getArticleId(); |
| 107 | + $dbr->delete( 'approved_revs', array( 'page_id' => $page_id ) ); |
| 108 | + } |
| 109 | + |
| 110 | + /** |
| 111 | + * Unsets the approved revision for this page in the approved_revs DB |
| 112 | + * table; calls a "links update" on this page so that category |
| 113 | + * information can be stored correctly, as well as info for |
| 114 | + * extensions such as Semantic MediaWiki; and logs the action. |
| 115 | + */ |
| 116 | + public static function unsetApproval( $title ) { |
| 117 | + self::deleteRevisionApproval( $title ); |
| 118 | + |
| 119 | + $parser = new Parser(); |
| 120 | + $parser->setTitle( $title ); |
| 121 | + $article = new Article( $title ); |
| 122 | + $text = $article->getContent(); |
| 123 | + $options = new ParserOptions(); |
| 124 | + $parser->parse( $text, $title, $options ); |
| 125 | + $u = new LinksUpdate( $title, $parser->getOutput() ); |
| 126 | + $u->doUpdate(); |
| 127 | + |
| 128 | + $log = new LogPage( 'approval' ); |
| 129 | + $log->addEntry( |
| 130 | + 'unapprove', |
| 131 | + $title, |
| 132 | + '' |
| 133 | + ); |
| 134 | + |
| 135 | + wfRunHooks( 'ApprovedRevsRevisionUnapproved', array( $parser, $title ) ); |
| 136 | + } |
| 137 | +} |
Index: trunk/extensions/ApprovedRevs/ApprovedRevs.i18n.php |
— | — | @@ -0,0 +1,32 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Internationalization file for the Approved Revs extension. |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | +*/ |
| 9 | + |
| 10 | +$messages = array(); |
| 11 | + |
| 12 | +/** English |
| 13 | + * @author Yaron Koren |
| 14 | + */ |
| 15 | +$messages['en'] = array( |
| 16 | + // user messages |
| 17 | + 'approvedrevs-desc' => 'Lets administrators set a single revision of a page as approved', |
| 18 | + 'approvedrevs-logname' => 'Revision approval log', |
| 19 | + 'approvedrevs-logdesc' => 'This is the log of revisions that have been approved.', |
| 20 | + 'approvedrevs-approve' => 'approve', |
| 21 | + 'approvedrevs-unapprove' => 'unapprove', |
| 22 | + 'approvedrevs-approvesuccess' => 'This revision of the page has been set as the approved version.', |
| 23 | + 'approvedrevs-unapprovesuccess' => 'There is no longer an approved version for this page. Instead, the most recent revision will be shown.', |
| 24 | + 'approvedrevs-approveaction' => 'set $2 as the approved revision for "[[$1]]"', |
| 25 | + 'approvedrevs-unapproveaction' => 'unset approved revision for "[[$1]]"', |
| 26 | + 'approvedrevs-notlatest' => 'This is the approved revision of this page; it is not the most recent.', |
| 27 | + 'approvedrevs-approvedandlatest' => 'This is the approved revision of this page, as well as being the most recent.', |
| 28 | + 'approvedrevs-viewlatest' => 'View most recent revision.', |
| 29 | + 'approvedpages' => 'Approved pages', |
| 30 | + 'approvedrevs-approvedpages-docu' => 'The following are the pages in the wiki that have an approved revision.', |
| 31 | + 'right-approverevisions' => 'Set a certain revision of a wiki page as approved', |
| 32 | + 'right-viewlinktolatest' => 'View explanatory text at the top of pages that have an approved revision', |
| 33 | +); |
Index: trunk/extensions/ApprovedRevs/ApprovedRevs.php |
— | — | @@ -0,0 +1,61 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +if (!defined('MEDIAWIKI')) die(); |
| 5 | + |
| 6 | +/** |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + * |
| 10 | + * @author Yaron Koren |
| 11 | + */ |
| 12 | + |
| 13 | +define( 'APPROVED_REVS_VERSION', '0.1' ); |
| 14 | + |
| 15 | +// credits |
| 16 | +$wgExtensionCredits['other'][] = array( |
| 17 | + 'name' => 'Approved Revs', |
| 18 | + 'version' => APPROVED_REVS_VERSION, |
| 19 | + 'author' => 'Yaron Koren', |
| 20 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:Approved_Revs', |
| 21 | + 'descriptionmsg' => 'approvedrevs-desc' |
| 22 | +); |
| 23 | + |
| 24 | +// global variables |
| 25 | +$egApprovedRevsIP = dirname( __FILE__ ) . '/'; |
| 26 | +$egApprovedRevsExcludedNamespaces = array(); |
| 27 | + |
| 28 | +// internationalization |
| 29 | +$wgExtensionMessagesFiles['ApprovedRevs'] = $egApprovedRevsIP . 'ApprovedRevs.i18n.php'; |
| 30 | + |
| 31 | +// register all classes |
| 32 | +$wgAutoloadClasses['ApprovedRevs'] = $egApprovedRevsIP . 'ApprovedRevs_body.php'; |
| 33 | +$wgAutoloadClasses['ApprovedRevsHooks'] = $egApprovedRevsIP . 'ApprovedRevs.hooks.php'; |
| 34 | +$wgSpecialPages['ApprovedPages'] = 'ARApprovedPages'; |
| 35 | +$wgAutoloadClasses['ARApprovedPages'] = $egApprovedRevsIP . 'AR_ApprovedPages.php'; |
| 36 | +$wgSpecialPageGroups['ApprovedPages'] = 'pages'; |
| 37 | + |
| 38 | +// hooks |
| 39 | +$wgHooks['ParserBeforeInternalParse'][] = 'ApprovedRevsHooks::setApprovedRevForParsing'; |
| 40 | +$wgHooks['ArticleFromTitle'][] = 'ApprovedRevsHooks::showApprovedRevision'; |
| 41 | +$wgHooks['DisplayOldSubtitle'][] = 'ApprovedRevsHooks::setSubtitle'; |
| 42 | +$wgHooks['SkinTemplateNavigation'][] = 'ApprovedRevsHooks::changeEditLink'; |
| 43 | +$wgHooks['PageHistoryBeforeList'][] = 'ApprovedRevsHooks::storeApprovedRevisionForHistoryPage'; |
| 44 | +$wgHooks['PageHistoryLineEnding'][] = 'ApprovedRevsHooks::addApprovalLink'; |
| 45 | +$wgHooks['UnknownAction'][] = 'ApprovedRevsHooks::setAsApproved'; |
| 46 | +$wgHooks['UnknownAction'][] = 'ApprovedRevsHooks::unsetAsApproved'; |
| 47 | +$wgHooks['BeforeParserFetchTemplateAndtitle'][] = 'ApprovedRevsHooks::setTranscludedPageRev'; |
| 48 | +$wgHooks['ArticleDeleteComplete'][] = 'ApprovedRevsHooks::deleteRevisionApproval'; |
| 49 | +$wgHooks['AdminLinks'][] = 'ApprovedRevsHooks::addToAdminLinks'; |
| 50 | + |
| 51 | +// logging |
| 52 | +$wgLogTypes['approval'] = 'approval'; |
| 53 | +$wgLogNames['approval'] = 'approvedrevs-logname'; |
| 54 | +$wgLogHeaders['approval'] = 'approvedrevs-logdesc'; |
| 55 | +$wgLogActions['approval/approve'] = 'approvedrevs-approveaction'; |
| 56 | +$wgLogActions['approval/unapprove'] = 'approvedrevs-unapproveaction'; |
| 57 | + |
| 58 | +// user rights |
| 59 | +$wgAvailableRights[] = 'approverevisions'; |
| 60 | +$wgGroupPermissions['sysop']['approverevisions'] = true; |
| 61 | +$wgAvailableRights[] = 'viewlinktolatest'; |
| 62 | +$wgGroupPermissions['*']['viewlinktolatest'] = true; |
Index: trunk/extensions/ApprovedRevs/AR_ApprovedPages.php |
— | — | @@ -0,0 +1,66 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Special page that lists all pages that have an approved revision. |
| 5 | + * |
| 6 | + * @author Yaron Koren |
| 7 | + */ |
| 8 | + |
| 9 | +if ( !defined( 'MEDIAWIKI' ) ) die(); |
| 10 | + |
| 11 | +class ARApprovedPages extends SpecialPage { |
| 12 | + |
| 13 | + /** |
| 14 | + * Constructor |
| 15 | + */ |
| 16 | + function ARApprovedPages() { |
| 17 | + SpecialPage::SpecialPage( 'ApprovedPages' ); |
| 18 | + wfLoadExtensionMessages( 'ApprovedRevs' ); |
| 19 | + } |
| 20 | + |
| 21 | + function execute( $query ) { |
| 22 | + $this->setHeaders(); |
| 23 | + list( $limit, $offset ) = wfCheckLimits(); |
| 24 | + $rep = new ARApprovedPagesPage(); |
| 25 | + return $rep->doQuery( $offset, $limit ); |
| 26 | + } |
| 27 | +} |
| 28 | + |
| 29 | +class ARApprovedPagesPage extends QueryPage { |
| 30 | + function getName() { |
| 31 | + return "ApprovedPages"; |
| 32 | + } |
| 33 | + |
| 34 | + function isExpensive() { return false; } |
| 35 | + |
| 36 | + function isSyndicated() { return false; } |
| 37 | + |
| 38 | + function getPageHeader() { |
| 39 | + $header .= '<p>' . wfMsg( 'approvedrevs-approvedpages-docu' ) . "</p><br />\n"; |
| 40 | + return $header; |
| 41 | + } |
| 42 | + |
| 43 | + function getPageFooter() { |
| 44 | + } |
| 45 | + |
| 46 | + function getSQL() { |
| 47 | + $dbr = wfGetDB( DB_SLAVE ); |
| 48 | + $approved_revs = $dbr->tableName( 'approved_revs' ); |
| 49 | + $page = $dbr->tableName( 'page' ); |
| 50 | + // QueryPage uses the value from this SQL in an ORDER clause, |
| 51 | + // so return page_title as title. |
| 52 | + return "SELECT 'Page' AS type, |
| 53 | + p.page_title AS title, |
| 54 | + p.page_id AS value |
| 55 | + FROM $approved_revs ar JOIN $page p |
| 56 | + ON ar.page_id = p.page_id"; |
| 57 | + } |
| 58 | + |
| 59 | + function sortDescending() { |
| 60 | + return false; |
| 61 | + } |
| 62 | + |
| 63 | + function formatResult( $skin, $result ) { |
| 64 | + $title = Title::newFromId( $result->value ); |
| 65 | + return $skin->makeLinkObj( $title ); |
| 66 | + } |
| 67 | +} |
Index: trunk/extensions/ApprovedRevs/ApprovedRevs.hooks.php |
— | — | @@ -0,0 +1,280 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +if ( ! defined( 'MEDIAWIKI' ) ) die(); |
| 5 | + |
| 6 | +/** |
| 7 | + * Functions for the Approved Revs extension called by hooks in the MediaWiki |
| 8 | + * code. |
| 9 | + * |
| 10 | + * @file |
| 11 | + * @ingroup Extensions |
| 12 | + * |
| 13 | + * @author Yaron Koren |
| 14 | + */ |
| 15 | + |
| 16 | +class ApprovedRevsHooks { |
| 17 | + |
| 18 | + static public function setApprovedRevForParsing( &$parser, &$text, &$stripState ) { |
| 19 | + global $wgRequest; |
| 20 | + $action = $wgRequest->getVal( 'action' ); |
| 21 | + if ( $action == 'submit' ) { |
| 22 | + $title = $parser->getTitle(); |
| 23 | + $approvedText = ApprovedRevs::getApprovedContent( $title ); |
| 24 | + if ( ! is_null( $approvedText ) ) { |
| 25 | + $text = $approvedText; |
| 26 | + } |
| 27 | + } |
| 28 | + return true; |
| 29 | + } |
| 30 | + |
| 31 | + /** |
| 32 | + * Return the approved revision of the page, if there is one, and if |
| 33 | + * the page is simply being viewed, and if no specific revision has |
| 34 | + * been requested. |
| 35 | + */ |
| 36 | + static function showApprovedRevision( &$title, &$article ) { |
| 37 | + // if a revision ID is set, exit |
| 38 | + if ( $title->mArticleID > -1 ) { |
| 39 | + return true; |
| 40 | + } |
| 41 | + // if it's any action other than viewing, exit |
| 42 | + global $wgRequest; |
| 43 | + if ( $wgRequest->getCheck( 'action' ) && |
| 44 | + $wgRequest->getVal( 'action' ) != 'view' && |
| 45 | + $wgRequest->getVal( 'action' ) != 'purge' && |
| 46 | + $wgRequest->getVal( 'action' ) != 'render' ) { |
| 47 | + return true; |
| 48 | + } |
| 49 | + |
| 50 | + $revisionID = ApprovedRevs::getApprovedRevID( $title ); |
| 51 | + if ( ! empty( $revisionID ) ) { |
| 52 | + $article = new Article( $title, $revisionID ); |
| 53 | + } |
| 54 | + return true; |
| 55 | + } |
| 56 | + |
| 57 | + /** |
| 58 | + * If user is viewing the page via its main URL, and what they're |
| 59 | + * seeing is the approved revision of the page, remove the standard |
| 60 | + * subtitle shown for all non-latest revisions, and replace it with |
| 61 | + * either nothing or a message explaining the situation, depending |
| 62 | + * on the user's rights |
| 63 | + */ |
| 64 | + static function setSubtitle( &$article, &$revisionID ) { |
| 65 | + if ( ! ApprovedRevs::hasApprovedRevision( $article->getTitle() ) ) { |
| 66 | + return true; |
| 67 | + } |
| 68 | + |
| 69 | + global $wgRequest; |
| 70 | + if ( $wgRequest->getCheck( 'oldid' ) ) { |
| 71 | + return true; |
| 72 | + } |
| 73 | + |
| 74 | + if ( ! $article->getTitle()->userCan( 'viewlinktolatest' ) ) { |
| 75 | + return false; |
| 76 | + } |
| 77 | + |
| 78 | + if ( $revisionID == $article->getLatest() ) { |
| 79 | + $text = wfMsg( 'approvedrevs-approvedandlatest' ); |
| 80 | + } else { |
| 81 | + $text = wfMsg( 'approvedrevs-notlatest' ); |
| 82 | + global $wgUser; |
| 83 | + $sk = $wgUser->getSkin(); |
| 84 | + $curRevLink = $sk->link( |
| 85 | + $article->getTitle(), |
| 86 | + wfMsgHtml( 'approvedrevs-viewlatest' ), |
| 87 | + array(), |
| 88 | + array( 'oldid' => $article->getLatest() ), |
| 89 | + array( 'known', 'noclasses' ) |
| 90 | + ); |
| 91 | + $text .= ' ' . $curRevLink; |
| 92 | + } |
| 93 | + global $wgOut; |
| 94 | + $wgOut->setSubtitle( $text ); |
| 95 | + return false; |
| 96 | + } |
| 97 | + |
| 98 | + /** |
| 99 | + * If user is looking at a revision through a main 'view' URL (no |
| 100 | + * revision specified), have the 'edit' tab link to the basic |
| 101 | + * 'action=edit' URL (i.e., the latest revision), no matter which |
| 102 | + * revision they're actually on. |
| 103 | + */ |
| 104 | + static function changeEditLink( &$skin, &$contentActions ) { |
| 105 | + global $wgRequest; |
| 106 | + if ( $wgRequest->getCheck( 'oldid' ) ) { |
| 107 | + return true; |
| 108 | + } |
| 109 | + if ( ApprovedRevs::hasApprovedRevision( $skin->getTitle() ) ) { |
| 110 | + $contentActions['views']['edit']['href'] = $skin->getTitle()->getLocalUrl( array( 'action' => 'edit' ) ); |
| 111 | + } |
| 112 | + return true; |
| 113 | + } |
| 114 | + |
| 115 | + /** |
| 116 | + * Store the approved revision ID, if any, directly in the object |
| 117 | + * for this article - this is called so that a query to the database |
| 118 | + * can be made just once for every view of a history page, instead |
| 119 | + * of for every row. |
| 120 | + */ |
| 121 | + static function storeApprovedRevisionForHistoryPage( &$article ) { |
| 122 | + // this will be null if there's no ID |
| 123 | + $approvedRevID = ApprovedRevs::getApprovedRevID( $article->getTitle() ); |
| 124 | + $article->approvedRevID = $approvedRevID; |
| 125 | + return true; |
| 126 | + } |
| 127 | + |
| 128 | + /** |
| 129 | + * If the user is allowed to make revision approvals, add either an |
| 130 | + * 'approve' or 'unapprove' link to the end of this row in the page |
| 131 | + * history, depending on whether or not this is already the approved |
| 132 | + * revision. If it's the approved revision also add on a "star" |
| 133 | + * icon, regardless of the user. |
| 134 | + */ |
| 135 | + static function addApprovalLink( $historyPage, &$row , &$s ) { |
| 136 | + $title = $historyPage->getTitle(); |
| 137 | + if ( ApprovedRevs::hasUnsupportedNamespace( $title ) ) { |
| 138 | + return true; |
| 139 | + } |
| 140 | + |
| 141 | + $article = $historyPage->getArticle(); |
| 142 | + // use the rev ID field in the $article object, which was |
| 143 | + // stored earlier |
| 144 | + $approvedRevID = $article->approvedRevID; |
| 145 | + if ( $row->rev_id == $approvedRevID ) { |
| 146 | + $s .= '★ '; |
| 147 | + } |
| 148 | + if ( $title->userCan( 'approverevisions' ) ) { |
| 149 | + if ( $row->rev_id == $approvedRevID ) { |
| 150 | + $url = $title->getLocalUrl( |
| 151 | + array( 'action' => 'unapprove' ) |
| 152 | + ); |
| 153 | + $msg = wfMsg( 'approvedrevs-unapprove' ); |
| 154 | + } else { |
| 155 | + $url = $title->getLocalUrl( |
| 156 | + array( 'action' => 'approve', 'oldid' => $row->rev_id ) |
| 157 | + ); |
| 158 | + $msg = wfMsg( 'approvedrevs-approve' ); |
| 159 | + } |
| 160 | + $s .= '(' . Xml::element( |
| 161 | + 'a', |
| 162 | + array( 'href' => $url ), |
| 163 | + $msg |
| 164 | + ) . ')'; |
| 165 | + } |
| 166 | + return true; |
| 167 | + } |
| 168 | + |
| 169 | + /** |
| 170 | + * Handle the 'approve' action, defined for ApprovedRevs - |
| 171 | + * mark the revision as approved, log it, and show a message to |
| 172 | + * the user. |
| 173 | + */ |
| 174 | + static function setAsApproved( $action, $article ) { |
| 175 | + // return "true" if the call failed (meaning, pass on handling |
| 176 | + // of the hook to others), and "false" otherwise |
| 177 | + if ( $action != 'approve' ) { |
| 178 | + return true; |
| 179 | + } |
| 180 | + $title = $article->getTitle(); |
| 181 | + if ( ApprovedRevs::hasUnsupportedNamespace( $title ) ) { |
| 182 | + return true; |
| 183 | + } |
| 184 | + if ( ! $title->userCan( 'approverevisions' ) ) { |
| 185 | + return true; |
| 186 | + } |
| 187 | + global $wgRequest; |
| 188 | + if ( ! $wgRequest->getCheck( 'oldid' ) ) { |
| 189 | + return true; |
| 190 | + } |
| 191 | + $revision_id = $wgRequest->getVal( 'oldid' ); |
| 192 | + ApprovedRevs::setApprovedRevID( $title, $revision_id ); |
| 193 | + |
| 194 | + global $wgOut; |
| 195 | + $wgOut->addHTML( ' ' . Xml::element( |
| 196 | + 'div', |
| 197 | + array( 'class' => 'successbox' ), |
| 198 | + wfMsg( 'approvedrevs-approvesuccess' ) |
| 199 | + ) . "\n" ); |
| 200 | + $wgOut->addHTML( ' ' . Xml::element( |
| 201 | + 'p', |
| 202 | + array( 'style' => 'clear: both' ) |
| 203 | + ) . "\n" ); |
| 204 | + |
| 205 | + // show the revision, instead of the history page |
| 206 | + $article->doPurge(); |
| 207 | + $article->view(); |
| 208 | + return false; |
| 209 | + } |
| 210 | + |
| 211 | + /** |
| 212 | + * Handle the 'unapprove' action, defined for ApprovedRevs - |
| 213 | + * unset the previously-approved revision, log the change, and show |
| 214 | + * a message to the user. |
| 215 | + */ |
| 216 | + static function unsetAsApproved( $action, $article ) { |
| 217 | + // return "true" if the call failed (meaning, pass on handling |
| 218 | + // of the hook to others), and "false" otherwise |
| 219 | + if ( $action != 'unapprove' ) { |
| 220 | + return true; |
| 221 | + } |
| 222 | + $title = $article->getTitle(); |
| 223 | + if ( ! $title->userCan( 'approverevisions' ) ) { |
| 224 | + return true; |
| 225 | + } |
| 226 | + |
| 227 | + ApprovedRevs::unsetApproval( $title ); |
| 228 | + |
| 229 | + global $wgOut; |
| 230 | + $wgOut->addHTML( ' ' . Xml::element( |
| 231 | + 'div', |
| 232 | + array( 'class' => 'successbox' ), |
| 233 | + wfMsg( 'approvedrevs-unapprovesuccess' ) |
| 234 | + ) . "\n" ); |
| 235 | + $wgOut->addHTML( ' ' . Xml::element( |
| 236 | + 'p', |
| 237 | + array( 'style' => 'clear: both' ) |
| 238 | + ) . "\n" ); |
| 239 | + |
| 240 | + // show the revision, instead of the history page |
| 241 | + $article->doPurge(); |
| 242 | + $article->view(); |
| 243 | + return false; |
| 244 | + } |
| 245 | + |
| 246 | + /** |
| 247 | + * Use the approved revision, if it exists, for templates and other |
| 248 | + * transcluded pages. |
| 249 | + */ |
| 250 | + static function setTranscludedPageRev( $parser, &$title, &$skip, &$id ) { |
| 251 | + $revision_id = ApprovedRevs::getApprovedRevID( $title ); |
| 252 | + if ( ! is_null( $revision_id ) ) { |
| 253 | + $id = $revision_id; |
| 254 | + } |
| 255 | + return true; |
| 256 | + } |
| 257 | + |
| 258 | + /** |
| 259 | + * Deletes the approval record in the database if the page itself is |
| 260 | + * deleted. |
| 261 | + */ |
| 262 | + static function deleteRevisionApproval( &$article, &$user, $reason, $id) { |
| 263 | + ApprovedRevs::deleteRevisionApproval( $article->getTitle() ); |
| 264 | + return true; |
| 265 | + } |
| 266 | + |
| 267 | + /** |
| 268 | + * Adds a link to 'Special:ApprovedPages' to the the page |
| 269 | + * 'Special:AdminLinks', defined by the Admin Links extension. |
| 270 | + */ |
| 271 | + function addToAdminLinks( &$admin_links_tree ) { |
| 272 | + $general_section = $admin_links_tree->getSection( wfMsg( 'adminlinks_general' ) ); |
| 273 | + $extensions_row = $general_section->getRow( 'extensions' ); |
| 274 | + if ( is_null( $extensions_row ) ) { |
| 275 | + $extensions_row = new ALRow( 'extensions' ); |
| 276 | + $general_section->addRow( $extensions_row ); |
| 277 | + } |
| 278 | + $extensions_row->addItem( ALItem::newFromSpecialPage( 'ApprovedPages' ) ); |
| 279 | + return true; |
| 280 | + } |
| 281 | +} |
Index: trunk/extensions/ApprovedRevs/README |
— | — | @@ -0,0 +1,35 @@ |
| 2 | +Approved Revs Extension |
| 3 | + |
| 4 | + Version 0.1 |
| 5 | + Yaron Koren |
| 6 | + |
| 7 | +This is free software licensed under the GNU General Public License. Please |
| 8 | +see http://www.gnu.org/copyleft/gpl.html for further details, including the |
| 9 | +full text and terms of the license. |
| 10 | + |
| 11 | +== Overview == |
| 12 | + |
| 13 | +Approved Revs is an extension to MediaWiki that lets administrators mark a |
| 14 | +certain revision of a page as "approved". The approved revision is the one |
| 15 | +displayed when users view the page at its main URL. |
| 16 | + |
| 17 | +For more information, see the extension homepage at: |
| 18 | +http://www.mediawiki.org/wiki/Extension:Approved_Revs |
| 19 | + |
| 20 | +== Requirements == |
| 21 | + |
| 22 | +This version of the Approved Revs extension requires MediaWiki 1.11 or |
| 23 | +higher. |
| 24 | + |
| 25 | +== Installation == |
| 26 | + |
| 27 | +To install the extension, place the entire 'ApprovedRevs' directory |
| 28 | +within your MediaWiki 'extensions' directory, then add the following |
| 29 | +line to your 'LocalSettings.php' file: |
| 30 | + |
| 31 | + require_once( "$IP/extensions/ApprovedRevs/ApprovedRevs.php" ); |
| 32 | + |
| 33 | +== Contact == |
| 34 | + |
| 35 | +Comments, questions, suggestions and bug reports should be sent to Yaron |
| 36 | +Koren, at yaron57@gmail.com. |
Index: trunk/extensions/ApprovedRevs/ApprovedRevs.sql |
— | — | @@ -0,0 +1,6 @@ |
| 2 | +CREATE TABLE approved_revs ( |
| 3 | + page_id int(8) default NULL, |
| 4 | + rev_id int(8) default NULL |
| 5 | +) |
| 6 | + |
| 7 | +CREATE UNIQUE INDEX approved_revs_page_id ON approved_revs (page_id); |