MediaWiki HOWTOs
From Zedomax Wiki
Password change
UPDATE user SET user_password = MD5(CONCAT(user_id, '-', MD5('somepass'))) WHERE user_name = 'whatever';
==Install MediaWiki Steps to installing MediaWiki:
Requirements
- Download MediaWiki (current stable version is Template:MW stable release number)
- Web Server such as Apache or IIS
- PHP version 5.0 or later (5.1.x recommended)
- Database Server
- MySQL 4.0 or later
- or PostgreSQL 8.1 or later (also requires plpgsql and tsearch2)
Some users find it helpful to install an additional software package such as phpMyAdmin (MySQL) or phpPgAdmin (Postgres) to help administer the database server.
1. copy the tar.gz file and untar using "tar xvf mediaXXX.tar.gz"
2. you can do "cp mediawikiXXX/* . -rf" to copy to root directory if untarred to a directory
3. Open your website now such as FiveDollarWiki.com
4. Follow instructions
Recommended Installs
Remove Robot NoFollow
Remove Robot NoFollow from MediaWiki
Category Cloud
Voting AJAX MediaWiki Extension
Voting AJAX MediaWiki Extension
eliminate index in mediawiki
1. Add this to your LocalSettings.php $wgArticlePath = "/$1";
2. Make a new .htaccess file and add this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?title=$1 [PT,L,QSA]
Problems with MediaWiki 1.11 / "Index.php" article
If you find yourself editing a page called "Index.php", try adding this to LocalSettings.php:
$wgUsePathInfo = false;
Note that setting this global to false means that the semi-friendly solutions described above for handling ampersands etc will no longer work. To temporarily fix this 1.11 bug before the developers have released a fixed version, see OrganicDesign:MediaWiki 1.11 title extraction bug for details about how to revert 1.11's title handling code to the 1.10 version.
Get rid of No-Follow
$wgNoFollowLinks = false;
Install WikiScript
Allowing external image links
Add this to LocalSettings.php:
$wgAllowExternalImages = true;
Add this to Template:Clickpic page:
<span class="plainlinks">[{{SERVER}}{{localurl:{{{1}}}}} {{{2}}}]</span>
Install GoogleMaps Extension
Who's Online Extension
Install websiteFrame Extension
Install websiteFrame Extension
Install ImageMap Extension
ImageMap Installation directions
<?php
# ImageMap Mediawiki extension
#
# original by smcnaught 29.06.2005
# Installation:
# * put this file (ImageMap.php) into the extension directory of your mediawiki installation
# * add the following to the end of LocalSettings.php: include("extensions/ImageMap.php");
#
# Usage:
# Use one section between <ImageMap>-tags for each feed. The ImageMap section may contain parameters
# separated by a pipe ("|"), just like links and templates. These parameters are supported:
#
# Example:
# <ImageMap>Image=ImageURL|Map=MapURL</ImageMap>
#
#install extension hook
$wgExtensionFunctions[] = "wfImageMapExtension";
#extension hook callback function
function wfImageMapExtension() {
global $wgParser;
#install parser hook for <ImageMap> tags
$wgParser->setHook( "ImageMap", "renderImageMap" );
}
#parser hook callback function
function renderImageMap( $input ) {
global $wgServer, $wgScriptPath, $wgTitle, $wgUrlProtocols, $wgUser, $IP;
# global $wgOutputEncoding;
if (!$input) return "";
$fields= explode("|",$input);
$args= array();
for ($i=0; $i<sizeof($fields); $i++) {
$f= $fields[$i];
if (strpos($f,"=")===False) $args[strtolower(trim($f))]= False;
else {
list($k,$v)= explode("=",$f,2);
if (trim($v)==False) $args[strtolower(trim($k))] = False;
else $args[strtolower(trim($k))]= trim($v);
}
}
$timestamp = mktime() . rand(1,29);
#get title from argument-array
$ImageURL= @$args["image"];
$ImageURL= trim($ImageURL);
if ($ImageURL=='') {
return "No Image";
}
$MapURL= @$args["map"];
$MapURL= trim($MapURL);
if ($MapURL=='') {
return "No Map";
}
$localParser = new Parser();
$parserOptions = ParserOptions::newFromUser( $wgUser );
$html = $localParser->parse($ImageURL,$wgTitle,$parserOptions);
$Imageurl = preg_replace('/^.*<a[\s]+href=*"(.*?)".*$/is', '\1' , $html->mText);
$html = $localParser->parse($MapURL,$wgTitle,$parserOptions);
$Mapurl = preg_replace('/^.*<a[\s]+href=*"(.*?)".*$/is', '\1' , $html->mText);
$mapfile = "$IP/../$Mapurl";
$lines = array_map('rtrim',file("$mapfile"));
$output="<img src=\"$Imageurl\" usemap=\"#$timestamp\">";
if (!file_exists($mapfile)) {
$output = $output . "Path to mapfile is incorrect or file does not exist. mapfile should look like: /var/www/html/wiki/images/4/4d/Fish.map";
# Enable for troubleshooting, otherwise comment to hide directory path.
# $output = $output . "$mapfile";
}
// Loop through our array, show HTML source as HTML source; and line numbers too.
foreach ($lines as $line_num => $line) {
if (preg_match ("/\sname=/i", $line)) {
$replacestr = " name=\"$timestamp\"";
$line = preg_replace('/\sNAME=\"[a-zA-Z0-9 ]+\"/i',$replacestr,$line);
}
$line = preg_replace(array('/\s{2,}/','/^\s+/','/\s+$/'),array(' ','',''),$line);
$output = $output . $line . "\n";
}
return $output;
}
?>
prevent new users
Useful MediaWiki Resources
MediaWiki installation and twiks
prevent new users
Making search for keywords
include utils.php from Pligg
Welcome <?php echo $_POST["words"]; ?>.<br />
<?php
$words=$_POST["words"];
//$foo = new Title;
//$test = $foo->cleanUp($_POST["words"]);
//$test = $foo->NFC($_POST["words"]);
//$test = Title::getInterwikiLink( $_POST["words"]);
//$test = Title::newFromText( $_POST["words"]);
//$test = urlencode("hello-there");
//$test = Sanitizer::stripAllTags("Hello there");
//$test = strip_tags(trim($words));
//$test = makeUrlFriendly($test);
//$test = utf8_substr($test);
$words = stripslashes(strip_tags(trim($words)));
$words = ucwords(strtolower($words));
$words = makeUrlFriendly($words);
//$test = utf8_substr($input, 0, 240);
//class foo extends UtfNormal {
//}
//$urlfriendly = toNFC($_POST["words"]);
?>
URL friendly: <?php echo $urlfriendly; ?>
<?php echo $words; ?>
<br />
<?php
$db = mysql_connect("localhost", "asdasd", "asdasd");
if (!$db) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("asdasd",$db);
$result = mysql_query("SELECT count(page_title) from page where page_title='".$words."'",$db);
if (mysql_result($result,0) == 0) {
printf("NONE!");
}
printf("Records: %s\n", mysql_result($result,0));
Install PageFunctions Extension
PageFunctions MediaWiki Extension HOWTO
*/
$wgExtensionCredits[PageFunctions::thisType][] = array(
'name' => PageFunctions::thisName,
'version' => StubManager::getRevisionId( '$Id: PageFunctions.php 634 2007-08-10 00:58:50Z jeanlou.dupont $' ),
'author' => 'Jean-Lou Dupont',
'description' => 'Provides page scope functions',
'url' => StubManager::getFullUrl(__FILE__),
);
class PageFunctions
{
const thisName = 'PageFunctions';
const thisType = 'other';
var $pageVars;
// Our class defines magic words: tell it to our helper class.
public function __construct()
{
$this->pageVars = array();
}
// ===============================================================
public function mg_pagetitle( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
return $this->setTitle( $params[0] );
}
private function setTitle( &$title )
{
global $wgOut;
$wgOut->setPageTitle( $title );
}
// ===============================================================
public function mg_pagesubtitle( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
$this->setSubTitle( $params[0] );
}
private function setSubTitle( &$title )
{
global $wgOut;
$wgOut->setSubtitle( $title );
}
// ===============================================================
public function mg_pageexists( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
return $this->doesPageExists( $params[0] );
}
private function doesPageExists( &$title )
{
$a = StubManager::getArticle( $title );
if (is_object($a))
$id=$a->getID();
else $id = 0;
return ($id == 0 ? false:true);
}
// ===============================================================
/**
Hook based Page Variable 'get'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
public function hPageVarGet( &$varname, &$value )
{
$value = @$this->pageVars[ $varname ];
return true; // continue hook-chain.
}
/**
Hook based Page Variable 'set'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
public function hPageVarSet( &$varname, &$value )
{
$this->pageVars[ $varname ] = $value;
return true; // continue hook-chain.
}
public function mg_varset( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
$this->pageVars[ $params[0] ] = $params[1];
}
public function mg_varget( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
return @$this->pageVars[ $params[0] ];
}
/**
Captures a variable
Useful when building complex HTML pages.
{{#varcapset: variable name|value }}
((#varcapset: variable name|value ))
*/
public function mg_varcapset( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
@$this->pageVars[ $params[0] ] = $params[1];
return $params[1];
}
/**
Sets a variable to an array.
param 0: variable name
param 1: array key
param 2: array value corresponding to key.
*/http://zedomax.com/wiki/index.php/Main_Page
http://zedomax.com/wiki/index.php/Main_Page
public function mg_varaset( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
@$this->pageVars[ $params[0] ][ $params[1] ] = $params[2];
}
/**
Gets a variable to an array.
param 0: variable name
param 1: array key
*/
public function mg_varaget( &$parser )
{
$params = StubManager::processArgList( func_get_args(), true );
return @$this->pageVars[ $params[0] ][ $params[1] ];
}
// ===============================================================
public function mg_cshow( &$parser, &$group, &$text )
// Conditional Show: if user is part of $group, then allow for '$text'
// Parser Cache friendly of 'ConditionalShowSection' extension.
{
global $wgUser;
$g = $wgUser->getEffectiveGroups();
if (in_array( $group, $g ))
return $text;
}
/**
Magic Word 'noclientcaching'
The actual action of disabling the client caching process is already performed through
'ParserCache2' extension when processing 'magic words' such as this one (($noclientcaching$)).
If on the contrary this function is called through the usual {{noclientcaching}} statement, then
1) If 'parser caching' is used, this statement will have limited effect
2) If 'parser caching' is not used, then this statement will have an effect everytime the page is visited.
*/
public function MW_noclientcaching( &$parser, &$varcache, &$ret )
{
global $wgOut;
$wgOut->enableClientCache(false);
}
public function mg_noext( &$parser, $pagename = null)
{
if (empty( $pagename ))
return null;
return substr( $pagename, 0, strpos( $pagename, '.' ) );
}
} // end class
//
Simple Security MediaWiki Extension for controlling each page edit rights
#EXTENSIONS
#security
include('extensions/SimpleSecurity.php');
$wgSecurityMagic = "security";
$wgSecurityMagicNoi = "!security";
$wgSecurityMagicIf = "ifusercan";
$wgSecurityMagicGroup = "ifgroup";
$wgSecurityEnableInheritance = false;
$wgSecuritySysops = "sysop";
$wgSecurityDenyTemplate = "Template:Action not permitted";
$wgSecurityInfoTemplate = "Template:Security info";
$wgSecurityEnableForImages = false;
$wgSecurityDenyImage = "local mediawiki logo";
$wgSecurityParseInfo = false;
#BASIC USER RIGHTS
$wgGroupPermissions['*' ]['createaccount'] = false;
$wgGroupPermissions['*' ]['createpage'] = false;
$wgGroupPermissions['*' ]['edit'] = false;
$wgGroupPermissions['user' ]['createpage'] = false;
$wgShowIPinHeader = false;
Adding RSS
<?php
/*
Wiki Feed Generator for MediaWiki
Gregory Szorc <gregory.szorc@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Directions:
This script requires MediaWiki 1.5+ and PHP 5 to run. It was developed against MediaWiki
1.8.2 and PHP 5.1.6. If it doesn't work, upgrade!
To use this script, copy it to your extensions/ subdirectory inside the MediaWiki install.
Add the following in LocalSettings.php:
include_once('SpecialWikiFeeds.php');
This script also needs my GenericXmlSyndicationFeed class, which can be found at
http://opensource.case.edu/svn/MediaWikiHacks/classes/GenericXmlSyndicationFeed/GenericXmlSyndicationFeed.php
You will need to manually include this file before the require/include SpecialWikiFeeds.php
in LocalSettings.php or else when this file loads, you will get a big, fat error message.
Example LocalSettings.php entry:
require("$IP/extensions/GenericXmlSyndicationFeed.php");
require("$IP/extensions/SpecialWikiFeeds.php");
$wgWikiFeedsSettings['cacheEnable'] = true;
Once WikiFeeds is enabled in LocalSettings.php,
go to Special:WikiFeeds in your wiki. Everything should be set!
WikiFeeds can be slightly customized. Settings which can be changed are located
in the $wgWikiFeedsSettings array (defined and documentation below). If you wish
to change a setting, re-set it in LocalSettings.php, after including this file
(see above example)
If you encounter a bug, please file it at http://opensource.case.edu/projects/MediaWikiHacks
or e-mail me.
Other:
The script supports ATOM 1.0 better than RSS 2.0. ATOM is the future. I'm not
wasting my time adding full support for RSS.
ToDo:
Use MediaWiki language support through system messages (partially done)
Better error checking
Optimize SQL queries
*/
if (!defined('MEDIAWIKI')) die();
$wgExtensionFunctions[] = 'wfWikiFeeds';
$wgExtensionCredits['specialpage'][] = array(
'name'=>'Wiki Feeds',
'author'=>'Gregory Szorc <gregory.szorc@gmail.com>',
'url'=>'http://wiki.case.edu/User:Gregory.Szorc',
'description'=>'Produces syndicated feeds for MediaWiki.',
'version'=>'0.5'
);
/**
* Holds default settings for WikiFeeds
*
* Override values in LocalSettings.php after you include this file
*/
$wgWikiFeedsSettings = array(
'cacheEnable' => false, //whether to enable the cache
'cacheRoot' => '/tmp/', //cache directory, with trailing slash
'cacheMaxAge' => 600, //max age of cached files, in seconds
'cachePruneFactor' => 100, //prune stale cache entries 1 out of every this many requests
'watchlistPrivate' => false, //when true, make per-user watchlists require special access token
);
function wfWikiFeeds() {
global $wgMessageCache, $wgHooks;
if (!class_exists('GenericXmlSyndicationFeed')) {
throw new MWException('GenericXmlSyndicationFeed class not loaded. Please read the install directions!');
}
require_once('SpecialPage.php');
$wgMessageCache->addmessages(
array(
'wikifeeds'=>'Wiki Feeds',
'wikifeeds_unknownformat' => "==Unknown format==\nThe feed format you requested is not available.",
'wikifeeds_unknownfeed' => "==Unknown feed==\nThe feed you selected is not available.",
'wikifeeds_undefinedcategory' => "==Undefined category==\nThe feed you requested requires that the ''category'' parameter be defined",
'wikifeeds_categorynoexist' => "==Unknown category==\nThe category you tried to request does not exist. Category names are case sensitive. Be sure the category is listed at [[Special:Categories]]",
'wikifeeds_undefineduser' => "==Undefined user==\nThe feed you requested requires that the ''user'' parameter be defined",
'wikifeeds_unknownuser' => "==Unknown user==\nThe user specified does not exist. Be sure the user is listed at [[Special:User]]",
'wikifeeds_nowatchlisttoken' => "==No Token==\nYou must supply a token to access your user watchlist",
'wikifeeds_invalidwatchlisttoken' => "==Invalid Token==\nThe token specified to access the watchlist is invalid",
'wikifeeds_tokeninfo' => "==Watchlist Token==\nYour private watchlist token is $1. Access your watchlist via $2",
'wikifeeds_feed_newestarticles_title' => 'Newest Articles',
'wikifeeds_feed_newestarticles_description' => 'Newest articles in the wiki',
'wikifeeds_feed_recentarticlechanges_title' => 'Recently Changed Articles',
'wikifeeds_feed_recentarticlechanges_description' => 'Recently changed articles in the wiki',
'wikifeeds_feed_newestarticlesbyuser_title' => 'Newest articles created by $1',
'wikifeeds_feed_newestarticlesbyuser_description' => 'Newest articles created by $1',
'wikifeeds_feed_recentuserchanges_title' => 'Recent changes by $1',
'wikifeeds_feed_recentuserchanges_description' => 'Recent changes made by user $1',
'wikifeeds_feed_userwatchlist_title' => 'Watchlist for $1',
'wikifeeds_feed_userwatchlist_description' => 'Watchlist for $1',
'wikifeeds_feed_recentcategorychanges_title' => 'Recently changed articles in $1',
'wikifeeds_feed_recentcategorychanges_description' => 'Recently changed articles in category $1',
'wikifeeds_feed_newestarticlesincategory_title' => 'Newest articles in the category $1',
'wikifeeds_feed_newestarticlesincategory_description' => 'Newly created articles that are part of the category $1',
'wikifeeds_mainpage' =>
"WikiFeeds generates syndicated feeds for this wiki.
==WikiArticleFeeds Extension==
[http://jimbojw.com/wiki/index.php?title=WikiArticleFeeds_Extension Get it here]
<pre>
<?php
/*
* WikiArticleFeeds.php - A MediaWiki extension for converting regular pages into feeds.
* @author Jim R. Wilson
* @version 0.6.3
* @copyright Copyright (C) 2007 Jim R. Wilson
* @license The MIT License - http://www.opensource.org/licenses/mit-license.php
* -----------------------------------------------------------------------
* Description:
* This is a MediaWiki (http://www.mediawiki.org/) extension which adds support
* for publishing RSS or Atom feeds generated from standard wiki articles.
* Requirements:
* MediaWiki 1.6.x, 1.8.x, 1.9.x or higher
* PHP 4.x, 5.x or higher
* Installation:
* 1. Drop this script (WikiArticleFeeds.php) in $IP/extensions
* Note: $IP is your MediaWiki install dir.
* 2. Enable the extension by adding this line to your LocalSettings.php:
* require_once('extensions/WikiArticleFeeds.php');
* Usage:
* Once installed, you may utilize WikiArticleFeeds by invoking the 'feed' action of an article:
* $wgScript?title=Some_Article&action=feed
* Note: You may optionally supply a feed type. Acceptable values inculde 'rss' and 'atom'.
* If no feed type is specified, the default is 'atom'. For example:
* $wgScript?title=Some_Article&action=feed&feed=atom
* Creating a Feed:
* To delimit a section of an article as containing feed items, use the <startFeed />
* and <endFeed /> tags respectively. These tags are merely flags, and any attributes
* specified, or content inside the tags themselves will be ignored.
* Tagging a Feed item:
* To tag a feed item, insert either the <itemTags> tag, or the a call to the {{#itemTags}} parser
* function somewhere between the opening header of the item (== Item Title ==) and the header of
* the next item. For example, to mark an item about dogs and cats, you could do any of the following:
* <itemTags>dogs, cats</itemTags>
* {{#itemTags:dogs, cats}}
* {{#itemTags:dogs|cats}}
* Version Notes:
* version 0.6.3:
* Wrapped extension points for versions less than 1.7 (old version compatibility)
* version 0.6.2:
* Added support for alternate signatures (when users are not in the User namespace)
* Tied purge of xml feeds to purge of page - helps with consumers of semantic and DPL
* (Thanks to Charlie Huggard of charlie.huggardlee.net for these contributions)
* version 0.6.1:
* Fixed stale feed problem by expiring the feed cache when any of an article's transcluded pages change.
* version 0.6:
* Added support for "tagging" feed items by way of <itemTags> or {{itemTags}}
* Added support for filtering generated feed based on item tags.
* Added global ($wgWikiArticleFeedsSkipCache) used for skipping object-cache while debugging.
* Fixed namespace restriction - now works for namespaces other than NS_MAIN
* version 0.5:
* Now supports offloading to FeedBurner (http://feedburner.com/) via <feedBurner> tag.
* Capitalized RSS and Atom links in the toolbox.
* version 0.4:
* Added wgForceArticleFeedSectionLinks to override default link behavior (set in LocalSettings).
* Feed generator now follows Article redirects.
* version 0.3:
* Added Version Notes.
* Fixed relative-links bug (all links in item descriptions are now fully qualified).
* Fixed date-overwrite bug (previously, items with the exact same timestamp would be ignored).
* Improved W3C validation. Feeds validate, but there are still warnings.
* version 0.2:
* Renamed from WikiFeeds.php to WikiArticleFeeds.php
* Corrected credits and copyright info.
* Numerous minor fixes and tweaks.
* Expanded support for versions 1.6.x, 1.8.x and 1.9.x.
* Improved return values from hooking functions (plays better with other extensions).
* version 0.1:
* Initial release.
* -----------------------------------------------------------------------
* Copyright (c) 2007 Jim R. Wilson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
* -----------------------------------------------------------------------
*/
# Confirm MW environment
if (!defined('MEDIAWIKI')) die();
define('WIKIARTICLEFEEDS_VERSION','0.6.3');
# Bring in supporting classes
require_once("$IP/includes/Feed.php");
require_once("$IP/includes/Sanitizer.php");
# Credits
$wgExtensionCredits['specialpage'][] = array(
'name'=>'WikiArticleFeeds',
'author'=>'Jim Wilson (wilson.jim.r<at>gmail.com)',
'url'=>'http://jimbojw.com/wiki/index.php?title=WikiArticleFeeds',
'description'=>'Produces feeds generated from MediaWiki articles.',
'version'=>WIKIARTICLEFEEDS_VERSION
);
/**
* Wrapper class for consolidating all WAF related parser methods
*/
class WikiArticleFeedsParser {
function feedStart( $text, $params = array() ) {
return '<!-- FEED_START -->';
}
function feedEnd( $text, $params = array() ) {
return '<!-- FEED_END -->';
}
function burnFeed( $text, $params = array() ) {
return ($params['name']?'<!-- BURN_FEED '.base64_encode(serialize($params['name'])).' -->':'');
}
function itemTagsTag( $text, $params = array() ) {
return ($text?'<!-- ITEM_TAGS '.base64_encode(serialize($text)).' -->':'');
}
function itemTagsFunction( $parser ) {
$tags = func_get_args();
array_shift( $tags );
return (!empty($tags)?'<pre>@ITEMTAGS@'.base64_encode(serialize(implode(',',$tags))).'@ITEMTAGS@':);
}
function itemTagsMagic( &$magicWords, $langCode=null ) {
$magicWords['itemtags'] = array( 0, 'itemtags' );
return true;
}
function itemTagsPlaceholderCorrections( $parser, &$text ) {
$text = preg_replace(
'|@ITEMTAGS@([0-9a-zA-Z\\+\\/]+=*)@ITEMTAGS@|',
,
$text
);
return true;
}
}
- Create global instance
$wgWikiArticleFeedsParser = new WikiArticleFeedsParser(); if (version_compare($wgVersion, '1.7', '<')) {
# Hack solution to resolve 1.6 array parameter nullification for hook args
function wfWAFParserItemTagsMagic( &$magicWords ) {
global $wgWikiArticleFeedsParser;
$wgWikiArticleFeedsParser->itemTagsMagic( $magicWords );
return true;
}
function wfWAFParserPlaceholderCorrections( $parser, &$text ) {
global $wgWikiArticleFeedsParser;
$wgWikiArticleFeedsParser->itemTagsPlaceholderCorrections( $parser, $text );
return true;
}
$wgHooks['LanguageGetMagic'][] = 'wfWAFParserItemTagsMagic';
$wgHooks['ParserBeforeTidy'][] = 'wfWAFParserPlaceholderCorrections';
} else {
$wgHooks['LanguageGetMagic'][] = array($wgWikiArticleFeedsParser, 'itemTagsMagic'); $wgHooks['ParserBeforeTidy'][] = array($wgWikiArticleFeedsParser, 'itemTagsPlaceholderCorrections');
}
- Add Extension Functions
$wgExtensionFunctions[] = 'wfWikiArticleFeedsParserSetup';
- Sets up the WikiArticleFeeds Parser hooks
function wfWikiArticleFeedsParserSetup() { global $wgParser, $wgWikiArticleFeedsParser;
$wgParser->setHook( 'startFeed', array($wgWikiArticleFeedsParser, 'feedStart') ); $wgParser->setHook( 'endFeed', array($wgWikiArticleFeedsParser, 'feedEnd') ); $wgParser->setHook( 'feedBurner', array($wgWikiArticleFeedsParser, 'burnFeed') ); $wgParser->setHook( 'itemTags', array($wgWikiArticleFeedsParser, 'itemTagsTag') );
$wgParser->setFunctionHook( 'itemtags', array($wgWikiArticleFeedsParser, 'itemTagsFunction') ); }
- Attach Hooks
$wgHooks['OutputPageBeforeHTML'][] = 'wfAddWikiFeedHeaders'; $wgHooks['MonoBookTemplateToolboxEnd'][] = 'wfWikiArticleFeedsToolboxLinks'; $wgHooks['UnknownAction'][] = 'wfWikiArticleFeedsAction'; $wgHooks['ArticlePurge'][] = 'wfPurgeFeedsOnArticlePurge';
/**
* Adds the Wiki feed link headers. * Usage: $wgHooks['OutputPageBeforeHTML'][] = 'wfAddWikiFeedHeaders'; * @param $out Handle to an OutputPage object (presumably $wgOut). * @param $text Article/Output text. */
function wfAddWikiFeedHeaders($out, $text) {
# Short-circuit if this article contains no feeds
if (!preg_match('//m', $text)) return true;
$rssArr = array(
'rel' => 'alternate',
'type' => 'application/rss+xml',
'title' => 'RSS 2.0',
);
$atomArr = array(
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => 'Atom 0.3',
);
# Test for feedBurner presence
if (preg_match('//m', $text, $matches)) {
$name = @unserialize(@base64_decode($matches[1]));
if ($name) {
$rssArr['href'] = 'http://feeds.feedburner.com/'.urlencode($name).'?format=xml';
$atomArr['href'] = 'http://feeds.feedburner.com/'.urlencode($name).'?format=xml';
}
}
# If its not being fed by feedBurner, do it ourselves!
if (!array_key_exists('href', $rssArr) || !$rssArr['href']) {
global $wgServer, $wgScript, $wgTitle;
$baseUrl = $wgServer.$wgScript.'?title='.$wgTitle->getDBkey().'&action=feed&feed=';
$rssArr['href'] = $baseUrl.'rss';
$atomArr['href'] = $baseUrl.'atom';
}
$out->addLink($rssArr);
$out->addLink($atomArr);
global $wgWikiFeedPresent;
$wgWikiFeedPresent = true;
# True to indicate that other action handlers should continue to process this page
return true;
}
/**
* Adds the Wiki feed links to the bottom of the toolbox in Monobook or like-minded skins. * Usage: $wgHooks['MonoBookTemplateToolboxEnd'][] = 'wfWikiArticleFeedsToolboxLinks'; * @param QuickTemplate $template Instance of MonoBookTemplate or other QuickTemplate */
function wfWikiArticleFeedsToolboxLinks($template) {
global $wgOut, $wgServer, $wgScript, $wgArticle, $wgWikiFeedPresent; # Short-circuit if wgArticle has not been set or there are no Feeds present if (!$wgArticle || !$wgWikiFeedPresent) return true;$result = '
prevent new users
# require that users log in to read $wgGroupPermissions['*']['read'] = false; # require that users log in to edit $wgGroupPermissions['*']['edit'] = false; # allow these pages for anonymous users $wgWhitelistRead = array( "Main Page", "Special:Userlogin", "-", "MediaWiki:Monobook.css" ); # remove the link to the talk page for non-logged in users $wgShowIPinHeader = false;
Example requests
- http://zedomax.com/wiki/Special:WikiFeeds/atom/newestarticles - ATOM 1.0 feed of newest articles in the wiki
- http://zedomax.com/wiki/Special:WikiFeeds/atom/recentuserchanges/user/Gregory.Szorc - ATOM 1.0 feed for recent changes by Gregory.Szorc
- http://zedomax.com/wiki/Special:WikiFeeds/rss/watchlist/user/Jeremy.Smith/count/50 - RSS feed for Jeremy.Smith's watchlist
- http://zedomax.com/wiki/Special:WikiFeeds/rss/recentcategorychanges/category/Buildings - RSS feed for recently changed articles in the Buildings category
",
) );
$wgHooks['ParserAfterTidy'][] = 'wfWikiFeeds_Linker';
class SpecialWikiFeeds extends SpecialPage { const FEED_NEWESTARTICLES = 1; const FEED_RECENTARTICLECHANGES = 2; const FEED_RECENTUSERCHANGES = 3; const FEED_USERWATCHLIST = 4; const FEED_RECENTCATEGORYCHANGES = 5; const FEED_NEWESTCATEGORYARTICLES = 6; const FEED_NEWESTARTICLESBYUSER = 7;
const DEFAULT_COUNT = 15;
protected $_settings = array();
public function __construct() { global $wgWikiFeedsSettings;
$this->_settings = $wgWikiFeedsSettings;
SpecialPage::SpecialPage('WikiFeeds');
//we automatically prune the cache randomly if ($this->_settings['cacheEnable']) { if (rand(1, $this->_settings['cachePruneFactor']) === 1) { $this->_cachePrune(); } }
}
public function execute($par = null) { global $wgOut, $wgRequest, $wgServer, $wgWikiFeedsSettings, $wgUser;
$request = isset($par) ? $par : $wgRequest->getText('request');
if (!$request) { $wgOut->addWikiText(wfMsg('wikifeeds_mainpage'));
// do special voodoo if private watchlist is enabled if ($wgWikiFeedsSettings['watchlistPrivate'] && $wgUser->isLoggedIn()) { if (!$wgUser->getOption('watchlistToken')) { $token = md5(microtime() . $wgUser->getID());
$wgUser->setOption('watchlistToken', $token); $wgUser->saveSettings(); }
$token = $wgUser->getOption('watchlistToken');
$privateFeedUrl = Title::newFromText('WikiFeeds/atom/watchlist/user/' . $wgUser->getName() . '/token/' . $token, NS_SPECIAL);
// and display blurb about token $wgOut->addWikiText(wfMsg('wikifeeds_tokeninfo', $token, $privateFeedUrl->getFullUrl())); } } else { $arr = explode('/', $request);
//might have a valid request for a feed
if (count($arr) >= 2) {
$format = null;
$feed = null;
$count = self::DEFAULT_COUNT;
$params = array();
$areSane = true;
if (strtolower($arr[0]) == 'atom') { $format = GenericXmlSyndicationFeed::FORMAT_ATOM10; } else if (strtolower($arr[0]) == 'rss') { $format = GenericXmlSyndicationFeed::FORMAT_RSS20; } else { $wgOut->addWikiText(wfMsg('wikifeeds_unknownformat')); $areSane = false; }
switch (strtolower($arr[1])) { case 'newestarticles': $feed = self:: FEED_NEWESTARTICLES; break;
case 'recentarticlechanges': $feed = self::FEED_RECENTARTICLECHANGES; break;
case 'recentuserchanges': $feed = self::FEED_RECENTUSERCHANGES; break;
case 'newestuserarticles': $feed = self::FEED_NEWESTARTICLESBYUSER; break;
case 'watchlist': $feed = self::FEED_USERWATCHLIST; break;
case 'recentcategorychanges': $feed = self::FEED_RECENTCATEGORYCHANGES; break;
case 'newestcategoryarticles': $feed = self::FEED_NEWESTCATEGORYARTICLES; break;
default: $wgOut->addWikiText(wfMsg('wikifeeds_unknownfeed')); $areSane = false; }
//now we look for additional parameters if ( (count($arr) > 3) && ((count($arr) % 2) == 0) ) { for ($i = 2; $i < count($arr); $i += 2) { $params[$arr[$i]] = $arr[$i+1]; } }
//if we are dealing with a category feed, we need a category specified if ($feed === self::FEED_RECENTCATEGORYCHANGES || $feed === self::FEED_NEWESTCATEGORYARTICLES) { if (!array_key_exists('category', $params)) { $wgOut->addWikiText(wfMsg('wikifeeds_undefinedcategory')); $areSane = false; } else { //verify category is valid if (!$this->categoryExists($params['category'])) { $wgOut->addWikiText(wfMsg('wikifeeds_categorynoexist')); $areSane = false; } } }
//if we are asking for a user feed, we need the user parameter if ($feed === self::FEED_RECENTUSERCHANGES || $feed === self::FEED_USERWATCHLIST || $feed === self::FEED_NEWESTARTICLESBYUSER) { if (!array_key_exists('user', $params)) { $wgOut->addWikiText(wfMsg('wikifeeds_undefineduser')); $areSane = false; } else { //verify the user exists $userId = User::idFromName($params['user']);
if (is_null($userId) || $userId === 0) { $wgOut->addWikiText(wfMsg('wikifeeds_unknownuser')); $areSane = false; } else if ($feed === self::FEED_USERWATCHLIST && $wgWikiFeedsSettings['watchlistPrivate']) { if (!array_key_exists('token', $params)) { $wgOut->addWikiText(wfMsg('wikifeeds_nowatchlisttoken')); $areSane = false; } else { $token = $params['token'];
// verify token is sane $user = User::newFromId($userId);
if ($token != $user->getOption('watchlistToken')) { $wgOut->addWikiText(wfMsg('wikifeeds_invalidwatchlisttoken')); $areSane = false; } } } } }
if (array_key_exists('count', $params) && ctype_digit($params['count']) && $params['count'] > 0) { $count = $params['count']; }
if (array_key_exists('unique', $params) && $params['count'] != 'false') { $unique = true; } else { $unique = false; }
//we are sane, so let's create a feed if ($areSane) { $wgOut->disable();
//if we successfully fetched a feed from the cache
if ($this->_settings['cacheEnable'] && $cached = $this->_cacheFetchFeed($feed, $format, $params)) {
//$cached is an array containing feed text and some metadata
header('Content-Type: ' . $cached['content-type']);
print $cached['content'];
} else { //no cache was hit, assemble the feed
$Feed = new GenericXmlSyndicationFeed($format);
switch ($feed) { case self::FEED_NEWESTARTICLES: $this->makeNewestArticles($Feed, $count); break;
case self::FEED_RECENTARTICLECHANGES: $this->makeRecentArticleChanges($Feed, $count, $unique); break;
case self::FEED_NEWESTARTICLESBYUSER: $this->makeNewestArticleByUser($Feed, $params['user'], $count); break;
case self::FEED_RECENTUSERCHANGES: $this->makeRecentUserChanges($Feed, $params['user'], $count); break;
case self::FEED_USERWATCHLIST: $this->makeUserWatchlist($Feed, $params['user'], $count); break;
case self::FEED_RECENTCATEGORYCHANGES: $this->makeRecentCategoryPageChanges($Feed, $params['category'], $count); break;
case self::FEED_NEWESTCATEGORYARTICLES: $this->makeNewestArticlesInCategory($Feed, $params['category'], $count); break;
default:
echo 'unknown feed'; }
$feedDate = 0; foreach ($Feed->items as $i) { if ($i->mArticle->mTimestamp > $feedDate) $feedDate = $i->mArticle->mTimestamp; }
$Feed->lastUpdated = wfTimestamp(TS_UNIX, $feedDate);
$Feed->linkSelf = $wgServer.$_SERVER['REQUEST_URI'];
$Feed->sendOutput();
//finally, cache the feed if ($this->_settings['cacheEnable']) { $this->_cacheSaveFeed($Feed, $feed, $format, $params); } } } }
}
$this->setHeaders();
}
/** * This function checks to see if a category exists * It would be really nice if MediaWiki had this method available, but all the SQL is inline * Comparison is case sensitive */ protected function categoryExists($cat) { $dbr =& wfGetDB( DB_SLAVE ); $categorylinks = $dbr->tableName( 'categorylinks' ); if ($result = $dbr->safeQuery("SELECT count(*) FROM $categorylinks WHERE cl_to=?", $cat)) { if ($row = $dbr->fetchRow($result)) { return $row[0] > 0 ? true : false; } }
return false;
}
/** * Create a feed for newest articles in the wiki */ protected function makeNewestArticles(GenericXmlSyndicationFeed &$feed, $count = self::DEFAULT_COUNT) { $feed->title = wfMsg('wikifeeds_feed_newestarticles_title'); $feed->description = wfMsg('wikifeeds_feed_newestarticles_description');
$altUrlTitle = Title::makeTitle(NS_SPECIAL, 'Newpages'); $feed->linkAlternate = $altUrlTitle->getFullURL();
$dbr = wfGetDB(DB_SLAVE);
extract($dbr->tableNames('recentchanges', 'page', 'text'));
$sql = "SELECT 'Newpages' as type, rc_namespace AS namespace, rc_title AS value, rc_user AS user,
rc_user_text AS user_text,
rc_comment AS comment,
rc_timestamp AS timestamp,
rc_id AS rcid,
page_id AS page,
page_len AS length,
page_latest AS latest
FROM $recentchanges,$page
WHERE rc_cur_id=page_id AND rc_new=1 AND page_is_redirect=0
ORDER BY rc_timestamp DESC LIMIT $count";
if ($result = $dbr->doQuery($sql)) { if ($dbr->numRows($result)) { while ($row = $dbr->fetchRow($result)) { $title = Title::newFromID($row['page']); $item = new MediaWikiFeedItem($title); $feed->addItem($item); } } } }
/** * Feed for recently changed articles * * @todo Implement $unique changes to SQL query */ protected function makeRecentArticleChanges(GenericXmlSyndicationFeed &$feed, $count = self::DEFAULT_COUNT, $unique = false) { $feed->title = wfMsg('wikifeeds_feed_recentarticlechanges_title'); $feed->description = wfMsg('wikifeeds_feed_recentarticlechanges_description');
$altUrlTitle = Title::makeTitle(NS_SPECIAL, 'Recentchanges'); $this->linkAlternate = $altUrlTitle->getFullURL();
$db = wfGetDB(DB_SLAVE);
extract($db->tableNames('recentchanges','page', 'revision'));
$sql = "SELECT rev_id AS revid, rev_page AS page, rev_user_text as user, rc_id AS rcid
FROM $recentchanges, $revision
WHERE rc_this_oldid=rev_id AND rev_deleted=0
ORDER BY rev_id DESC LIMIT $count";
if ($result = $db->doQuery($sql)) { if ($db->numRows($result)) { while ($row = $db->fetchRow($result)) { $title = Title::newFromID($row['page']); $item = new MediaWikiFeedItem($title, $row['revid'], $row['rcid']);
$feed->addItem($item); } } } }
/** * Recent articles created by a specified user */ protected function makeNewestArticleByUser(GenericXmlSyndicationFeed &$feed, $user, $count = self::DEFAULT_COUNT) {
$u = User::newFromName($user);
if (!$u) return;
$feed->title = wfMsg('wikifeeds_feed_newestarticlesbyuser_title', $user); $feed->description = wfMsg('wikifeeds_feed_newestarticlesbyuser_description', $user);
$altUrlTitle = Title::makeTitle(NS_SPECIAL, "Contributions/$user"); $feed->linkAlternate = $altUrlTitle->getFullURL();
$author = array(); $author['name'] = $user; $author['email'] = $u->getEmail(); $userPage = $u->getUserPage(); $author['uri'] = $userPage->getFullURL();
$feed->addAuthor($author);
$db = wfGetDB(DB_SLAVE);
extract($db->tableNames('recentchanges','page', 'revision'));
$sql = "SELECT
rc_id AS rcid,
page_id AS page,
page_latest AS latest
FROM $recentchanges,$page
WHERE rc_cur_id=page_id AND rc_new=1 AND page_is_redirect=0 AND rc_user_text='{$u->getName()}'
ORDER BY rc_timestamp DESC LIMIT $count";
if ($result = $db->doQuery($sql)) { if ($db->numRows($result)) { while ($row = $db->fetchRow($result)) { $title = Title::newFromID($row['page']); $item = new MediaWikiFeedItem($title);
$feed->addItem($item); } } } }
/** * Recent article changes by a specified user */ protected function makeRecentUserChanges(GenericXmlSyndicationFeed &$feed, $user, $count = self::DEFAULT_COUNT) { $u = User::newFromName($user);
if (!$u) return;
$feed->title = wfMsg('wikifeeds_feed_recentuserchanges_title', $user); $feed->description = wfMsg('wikifeeds_feed_recentuserchanges_description', $user);
$altUrlTitle = Title::makeTitle(NS_SPECIAL, "Contributions/$user"); $feed->linkAlternate = $altUrlTitle->getFullURL();
$author = array(); $author['name'] = $user; $author['email'] = $u->getEmail(); $userPage = $u->getUserPage(); $author['uri'] = $userPage->getFullURL();
$feed->addAuthor($author);
$db = wfGetDB(DB_SLAVE);
extract($db->tableNames('recentchanges', 'page', 'revision'));
$sql = "SELECT rev_id AS revid, rev_page AS page, rev_user_text as user, rc_id AS rcid
FROM $recentchanges, $revision
WHERE rc_this_oldid=rev_id AND rev_deleted=0 AND rev_user_text='{$u->getName()}'
ORDER BY rev_id DESC LIMIT $count";
if ($result = $db->doQuery($sql)) { if ($db->numRows($result)) { while ($row = $db->fetchRow($result)) { $title = Title::newFromID($row['page']); $item = new MediaWikiFeedItem($title, $row['revid'], $row['rcid']);
$feed->addItem($item); } } } }
/** * Watchlist for a specified user */ protected function makeUserWatchlist(GenericXmlSyndicationFeed &$feed, $user, $count = self::DEFAULT_COUNT) { $feed->title = wfMsg('wikifeeds_feed_userwatchlist_title', $user); $feed->description = wfMsg('wikifeeds_feed_userwatchlist_description', $user);
$u = User::newFromName($user);
if (!$u) return;
$author = array(); $author['name'] = $user; $author['email'] = $u->getEmail(); $userPage = $u->getUserPage(); $author['uri'] = $userPage->getFullURL();
$feed->addAuthor($author);
$db = wfGetDB(DB_SLAVE);
extract($db->tableNames('recentchanges', 'page', 'revision', 'watchlist'));
$sql = "SELECT rev_id as revid, rev_page AS page, rc_id AS rcid
FROM $recentchanges, $revision, $watchlist
WHERE wl_user={$u->getID()} AND rc_namespace=wl_namespace AND rc_title=wl_title
AND rev_id=rc_this_oldid
ORDER BY rev_id DESC LIMIT $count";
if ($result = $db->doQuery($sql)) { if ($db->numRows($result)) { while ($row = $db->fetchRow($result)) { $title = Title::newFromID($row['page']); $item = new MediaWikiFeedItem($title, $row['revid'], $row['rcid']); $feed->addItem($item); } } } }
/** * Recently changes articles in a specified category */ protected function makeRecentCategoryPageChanges(GenericXmlSyndicationFeed &$feed, $category, $count = self::DEFAULT_COUNT) { $feed->title = wfMsg('wikifeeds_feed_recentcategorychanges_title', $category); $feed->description = wfMsg('wikifeeds_feed_recentcategorychanges_description', $category);
$pagesIn = $this->getPagesInCategory($category);
$db = wfGetDB(DB_SLAVE); extract($db->tableNames('recentchanges', 'page', 'revision'));
$sql = "SELECT rev_id AS revid, rev_page AS page, rc_id AS rcid
FROM $recentchanges, $revision
WHERE rev_page IN (".implode(',', $pagesIn).")
AND rev_deleted=0 AND rc_this_oldid=rev_id
ORDER BY rev_id DESC LIMIT $count";
if ($result = $db->doQuery($sql)) { if ($db->numRows($result)) { while ($row = $db->fetchRow($result)) { $title = Title::newFromID($row['page']); $item = new MediaWikiFeedItem($title, $row['revid'], $row['rcid']); $feed->addItem($item); } } }
}
/** * Newest articles in a specified category */ protected function makeNewestArticlesInCategory(GenericXmlSyndicationFeed &$feed, $category, $count = self::DEFAULT_COUNT) { $catTitle = Title::newFromText($category, NS_CATEGORY);
$feed->title = wfMsg('wikifeeds_feed_newestarticlesincategory_title', $catTitle->getText()); $feed->description = wfMsg('wikifeeds_feed_newestarticlesincategory_description', $catTitle->getText());
$db = wfGetDB(DB_SLAVE);
extract($db->tableNames('page','categorylinks'));
$sql = "SELECT
page_id AS page
FROM $page,$categorylinks
WHERE cl_to='{$catTitle->getDBkey()}' AND cl_from=page_id
ORDER BY cl_timestamp DESC LIMIT $count";
if ($result = $db->doQuery($sql)) { if ($db->numRows($result)) { while ($row = $db->fetchRow($result)) { $title = Title::newFromID($row['page']); $item = new MediaWikiFeedItem($title);
$feed->addItem($item); } } } }
/** * Return all the pages in a given category */ protected function getPagesInCategory($catName) { $db = wfGetDB(DB_SLAVE);
$catTitle = Title::newFromText($catName, NS_CATEGORY);
$db = wfGetDB(DB_SLAVE);
extract($db->tableNames('categorylinks'));
$sql = "SELECT cl_from AS page FROM $categorylinks WHERE cl_to='{$catTitle->getDBkey()}'";
$r = array();
if ($result = $db->doQuery($sql)) { if ($db->numRows($result)) { while ($row = $db->fetchRow($result)) { $r[] = $row['page']; } } }
return $r;
}
/** * Fetch a feed from the cache * * This function will try to fetch a feed specified by type, format * and parameters from the cache. If the feed does not exist in the * cache or if the cache entry is stale, we don't return anything * * @param $feed Feed type constant * @param $format Feed format constant * @param array $params Parameters to pass to the feed constructor * * @return array Array that describes the feed|false on failure */ protected function _cacheFetchFeed($feed, $format, $params) { $filename = $this->_cacheFilename($feed, $format, $params);
if (file_exists($filename) && is_readable($filename)) { if ( (time() - filemtime($filename)) < $this->_settings['cacheMaxAge']) { $content = unserialize(file_get_contents($filename));
if (is_array($content)) { return $content; } } else { //the file is old, we might as well prune it now //to save a few system calls unlink($filename); } }
return false; }
/** * Save a specified feed object corresponding to given parameters to the * cache */ protected function _cacheSaveFeed(GenericXmlSyndicationFeed $feedObj, $feed, $format, $params) { $filename = $this->_cacheFilename($feed, $format, $params);
$cacheContent = array(
'content-type' => $feedObj->contentType, 'content' => $feedObj->getContent(false)
);
file_put_contents($filename, serialize($cacheContent), LOCK_EX); }
/**
* Returns the filename a specified feed should have
*
* @param $feed Feed type constant
* @param $foramt Feed format constant
* @param array $params Array of feed parameters
*/
protected function _cacheFilename($feed, $format, $params) {
$s = $this->_settings['cacheRoot'] . 'wikifeeds_cache-';
$s .= md5($feed.$format.serialize($params));
return $s; }
/** * Prune the cache of stale entries */ protected function _cachePrune() { foreach ($this->_getCacheFiles() as $file) { if ((time() - filemtime($file)) > $this->_settings['cacheMaxAge']) { unlink($file); }
} }
/** * Purge the cache of all entries */ protected function _cachePurge() { foreach ($this->_getCacheFiles() as $file) { unlink($file); } }
/** * Returns an array of all files in the cache */ protected function _getCacheFiles() { $return = array();
$directory = new DirectoryIterator($this->_settings['cacheRoot']);
foreach ($directory as $file) { if ($file->isFile()) { if (strpos($file->getPathname(), $this->_settings['cacheRoot'] . 'wikifeeds_cache-') === 0) { $return[] = $file->getPathname(); } } }
return $return; }
}
/** * This is a MediaWiki-specific definition of a feed item */ class MediaWikiFeedItem extends GenericXmlSyndicationFeedItem {
public function __construct($title, $revId = 0, $rcid = 0) { parent::__construct();
$this->allowedVars = array_merge($this->allowedVars, array(
'mTitle','mRevId','mRCid','mArticle'
)
);
$this->mTitle = $title;
$this->mRevId = $revId;
$this->mRCid = $rcid;
$this->mArticle = new Article($this->mTitle);
$this->mArticle->fetchContent($this->mRevId);
$this->publishTime = wfTimestamp(TS_UNIX, $this->mArticle->mTimestamp);
$this->title = $this->mTitle->getFullText();
if ($rcid == 0) {
$this->guid = $this->mTitle->getFullURL();
}
else {
$this->guid = $this->mTitle->escapeFullURL("oldid={$this->mRevId}");
}
$this->linkSelf = $this->_guid;
$this->linkAlternate = $this->mTitle->getFullURL();
$author = array();
$author['name'] = $this->mArticle->getUserText();
if ($u = User::newFromName($author['name'])) {
$author['email'] = $u->getEmail();
$userPage = $u->getUserPage();
$author['uri'] = $userPage->getFullURL();
}
$this->_vars['authors'][] = $author;
//create a new default user to invoke the parser
$u = new User();
global $wgParser;
$output = $wgParser->parse($this->mArticle->getContent(false), $this->mTitle, ParserOptions::newFromuser($u));
$text = $output->mText;
//$this->_content = html_entity_decode($text);
$this->content = $text;
$categories = $this->mTitle->getParentCategories();
if (is_array($categories)) {
foreach ($categories as $c=>$v) {
$categoryTitle = Title::newFromText($c);
$this->_vars['categories'][] = $categoryTitle->getText();
}
}
}
}
SpecialPage::addPage(new SpecialWikiFeeds); }
/**
* Hooks registered on ParserAfterTidy hook * * Injects links to feeds in HTML <head> * */
function wfWikiFeeds_Linker($a, $b) { global $wgWikiFeedsSettings, $wgTitle;
// only link against each article once if (!array_key_exists('__linkerTracker', $wgWikiFeedsSettings)) { $wgWikiFeedsSettings['__linkerTracker'] = array(); }
// if we have already processed this title, don't do it again if (in_array($wgTitle->getFullText(), $wgWikiFeedsSettings['__linkerTracker'])) { return true; } else { // mark as processed $wgWikiFeedsSettings['__linkerTracker'][] = $wgTitle->getFullText(); }
switch ($wgTitle->getNamespace()) { case NS_USER: case NS_USER_TALK: { $username = $wgTitle->getPartialURL();
//strip out subpage if we are on one if ($pos = strpos($username, '/')) { $username = substr($username, 0, $pos); }
$t0 = Title::newFromText("WikiFeeds/atom/recentuserchanges/user/$username", NS_SPECIAL); $t1 = Title::newFromText("WikiFeeds/rss/recentuserchanges/user/$username", NS_SPECIAL); $t2 = Title::newFromText("WikiFeeds/atom/newestuserarticles/user/$username", NS_SPECIAL); $t3 = Title::newFromText("WikiFeeds/rss/newestuserarticles/user/$username", NS_SPECIAL); $t4 = Title::newFromText("WikiFeeds/atom/watchlist/user/$username", NS_SPECIAL); $t5 = Title::newFromText("WikiFeeds/rss/watchlist/user/$username", NS_SPECIAL);
wfWikiFeeds_AddLink('atom', "Recently changed articles by $username (ATOM 1.0)", $t0->getFullUrl()); wfWikiFeeds_AddLink('atom', "Latest articles created by $username (ATOM 1.0)", $t2->getFullUrl()); wfWikiFeeds_AddLink('atom', "Watchlist for $username (ATOM 1.0)", $t4->getFullUrl()); wfWikiFeeds_AddLink('rss', "Recently changes articles by $username (RSS 2.0)", $t1->getFullUrl()); wfWikiFeeds_AddLink('rss', "Latest articles created by $username (RSS 2.0)", $t3->getFullUrl()); wfWikiFeeds_AddLink('rss', "Watchlist for $username (RSS 2.0)", $t5->getFullUrl());
} break;
case NS_CATEGORY: case NS_CATEGORY_TALK: { $category = $wgTitle->getPartialURL(); $catName = $wgTitle->getText();
$atomCatNew = Title::newFromText("WikiFeeds/atom/newestcategoryarticles/category/$catName", NS_SPECIAL); $rssCatNew = Title::newFromText("WikiFeeds/rss/newestcategoryarticles/category/$catName", NS_SPECIAL); $atomCatRecent = Title::newFromText("WikiFeeds/atom/recentcategorychanges/category/$catName", NS_SPECIAL); $rssCatRecent = Title::newFromText("WikiFeeds/rss/recentcategorychanges/category/$catName", NS_SPECIAL);
wfWikiFeeds_AddLink('atom', "Newest pages to join the $catName category (ATOM 1.0)", $atomCatNew->getFullUrl()); wfWikiFeeds_AddLink('atom', "Recently changed articles in the $catName category (ATOM 1.0)", $atomCatRecent->getFullUrl()); wfWikiFeeds_AddLink('rss', "Newest pages to join the $catName category (RSS 2.0)", $rssCatNew->getFullUrl()); wfWikiFeeds_AddLink('rss', "Recently changed articles in the $catName category (RSS 2.0)", $rssCatRecent->getFullUrl()); } }
$atomRecentChanges = Title::newFromText("WikiFeeds/atom/recentarticlechanges", NS_SPECIAL); $atomNewestArticles = Title::newFromText("WikiFeeds/atom/newestarticles", NS_SPECIAL); $rssRecentChanges = Title::newFromText("WikiFeeds/rss/recentarticlechanges", NS_SPECIAL); $rssNewestArticles = Title::newFromText("WikiFeeds/rss/newestarticles", NS_SPECIAL);
wfWikiFeeds_AddLink('atom', 'Recently changed articles (ATOM 1.0)', $atomRecentChanges->getFullUrl()); wfWikiFeeds_AddLink('atom', 'Newest articles (ATOM 1.0)', $atomNewestArticles->getFullUrl()); wfWikiFeeds_AddLink('rss', 'Recently changed articles (RSS 2.0)', $rssRecentChanges->getFullUrl()); wfWikiFeeds_AddLink('rss', 'Newest articles (RSS 2.0)', $rssNewestArticles->getFullUrl());
return true; }
/**
* Helper function for wfWikiFeeds_Linker */
function wfWikiFeeds_AddLink($format, $title, $url) { global $wgOut;
$typeApp = 'application/atom+xml';
if ($format == 'rss') { $typeApp = 'application/rss+xml'; }
//else $wgOut->addLink(array('rel'=>'alternate', 'type'=>$typeApp, 'title'=>$title, 'href'=>$url)); }
</pre>
prevent new users
# require that users log in to read $wgGroupPermissions['*']['read'] = false; # require that users log in to edit $wgGroupPermissions['*']['edit'] = false; # allow these pages for anonymous users $wgWhitelistRead = array( "Main Page", "Special:Userlogin", "-", "MediaWiki:Monobook.css" ); # remove the link to the talk page for non-logged in users $wgShowIPinHeader = false;
Useful MediaWiki Resources
MediaWiki installation and twiks
prevent new users
How to capitalize every letter in the phrase with php
$bar = ucwords(strtolower($bar));
Making search for keywords
include utils.php from Pligg