Eigene Erweiterung entwerfen
Zur Navigation springen
Zur Suche springen
Ein Formular für Berechnungen entwerfen
<?php
/**
* MediaWiki extension: CalcForm
* =============================
*
* To activate, edit your LocalSettings.php,
* save this code as 'CalcForm.php' and copy the file into the subdirectory CalcForm of your extensions-directory and add
* require_once("$IP/extensions/CalcForm/CalcForm.php");
*/
# User Settings
# require_once("$IP/extensions/CalcForm/CalcForm.php");
# Parameter
# inlabels ... Beschriftung der Eingabefelder
# inids ... eindeutige IDs für die Eingabefelder (muss je Seite eindeutig sein)
# ivalues ... Vorbelegung der Eingabefelder
# outlabels ... Beschriftung der Ausgabefelder
# outids ... eindeutige IDs für die Ausgabefelder (muss je Seite eindeutig sein)
# onclick ... Berechnungsvorschrift, was bei Mausklick passieren soll
# oninput ... Berechnungsvorschrift, was bei Dateneingabe passieren soll
# zumindest eine der beiden Eingaben muss vorhanden sein
# die fehlende wird automatisch durch die andere ergänzt
# *********************************************************************************************
# Formatierung
# marginright ... Abstand zwischen Beschriftung und Ein/Ausgabefeld
# marginleft ... Abstand links
# fontsize ... Schriftgröße
# lwidth ... Breite der Beschriftungsfelder
# nwidth ... Breite der numerischen Felder
# End User Settings
# Diese Erweiterung erzeugt ein Formular zur Durchführung einfacher Berechnungen.
# Damit sollen gewisse Überprüfungen einfacher gemacht werden.
# Durch eine Extension wird die Aktivierung von RawHTML im Wiki überflüssig,
# somit werden viele Bearbeitungsschritte wieder einfacher
# es wird ein Formular erzeugt, dieses besitzt jedoch keinen Submit-Button
# jedes Formular erhält eine zufällige ID, dadurch können mehrere Formulare auf einer Seite
# verwendet werden
# JavaScript muss aktiviert sein, sonst funktioniert die Berechnung nicht
# im IE funktioniert die Berechnung ebenfalls nicht
define("X_CALC_TAG", "calc");
define("X_CALC_HOOK", "hookCalc");
define("X_CALC_NAME", "CalcForm");
if ( !defined( 'MEDIAWIKI' ) ) {
die( "This is not a valid entry point.\n" );
}
$wgExtensionCredits['parserhooks'][] = array(
'path' => __FILE__,
'name' => X_CALC_NAME,
'version' => '0.9',
'author' =>$extension_AUTH,
'url' => "$wgServer$wgScriptPath/index.php/Extension:" . X_CALC_NAME,
'description' => 'erzeugt Eingabeformulare zum Rechnen'
);
$wgExtensionFunctions[] = 'wfCalcFormExtension';
/*
* Setup OraForm extension.
* Sets a parser hook for <X_CALC_HOOK></X_CALC_HOOK>.
*/
function wfCalcFormExtension()
{
$extension_name = X_CALC_NAME;
new $extension_name();
}
class CalcForm
{
public function __construct()
{
global $wgParser;
$wgParser->setHook(X_CALC_TAG, array(&$this, X_CALC_HOOK));
}
public function hookCalc($input, $argv, $parser)
{
global $IP, $wgServer, $wgScriptPath, $wgUploadPath, $wgHooks, $wgParser, $wgHtml5, $wgScript, $wgTitle, $wgOut;
#return debug_zval_dump($_POST);
$input = trim($input);
$br = '<br>';
$onclick = $oninput = $inlabels = $outlabels = $inids = $outids = $ivalues = '' ;
$lwidth = '10em'; $nwidth = '5em';
$owidth = $iwidth = $lwidth;
$marginright = '0.5em'; $marginleft = '0'; $marginbottom = '0.5em'; $oright='0';
$fontsize = '1em'; $addstyle= '';
foreach ( $argv as $arg => $val )
{
$$arg = $val; # die Variablen erhalten den Namen der Parameter
}
if (empty($onclick) and empty($oninput)) return "irgendeine Berechnungsvorschrift sollte schon vorhanden sein";
else {
if (empty($onclick)) $onclick=$oninput;
if (empty($oninput)) $oninput=$onclick;
}
# Ein- und Ausgabebeschriftungen werden als Text übergeben, der durch ? getrennt ist
$ilabels = preg_split("/[\?\t\r\n\f\x0B]/", $inlabels);
$olabels = preg_split("/[\?\t\r\n\f\x0B]/", $outlabels);
# Ids für In- und Out-Felder
# deswegen erforderlich, damit mehrere Formulare auf einer Seite verwendet werden können
# automatische Generierung ist mir derzeit zu kompliziert
# da ich die Berechnungsergebnisse dann irgendwie auf diese Id's hintrimmen müsste
$iids = preg_split("/[\?\t\r\n\f\x0B]/", $inids);
$oids = preg_split("/[\?\t\r\n\f\x0B]/", $outids);
$istyle = "width: $iwidth; display: inline-block; font-size: $fontsize; font-weight: bold; padding: 0 0.5em;" .
"background-image: linear-gradient(#eaeaea, #f9f9f9, #eaeaea); margin-right: $marginright; margin-bottom: $marginbottom;";
$ostyle = "width: $owidth; display: inline-block; font-size: $fontsize; font-weight: bold; padding: 0 0.5em;" .
"background-image: linear-gradient(#eaeaea, #f9f9f9, #eaeaea); margin-right: $marginright; margin-bottom: $marginbottom;";
$nstyle = "width: $nwidth; font-size: $fontsize; display: inline-block; background-image: linear-gradient(#f9f9f9, #eaeaea); " .
"padding: 0 0.2em 0 0; margin-bottom: $marginbottom; margin-right: $oright;";
#return $style . $lstyle;
if (empty($class)) $class = "mono";
$izahl = count($iids);
$ozahl = count($oids);
$ivals = array_fill(0, $izahl, '');
$ivals = !empty($ivalues) ? preg_split("/[\?\t\r\n\f\x0B]/", $ivalues) : array_fill(0, $izahl, '');
$iput = "<div style='margin-left: $marginleft;$addstyle'>";
for ($x = 0; $x < $izahl; $x++)
{
$iput .= "<div style='$addstyle'><div style='$istyle' class='$class'>$ilabels[$x]</div><input " .
"style='$nstyle' id='$iids[$x]' type='text' value='$ivals[$x]' min='0'></input></div>
";
}
$iput .= '</div>';
$oput = '';
for ($x = 0; $x < $ozahl; $x++)
{
$oput .= "<div style='$ostyle' class='$class'>$olabels[$x]</div><output " .
"style='$nstyle' class='$class' id='$oids[$x]' type='text'></output>";
}
$formid = str_shuffle('abcdefghijklm');
$myform = "<form id='$formid' oninput='$oninput' onclick='$onclick'>" . $iput . $oput . "</form>";
return $myform;
}
}
Ein Formular für Vorlagenauswertung entwerfen
<?php
/**
* MediaWiki extension: OraForm
* =============================
*
* To activate, edit your LocalSettings.php,
* save this code as 'OraForm.php' and copy the file into the subdirectory OraForm of your extensions-directory and add
* require_once("$IP/extensions/OraForm/OraForm.php");
*/
# User Settings
# require_once("$IP/extensions/OraForm/OraForm.php");
# Parameter
# default ... Standardbelegung für Eingabefeld
# style ... CSS-Formatierung für Buttons
# namen ... String mit den Namen für die Eingabefelder, durch Leerzeichen getrennt
# cols ... String mit den Parameternamen, durch Leerzeichen getrennt
# falls die Anzahl der Eingabefelder von der Anzahl der Parameternamen abweicht,
# wird das Minimum der beiden Zahlen herangezogen
# typ ... t/m/j, gibt an ob das Datum ein Tag, Monat oder Jahr sein soll, default: t(Tag)
# ohne ... Form ohne Parameter, benötigt noch weitere Eingaben
# otext ... Buttonbeschriftung wenn SQL ohne Parameter
# End User Settings
define("ORA_NAME", "ora"); # Name of tag
define("ORA_IDENTIFIER", "sendOra"); # Name of POST identifier flag
define("ORA_HOOK", "hookOra"); # Name of hook
if ( !defined( 'MEDIAWIKI' ) ) {
die( "This is not a valid entry point.\n" );
}
$wgExtensionCredits['parserhooks'][] = array(
'path' => __FILE__,
'name' => 'OraForm',
'version' => '0.9',
'author' =>$extension_AUTH,
'url' => "$wgServer$wgScriptPath/index.php/Extension:OraForm",
'description' => 'ermöglicht es, SQL-Abfragen mittels Formulareingabe zu steuern'
);
$wgExtensionFunctions[] = 'wfOraFormExtension';
/*
* Setup OraForm extension.
* Sets a parser hook for <ORA_NAME></ORA_NAME>.
*/
function wfOraFormExtension()
{
new OraForm();
}
class OraForm
{
public function __construct()
{
global $wgParser;
$wgParser->setHook(ORA_NAME, array(&$this, ORA_HOOK));
}
public function hookOra($input, $argv, $parser)
{
global $IP, $wgServer, $wgScriptPath, $wgUploadPath, $wgHooks, $wgParser, $wgHtml5, $wgScript, $wgOut;
#if ( !($wgTitle->isProtected ('edit')))
# return $this->clear_input(" Die Erweiterung <" . ORA_NAME .
# "> darf nur auf geschützten Seiten verwendet werden.");
#return debug_zval_dump($_POST);
$input = trim($input);
$sent = $neu = $reset = $i_felder = $ohne = $otext = '';
if (!empty($_POST) and !empty($_POST["tuwas"])) $sent= true;
if ($sent)
{
#if (empty($_POST["tuwas"])) return; # irgendeine andere Aktion
$reset = ($_POST["tuwas"] == 2); # if sent: do or reset
$neu = ($_POST["tuwas"] == 1);
}
$div_beg = '<div style="margin-bottom: 0"><div style="';
$div_beg .= 'width: 15em; ';
$div_beg .= 'display: inline-block; padding-right: 0.5em; text-align: right">';
$button_style = 'border-radius: 1em; background-image: linear-gradient(90deg, #8f8,#cfc); padding: 0.5em 1.5em;'
. ' box-shadow: inset -2px -2px 5px #080; color: #080; font-weight: bold; font-size: 110%' ;
if (!empty($argv["style"])) # Änderung der Buttons möglich
$button_style = $argv["style"];
$ohne = false;
if (!empty($argv["ohne"])) # Buttonbeschriftung wenn SQL Statement ohne Parameter
{
$ohne = $argv["ohne"];
#$reset = false; # wenn keine Parameter dann gibt es auch kein Zurücksetzen
}
# Radiobutton abfragen
$radio = ''; # initialisieren um Fehlermeldungen zu vermeiden
if (!empty($argv["radiobutton"]) ) # es soll ein Feld mit Radiobuttons initialisiert werden
{
#$radioidx= intval($argv["radioindex"]);
#íf (!empty($radioindex)) # wenn Index fehlt ist alles andere hinfällig
#return $radioidx;
$radiolabels = preg_split("/[\?\t\r\n\f\x0B]/", $argv["radiolabels"]);
$radiobuttons = preg_split("/[;\?\t\r\n\f\x0B]/", $argv["radiobuttons"]);
$buttonzahl = count($radiobuttons) < count($radiolabels) ? count($radiobuttons) : count($radiolabels);
#return implode(":",$radiobuttons) . count($radiobuttons);
$radioname = $argv["radiobutton"];
$radio = '<div style="width: 15em; margin-left: 15em;"><fieldset><legend>' . $radioname . ':</legend>';
for ($x = 0; $x < $buttonzahl; $x++)
{
$radio .= "<label>" . '<input type="radio" name="' . $radioname . '" value="' . $x;
$radio .= $x ? '' : 'checked="checked"' ; # das erste Element checken
$radio .= '">' . $radiolabels[$x] . "</label><br>";
}
$radio .= "</fieldset></div>";
}
$dtyp = 'd'; $datumtext = 'Datum'; $dtxt = '{{#time:Ymd|'; # Datumseinstellungen: d/m/y
# wenn nach Tag abgefragt wird: dtyp=d, Standardwert: gestern
# wenn Monat gebraucht wird: dtyp=m, Standardwert: Vormonat
if (!empty($argv['typ']) and empty($ohne))
switch(strtolower($argv['typ']))
{
case 'j':
case 'y':
case 'jahr':
case 'year':
$dtyp = 'j';
$datumtext = 'Jahr';
$dtxt = '{{#time:Y0101|';
break;
case 'm':
case 'monat':
case 'month':
$dtyp = 'm';
$datumtext = 'Monat';
$dtxt = '{{#time:Ym01|';
break;
}
if (!empty($argv['datetext']))
$datumtext = $argv['datetext'];
if (empty($ohne))
if (empty($argv["default"])) $defdatum = $this->check_input('44.14.2011', 'd', $dtyp);
else $defdatum = $this->check_input($argv["default"], 'd', $dtyp);
if (!$sent and empty($ohne)) $datum = $defdatum; # wenn Formular noch nicht abgeschickt wurde
#return $defdatum . 'sent' . count($_POST);
$ccol = $cnames = -1;
$felder = [];
if (!empty($argv["cols"]))
# Namen der Vorlagenparameter
# falls man benannte Parameter verwenden will
{
#return "eingabefelder: " . $argv["cols"];
$felder = explode(' ', $argv["cols"]);
$ccol = count($felder);
}
else
{
$felder = false;
$ccol = 999;
}
if (!empty($argv["namen"]) )
# die Beschriftung der Eingabefelder
# durch Leerzeichen getrennt (jetzt mag ich es nicht mehr auf regex ändern)
{
$namen = str_replace('_', ' ', explode(' ', $argv["namen"])); # "_" durch Leerzeichen ersetzen
$cnames = count($namen);
}
$zahl = ($ccol < $cnames) ? $ccol : $cnames; # Zahl der Eingabefelder ermitteln, es dürfen nur so viele sein wie Feldnamen angegeben
$feld = array_fill(0, ($zahl>0) ? $zahl : 0, '');
if (empty($ohne))
{
$datum = $defdatum;
if (!empty($_POST['datum']))
$datum = $this->check_input($_POST['datum'],'d', $dtyp);
}
if ($sent and !$reset)
{
if ($zahl>=0) $feld = $_POST['feld'];
if (!empty($_POST['datum']))
$datum = $this->check_input($_POST['datum'],'d', $dtyp);
else
{
if (!empty($argv["default"]))
$datum = $this->check_input($defdatum, 'd', $dtyp);
else
$datum = $this->check_input('44.14.2011', 'd', $dtyp);
}
}
if ($reset)
{
$az = ($zahl>0) ? $zahl : 0;
$feld = array_fill(0, $az, '');
$datum = $this->check_input('44.14.2011', 'd', $dtyp);
if (!empty($argv["default"])) $datum = $defdatum;
}
# variable Feldanzahl für Abfragemöglichkeiten
# zuerst steht immer ein Datumswert außer es wird ohne angegeben
if (empty($ohne))
$i_felder = '<div style="margin-bottom: 1em">' . $div_beg . $datumtext
. ':</div><input type="text" name="datum" size="10" maxlength="10" value="' . $datum . '"></div>';
#else
#$i_felder = '<div style="margin: 1em; border: 1px solid green"></div>';
for ($x = 0; $x < $zahl; $x++)
{
$i_felder .= $div_beg . $namen[$x] . ':</div><input type="text" name="feld[]" size="10" value="' . $feld[$x] . '"></div>';
}
if (empty($ohne)) $i_felder .= '</div>';
#$meintitel = $wgOut->getPageTitle();
$formid = str_shuffle('abcdefghijklmnopqrst');
$myForm = '<div style="border: 2px dotted #afa; display: inline-block; padding: 1em"><form id="' . $formid . '" method="post">';
$myForm .= '<input type="hidden" name="action" value="view" >' ;
$myForm .= '<input type="hidden" name="' . ORA_IDENTIFIER . '" value="send" >';
$myForm .= $i_felder . $radio;
if (!empty($ohne)) $myForm .= '<div style="margin: 0.5em; "></div>';
$myForm .= $div_beg . '<button style="' . $button_style . '" type="submit" name="tuwas" value="3" formmethod="post">';
$myForm .= 'Abfrage durchführen';
$myForm .= '</button></div>';
$myForm .= '<div style="display: inline-block; padding-right: 0.5em;"><button style="';
$myForm .= $button_style . '" type="submit" name="tuwas" value="1" formtarget="_blank" formmethod="post">';
$myForm .= 'Abfrage in neuem Fenster durchführen';
$myForm .= '</button></div>';
$myForm .= '<button style="' . $button_style . '" type="submit" name="tuwas" value="2" formmethod="post">Eingabe zurücksetzen</button></div>';
$myForm .= '</form></div>';
$erg = $dateval = '';
if ($sent and !$reset)
# das Formular wurde gesendet und nicht zurück gesetzt
{
if (empty($ohne)) $dateval = $datum;# $this->check_input($_POST['datum'],'d', $dtyp); else $dateval = '1.1.2019';
$mitradio = '';
#return "Das soll das Eingabedatum sein : " . $dateval;
#return implode(":", $feld) . count($feld); # . implode(":", $felder) ;
if ($radio) # Radiobuttons
# die Vorlage sollte die Parameter radio und radiolabel auswerten
{
$i = intval($_POST[$radioname]);
$mitradio = '|radio=' . $radiobuttons[$i] . '|radiolabel=' . $radiolabels[$i];
#return "index: " . $radioidx . $radioname . $radiolabels[$i] . $radiobuttons[$i];
#$feld[$radioidx-2] = $radiobuttons[$i];
#$feld[$radioidx-1] = $radiolabels[$i];
}
#return implode(":", $feld) . '<br>Zahl: ' . $radioidx . $radiobuttons[$i] . $radiolabels[$i]; # . implode(":", $felder) ;
# dateval: Datumswert
# feld: Array mit den Parameterwerten
# felder: Array mit den Parameternamen, optional
$content = array($dateval, $feld, $felder);
#return implode(':',$felder) . $dateval;
$erg = $this->DoSomething($content, $input . $mitradio);
$seite = $this->render_wikitext($erg);
if ($neu)
$myForm = $seite;
else
$myForm .= $seite;
if (!empty($argv["mitvorlage"]))
$erg="<p><pre>" . $erg . "</pre>";
else $erg='';
}
return $myForm . $erg;
}
private function clear_input($data)
{
return htmlspecialchars(stripslashes(trim($data)));
}
private function render_wikitext($input)
{
global $wgParser;
$output = $wgParser->recursiveTagParse( $input );
return $output;
}
private function check_input($data, $typ = 'int', $was = 'd')
{
global $IP, $wgServer, $wgScriptPath, $wgUploadPath, $wgHooks, $wgParser, $wgHtml5, $wgScript, $wgTitle;
switch($typ)
{
case 'int':
case 'i':
default:
return intval($data );
break;
case 'date':
case 'd':
case 'datum':
$datestring = '{{#time:j.n.Y|';
if ($was == 'y' or $was == 'j') $datestring = '{{#time:Y|';
if ($was == 'm') $datestring = '{{#time:1.n.Y|';
$test = $wgParser->recursiveTagParse( '{{#time:l, j. F Y|' . $data . '}}' );
if (strpos($test, 'error'))
{
if ($was == 'm')
return $wgParser->recursiveTagParse( $datestring . '-1 months}}' );
if ($was == 'y' or $was == 'j')
return $wgParser->recursiveTagParse( $datestring . '-1 years}}' ) ;
return $wgParser->recursiveTagParse( $datestring . '-1 days}}' ) ;
}
else
return $wgParser->recursiveTagParse($datestring . $data . '}}');
}
}
private function DoSomething($params, $input)
{
global $IP, $wgServer, $wgScriptPath, $wgUploadPath, $wgHooks, $wgParser, $wgHtml5, $wgScript, $wgTitle, $wgOut;
#
# derzeit ist außer dem Datum noch keine Auswertefunktion implementiert
#
# wenn wir ein Select-Statement haben, müssen wir orasql hinzufügen
# params[0]: Datum
# params[1]: Array mit den restlichen Parametern
# params[2]: Array mit den Parameternamen, optional
$sel = strtolower(substr($input,0,6));
if ($sel == "select")
{
# wenn die Abfrage direkt eingefügt wird, können keine Parameter berücksichtigt werden
#$wrapped = $this->render_wikitext('<orasql>' . $input . '</orasql>');
$wrapped = '<orasql>' . $input . '</orasql>';
}
else
{
# als input muss eine Vorlage übergeben werden, die orasql auswertet
$argstr = '|1=' . $params[0] ; # der erste Parameter muss das Datum sein
if (!empty($params[1]) and is_array($params[1])) # Auswertung der restlichen Parameter
{
$argnames = false;
$args = $params[1];
$n = count($args);
if (is_array($params[2])) # ist ein Array mit Parameternamen vorhanden?
$argnames = $params[2]; # wenn ja übernehme Parameternamen für Vorlage
for ($x = 0; $x < $n; $x++)
{
if (!empty($args[$x])) $argstr .= '|' . (!$argnames ? $x+2 : $argnames[$x]) . '=' . $args[$x];
}
}
$sql = "{{" . $input . $argstr . "}}";
$wrapped = "{{" . $input . $argstr . "}}";
}
return $wrapped;
#return $this->render_wikitext($wrapped) . '<p>' . $wrapped . '<p>' . $sql;
#return "insert a useful action here";
}
}
Vorlagenauswertung
Diese Erweiterung wertet Vorlagen mit Parametern aus, wobei die Parameter über die URL übergeben werden.
<?php
/**
* MediaWiki extension: ExtAuswertung
* ==================================
*
* To activate, edit your LocalSettings.php,
* save this code as 'ExtAuswertung.php' and copy the file into the subdirectory ExtAuswertung of your extensions-directory and add
* require_once("$IP/extensions/ExtAuswertung/ExtAuswertung.php");
*/
# User Settings
# require_once("$IP/extensions/ExtAuswertung/ExtAuswertung.php");
# Parameter
# derzeit keine
# End User Settings
# diese Erweiterung ruft eine Vorlage mit Parametern zum Auswerten auf
# das Tag wird in der Seite gespeichert <auswertung />
# für die Anwendung wird die Seite folgendermaßen aufgerufen: Auswertung?vorlage=xxx&name=was_soll_ausgewertet_werden
# es erfolgt auch eine Auswertung der im Tag enthaltenen Parameter
# da diese später ausgewertet werden, überschreiben sie evtl. über die URL übergebene Paramter
define("AUSWERT_NAME", "auswertung"); # Name of tag
define("AUSWERT_IDENTIFIER", "sendAuswertung"); # Name of POST identifier flag
define("AUSWERT_HOOK", "hookAuswertung"); # Name of hook
if ( !defined( 'MEDIAWIKI' ) ) {
die( "This is not a valid entry point.\n" );
}
$wgExtensionCredits['parserhooks'][] = array(
'path' => __FILE__,
'name' => 'ExtAuswertung',
'version' => '0.9',
'author' => $extension_AUTH,
'url' => "$wgServer$wgScriptPath/index.php/Extension:ExtAuswertung",
'description' => 'wertet eine Vorlage mit Parametern aus'
);
$wgExtensionFunctions[] = 'wfExtAuswertung';
/*
* Setup ExtAuswertung extension.
* Sets a parser hook for <auswertung></auswertung>.
*/
function wfExtAuswertung()
{
new ExtAuswertung();
}
class ExtAuswertung
{
public function __construct()
{
global $wgParser;
$wgParser->setHook(AUSWERT_NAME, array(&$this, AUSWERT_HOOK));
}
public function hookAuswertung($input, $argv, $parser)
{
global $IP, $wgServer, $wgScriptPath, $wgUploadPath, $wgHooks, $wgParser, $wgHtml5, $wgScript;
$output = 'Vorlagenauswertung';
global $wgUploadDirectory, $wgArticlePath, $wgTmpDirectory;
$vorlage = $was = $liste = "";
foreach ( $_REQUEST as $arg => $val )
{
$$arg = $val; # die Variablen erhalten den Namen der Parameter
if ($arg != 'vorlage') $liste .= "|$arg=$val";
}
foreach ( $argv as $arg => $val )
{
$$arg = $val; # die Variablen erhalten den Namen der Parameter
if ($arg != 'vorlage') $liste .= "|$arg=$val";
}
$output = "{{" . $vorlage . $liste . "}}";
if (empty($vorlage)) $output="{{Bluetitel|1=Diese Seite enthält eine Anwendung der [[Extension:OraAuswertung|{{Taste|Erweiterung ExtAuswertung}}]]}}"
. "{{Absatz2}}"
. "Der Aufruf soll folgendermaßen erfolgen: In einer Wikiseite {{Taste|seitenname}} das Tag <nowiki><auswertung /></nowiki> speichern, "
. "{{Absatz2}}"
. "die Seite folgendermaßen aufrufen {{Taste|1=seitenname?vorlage=xxx&name=was_soll_ausgewertet_werden}}";
return $wgParser->recursiveTagParse($output);
}
}
Datenbankzugriff auf eine Oracle-SQL-Datenbank
CSS-Code
/*/Klassen für Oracle-Tabellen
.oratable td:last-of-type { border:none; }
.oratable tr { background-image: linear-gradient(#f9f9f9, #eaeaea); border:none; }
/*/
.oratable { border-collapse: collapse; }
.oratable table,
table.wikitable
{ border: 1px solid #036; border-collapse: collapse; box-shadow: 3px rgba(0,0,0,.35); }
.oratable tr { background-image: linear-gradient(#f9f9f9, #eaeaea); border:none; }
.oratable td { padding: 0.1em 0.5em; border-left: 1px solid #666; }
.oratable th { padding: 0.1em 0.5em; border-left: 1px solid #008fd1; border-bottom: 1px solid #036; font-weight: bold; font-size: 105%; color: #fff;
background-image: linear-gradient(#036, #008fd1); }
.oratable th:first-of-type { border-left: none; }
.oratable tr:first-child { border: 1px solid #666; border-radius: 0.5em 0 0 0.5em; }
/*/ Links in einer durch eine Oracle-Abfrage erzeugten Tabelle /*/
.oratable a,
.oratable a:link,
.oratable a:visited { text-decoration: none; color: inherit; }
.oratable a:hover,
.oratable a:active { cursor: default; border: 1px dotted #036; color: #036; }
/* wenn die Tabelle rechts offen sein soll */
.rechtsoffen table { border-right: none; }
.rechtsoffen td:last-child { border-right: none; background-color: #fff; }
table.sortable > tr > th,
table.sortable > * > tr > th,
table.wikitable > tr > th,
table.wikitable > * > tr > th,
.headerSort
{ background-color: #036; background-image: linear-gradient(#036, #008fd1) !important; color: #fff !important; font-weight: bold !important; font-size: 105%; }
.single { border-collapse: collapse; }
.single table { border: 1px solid #005cb8; border-collapse: collapse; box-shadow: 2px 2px 4px #002e5c; }
.single tr { background-image: linear-gradient(#f9f9f9, #eaeaea); border:none; }
.single td { padding: 0.1em 0.5em; border-left: 1px solid #666; }
.single th { padding: 0.1em 0.5em; border-left: 1px solid #85c2ff; border-bottom: 1px solid #005cb8; font-weight: normal; color: #fff;
background-image: linear-gradient(#005cb8, #85c2ff); text-align: right; }
PHP-Code
<?php
$extension_TAG = "orasql";
$extension_HOOK = "hookSql";
$extension_NAME = "OraSql";
$wgExtensionFunctions[] = "wfOraSqlSetup";
$wgExtensionCredits['parserhook'][] = array(
'name' => 'OraSql',
'url' => "$wgServer$wgScriptPath/index.php/Extension:OraSql",
'author' => $extension_AUTH,
'version' => '0.9',
'description' => 'Zugriff auf eine Oracle-Datenbank, nur SELECT erlaubt',
);
function wfOraSqlSetup()
/*/
Die Stelle, an der das Programm in das Wiki "eingehängt" wird
Der [[Hilfe:Tags|Text des Tags]] wird hier festgelegt
der Aufruf der Erweiterung erfolgt mit <orasql>...</orasql>
/*/
{
global $wgParser;
$wgParser->setHook( "orasql", "wfOraSql" );
}
function wfOraSql( $input, $argv, $parser )
/*/
Eintragungen in der LocalSettings.php
/*/
{
global $oraDBUser, $oraDBPass, $oraDBDatabase, $wgParser;
$dbID = 'Standard-Oracle-Instanz';
$class = $view = $onlycode = $table = $code = $header = $spaltentitel = $entiti = $offen = '';
#return '';
/*/
Abfrage von zusätzlichen parametern
das sind jene, die innerhalb der spitzen Klammern stehen
/*/
foreach ($argv as $key => $val)
{
$$key = $val; # die Variablen erhalten den Namen der Parameter
if ($key == 'dbid')
$dbID = $val;
else if ($key == 'spaltentitel')
$spaltentitel = preg_split("/[\?\t\r\n\f\x0B]/", $val);
else if (($key == 'onlycode') or ($key == 'codeonly'))
$onlycode = $val;
}
$input = $input;
if (!empty ($onlycode)) # nur Code darstellen
{
$coco = $wgParser->recursiveTagParse("{{coco|lang=sql|border=none|kla=|code=" . $input . "}}");
return $coco;
}
$page = str_replace('"', "\"", $input); // doppelte Anführungszeichen escapieren
// wenn zu Beginn kein select steht, wird eines dazu gefügt
$sel = strtolower(substr($page,0,6));
if ($sel != "select" and substr($sel,0,2) != "--")
$page .= 'SELECT ' . $page;
$wiki = ($table != 'wiki');
// Zugangsdaten für die Oracle-Datenbank
// es können verschiedene UserIDs bzw. Datenbankserver in der LocalSettings.php festgelegt werden
$db_server = $oraDBDatabase[$dbID];
$db_username = $oraDBUser[$dbID];
$db_password = $oraDBPass[$dbID];
// öffnen der Verbindung
$conn = oci_connect($db_username, $db_password, $db_server, 'AL32UTF8');
if (!$conn)
{
// Verbindung hat nicht geklappt, Rückgabe einer Fehlermeldung
$m = oci_error();
$output = $m['message'] . "\n";
}
else
{
$zz = true;
//$output = "Connected to Oracle!";
// Verbindung hat geklappt
$tablinks = '';
$stid = oci_parse($conn, $page);
$result = oci_execute($stid);
if (!$result)
return "SQL Fehler : " . $wgParser->recursiveTagParse("{{coco|lang=sql|border=none|kla=|code=" . $page . "}}");
$ncols = oci_num_fields($stid);
$nrows = oci_num_rows ($stid);
#var_dump($view );
$crlf = chr(13) . chr(10);
if ($view == 'single' and $nrows <= 1) # Einzelansicht nur wenn eine Zeile zurückgeliefert wurde
{
$output = "<div class='mono single $class' ><table>\n";
$row = oci_fetch_array($stid, OCI_NUM+OCI_RETURN_NULLS);
#var_dump($row );
for ($i = 1; $i <= $ncols; $i++)
{
$column_name = empty($spaltentitel[$i-1]) ? oci_field_name($stid, $i) : $spaltentitel[$i-1];
$val = ($row[$i-1] !== null ? htmlentities($row[$i-1], ENT_QUOTES) : " ");
$output .= "<tr><th>$column_name:</th><td>$val</td></tr>";
}
}
else
{
if ($view == 'zahl')
{
# es wird ein einziger Wert ohne Formatierung als Ergebnis zurück geliefert
$row = oci_fetch_array($stid, OCI_NUM+OCI_RETURN_NULLS);
if ($row == false) return "---";
$mywert = $row[0];
return $mywert;
}
$oclass = empty($offen) ? "" : " rechtsoffen";
$output = $wiki ? "<div class='mono oratable plainlinks tablink neu $oclass' ><table class='$class'>\n"
: "{| class='wikitable sortable mono plainlinks tablink neu $class'" . $crlf; # . "\n|-" . $crlf;
$output .= $wiki ? "<tr>" : $crlf . "\n!";
$snrcol = ''; $tablinks = array();
for ($i = 1; $i <= $ncols; $i++)
{
$feldname = strtolower (oci_field_name($stid, $i));
if ($feldname == "snr" or $feldname == "sondennummer" or strpos(strtolower ($feldname), 's#') !== False)
{
$snrcol=$i; # Spalte mit Sondennummer eruieren
$tablinks[] = $i-1;
}
else if (strpos( $feldname, 'name') !== False or strpos($feldname, 'sond') !== False)
$tablinks[] = $i-1;
$column_name = empty($spaltentitel[$i-1]) ? oci_field_name($stid, $i) : $spaltentitel[$i-1];
$output .= $wiki ? "<th>$column_name</th>" : "$column_name !!";
}
#return $feldname . strpos( $feldname, 'name') . " sonde " . strpos($feldname, 'sonde') . "<pre>" . print_r($tablinks) . "</pre>";
$output = rtrim($output,' !');
$output .= $wiki ? "</tr>" : $crlf . "\n|-";
if (!empty($auswertung))
{
$mylink ="[{{fullurl:Auswertung}}?vorlage=$auswertung&name=";
#return $mylink;
}
while ($row = oci_fetch_row($stid))
// alle gefundenen Sätze abarbeiten
{
$zz = false;
$output .= $wiki ? "<tr>" : $crlf . "\n\r|class='$class'|"; // Tabellenzeile
for ($i = 0; $i < $ncols; $i++)
{
$item = $row[$i];
#$item = htmlentities($row[$i], ENT_QUOTES);
if (!empty($snrcol)) # eine Spalte mit Sondennummer ist vorhanden
{
$snr = $row[$snrcol-1];
if (in_array($i, $tablinks) and is_numeric($snr)) # eine referenzierbare Spalte liegt vor, aber nur wenn die Sondennumer nicht leer ist
{
$item = '[{{fullurl:Snr}}?snr=' . $snr . " " . $item . "]";
}
}
else
if (!empty($auswertung) and ($i==0)) # die Spalten sollen mit Auswertung verlinkt werden, in der 1. Spalte muss das Kriterium stehen
{
#$item = '[{{fullurl:Snr}}?snr=234 ' . $item . "]";
#$item = $row[$i] . "$i";
#return $item . " *** " . htmlentities($row[$i], ENT_NOQUOTES);
$item = $mylink . urlencode($row[0]) . " " . $item . "]";
}
else
{
if (!empty($entiti)) $item = '<span style="white-space: pre">' . htmlentities($row[$i], ENT_NOQUOTES) . '</span>';
}
$val = $item !== null ? $item : " ";
$output .= $wiki ? "<td class='$oclass'>$val</td>\n" : "$val ||";
}
$output = rtrim($output,' |');
$output .= $wiki ? "</tr>\n" : $crlf . "\n|-";
}
if ($zz and (!empty($header))) return "";
}
$output .= $wiki ? "</table></div>" : $crlf . "\n|}";
$output = $wgParser->recursiveTagParse($output);
#$output .= "<pre>" . print_r($tablinks) . "</pre>" . count($tablinks);
// Close the Oracle connection
oci_close($conn);
if (!empty($code))
{
if (!isset($titel) or (empty($titel)))
$titel="";
else
$titel = "<div style='font-weight: bold; font-size: larger; margin: 0.75em 0 -0.5em 0; '>$titel</div>";
$coco = $titel . $wgParser->recursiveTagParse("{{coco|lang=sql|border=none|kla=|code=" . $input . "}}");
$output .= "$coco";
}
}
return $output;
}
Tabellenwerte mittels SVG darstellen
<?php
/**
* MediaWiki extension: OraSVG
* =============================
*
* To activate, edit your LocalSettings.php,
* save this code as 'OraSVG.php' and copy the file into the subdirectory OraSVG of your extensions-directory and add
* require_once("$IP/extensions/InlineSVG/OraSVG.php");
* Verwendung: <orasvg></orasvg>
*/
/*/ # User Settings
# Parameter
# default ... derzeit keine
# End User Settings
/*/
if ( !defined( 'MEDIAWIKI' ) ) {
die( "This is not a valid entry point.\n" );
}
$wgExtensionCredits['parserhooks'][] = array(
'path' => __FILE__,
'name' => 'OraSVG',
'version' => '0.9',
'author' =>$extension_AUTH,
'url' => "$wgServer$wgScriptPath/index.php/Extension:OraSVG",
'description' => 'stellt SVGs dar'
);
$wgExtensionFunctions[] = 'wfOraSVGExtension';
function wfOraSVGExtension() {
new OraSVG();
}
class OraSVG
{
public function __construct()
{
global $wgParser;
$wgParser->setHook('orasvg', array(&$this, 'wfOraSVG'));
}
public function wfOraSVG($input, $argv, $parser)
{
global $wgUploadDirectory, $wgUploadPath, $IP, $wgArticlePath, $wgTmpDirectory, $wgParser;
global $oraDBUser, $oraDBPass, $oraDBDatabase;
global $wgServer, $wgScriptPath, $wgUploadPath;
$dbID = 'Standard-Oracle-Instanz';
// Aktionen und Definitionen
$style = '
<style type="text/css"><![CDATA[
.numbers { fill: green; font-size: 12px; }
.smallnumbers { fill: green; font-size: 10px; }
.label { fill: blue; font-size: 15px; }
.linethick { fill: none; stroke:#6c0; stroke-width: 1; }
.linethin { fill: none; stroke: #6c0; stroke-width: 0.5; }
.bar { stroke: #036; fill: none; opacity: 1; stroke-width: 0; }
.barg { fill: #6c0; }
.pfad { fill: none; stroke-width: 2; }
]]>
</style>';
$text_a = '
<g transform="translate(' ;
$text_b = ') rotate(60)"><text class="label" >' ;
if (empty($input))
{
$page = "SELECT LEVEL X, TRUNC (DBMS_RANDOM.VALUE (1, 1000)) A
,TO_CHAR (ADD_MONTHS (TRUNC (SYSDATE, 'MM'), 1 - LEVEL), 'fmDay, fmDD. fmMonth YYYY', 'NLS_DATE_LANGUAGE=german') TAG
FROM DUAL CONNECT BY LEVEL < 20 ORDER BY 1";
}
else $page = str_replace('"', "\"", $input);
// Zugangsdaten für die Oracle-Datenbank
// es können verschiedene UserIDs bzw. Datenbankserver in der LocalSettings.php festgelegt werden
$db_server = $oraDBDatabase[$dbID];
$db_username = $oraDBUser[$dbID];
$db_password = $oraDBPass[$dbID];
// öffnen der Verbindung
$conn = oci_connect($db_username, $db_password, $db_server, 'AL32UTF8');
if (!$conn)
{
// Verbindung hat nicht geklappt, Rückgabe einer Fehlermeldung
$m = oci_error();
return $m['message'] . "\n";
}
$code = empty($argv["mitcode"]) ? '' : $wgParser->recursiveTagParse("{{hili|lang=sql|code=" . $page . "}}");
$tablinks = '';
$stid = oci_parse($conn, $page);
$result = oci_execute($stid);
if (!$result)
return "SQL Fehler : " . $wgParser->recursiveTagParse("{{hili|lang=sql|code=" . $page . "}}");
$ncols = oci_num_fields($stid); # Anzahl der Spalten
$nrows = oci_num_rows ($stid); # Anzahl der Zeilen
$y_wert = $label = [];
while ($row = oci_fetch_row($stid))
{
$y_wert[] =$row[1]; # Spalte 2 enthält den Produktionswert
$label[] =$row[2]; # Spalte 3 enthält die Beschriftung
}
if (empty($y_wert)) return "Im angegebenen Zeitraum sind keine Mengen vorhanden</p>" . $code;
$max_y = max($y_wert);
$min_y = min($y_wert);
if ($min_y > 0) $min_y = 0; # wir fangen nicht über der Nullinie an
$pfaddaten = [];
if ($max_y == 0 and $min_y == 0)
{
return "Im angegebenen Zeitraum sind keine Mengen vorhanden</p>" . $code;
}
$punkte = count($y_wert);
$faktor = 1200/$punkte;
#$rh = round($max_y,-round(log10($max_y))) ;
$hoch = empty($argv["hoch"]) ? 600 : intval($argv["hoch"]);
$yfaktor = $hoch/($max_y - $min_y); # der Skalierungsfaktor für die y-Koordinaten, damit das Ausgaberechteck genau 600 hoch ist
$rb = 1200;
$ry = 0; # Startpunkt des Rechtecks mit den Querlinien
for ($i=0; $i<$punkte; $i++)
{
$pfaddaten[$i] = $y_wert[$i] * $yfaktor;
}
#return implode(':', $pfaddaten);
$farbe = '#036';
if (!empty($argv["farbe"])) $farbe=$argv["farbe"];
$pfad = '
<path d="' . $this->toPfad($pfaddaten, $faktor) . '"
class="pfad" stroke="' . $farbe . '" />';
$rect = '
<rect width="' . $faktor . '" height="';
$rectg = '
<rect class="barg" width="' . $faktor . '" height="';
$labels = $bars = '';
$delta = $faktor/5;
$lablen = 0;
#return $punkte;
for ($i=0; $i<$punkte; $i++)
{
$x = $i * $faktor; $xx = $x + $delta;
$y = $yfaktor * ($max_y - $y_wert[$i] - $min_y);
$yy = $hoch;
$ywert = $pfaddaten[$i];
if (!empty($label[$i]))
{
$labels .= $text_a . $xx . ',' . $yy . $text_b . $label[$i] . '</text></g>';
$bars .= $rectg . $ywert . '" x="' . $x . '" y="0"></rect>';
if (strlen($label[$i]) > $lablen) $lablen=strlen($label[$i]);
}
else
$bars .= $rect . $ywert . '" x="' . $x . '" y="0"></rect>';
}
$bars = '
<g class="bar" transform="translate(0,' . $hoch . ') scale(1,-1)">' . $bars . '</g>';
if (!empty($argv["bars"]) and $argv["bars"] == 'no')
$bars='';
$ylabel = '
<g class="numbers">';
$ysmall = '
<g class="smallnumbers">';
$linethick = '
<g class="thick">';
$linethin = '
<g class="thin">';
$log = floor(log10($max_y)); # 10er logarithmus des Maximums der Messwerte
$pow = 10**$log; # die Größenordnung der Messwerte z.B. 0.1, 1, 10...
$steps = floor($max_y / $pow ); # die Zahl der Querlinien
#return '<br>ordnung: ' . $pow . '<br>max: ' . $max_y . '<br>schritte: ' . $steps;
for ($i=1; $i<= $steps; $i++)
{
$j = $i * $pow ;
$jj = $hoch - $yfaktor * $j;
if ($log < 2) $maxlab = number_format($j,2,",",".");
else $maxlab = number_format($j,0,",",".");
$ylabel .= '
<text text-anchor="start" dy="0.5" y="' . $jj . '">' . $maxlab . '</text>';
#if ($i>0 and $i<$val)
$linethick .= '
<rect y="' . $jj . '" width="1200" height="0.01" class="linethick"/>';
$j = $j - $pow/2;
if ($log < 2) $maxlab = number_format($j,2,",",".");
else $maxlab = number_format($j,0,",",".");
$jj = $hoch - $yfaktor * $j;
$ysmall .= '
<text text-anchor="start" dy="0.5" y="' . $jj . '">' . $maxlab . '</text>';
$linethin .= '
<rect y="' . $jj . '" width="1200" height="0.01" class="linethin"/>';
if ($steps < 2)
{
$j = $i * $pow - $pow/4;
if ($log < 2) $maxlab = number_format($j,2,",",".");
else $maxlab = number_format($j,0,",",".");
$jj = $hoch - $yfaktor * $j;
$ysmall .= '
<text text-anchor="start" dy="0.5" y="' . $jj . '">' . $maxlab . '</text>';
$linethin .= '
<rect y="' . $jj . '" width="1200" height="0.01" class="linethin"/>';
$j = $i * $pow - 3 * $pow/4;
if ($log < 2) $maxlab = number_format($j,2,",",".");
else $maxlab = number_format($j,0,",",".");
$jj = $hoch - $yfaktor * $j;
$ysmall .= '
<text text-anchor="start" dy="0.5" y="' . $jj . '">' . $maxlab . '</text>';
$linethin .= '
<rect y="' . $jj . '" width="1200" height="0.01" class="linethin"/>';
}
}
#number_format("1000000",2,",",".")
# und jetzt noch das Maximum der Messwerte explizit dazu schreiben
if ($log < 2) $maxlab = number_format($max_y,3,",",".");
else $maxlab = number_format($max_y,0,",",".");
$ylabel .= '
<text text-anchor="start" dy="0.5" y="0">' . $maxlab . '</text>
</g>';
$ysmall .= '
</g>';
$linethick .= '
</g>';
$linethin .= '
</g>';
#return $pow . ' * ' . $max_y . ' * ' . $val . ' # ' . floor(log10($max_y)) . ' + ' . $ry;
#return '<p>' . $pfad ; <g transform="translate(50,30) rotate(180)">
$lablen = $lablen * 10;
$boxheight = $lablen + $hoch;
$output = '
<svg
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1"
viewbox="0 0 1300 ' . $boxheight . '" width="1300" height="' . $boxheight . '">
' .
$style .
'
<g transform = "translate(0,20)">
<g transform = "translate(15)">
<rect width="1200" height="' . $hoch . '" y="0"
id="paper" fill="#85c2ff" opacity="0.1" />' .
$bars .
$labels .
$linethick . $linethin .
$pfad . '
</g>
<g transform = "translate(0)">' .
$ylabel . $ysmall . '
</g>
</g>' .
'
</svg>';
#$output = empty($input) ? $svgtest : $input;
$tmppath = "/images/png/";
$bildurl = "$wgServer$wgScriptPath$tmppath";
$bildfolder = $_SERVER['DOCUMENT_ROOT'] . $wgScriptPath . '/images/png/';
$mydatum = date('Y-m-d-His');
$bildname = "produktionsgrafik-" . $mydatum;
$html = "<p style='font-size:0.7em'>
<a href='$bildurl$bildname.png' target='_blank'><img src='$bildurl$bildname.png' width='50'>Grafik im PNG-Format speichern</a>
· <a href='$bildurl$bildname.svg' target='_blank'>Grafik im SVG-Format speichern</a>
</p>";
$erzeug = $this->toPng($output, $bildfolder, $bildname);
if (!empty($argv["svg"])) $output .= '<pre>' . $wgParser->recursiveTagParse($output) . '<pre>';
#return $code;
return '<p>' . $output . '</p>' . $html . '</p>' . $code;
}
private function toPfad($daten, $xfaktor = 10)
{
# liefert einen Pfad als Ergebnis zurück
# aufeinanderfolgende Elemente sollen nur ein Pfadelement ergeben
# optional können die Daten skaliert werden
$pfad = '';
#return implode('+', $daten);
if (!is_array($daten)) return; # wenn kein Array übergeben wurde, zurück
#$faktor = 1;
$max_y = max($daten);
$wert = $max_y - $daten[0]; # Y-Startwert
$pfad = "M0," . $wert;
$hor = $xfaktor;
for ($i=1; $i<count($daten); $i++)
{
if ($daten[$i] == $wert) ## Wiederholung des y-Wertes, wir erhöhen nur den Zähler
{
$hor+=$xfaktor;
}
else
{
$vert = ($daten[$i-1] - $daten[$i]);
$pfad .= "h $hor v $vert ";
$hor=$xfaktor;
$wert = $daten[$i];
}
}
# Abschluss des Pfades
$pfad .= "h $hor";
return $pfad;
}
private function toPng($bild, $pfad, $name, $breit=1300, $hoch=700)
{
# wandelt ein SVG in ein PNG um
# der SVG-Inhalt muss in der Variablen bild gespeichert sein
# Parameter:
# bild ... string mit dem SVG-Text
# pfad ... Pfad des zu speichernden Bildes
# name ... Name unter dem das Bild gespeichert werden soll
global $wgServer, $wgScriptPath, $wgUploadPath;
if (empty($bild) or empty($pfad) or empty($name))
{
return 'Fehler bei Bildererzeugung, fehlender Parameter';
}
$bname = $pfad . $name . ".png";
$im = new Imagick();
#return "$pfad $name .png";
$svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
' . $bild;
$im->readImageBlob($svg);
$geo = $im->getImageGeometry ();
$hoch= $geo['height']*2 ;
$breit = $geo['width']*2;
#return $geo['width'] . $geo['height'] ;
$svgname = "$pfad$name.svg";
$x = file_put_contents($svgname, $svg);
#return "svgname" . $svgname;
#return "imageblob";
$im->setImageBackgroundColor(new ImagickPixel('transparent'));
$im->resizeImage($breit, $hoch, imagick::FILTER_BOX, 1);
$im->setImageFormat("png");
#$im->scaleImage($breit, $hoch);
$im->borderImage('#fff', 10, 10);
$im->writeImage($bname);
$im->clear();
$im->destroy();
return "Bild als $bname gespeichert";
}
}