Extension:Dynamic Article List for PHP4

Maintainer
Shannon McNaught (smcnaught) - I am also available on irc.chekmate.org #MediaWiki

Homepage
ChekMate Technical Focus Group

License
Copyright (C) 2005 Shannon McNaught

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Introduction
Original Code by: Zengji (11:41, 13 December 2005)

DynamicArticleList is a Mediawiki 1.5 extension. It is designed to provide add-on sort ability among all posted articles. Now five types of Dynamic Article List have been implemented. User could easily find the latest or most popular topics cross site with the help of Dynamic Article List.
 * 1) Newly Posted Articles
 * 2) Recently Updated Articles
 * 3) Recent Discussions
 * 4) Most Popular Articles
 * 5) Recent BLOG Entries

Note: Most up to date version of this extension can be found at: http://www.chekmate.org/wiki/index.php/Projects

This extension is written with the help from Dynamic Page List on the MediaWiki extensions area.

Prerequisite

 * This version works with PHP4 or higher
 * Dynamic Article List strongly depends on "recentchanges" table, however Mediawiki engine 1.5.0 preiodically flushes old entries from the "recentchanges" table. It's recommended to disable the auto-deletion feature. - Open  Article.php  in "includes" folder, comment the line "$dbw->query( $sql )" at the start of function "editUpdates".

Installation

 * Copy  DynamicArticleList.php  to "extensions" folder.
 * Add a line  require_once( "extensions/DynamicArticleList.php" );  into "LocalSettings.php".

Tag and its Parameters
Note:
 * "categoryRoot" has been removed to work with PHP4
 * All articles will be candidates.
 * The value of parameter "type" could be one of the following (default is  new ):
 * new => Newly Posted Articles
 * update => Recently Updated Articles
 * discussion => Recent Discussions
 * hot => Most Popular Articles
 * blog => Recent BLOG Entries
 * The default value of "count" is  5 .

Samples
A sample snapshot of Dynamic Article List is shown below.  title=Newly Posted Articles type=new count=5 

When "type" is set to  new , The output record format would be  Page Title (author) - [create time]  When "type" is set to  update  or  discussion , The output record format would be  Page Title (last editor) - [update time] 

The underlaying wiki codes are:  title=Newly Posted Articles type=new count=5 

Another sample snapshot of Dynamic Article List is shown below.  title=Most Popular Articles type=hot count=5 

When "type" is set to  hot , The output record format would be  Page Title - (accessed times) 

The underlaying wiki codes are:  title=Most Popular Articles type=hot count=5 

DynamicArticleList.php
 Newly Posted Articles *     update          => Recently Updated Articles *     hot             => Most Popular Articles *     discussion      => Recently Updated Discussion * @author: Zeng Ji (zengji@gmail.com) * * To install, add following to LocalSettings.php * require_once ("extensions/DynamicArticleList.php"); */

$wgExtensionFunctions[] = "wfDynamicArticleList";

function wfDynamicArticleList { global $wgParser;

$wgParser->setHook( "DynamicArticleList", "DynamicArticleList" ); }

// The callback function for converting the input text to HTML output function DynamicArticleList( $input ) {

$dbr =& wfGetDB( DB_SLAVE );

// INVALIDATE CACHE global $wgTitle; $wgTitle->invalidateCache;

// Default Values $listTitle = false; $listType = 'new'; $listCount = 5;

// ###### PARSE PARAMETERS ###### $aParams = explode("\n", $input); foreach($aParams as $sParam) { $aParam = explode("=", $sParam); if( count( $aParam ) < 2 ) continue; $sType = trim($aParam[0]); $sArg = trim($aParam[1]);

switch ($sType) { case 'title': $listTitle = $sArg; break;

case 'type': if ( in_array($sArg, array('new','hot','update', 'discussion','blog')) ) $listType = $sArg; break;

case 'count': $listCount = IntVal( $sArg ); break;

}      }

// ###### CHECKS ON PARAMETERS ###### if ($listTitle!=false && strlen($listTitle)==0) $listTitle=false;

// ###### BUILD SQL QUERY ###### $sql = genSQL($listType, $listCount);

// ###### PROCESS SQL QUERY ###### global $wgUser; global $wgLang; global $wgContLang;

$res = $dbr->query($sql); $sk =& $wgUser->getSkin; if ($dbr->numRows( $res ) != 0) { while( $row = $dbr->fetchObject ( $res ) ) { $title = Title::makeTitle( $row->namespace, $row->title); if ($listType == 'discussion') $sLink = $sk->makeKnownLinkObj($title, $wgContLang->convertHtml($title->getText), , , 'Discussion: '); else $sLink = $sk->makeKnownLinkObj($title, $wgContLang->convertHtml($title->getText));

// Generate 'View Count' String (for 'hot') if ($listType == 'hot') $aViews[] = ' - ( ' . $row->count . ' views ) '; else $aViews = false;

// Generate 'Time' String (for 'new', 'update', 'discussion') if ($listType != 'hot') { $aDates[] = ' - [ '. $wgLang->timeanddate($row->timestamp, true). ' ] ';                               $editorID = $row->user; if ($editorID == 0) { $editor = wfMsg('anonymous'); $aEditors[] = ' (' . $editor . ')'; } else { $editor = User::whoIs($editorID); $aEditors[] = ' ( ' . $sk->makeLink($wgContLang->getNsText(NS_USER). ':' . $editor, htmlspecialchars($editor)) . ' )'; }                     }         else { $aDates = false; $aEditors = false; }

if ($listType == 'blog') { $aViews = false; $aDates = false; $aEditors = false; }                      $aArticles[] = $sLink; }      }       $dbr->freeResult( $res );

// ###### GENERATE OUTPUT ###### return OutputList($aArticles, $aEditors, $aDates, $aViews, $listTitle); }

function genSQL( $type, $count) { $dbr =& wfGetDB( DB_SLAVE ); $sPageTable = $dbr->tableName( 'page' ); $sRevisionTable = $dbr->tableName( 'revision' ); $sRecentChangesTable = $dbr->tableName( 'recentchanges' );

$sql = ''; if ($type == 'hot') {

$sql = "                            SELECT DISTINCT                             page_title as title,                             page_namespace AS namespace,                             page_counter as count                             FROM $sPageTable                             WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0 AND page_id!=1 AND page_title NOT LIKE \"%Sandbox%\"                             ORDER by count DESC                             LIMIT $count                     ";

} elseif ($type == 'update') {

// Step 1: Get revision list order by rev_id

$sql = "                           SELECT                             page_id,                             MAX(rev_id) AS max_rev_id                            FROM $sPageTable                            INNER JOIN $sRevisionTable ON page_id=rev_page

WHERE page_is_new!=1 AND page_namespace=0 AND page_is_redirect=0 AND page_id!=1 AND page_title NOT LIKE \"%Sandbox%\" GROUP BY page_id ORDER by max_rev_id DESC LIMIT $count ";

// Step 2: According to revision list, generate SQL to retrieve article page information. $res = $dbr->query($sql); $inClause = ''; if ($dbr->numRows( $res ) == 0) { $inClause = "-1"; } else { while( $obj = $dbr->fetchObject( $res ) ) { if( isset( $obj->max_rev_id ) ) { $inClause .= $obj->max_rev_id. ',';                            }                     }                     $inClause = substr($inClause, 0, strlen($inClause)-1);   //delete tailing ',' }            $dbr->freeResult( $res );

$sql = "                    SELECT                      page_title AS title,                      page_namespace AS namespace,                      rev_user AS user,                      rev_timestamp AS timestamp                     FROM $sRevisionTable, $sPageTable                     WHERE rev_page=page_id AND rev_id IN (". $inClause . ") AND page_title NOT LIKE \"%Sandbox%\"                     ORDER BY rev_id DESC";

} elseif ($type == 'discussion') {

// Step 1: Get revision list order by rev_id. $sql = "                            SELECT                              p1.page_id,                              MAX(rev_id) AS max_rev_id                             FROM $sPageTable AS p1                             INNER JOIN $sRevisionTable ON p1.page_id=rev_page                            WHERE p1.page_is_redirect=0 AND (p1.page_namespace=1 OR p1.page_namespace=3)                            GROUP BY rev_page                            ORDER by max_rev_id DESC                            LIMIT $count                    ";

// Step 2: According to revision list, generate SQL to retrieve discussion page information. $res = $dbr->query($sql); $inClause = ''; if ($dbr->numRows( $res ) == 0) { $inClause = "-1"; } else { while( $obj = $dbr->fetchObject( $res ) ) { if( isset( $obj->max_rev_id ) ) { $inClause .= $obj->max_rev_id. ',';                           }                    }                    $inClause = substr($inClause, 0, strlen($inClause)-1);        //delete tailing ',' }           $dbr->freeResult( $res );

$sql = "                   SELECT                     page_title AS title,                     page_namespace AS namespace,                     rev_user AS user,                     rev_timestamp AS timestamp                    FROM $sRevisionTable, $sPageTable                    WHERE rev_page=page_id AND rev_id IN (". $inClause . ")                    ORDER BY rev_id DESC";

} elseif ($type == 'blog') { $sql = "                              SELECT DISTINCT                                page_title AS title,                                page_namespace AS namespace,                                rc_user AS user,                                rc_timestamp AS timestamp                               FROM $sPageTable                               INNER JOIN $sRecentChangesTable ON page_id=rc_cur_id                               WHERE rc_new=1 AND rc_namespace=2 AND page_is_redirect=0 AND page_id!=1 AND page_title LIKE '%BlogEntry%'

ORDER by rc_id DESC LIMIT $count ";

}    else { // default type is 'new'

$sql = "                              SELECT DISTINCT                                page_title AS title,                                page_namespace AS namespace,                                rc_user AS user,                                rc_timestamp AS timestamp                               FROM $sPageTable                               INNER JOIN $sRecentChangesTable ON page_id=rc_cur_id                               WHERE rc_new=1 AND rc_namespace=0 AND page_is_redirect=0 AND page_id!=1                               ORDER by rc_id DESC                               LIMIT $count                      "; }

return $sql; }

function OutputList ( $aArticles, $aEditors, $aDates, $aViews, $listTitle ) { if ($listTitle != false) { $r .= " ". $listTitle. " \n"; $r .= " \n"; }

$sStartList = ''; $sEndList = ''; $sStartItem = ''; $sEndItem = '';

$r .= $sStartList. "\n"; for ($i=0; $i". $aEditors[$i]. " ";              if ($aDates != false) $dateString = "". $aDates[$i]. " ";              if ($aViews != false) $viewString = "". $aViews[$i]. " ";              $r .= $sStartItem. $aArticles[$i]. $viewString ." ". $editorString. $dateString. $sEndItem. "\n"; }      $r .= $sEndList. "\n";

return $r; } ?>

Other sites using this extension

 * ChekMate Technical Focus Group
 * ClickToNews.com
 * HamachiWiki.com
 * PaymentMerchant.com
 * GameShift.com
 * GoGoTraffic.com
 * BigBTV.com
 * Wereldpagina.nl