Difference between revisions of "MediaWiki/archive/extensions/Contributors"

from HTYP, the free directory anyone can edit if they can prove to me that they're not a spambot
Jump to navigation Jump to search
(→‎Contributors.php: 11/15 suppression of selected usernames)
m (Woozle moved page MediaWiki/extensions/Contributors to MediaWiki/archive/extensions/Contributors without leaving a redirect: very likely to be quite obsolete)
 
(2 intermediate revisions by the same user not shown)
Line 145: Line 145:
 
===Contributors.page.php===
 
===Contributors.page.php===
 
<php><?php
 
<php><?php
 
+
 
/**
 
/**
 
  * Special page class for the Contributors extension
 
  * Special page class for the Contributors extension
Line 154: Line 154:
 
   
 
   
 
class SpecialContributors extends IncludableSpecialPage {
 
class SpecialContributors extends IncludableSpecialPage {
 
+
 
protected $target;
 
protected $target;
 
+
 
public function __construct() {
 
public function __construct() {
 
parent::__construct( 'Contributors' );
 
parent::__construct( 'Contributors' );
 
}
 
}
+
 
public function execute( $target ) {
 
public function execute( $target ) {
 
wfProfileIn( __METHOD__ );
 
wfProfileIn( __METHOD__ );
Line 166: Line 166:
 
$this->setHeaders();
 
$this->setHeaders();
 
$this->determineTarget( $wgRequest, $target );
 
$this->determineTarget( $wgRequest, $target );
+
 
# What are we doing? Different execution paths for inclusion,
 
# What are we doing? Different execution paths for inclusion,
 
# direct access and raw access
 
# direct access and raw access
Line 178: Line 178:
 
$this->showNormal();
 
$this->showNormal();
 
}
 
}
+
 
wfProfileOut( __METHOD__ );
 
wfProfileOut( __METHOD__ );
 
}
 
}
+
 
private function showInclude() {
 
private function showInclude() {
 
global
 
global
Line 189: Line 189:
 
$wgContributorsShowAnon,
 
$wgContributorsShowAnon,
 
$wgContributorsShowOthers,
 
$wgContributorsShowOthers,
$wgContributorsUseRealName;
+
$wgContributorsUseRealName,
 
+
$wgUsernameAliases;
 +
 
wfProfileIn( __METHOD__ );
 
wfProfileIn( __METHOD__ );
 
global $wgOut;
 
global $wgOut;
Line 201: Line 202:
 
if ($idUser) {
 
if ($idUser) {
 
// logged-in user
 
// logged-in user
$objUser = User::newFromName($username);
+
$strUserSeek = strtolower($username);
$strUserName = $username;
+
/**/ if (array_key_exists($strUserSeek,$wgUsernameAliases))  {
if ($wgContributorsUseRealName) {
+
$strUserName = $wgUsernameAliases[$strUserSeek];
$strUserFull = $objUser->getRealName();
+
$strUser = $wgContributorsIncludeBefore.$strUserName;
if ($strUserFull) {
+
} else { /**/
$strUserName = $strUserFull;
+
$objUser = User::newFromName($username);
 +
$strUserName = $username;
 +
if ($wgContributorsUseRealName) {
 +
$strUserFull = $objUser->getRealName();
 +
if ($strUserFull) {
 +
$strUserName = $strUserFull;
 +
}
 
}
 
}
}
+
$objUserTitle = $objUser->getUserPage();
$objUserTitle = $objUser->getUserPage();
+
if ($objUserTitle->exists()) {
if ($objUserTitle->exists()) {
+
$strUserURL = $objUserTitle->getLocalURL();
$strUserURL = $objUserTitle->getLocalURL();
+
$strClass = '';
} else {
+
} else {
$strUserURL = $objUserTitle->getEditURL();
+
$strUserURL = $objUserTitle->getEditURL();
$strClass = ' class="new"';
+
$strClass = ' class="new"';
}
+
}
$strUser = $wgContributorsIncludeBefore.'<a href="'.$strUserURL.'"'.$strClass.'>'.$strUserName.'</a>';
+
$strUser = $wgContributorsIncludeBefore.'<a href="'.$strUserURL.'"'.$strClass.'>'.$strUserName.'</a>';
 +
/**/ } /**/
 
} else {
 
} else {
 
if ($wgContributorsShowAnon) {
 
if ($wgContributorsShowAnon) {
Line 224: Line 232:
 
}
 
}
 
}
 
}
// $names[] = '[[User:'.$username.'|]]';
 
 
if ($strUser != '') {
 
if ($strUser != '') {
 
$names[] = $strUser;
 
$names[] = $strUser;
Line 242: Line 249:
 
wfProfileOut( __METHOD__ );
 
wfProfileOut( __METHOD__ );
 
}
 
}
+
 
/**
 
/**
 
* Output a machine-readable form of the raw information
 
* Output a machine-readable form of the raw information
Line 262: Line 269:
 
wfProfileOut( __METHOD__ );
 
wfProfileOut( __METHOD__ );
 
}
 
}
+
 
private function showNormal() {
 
private function showNormal() {
 
wfProfileIn( __METHOD__ );
 
wfProfileIn( __METHOD__ );
Line 289: Line 296:
 
wfProfileOut( __METHOD__ );
 
wfProfileOut( __METHOD__ );
 
}
 
}
+
 
/**
 
/**
 
* Retrieve all contributors for the target page worth listing, at least
 
* Retrieve all contributors for the target page worth listing, at least
Line 316: Line 323:
 
return array( $ret, $others );
 
return array( $ret, $others );
 
}
 
}
+
 
/**
 
/**
 
* Retrieve the contributors for the target page with their contribution numbers
 
* Retrieve the contributors for the target page with their contribution numbers
Line 353: Line 360:
 
return $contributors;
 
return $contributors;
 
}
 
}
+
 
/**
 
/**
 
* Get conditions for the main query
 
* Get conditions for the main query
Line 366: Line 373:
 
return $conds;
 
return $conds;
 
}
 
}
+
 
/**
 
/**
 
* Given the web request, and a possible override from a subpage, work
 
* Given the web request, and a possible override from a subpage, work
Line 379: Line 386:
 
$this->target = Title::newFromUrl( $target );
 
$this->target = Title::newFromUrl( $target );
 
}
 
}
+
 
/**
 
/**
 
* Make a nice little form so the user can enter a title and so forth
 
* Make a nice little form so the user can enter a title and so forth
Line 404: Line 411:
 
return $form;
 
return $form;
 
}
 
}
 
+
}</php>
+
}
 +
?></php>

Latest revision as of 23:58, 14 December 2017

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, and gives a more friendly URL.

<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

2007-11-15 (Woozle) Added ability to hide or alias certain usernames
  • /

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/MediaWiki_Contributors_extension', 'version' => '2007-11-15.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 /** * Override to prevent certain users (e.g. internal authors) from being listed */ // $wgUsernameAliases['username'] = 'alias'; // add as many different aliases as needed /* Where multiple usernames map to one alias, each one is still listed individually -- but grouping should be easy enough to add if anyone actually wants it. Empty string suppresses listing of that name, including the separation string.

  • /

/** * 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, $wgUsernameAliases;

    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 $strUserSeek = strtolower($username); /**/ if (array_key_exists($strUserSeek,$wgUsernameAliases)) { $strUserName = $wgUsernameAliases[$strUserSeek]; $strUser = $wgContributorsIncludeBefore.$strUserName; } else { /**/ $objUser = User::newFromName($username); $strUserName = $username; if ($wgContributorsUseRealName) { $strUserFull = $objUser->getRealName(); if ($strUserFull) { $strUserName = $strUserFull; } } $objUserTitle = $objUser->getUserPage(); if ($objUserTitle->exists()) { $strUserURL = $objUserTitle->getLocalURL(); $strClass = ; } else { $strUserURL = $objUserTitle->getEditURL(); $strClass = ' class="new"'; } $strUser = $wgContributorsIncludeBefore.'<a href="'.$strUserURL.'"'.$strClass.'>'.$strUserName.'</a>'; /**/ } /**/ } else { if ($wgContributorsShowAnon) { $strUser = $wgContributorsIncludeBefore.$username; } else { $strUser = ; } } 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>