Beschreibung
SGPack ist eine Sammlung von Mediawiki Erweiterungen die speziell für Stargate-Wiki programmiert wurden. Die Sammlung enthält die folgenden Erweiterungen:
- BlockSpammer
- Die Erweiterung prüft die Änderungen von Anonymen Benutzern. Wird versucht eine Internetadresse einzugeben so wird die Übernahme der Änderungen abgelehnt.
- NewArticle
- Um das Anlegen von neuen Artikeln zu erleichtern ermöglicht es diese Erweiterung Artikelvorlagen direkt in den neuen Artikel einzubinden.
Copyright
Die Erweiterung unterliegt der GPL (Version 2). Das bedeutet der Einsatz in anderen MediaWikis ist erlaubt solange der Hinweis auf den Author und die GPL erhalten bleibt. Dazu genügt, in diesem Falle, bereits der von der Erweiterung selbst erzeugte Link auf der System Seite Spezial:Version. Natürlich kann die Erweiterung auch in anderen System benutzt werden, unter Beachtung der GPL.
Über einen kleinen Hinweis (auf der Diskussionsseite) in welchem Wiki die Erweiterung eingesetzt wird würde ich mich freuen, ist aber keine Pflicht.
BlockSpammer
Beschreibung
BlockSpammer ist eine Mediawiki Erweiterung die verhindert das unangemeldete Benutzer (IPs) externe Links in Artikel eintragen. Die Erweiterung prüft Änderungen von nicht angemeldeten Benutzern. Wenn diese einen verdächtigen Eintrag machen wird die Übername der Änderungen verweigert. Momentan prüft die Erweiterung nur auf externe Links.
NewArticle
Beschreibung
Die Erweiterung NewArticle erzeugt, immer wenn ein neuer Artikel angelegt wird, eine Auswahl an Vorlagen. Wird eine dieser Vorlagen ausgewählt so wird die Vorlage in das Editorfeld eingefügt. Sinn ist es das Erstellen von Artikeln nach den Artikelvorlagen zu erleichtern.
Hinweis: Die Erweiterung wurde mit den MediaWiki Versionen 1.10.0+ getestet.
Technik
NewArticle ist eine MediaWiki Erweiterung die sich an den Hook AlternateEdit anhängt. Dabei wird bei jedem Aufruf des Editors geprüft ob es sich um einen neuen Artikel handelt. Ist dies der Fall wird die Steuerdatei MediaWiki:NewArticle ausgelesen und entsprechend der Einleitungstext erzeugt. Das Einfügen des Vorlage erfolgt dann online über eine Javascript. Dazu werden die Vorlagen bei der Erstellung der Seite eingelesen und in eine Javascript Funktion verpackt.
Ab der Version 0.9 prüft die Erweiterung auf die Anweisungen <noinclude> und <includeonly>. Diese werden erkannt und entsprechend ausgewertet.
Hinweis Es wird geprüft ob es sich um einen neuen Artikel handelt, d.h. ein bereits gespeicherte Artikel ohne Inhalt wird nicht als neu angesehen.
Einstellungen
Die Steuerung der Erweiterung erfolgt über Befehle auf der Seite MediaWiki:NewArticle. Der Aufbau der Seite ist:
Parameter1==Wert1 // Parameter2==Wert2
Die einzelnen Befehlszeilen werden jeweils durch eine Zeile getrennt die nur die Zeichenfolge // enthält.
Folgende Werte können für den Parameter benutzt werden:
- Start - Der Wert nach dem Trennzeichen (==) wird vor der Liste der Vorlagen ausgegeben. Der Text wird direkt als HTML ausgegeben, MediWiki Code wird nicht ausgewertet.
- End - Wie beim Parameter Start, nur wird der Text als Abschluss nach der Liste der Vorlagen ausgegeben.
- Einleitung - Der Wert wird in der ersten Zeile der Auswahlbox angezeigt. Wird der Parameter nicht angegeben so erscheint dort Bitte wählen.
Bei allen anderen Zeilen ist der Parameter der Text der in der Liste angezeigt wird und der Wert ist der Name des Artikels, ohne die Namensraumangabe. Das folgende Beispiel
Start==<div class="main"><div class="heading">Neuen Artikel anlegen</div> Du bist dabei einen neuen Artikel in Stargate Wiki zu schreiben. Um dir die Arbeit zu erleichtern und ein einheitliches Erscheinungsbild der Artikel zu erreichen gibt es in Stargate Wiki Vorlagen für einzelne Artikelgruppen. Wähle daher bitte aus der Liste das Thema des neuen Artikels aus. Die entsprechende Artikelvorlage wird dann in das Editorfeld eingefügt und kann sofort bearbeitet werden.<br /><br />Natürlich kannst du auch einen Artikel ohne Vorlage anlegen. Dies ist z.B. bei Diskussions-, Weiterleitungs- oder auch Begriffsklärungs-Seiten nötig.<br /><br /> Thema des Artikels // Person -> Vorlage:Personenbeschreibung==Personenbeschreibung // Objekt -> Vorlage:Objektbeschreibung==Objektbeschreibung // Episode -> Vorlage:Episodenbeschreibung==Episodenbeschreibung // Darsteller -> Vorlage:Darstellerbeschreibung==Darstellerbeschreibung // Planet -> Vorlage:Planetenbeschreibung==Planetenbeschreibung // End==<br /><br />Vielen Dank.</div>
erzeugt über dem Editorfeld die folgende Ausgabe:
Hinweis: Die CSS-Klassen main und heading sind in Stargate Wiki definiert. Bei einem Einsatz in einem anderen Wiki kann man hier natürlich andere Definitionen benutzen.
Probleme & Ideen
- Es finden noch kaum Prüfungen auf Fehler statt.
- Text als Wikitext interpretieren.
SGHtml
Beschreibung
Die Erweiterung verändert der HTML Code der von MediaWiki erzeugt wird. Dabei werden die folgenden Anpassungen gemacht:
- Externe Seiten werden in einem eigenen Fenster aufgerufen
- Alle Überschriften der Stufe 2 (==) erhalten am rechten Rand einen ~^ als Link auf den Seitenanfang.
- Bild Datei:Bearbeiten.png statt Text Bearbeiten um einen Abschnitt zu bearbeiten
- Werkzeug Spoiler aufdecken als Javascript-Button einbinden wenn auf der Seite ein Spoiler benutzt wird.
- Pfeile <~, ~>,~^ und ~V im Artikel durch Bilder (<~,~>,~^,~V) ersetzen.
- Hinweis: Die Erweiterung ersetzt die Pfeile auch im Bereich <pre> und <nowiki>. Die einzige Möglichkeit dies zu verhindern besteht darin statt dem Zeichen ~ im Text den Code ~ zu schreiben.
Installation
Um die Erweiterung zu benutzen müssen die Bilder für die Pfeile in das Verzeichnis skins/common/images/16x16 gespeichert werden. Am einfachsten ist es dazu die Bilder auf dieser Seite mit dem Browser zu speichern und sie dann auf den Server zu laden.
Programmcode
Die Erweiterung benutzt die MediaWiki Hooks OutputPageBeforeHTML, PersonalUrls und BeforePageDisplay.
Code
Download des Codes: SGPack.php
<?php
if(!defined('MEDIAWIKI')) { die('This filse is a MediaWIki extension, it is not a valid entry point'); }
// Information about the extension
$credits = array(
'path' => __FILE__,
'name' => 'SGPack',
'version' => '0.5.0',
'url' => 'http://www.stargate-wiki.de/wiki/Benutzer:Rene/SGPack',
'author' => 'René Raule',
'description' => 'Extensions-Pack for [http://www.stargate-wiki.de/ Stargate-Wiki]'.
'<br/>* Cache-Array: Array Function for templates'.
'<br/>* SGHTML: Modify HTML-Code (external page, edit button, spoiler)'.
'<br/>* DDInsert: Insert text by Buttons, Text or DropDownList'.
'<br/>* PageProtection: Protect User Pages'.
'<br/>* NewArticle: Choose template for new article'.
'<br/>* BlockSpammer: Simple spammblocker'.
'<br/>* ParserAdds: Some small parser-functions (trim,userinfo,recursiv)'
);
$wgExtensionCredits['parserhook'][] = $credits;
$wgExtensionCredits['other'][] = $credits;
/* Register extension , install hook handler */
$wgExtensionFunctions[] = 'SGP_Setup'; // set Hooks for functions
$wgHooks['LanguageGetMagic'][] = 'SGP_Magic'; // define parser words
// Register parser-extension
function SGP_Setup() {
global $wgParser,$wgHooks,$wgExtensionMessagesFiles;
$SGP_CacheArray = new SGP_CacheArray();
$SGP_ParserAdds = new SGP_ParserAdds();
$SGP_PageProtection = new SGP_PageProtection();
$SGP_DDInsert = new SGP_DDInsert();
$SGP_SGHTML = new SGP_SGHTML();
$SGP_NewArticle = new SGP_NewArticle();
$SGP_BlockSpammer = new SGP_BlockSpammer();
$wgParser->setFunctionHook( 'carray', array(&$SGP_CacheArray,'carray'), SFH_NO_HASH );
$wgParser->setFunctionHook( 'keys', array(&$SGP_CacheArray,'keys'), SFH_NO_HASH );
$wgParser->setFunctionHook( 'trim', array(&$SGP_ParserAdds,'trim') , SFH_NO_HASH );
$wgParser->setFunctionHook( 'userinfo', array(&$SGP_ParserAdds,'userinfo') , SFH_NO_HASH );
$wgParser->setFunctionHook( 'recursiv', array(&$SGP_ParserAdds,'recursiv') );
$wgParser->setHook('ddselect',array(&$SGP_DDInsert,'ddISelect'));
$wgParser->setHook('ddvalue',array(&$SGP_DDInsert,'ddIValue'));
$wgParser->setHook('ddbutton',array(&$SGP_DDInsert,'ddIButton'));
$wgParser->setHook('user',array($SGP_PageProtection, 'fnSGPPUser'));
$wgHooks['userCan'][] = array($SGP_PageProtection, 'fnSGPageProtection'); // check the page permissions
$wgHooks['OutputPageBeforeHTML'][] = array(&$SGP_SGHTML,'SGHtml');
$wgHooks['BeforePageDisplay'][] = array(&$SGP_SGHTML,'fnSGHtmlBPD');
$wgHooks['SkinTemplateContentActions'][] = array(&$SGP_SGHTML,'ContentActions');
//$wgHooks['PersonalUrls'][] = array(&$SGP_SGHTML,'ShowSpoiler');
$wgHooks['AlternateEdit'][] = array(&$SGP_NewArticle,'NewArticle');
$wgHooks['ArticleSave'][] = array(&$SGP_BlockSpammer,'CheckBlockSpammer');
// load messages
$wgExtensionMessagesFiles['SGPack'] = dirname(__FILE__) . '/SGPack.i18n.php';
wfLoadExtensionMessages( 'SGPack' );
}
// Define magic words
function SGP_Magic( &$magicWords, $langCode ) {
$magicWords['carray'] = array( 0, 'carray' );
$magicWords['keys'] = array( 0, 'keys' );
$magicWords['trim'] = array( 0, 'trim' );
$magicWords['userinfo'] = array( 0, 'userinfo' );
$magicWords['recursiv'] = array( 0, 'recursiv' );
return true;
}
/* Simple Spam Blocker */
class SGP_BlockSpammer {
function __construct() {
global $wgBlockSpammerPatterns;
if(!is_array($wgBlockSpammerPatterns)) {
$wgBlockSpammerPatterns = array ('/http/i', // externe Links beginnen mit: http
);
}
}
function diff($old, $new) {
foreach($old as $oindex => $ovalue) {
$nkeys = array_keys($new, $ovalue);
foreach($nkeys as $nindex) {
$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ? $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
if($matrix[$oindex][$nindex] > $maxlen) {
$maxlen = $matrix[$oindex][$nindex];
$omax = $oindex + 1 - $maxlen;
$nmax = $nindex + 1 - $maxlen;
}
}
}
if($maxlen == 0) return array(array('d'=>$old, 'i'=>$new));
return array_merge(
$this->diff(array_slice($old, 0, $omax), array_slice($new, 0, $nmax)),
array_slice($new, $nmax, $maxlen),
$this->diff(array_slice($old, $omax + $maxlen), array_slice($new, $nmax + $maxlen)));
}
function diffwalkI($value,$key,$collect) {
if(isset($value['i'])) {
foreach($value['i'] as $str) {
$collect .= $str;
}
}
}
function diffdiff($old,$new) {
$result = $this->diff($old,$new);
$insert = '';
array_walk($result,array($this,'diffwalkI'),&$insert);
return $insert;
}
function CheckBlockSpammer (&$article,&$user,&$text ) {
global $wgBlockSpammerPatterns;
global $wgOut;
if($user->mId == 0) {
$t = $this->diffdiff(explode("\n",$article->mContent),explode("\n",$text));
foreach ($wgBlockSpammerPatterns as $re) {
if (preg_match($re, $t)===1) {
$wgOut->errorpage('block_spammer_error_page_title', 'block_spammer_error' );
return false;
}
}
}
return true;
}
}
/* Template for new Article */
class SGP_NewArticle {
// Umwandeln einer Zeichenkette fuer die JS Funktion unescape()
function JSencode($text) {
return rawurlencode(html_entity_decode(htmlentities($text,ENT_QUOTES,'UTF-8')));
}
/* Filter des Artikels, noinclude Bereiche entfernen */
function FilterPage($text) {
// <noinclude> Bereiche komplett entfernen
$expr = '/(.*)<noinclude>(?s).*<\/noinclude>(.*)/';
$replace = '$1$2';
$text = preg_replace($expr,$replace,$text);
// <includeonly>, </includeonly> einfach entfernen
$expr = '/(.*)<includeonly>|<\/includeonly>(.*)/';
$replace = '$1$2';
$text = preg_replace($expr,$replace,$text);
return $text;
}
function NewArticle(&$seite) {
global $wgOut;
// Pruefen ob der Artikel neu ist
if( !$seite->mArticle->exists() ) {
// Steuerseite einlesen "MediaWiki:NewArticle"
$steuer = new Article(Title::makeTitle(8,'NewArticle'));
$steuer->getContent();
// Pruefen ob Steuerseite vorhanden
if( $steuer->mContentLoaded ) {
// Ausgabe Puffer Variablen anlegen
$einleitung = ''; $abschluss = ''; $artikelListe = ''; $textErsteWahl = 'Bitte wählen';
$listenKopf = '<script type="text/javascript">';
$listenKopf .= 'function NewArticleGo(select) {';
$listenKopf .= 'var wert=select.options[select.options.selectedIndex].value;';
$listenKopf .= "insertTags('',unescape(wert),'');";
$listenKopf .= "}</script>\n";
$listenKopf .= '<select size="1" id="NewArticleSelect" onchange="NewArticleGo(this);">'."\n";
// Die einzelnen Zeilen, getrennt durch eine Zeile mit //, in Array einlesen
$steuerArray = explode("\n//\n", $steuer->mContent);
foreach( $steuerArray as $index => $value ) {
// Die Zeile aufteilen an den Zeichen ==
$zeile = explode("==",$value);
if( $zeile[0] == 'Start' ) {
$einleitung = $zeile[1];
} elseif ( $zeile[0] == 'End' ) {
$abschluss = $zeile[1];
} elseif ( $zeile[0] == 'Einleitung' ) {
$textErsteWahl = $zeile[1];
} else {
// Artikel einlesen umwandeln und im HTML Code ablegen
$artikel = new Article(Title::makeTitle(10,$zeile[1]));
$artikel->getContent();
$artikelListe .= '<option value="'.$this->JSencode($this->FilterPage($artikel->mContent)).'">';
$artikelListe .= $zeile[0]."</option>\n";
unset($artikel);
}
}
$ersteWahl = '<option value="">'.$textErsteWahl.'</option>'."\n";
// Ergebniss in die Ausgabe einfuegen
$wgOut->addHTML($einleitung.$listenKopf.$ersteWahl.$artikelListe.'</select>'.$abschluss);
}
}
return true;
}
}
/* Modify HTML-Code */
class SGP_SGHTML {
private $isSpoiler = false;
// Letzte Änderungen direkt vor der Ausgabe
function fnSGHtmlBPD(&$out) {
$keywords = array('Stargate','Stargate SG-1','Stargate Atlantis','Stargate Universe','Stargate Lexikon');
if($this->isSpoiler) {
$out->addScript('<script type="text/javascript">/*<![CDATA[*/
function switchSpoiler() {
var Rows = [document.getElementsByTagName("div"),document.getElementsByTagName("span")];
for(var c in Rows) { for(var i=0, j=Rows[c].length; element=Rows[c][i]; i++) {
switch(element.className) { case "spoiler" : element.className = "spoilerOK"; break;
case "spoilerOK" : element.className = "spoiler"; break; } } }
var caSpoiler = document.getElementById("ca-Spoiler");
if(catSpoiler.innerHTML.search(/Spoiler aufdecken/)!=-1) { caSpoiler.innerHTML = caSpoiler.innerHTML.replace(/aufdecken/,"verdecken");
} else { caSpoiler.innerHTML = caSpoiler.innerHTML.replace(/verdecken/,"aufdecken"); } }
/*]]>*/</script>');
}
// Weitere Meta Begriffe
foreach($keywords as $word) {
$out->addKeyword($word);
}
return true;
}
function ContentActions(&$content_actions) {
if($this->isSpoiler) {
$ref = "javascript:switchSpoiler()";
$text = 'Spoiler aufdecken';
$class = 'bt-Spoiler';
$active = false;
$content_actions['Spoiler'] = array('class'=>$class,'text'=>$text,'href'=>$ref);
}
return true;
}
function ShowSpoiler(&$personal_urls,&$wgTitle) {
if($this->isSpoiler) {
$ref = "javascript:switchSpoiler()";
$text = 'Spoiler aufdecken';
$class = 'bt-Spoiler';
$active = false;
$personal_urls['Spoiler'] = array( 'text' => $text,'href' => $ref,'class' => $class, 'active' => $active );
$content_actions[] = array('class'=>false,'text'=>$text,'href'=>$ref);
}
return true;
}
function SGHtml( &$out, &$text ) {
global $wgScriptPath;
$mTable = array(
'class="external text"' => 'class="external text" target="_blank"', // Externe Seiten in eigenem Fenster
'class="external autonumber"' => 'class="external autonumber" target="_blank"',
'<~' => '<img src="'.$wgScriptPath.'/skins/common/images/16x16/blue_left.gif" alt="<-" />',
'~>' => '<img src="'.$wgScriptPath.'/skins/common/images/16x16/blue_right.gif" alt="->" />',
'~^' => '<img src="'.$wgScriptPath.'/skins/common/images/16x16/blue_up.gif" alt="^" />',
'~V' => '<img src="'.$wgScriptPath.'/skins/common/images/16x16/blue_down.gif" alt="V" />',
);
foreach( $mTable as $from => $to ) {
$text = str_replace( $from, $to, $text );
}
// Ueberschrift finden
$suchen = '#<h(\d)><span class="editsection">\[<a href="(.*?)"\s+title="(.*?)">Bearbeiten<\/a>\]<\/span>\s*<span class="mw-headline">(.*?)<\/span>#e';
// Neue Ueberschrift mit Bildern
// Test ob H2 Ueberschrift, nur dann wird der Link an den Seitenanfang eingefuegt.
$ersatz = '"<h$1>".($1==2?"';
$ersatz .= '<a href=\"#top\" title=\"Seiten Anfang\" style=\"vertical-align: top; float: right;\"><img src=\"'.$wgScriptPath.'/skins/common/images/16x16/blue_up.gif\" alt=\"^\" /></a>';
$ersatz .= '":"").';
$ersatz .= '"<span class=\"mw-headline\">$4</span> <a href=\"$2\" title=\"$3\">';
$ersatz .= '<img src=\"'.$wgScriptPath.'/skins/common/images/16x16/edit.png\" alt=\"[bearbeiten]\" style=\"vertical-align:top; margin-top:-3px;\" /></a>"';
$text = stripslashes(preg_replace($suchen,$ersatz,$text));
$this->isSpoiler = strpos($text,'class="show_spoiler"');
return true;
}
}
/* Page Protection */
class SGP_PageProtection {
// buffer results from fnSGPageProtection to speed up program
private $lastResult = array();
function __construct() {
global $wgSGPPBlockNamespaces;
global $wgSGPPOpenNamespaces;
global $wgSGPPOwnerAlways;
global $wgGroupPermissions;
// Default values for PageProtection
if(!is_array($wgSGPPBlockNamespaces)) { $wgSGPPBlockNamespaces = array(NS_USER); }
if(!is_array($wgSGPPOpenNamespaces)) { $wgSGPPOpenNamespaces = array(NS_USER_TALK); }
if(!is_bool($wgSGPPOwnerAlways)) { $wgSGPPOwnerAlways = true; }
if(!is_bool($wgGroupPermissions['sysop']['SGPPEditFree'])) { $wgGroupPermissions['sysop']['SGPPEditFree'] = true; }
}
/* Handel user-tags, just drop them */
function fnSGPPUser($input,$argv,&$parser) {
return '';
}
function fnSGPageProtection( $title, $user, $action, &$result ) {
global $wgSGPPBlockNamespaces;
global $wgSGPPOpenNamespaces;
global $wgSGPPOwnerAlways;
global $wgGroupPermissions;
// if this article was already testet just give the result
if(isset($this->lastResult[$title->getText()][$action])) { return $this->lastResult[$title->getText()][$action]; }
// Name of actual user
$username = $user->getName();
/* Do nothing if ...
... usergroup is free */
if( $user->isAllowed('SGPPEditFree') ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
/* ... wrong namespace */
if( !in_array($title->mNamespace,array_merge($wgSGPPBlockNamespaces,$wgSGPPOpenNamespaces)) ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
/* ... action not edit or move */
if( !($action == 'edit' || $action == 'move') ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
/* ... user is owner of article and ownerflag is set (only in USER & USER_TALK namespaces) */
if( ($title->mNamespace == NS_USER) || ($title->mNamespace == NS_USER_TALK) ) {
/* get user name, title and get user part out of title */
$fulltitle = $title->getText();
list($usertitle,$subtitle) = explode('/',$fulltitle,2);
if( $wgSGPPOwnerAlways && ($usertitle == $username) ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
}
/* simple checks are over now, look for user-tags in article content */
/* get article (? can we find it already somewhere ?) */
$article = new Article($title);
$text = $article->fetchContent(0);
/* drop <nowiki>xxx parts */
$expr = '/(.*?)<\s*nowiki\s*>(?s).*?<\/\s*nowiki\s*>(.*?)/i';;
$replace = '$1';
$text = preg_replace($expr,$replace,$text);
/* ip-user */
if( $user->mId == 0 ) {
/* look for <user>**</user> */
if( preg_match("/<\s*user\s*>\s*\*\*\s*<\/\s*user\s*>/",$text) > 0 ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
} else { /* normal user */
/* look for <user>$username</user> */
if( preg_match("/<\s*user\s*>\s*$username\s*<\/\s*user\s*>/",$text) > 0 ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
/* look for <user>*</user> */
if( preg_match("/<\s*user\s*>\s*\*\s*<\/\s*user\s*>/",$text) > 0 ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
}
/* if open namespaces and no user-tag is defined */
if( in_array($title->mNamespace,$wgSGPPOpenNamespaces) && preg_match("/<\s*user\s*>.*<\/\s*user\s*>/",$text) == 0 ) {
$this->lastResult[$title->getText()][$action] = true;
return true;
}
/* Nothing matched so the result ist NOT ALLOWED */
$this->lastResult[$title->getText()][$action] = false;
$result = false;
return false;
}
}
/* DropDownInsert */
class SGP_DDInsert {
private $ddIBlock = array();
// button
function ddIButton($input,$argv,&$parser) {
// if no show parameter is given use input also as showText
$show = isset($argv['show']) ? htmlspecialchars($argv['show']) : $input;
// get sampleText if given
$sample = isset($argv['sample']) ? $argv['sample'] : '';
// picture
if(isset($argv['picture'])) {
$image = Image::newFromName($argv['picture']);
if($image->exists()) {
$iwidth = $image->getWidth();
$iheight = $image->getHeight();
$show = '<img src="'.$image->getURL().'" width="'.$iwidth.'" height="'.$iheight.'" />';
}
}
$einput = explode('+',htmlspecialchars($input,ENT_QUOTES,'UTF-8'));
$output = '<a name="'.$name.'"';
$output .= ' style="padding:1px; font-size:small;"';
$output .= ' href="javascript:insertTags(\''.$einput[0].'\',\''.$einput[1].'\',\''.$sample.'\');"';
$output .= '>'.$show.'</a>';
return $output;
}
// Create Output
function ddIOutput() {
global $wgOut;
$cssimage = '';
$output = '';
$output .= '<select size="'.$this->ddIBlock['size'].'" name="'.$this->ddIBlock['name'].'"';
$output .= ' onChange="insertTags(unescape(this.options[this.options.selectedIndex].value).split(\'+\')[0],unescape(this.options[this.options.selectedIndex].value).split(\'+\')[1],unescape(this.options[this.options.selectedIndex].value).split(\'+\')[2]); this.options.selectedIndex=0;"';
$output .= '>';
$output .= '<option value="++" selected="selected">';
$output .= $this->ddIBlock['title'];
$output .= '</option>';
foreach($this->ddIBlock['values'] as $values) {
$output .= $this->ddILine($values['text'],$values['value'],$values['image']);
}
$output .= "</select>";
return $output;
}
// <ddselect title="titleText" size="sizeInt" name="nameText">...</ddselect>
function ddISelect($input,$argv,&$parser) {
$this->ddIBlock = array('size'=>1,'name'=>'Auswahl','title'=>'[ bitte wählen ]','pwidth'=>0,'pheight'=>1,'values'=>array());
if(isset($argv['title'])) {
$this->ddIBlock['title'] = $argv['title'];
}
if(isset($argv['size'])) {
$this->ddIBlock['size'] = $argv['size'];
}
if(isset($argv['name'])) {
$this->ddIBlock['name'] = $argv['name'];
}
$parser->recursiveTagParse($input);
return $this->ddIOutput();
}
// <ddvalue show="showText" sample="sampleText" picture="name">value</ddvalue>
function ddIValue($input,$argv,&$paser) {
// if no show parameter is given use input also as showText
$show = isset($argv['show']) ? $argv['show'] : $input;
// get sampleText if given
$sample = isset($argv['sample']) ? $argv['sample'] : '';
// add + to input if not set - need for javascript-split
if(strpos($input,"+") === false) {
$input .= "+";
}
// picture
$iURL = '';
if(isset($argv['picture'])) {
$image = Image::newFromName($argv['picture']);
if($image->exists()) {
$iURL = $image->getURL();
$iwidth = $image->getWidth();
$iheight = $image->getHeight();
if($iwidth > ($this->ddIBlock['pwidth']-5)) {
$this->ddIBlock['pwidth'] = $iwidth+5;
}
if($iheight > ($this->ddIBlock['pheight'])) {
$this->ddIBlock['pheight'] = $iheight;
}
}
}
// save parameter to global array
$this->ddIBlock['values'][] = array('value'=>$input.'+'.$sample,'text'=>$show,'image'=>$iURL);
return '';
}
// create option line
function ddILine($text,$value,$image) {
if($this->ddIBlock['pwidth'] > 0) {
if(!empty($image)) {
$css = 'style="height: '.$this->ddIBlock['pheight'].'px; padding-left: '.$this->ddIBlock['pwidth'].'px; padding-right: 5px; background-repeat: no-repeat; background-image: url('.$image.');"';
} else {
$css = 'style="padding-left: '.$this->ddIBlock['pwidth'].'px; padding-right: 5px;"';
}
} else {
$css = '';
}
$output = '<option '.$css.' value="'.rawurlencode(html_entity_decode(htmlentities($value,ENT_NOQUOTES,'UTF-8'))).'">'.$text.'</option>'."\n";
return $output;
}
}
/* ParserAdds */
class SGP_ParserAdds {
// trim
function trim( &$parser, $inStr='') {
return array(trim($inStr),'isHTML'=>true,'noparse'=>true);
}
//
function userinfo( &$parser, $inStr='name') {
global $wgUser;
$back = '';
switch($inStr) {
case 'name' : $back = $wgUser->mName;
break;
case 'id' : $back = $wgUser->mId;
break;
case 'realname' : $back = $wgUser->mRealName;
break;
case 'email' : $back = $wgUser->mEmail;
break;
case 'home' : $back = '[[Benutzer:'.$wgUser->mName.']]';
break;
case 'talk' : $back = '[[Benutzer Diskussion:'.$wgUser->mName.']]';
break;
}
return array($back,'noparse'=>true);
}
function recursiv( &$parser, $parstext = '', $calltemplate = '', $callparameter = '' ) {
# The parser function itself
# The input parameters are wikitext with templates expanded
# The output should be wikitext too
if(empty($callparameter)) {
$replace = '{{'.$calltemplate.'|\1|kl}}';
} else {
$replace = '{{'.$calltemplate.'|(\1)|'.$callparameter.',kl}}';
}
// $output = preg_replace("/\{\{\{\{(.*?)\}\}\}\}/", $replace , $parstext,-1,$count);
$output = preg_replace("/\((.*?)\)/", $replace , $parstext,-1,$count);
if($count == 0) {
if(empty($callparameter)) {
$output = '{{'.$calltemplate.'|'.$parstext.'}}';
} else {
$output = '{{'.$calltemplate.'|'.$parstext.'|'.$callparameter.'}}';
}
}
return array($output,'noparse'=>false);
}
}
/* Cache Array */
class SGP_CacheArray {
private $Cache = array();
private $Key_Delimiter = '_';
// combinate keys
function keys() {
// get the parser parameter
$param = func_get_args();
$parser = current($param);
// get the parts for the key
$key = '';
while($value = next($param)) {
// get key-modifier(s) m:key
list($mod,$mvalue) = explode(':',$value,2);
// if mvalue is set means we also have modifier
if(isset($mvalue)) {
if(strpos($mod,'u')!==false) { // uppercase
$mvalue = strtoupper($mvalue);
}
if(strpos($mod,'l')!==false) { // lowercase
$mvalue = strtolower($mvalue);
}
$value = $mvalue;
}
// keys always trim
$value = trim($value);
// drop empty mw-variables
$value = preg_replace('/\{\{\{.*?\}\}\}/','',$value);
// if value is not empty add to key
if(!empty($value)) {
if(!empty($key)) {
$key .= $this->Key_Delimiter;
}
$key .= $value;
}
}
return $key;
}
// carray main part
function carray() {
// minimum parser, cachenumber and action are needed
if(func_num_args() < 3) {
return array('','noparse'=>true);
}
// get the parser parameter
$param = func_get_args();
$parser = current($param);
// get the first two wiki-parameters (chachenumber, action)
$cnumber = trim(next($param));
$action = strtolower(trim(next($param)));
// default output is empty
$output = '';
// action
switch($action) {
case 'f' :
case 'file' :
case 'fr' :
case 'fileread' :
// read array out of "file"
$file = next($param);
// if carray is already set do not read it again (cache!)
if(!isset($this->Cache[$cnumber])) {
$fh = new Article(Title::newFromText($file));
$content = $fh->fetchContent();
if($fh->mContentLoaded) {
$cont = explode('|',$content);
foreach($cont as $line) {
list($index,$value) = explode('=',$line,2);
$this->Cache[$cnumber][trim($index)] = trim($value);
}
}
}
// leave switch (only if file)
if(($action === 'f') or ($action === 'file')) {
break;
}
// read key
$key = trim(next($param));
// read cache
$value = $this->Cache[$cnumber][$key];
// if no value, look for default
if(isset($value)) {
$output = $value;
} else {
if(isset($this->Cache[$cnumber]['#default'])) {
$output = $this->Cache[$cnumber]['#default'];
}
}
break;
case 'w' : // only create new carray
case 'write' :
case 'rw' : // write new carray and read one value
case 'readwrite' :
// read key (only if readwrite)
if(($action === 'rw') or ($action === 'readwrite')) {
$key = trim(next($param));
}
// if carray is already set do not read it again (cache!)
if(!isset($this->Cache[$cnumber])) {
// read the keys and values and save in carray
while($values = next($param)) {
list($index,$value) = explode('=',$values,2);
$this->Cache[$cnumber][trim($index)] = trim($value);
}
}
// leave switch (only if write)
if(($action === 'w') or ($action === 'write')) {
break;
}
case 'r' : // read value out of carray
case 'read' :
// read key, if not already set by action readwrite
if(!isset($key)) {
$key = trim(next($param));
}
// read cache
$value = $this->Cache[$cnumber][$key];
// if no value, look for default
if(isset($value)) {
$output = $value;
} else {
if(isset($this->Cache[$cnumber]['#default'])) {
$output = $this->Cache[$cnumber]['#default'];
}
}
break;
case 'd' : // delete carray
case 'delete' :
unset($this->Cache[$cnumber]);
break;
case 'c' : // count elements in carray
case 'count' :
$output = count($this->Cache[$cnumber]);
break;
case 'u' : // test if cache is used
case 'used' :
// if carray is used give size
if(isset($this->Cache[$cnumber])) {
$output = count($this->Cache[$cnumber]);
}
break;
}
return array($output,'noparse'=>true);
}
}
</nowiki>
Download des Codes SGPack.i18n.php
<?php /** * Internationalisation file for extension BlockSpammer. * */ $messages = array(); /** * English */ $messages['en'] = array( 'block_spammer_error_page_title' => 'Spam suspicion', 'block_spammer_error-desc' => 'IP User are not allowed to make external links', 'block_spammer_error' => 'Sorry, your edit seems to be spam. You must register to make this edit.', ); /** Message documentation (Message documentation) * @author Purodha */ $messages['qqq'] = array( 'block_spammer_error-desc' => 'Shown in [[Special:Version]]', ); /** German (Deutsch) */ $messages['de'] = array( 'block_spammer_error_page_title' => 'Spam Verdacht', 'block_spammer_error-desc' => 'Nicht angemeldete Benutzer dürfen keine externen Links anlegen.', 'block_spammer_error' => 'Die letzte Änderungen kann nicht gespeichert werden da der Verdacht auf Spam besteht. Änderungen dieser Art sind nur angemeldeten Benutzern erlaubt.', );