MediaWiki/archive/extensions/Contributors

from HTYP, the free directory anyone can edit if they can prove to me that they're not a spambot
< MediaWiki‎ | archive‎ | extensions
Revision as of 00:01, 15 November 2007 by Woozle (talk | contribs) (→‎Contributors.php: 11/14 fixed author credit)
Jump to navigation Jump to search

Navigation

{{#lst:MediaWiki extensions|navbar}}: Contributors

Overview

This is a modification of an extension originally posted on mediawiki.org. If anyone wants to integrate these changes into the official release of that extension, please feel free to do so.

It adds the following features:

  • link to user's page, if available (with standard edit link if page doesn't exist)
  • allows display of user's real name, if available (configurable option)
  • more flexible formatting via LocalSettings options

Installation instructions are unchanged from those in the official release, except for the following new LocalSettings options:

  • $wgContributorsIncludeBefore: string to include before each contributor listing
  • $wgContributorsIncludeBetween: string to include between contributors (not before first or after last)
  • $wgContributorsIncludeBeforeOthers: string to include before the optional "and n others" listing
    • (text for after the "others" listing is set at Mediawiki:contributors-others)
  • $wgContributorsShowAnon: if FALSE, do not show anonymous (IP address) contributors
  • $wgContributorsShowOthers: if FALSE, do not show "and n others" line
  • $wgContributorsUseRealName: if TRUE, use real name if available (as entered by user in their "my preferences" page)

Code

The Contributors.i18n.php file is unaltered; use the one linked from mediawiki.org.

Contributors.php

  • 2007-11-14 Oops, didn't mean to hog all the credit! Rob Church did most of the work. This version corrects the "author" data.

<php><?php

/**

* Special page that lists the ten most prominent contributors to an article
*
* @addtogroup Extensions
* @author Rob Church <robchur@gmail.com>, Nick (Woozle) Staddon
*/

/*

2007-11-13 (Woozle) Better formatting for included contrib list; added some config options:

$wgContributorsIncludeBefore, $wgContributorsIncludeBetween, $wgContributorsIncludeBeforeOthers, $wgContributorsShowAnon, $wgContributorsShowOthers, $wgContributorsUseRealName

  • /

if( defined( 'MEDIAWIKI' ) ) {

$wgExtensionFunctions[] = 'efContributors'; $wgExtensionCredits['specialpage'][] = array( 'name' => 'Contributors', 'author' => 'Rob Church, Nick (Woozle) Staddon', 'description' => 'Summarises the main contributors to an article', 'url' => 'http://htyp.org/Contributors_%28MediaWiki_extension%29', 'version' => '2007-11-14.wzl', );

$wgAutoloadClasses['SpecialContributors'] = dirname( __FILE__ ) . '/Contributors.page.php'; $wgSpecialPages['Contributors'] = 'SpecialContributors';

/** * Intelligent cut-off limit; see below */ $wgContributorsLimit = 10;

/** * After $wgContributorsLimit is reached, contributors with less than this * number of edits to a page won't be listed in normal or inclusion lists */ $wgContributorsThreshold = 2;

/** * Some formatting specs for the included version of the contrib list: */ $wgContributorsIncludeBefore = ; // include this string before each contributor // $wgContributorsIncludeBetween = '
'; // include this string after each contributor $wgContributorsIncludeBetween = ', '; // include this string after each contributor $wgContributorsIncludeBeforeOthers = '
... '; // include this string before "others" // text for *after* "others" is set at Mediawiki:contributors-others $wgContributorsShowAnon = false; // if FALSE, do not show anonymous contributors $wgContributorsShowOthers = false; // if FALSE, do not show "and n others" line $wgContributorsUseRealName = true; // if TRUE, use real name if available

/** * Extension initialisation function */ function efContributors() { global $wgMessageCache, $wgHooks; require_once( dirname( __FILE__ ) . '/Contributors.i18n.php' ); foreach( efContributorsMessages() as $lang => $messages ) $wgMessageCache->addMessages( $messages, $lang ); $wgHooks['ArticleDeleteComplete'][] = 'efContributorsInvalidateCache'; $wgHooks['ArticleSaveComplete'][] = 'efContributorsInvalidateCache'; # Good god, this is ludicrous! $wgHooks['SkinTemplateBuildNavUrlsNav_urlsAfterPermalink'][] = 'efContributorsNavigation'; $wgHooks['MonoBookTemplateToolboxEnd'][] = 'efContributorsToolbox'; }

/** * Invalidate the cache we saved for a given title * * @param $article Article object that changed */ function efContributorsInvalidateCache( &$article ) { global $wgMemc; $wgMemc->delete( wfMemcKey( 'contributors', $article->getId() ) );

return true; }

/** * Prepare the toolbox link */ function efContributorsNavigation( &$skintemplate, &$nav_urls, &$oldid, &$revid ) { if ( $skintemplate->mTitle->getNamespace() === NS_MAIN && $revid !== 0 ) $nav_urls['contributors'] = array( 'text' => wfMsg( 'contributors-toolbox' ), 'href' => $skintemplate->makeSpecialUrl( 'Contributors', "target=" . wfUrlEncode( "{$skintemplate->thispage}" ) ) ); return true; }

/** * Output the toolbox link */ function efContributorsToolbox( &$monobook ) { if ( isset( $monobook->data['nav_urls']['contributors'] ) ) if ( $monobook->data['nav_urls']['contributors']['href'] == ) {

?>

  • <?php echo $monobook->msg( 'contributors-toolbox' ); ?>
  • <?php } else { ?>

  • <?php ?><a href="<?php echo htmlspecialchars( $monobook->data['nav_urls']['contributors']['href'] ) ?>"><?php echo $monobook->msg( 'contributors-toolbox' ); ?></a><?php ?>
  • <?php } return true; } } else { echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); exit( 1 ); } ?></php>

    Contributors.page.php

    <php><?php

    /**

    * Special page class for the Contributors extension
    *
    * @addtogroup Extensions
    * @author Rob Church <robchur@gmail.com>
    */
    
    

    class SpecialContributors extends IncludableSpecialPage {

    protected $target;

    public function __construct() { parent::__construct( 'Contributors' ); }

    public function execute( $target ) { wfProfileIn( __METHOD__ ); global $wgOut, $wgRequest; $this->setHeaders(); $this->determineTarget( $wgRequest, $target );

    # What are we doing? Different execution paths for inclusion, # direct access and raw access if( $this->including() ) { $this->showInclude(); } elseif( $wgRequest->getText( 'action' ) == 'raw' ) { $this->showRaw(); } else { $wgOut->addHtml( $this->makeForm() ); if( is_object( $this->target ) ) $this->showNormal(); }

    wfProfileOut( __METHOD__ ); }

    private function showInclude() { global $wgContributorsIncludeBefore, $wgContributorsIncludeBetween, $wgContributorsIncludeBeforeOthers, $wgContributorsShowAnon, $wgContributorsShowOthers, $wgContributorsUseRealName;

    wfProfileIn( __METHOD__ ); global $wgOut; if( is_object( $this->target ) ) { if( $this->target->exists() ) { $names = array(); list( $contributors, $others ) = $this->getMainContributors(); foreach( $contributors as $username => $info ) { $idUser = $info[0]; if ($idUser) { // logged-in user $objUser = User::newFromName($username); $strUserName = $username; if ($wgContributorsUseRealName) { $strUserFull = $objUser->getRealName(); if ($strUserFull) { $strUserName = $strUserFull; } } $objUserTitle = $objUser->getUserPage(); if ($objUserTitle->exists()) { $strUserURL = $objUserTitle->getLocalURL(); } else { $strUserURL = $objUserTitle->getEditURL(); $strClass = ' class="new"'; } $strUser = $wgContributorsIncludeBefore.'<a href="'.$strUserURL.'"'.$strClass.'>'.$strUserName.'</a>'; } else { if ($wgContributorsShowAnon) { $strUser = $wgContributorsIncludeBefore.$username; } else { $strUser = ; } } // $names[] = '[[User:'.$username.'|]]'; if ($strUser != ) { $names[] = $strUser; } } $output = implode( $wgContributorsIncludeBetween, $names ); if( ($others > 0) && $wgContributorsShowOthers) $output .= $wgContributorsIncludeBeforeOthers . wfMsgForContent( 'contributors-others', $others ); // $wgOut->addHtml( htmlspecialchars( $output ) ); $wgOut->addHtml( $output ); } else {

    $wgOut->addHtml( '

    ' . htmlspecialchars( wfMsgForContent( 'contributors-nosuchpage', $this->target->getPrefixedText() ) ) . '

    ' );

    } } else {

    $wgOut->addHtml( '

    ' . htmlspecialchars( wfMsgForContent( 'contributors-badtitle' ) ) . '

    ' );

    } wfProfileOut( __METHOD__ ); }

    /** * Output a machine-readable form of the raw information */ private function showRaw() { wfProfileIn( __METHOD__ ); global $wgOut; $wgOut->disable(); if( is_object( $this->target ) && $this->target->exists() ) { foreach( $this->getContributors() as $username => $info ) { list( $userid, $count ) = $info; header( 'Content-type: text/plain; charset=utf-8', true ); echo( htmlspecialchars( "{$username} = {$count}\n" ) ); } } else { header( 'Status: 404 Not Found', true, 404 ); echo( 'The requested target page does not exist.' ); } wfProfileOut( __METHOD__ ); }

    private function showNormal() { wfProfileIn( __METHOD__ ); global $wgOut, $wgUser, $wgLang; if( $this->target->exists() ) { $total = 0; $skin =& $wgUser->getSkin(); $link = $skin->makeKnownLinkObj( $this->target );

    $wgOut->addHtml( '

    ' . wfMsgHtml( 'contributors-subtitle', $link ) . '

    ' );

    list( $contributors, $others ) = $this->getMainContributors();

    $wgOut->addHtml( '

      ' ); foreach( $contributors as $username => $info ) { list( $id, $count ) = $info; $line = $skin->userLink( $id, $username ) . $skin->userToolLinks( $id, $username ); $line .= ' [' . $wgLang->formatNum( $count ) . ']'; $wgOut->addHtml( '
    • ' . $line . '
    • ' ); } $wgOut->addHtml( '

    ' );

    if( $others > 0 ) { $others = $wgLang->formatNum( $others ); $wgOut->addWikiText( wfMsgNoTrans( 'contributors-others-long', $others ) ); } } else {

    $wgOut->addHtml( '

    ' . htmlspecialchars( wfMsg( 'contributors-nosuchpage', $this->target->getPrefixedText() ) ) . '

    ' );

    } wfProfileOut( __METHOD__ ); }

    /** * Retrieve all contributors for the target page worth listing, at least * according to the limit and threshold defined in the configuration * * Also returns the number of contributors who weren't considered * "important enough" * * @return array */ protected function getMainContributors() { wfProfileIn( __METHOD__ ); global $wgContributorsLimit, $wgContributorsThreshold; $total = 0; $ret = array(); $all = $this->getContributors(); foreach( $all as $username => $info ) { list( $id, $count ) = $info; if( $total >= $wgContributorsLimit && $count < $wgContributorsThreshold ) break; $ret[$username] = array( $id, $count ); $total++; } $others = count( $all ) - count( $ret ); wfProfileOut( __METHOD__ ); return array( $ret, $others ); }

    /** * Retrieve the contributors for the target page with their contribution numbers * * @return array */ protected function getContributors() { wfProfileIn( __METHOD__ ); global $wgMemc; $k = wfMemcKey( 'contributors', $this->target->getArticleId() ); $contributors = $wgMemc->get( $k ); if( !$contributors ) { $contributors = array(); $dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( 'revision', array( 'COUNT(*) AS count', 'rev_user', 'rev_user_text', ), $this->getConditions(), __METHOD__, array( 'GROUP BY' => 'rev_user_text', 'ORDER BY' => 'count DESC', ) ); if( $res && $dbr->numRows( $res ) > 0 ) { while( $row = $dbr->fetchObject( $res ) ) $contributors[ $row->rev_user_text ] = array( $row->rev_user, $row->count ); } $wgMemc->set( $k, $contributors, 84600 ); } wfProfileOut( __METHOD__ ); return $contributors; }

    /** * Get conditions for the main query * * @return array */ protected function getConditions() { global $wgVersion; $conds['rev_page'] = $this->target->getArticleId(); if( version_compare( $wgVersion, '1.11alpha', '>=' ) ) $conds[] = 'rev_deleted & ' . Revision::DELETED_USER . ' = 0'; return $conds; }

    /** * Given the web request, and a possible override from a subpage, work * out which we want to use * * @param $request WebRequest we're serving * @param $override Possible subpage override * @return string */ private function determineTarget( &$request, $override ) { $target = $request->getText( 'target', $override ); $this->target = Title::newFromUrl( $target ); }

    /** * Make a nice little form so the user can enter a title and so forth * in normal output mode * * @return string */ private function makeForm() { global $wgScript; $self = parent::getTitleFor( 'Contributors' ); $target = is_object( $this->target ) ? $this->target->getPrefixedText() : ; $form = '<form method="get" action="' . htmlspecialchars( $wgScript ) . '">'; $form .= Xml::hidden( 'title', $self->getPrefixedText() ); $form .= '<fieldset><legend>' . wfMsgHtml( 'contributors-legend' ) . '</legend>';

    $form .= '

    '; $form .= ''; $form .= ''; $form .= ''; $form .= ''; $form .= ''; $form .= '
    <label for="target">' . wfMsgHtml( 'contributors-target' ) . '</label>' . Xml::input( 'target', 40, $target, array( 'id' => 'target' ) ) . '
     ' . Xml::submitButton( wfMsg( 'contributors-submit' ) ) . '

    ';

    $form .= '</fieldset>'; $form .= '</form>'; return $form; }

    }</php>