这是一个DokuWiki脚本/插件,它从数据库中提取数据,将其放入表中。我希望表格中的文字预先格式化/固定宽度。我已经8年没有使用PHP或HTML了,所以我有点生疏......有人可以帮助我吗?
<?php
/**
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Christoph Lang <calbity@gmx.de>
*/
// based on http://www.dokuwiki.org/plugin:tutorial
/**
*
* Usage:
* [[mysql:server:username:password:database|query|refresh]]
* [[mssql:server:username:password:database|query|refresh]]
* [[oracle:server:username:password:database|query|refresh]]
* [[sqlite:unused:unused:unused:path to sqlite3 database|query|refresh]]
* [[sqlcsv:unused:unused:unused:path to csv file|delimiter|refresh]]
* [[sqlaccess:unused:unused:password:path to mdb file|query|refresh]]
* [[postgresql:server:username:password:database|query|refresh]]
*/
/**
* Disabled, to use that class in standalone mode...
* // must be run within DokuWiki
*/
if (!defined('DOKU_INC')) die();
if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
require_once(DOKU_PLUGIN . 'syntax.php');
/**
* All DokuWiki plugins to extend the parser/rendering mechanism
* need to inherit from this class
*/
class syntax_plugin_sqlcomp extends DokuWiki_Syntax_Plugin {
private $sPath = "data/cache/sql/";
private $sConfig = "lib/plugins/sqlcomp/config.php";
/*
Layout
*/
private $aMessages = array(
"error" => "<div id=\"error\" style=\"text-align:center; font-weight: bold; border: 2px solid #0f0;background-color: #f00; padding: 5px; margin: 5px\">%text%</div>\n",
"message" => "<div id=\"difference\" style=\"text-align:center; font-weight: bold; border: 2px solid #fd0;background-color: #ffd; padding: 5px; margin: 5px\">%text%</div>\n",
"pre" => "<table class=\"inline\">\n",
"post" => "</table>\n",
"th" => "<th class=\"row%number%\" style=\"%type%\">%text%</th>",
"td" => "<td class=\"col%number%\" style=\"%type%\">%text%</td>",
"tr" => "<tr class=\"row%number%\" style=\"%type%\">%text%</tr>\n",
"same" => "",
"new" => "border:2px solid green;",
"deleted" => "border:2px solid red;",
"changed" => "border:2px solid blue;"
);
/*
Default Language - German
*/
private $aString = array(
//Number of affected Rows
"affected" => "Anzahl geänderter Zeilen",
//This Database Type is not yet Supported...
"nohandler" => "Dieser Datenbanktyp wird (noch) nicht unterstützt...",
//There are some differences in the table!
"difference" => "Es wurden Unterschiede in den Tabellen festgestellt!",
//Everything is allright.
"same" => "Alles in Ordnung.",
//The resultset is empty.
"empty" => "Das Resultset ist leer.",
//An unkown error occured!
"problem" => "Es ist ein unbekanntes Problem aufgetreten!",
//Cache is displayed, but new data could not be retrieved.
"cache" => "Cache wird angezeigt, aber neue Daten konnten nicht abgerufen werden.",
//Cache was refreshed, or table was collected for the first time.
"first" => "Der Cache wurde soeben erneuert, oder die Tabelle wurde das erste Mal abgerufen.",
//New data could not be retrieved.
"connection" => "Die neuesten Daten konnten nicht abgerufen werden.",
//The data is not valid. Please review your connection settings!
"wrong" => "Die eingegebenen Daten sind ungültig! Bitte Überprüfen!"
);
private $defaultRefresh = 1;
function getInfo() {
return array(
'author' => 'Christoph Lang',
'email' => 'calbity@gmx.de',
'date' => '2008-07-10',
'name' => 'SQLCOMP Plugin',
'desc' => 'This plugin let you display reultsets from various databases and show changes.',
'url' => 'http://www.google.de'
);
}
public function query($query){
$temp = null;
$data = $this->handle($query,"","",$temp);
return $this->_query($data,"csv");
}
public function __construct(){
}
private function _error($text){
return str_replace("%text%",$text,$this->aMessages["error"]);
}
private function _message($text){
return str_replace("%text%",$text,$this->aMessages["message"]);
}
private function _sqlaccess($Server,$User,$Pass,$Database,$Query){
if(!$connection = odbc_connect("DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$Database", "ADODB.Connection", $Pass, "SQL_CUR_USE_ODBC") or false)
throw new Exception($this->aString["problem"]);
$rs = odbc_exec($connection,$Query);
$dbArray = array();
while ($row = odbc_fetch_array($rs))
$dbArray[] = $row;
odbc_close($connection);
return $dbArray;
}
private function _postgresql($Server,$User,$Pass,$Database,$Query){
if(!$connection = pg_connect("host=".$Server." dbname=".$Database." user=".$User." password=".$Pass) or false)
throw new Exception($this->aString["problem"]);
$rs = pg_exec($Query);
$dbArray = pg_fetch_array($result, NULL, PGSQL_ASSOC);
pg_close($connection);
return $dbArray;
}
private function _mysql($Server,$User,$Pass,$Database,$Query){
if(!$connection = mysql_connect($Server, $User, $Pass) or false)
throw new Exception(mysql_error());
mysql_select_db($Database, $connection);
$rs = mysql_query($Query);
$dbArray = array();
if($rs === true)
$dbArray[] = array( $this->aString["affected"] => mysql_affected_rows ($connection));
else
while ($row = mysql_fetch_assoc($rs))
$dbArray[] = $row;
mysql_close($connection);
return $dbArray;
}
private function _mssql($Server,$User,$Pass,$Database,$Query){
if(!$dbhandle = mssql_connect($Server, $User, $Pass))
throw new Exception($this->aString["problem"]);
mssql_select_db($Database, $dbhandle);
$rs = mssql_query($Query);
$dbArray = array();
if($rs === true)
$dbArray[] = array( $this->aString["affected"] => mssql_rows_affected ($connection));
else
while ($row = mssql_fetch_assoc($rs))
$dbArray[] = $row;
mssql_close($dbhandle);
return $dbArray;
}
private function _oracle($Server,$User,$Pass,$Database,$Query){
throw new Exception($this->aString["nohandler"]);
}
private function _sqlcsv($Server,$User,$Pass,$Database,$Query){
if(!$handle = fopen($Database,"r"))
throw new Exception($this->aString["nohandler"]);
$dbArray = array();
$keys = fgetcsv ( $handle , 1000, $Query);
while ($row = fgetcsv ( $handle , 1000, $Query)){
$temprow = array();
foreach($row as $key => $value)
$temprow[$keys[$key]] = $value;
$dbArray[] = $temprow;
}
fclose($handle);
return $dbArray;
}
private function _sqlite($Server,$User,$Pass,$Database,$Query){
$dbHandle = new PDO('sqlite:'.$Database);
$result = $dbHandle->query($Query);
if(!$result)
throw new PDOException;
$dbArray = array();
if($result->rowCount() > 0)
$dbArray[] = array( $this->aString["affected"] => $result->rowCount() );
else
while($row = $result->fetch(PDO::FETCH_ASSOC))
$dbArray[] = $row;
return $dbArray;
}
private function _debug($data){
$sResponse = "";
foreach($data as $key => $value)
$sResponse .= "".$key . "=> " .$value ."<br/>\n";
return $sResponse;
}
private function _verifyInput($data){
if(!is_array($data))
return false;
if(count($data) != 7)
return false;
return true;
}
private function _load($filename){
$Cache = null;
$Update = true;
if(file_exists($filename)){
$Cache = file_get_contents($filename);
$Cache = unserialize($Cache);
$Update = $Cache["Update"];
if(time() > $Update)
$Update = true;
else
$Update = false;
$Cache = $Cache["Table"];
}
return array($Update,$Cache);
}
private function _save($filename,$rs,$timestamp){
$timestamp = (time() + ($timestamp*60));
$Cache["Update"] = $timestamp;
$Cache["Table"] = $rs;
$Cache = serialize($Cache);
$handle = fopen($filename,"w");
fwrite($handle,$Cache);
fclose($handle);
}
private function array2csv($data){
$sResponse = "";
$keys = array_keys($data[0]);
$sResponse .= implode(";",$keys)."\n";
foreach($data as $row)
$sResponse .= implode(";",$row)."\n";
return $sResponse;
}
private function _query($data,$type=null) {
//return $this->_debug($data);
if(!$this->_verifyInput($data))
return $this->_error($this->aString["wrong"]);
if(!is_dir($this->sPath))
mkdir($this->sPath);
$filename = $this->sPath.md5($data[0].$data[1].$data[2].$data[3].$data[4].$data[5]);
$Cache = $this->_load($filename);
$Update = true;
if(is_array($Cache)){
$Update = $Cache[0];
$Cache = $Cache[1];
}
try{
switch($data[0]){
case "mysql": $rs = $this->_mysql($data[1], $data[2], $data[3],$data[4],$data[5]); break;
case "mssql": $rs = $this->_mssql($data[1], $data[2], $data[3],$data[4],$data[5]); break;
case "oracle": $rs = $this->_oracle($data[1], $data[2], $data[3],$data[4],$data[5]); break;
case "sqlite": $rs = $this->_sqlite($data[1], $data[2], $data[3],$data[4],$data[5]); break;
case "sqlaccess": $rs = $this->_sqlaccess($data[1], $data[2], $data[3],$data[4],$data[5]); break;
case "postgresql": $rs = $this->_postgresql($data[1], $data[2], $data[3],$data[4],$data[5]); break;
case "sqlcsv": $rs = $this->_sqlcsv($data[1], $data[2], $data[3],$data[4],$data[5]); break;
default: return $this->_error($this->aString["nohandler"]);
}
}catch(Exception $ex){
$sResponse = $this->_error($this->aString["problem"]);
if(isset($Cache)){
$sResponse = $this->_print($Cache);
$sResponse .= $this->_error($this->aString["cache"]);
}
return $sResponse;
}
if ($rs === false){
return $this->_error($this->aString["empty"] );
}
if(isset($type) && $type == "csv")
return $this->array2csv($rs);
$difference = $this->_difference($Cache,$rs);
$sResponse = $difference[0];
if($Update && isset($rs)){
$this->_save($filename,$rs,$data[6]);
}
$sResponse .= $difference[1];
return $sResponse;
}
function _print($array){
$i = 0;
$th = "";
$td = "";
$tr = "";
if(!isset($array[0]))
return $this->_error($this->aString["problem"]);
$temp = array_keys($array[0]);
foreach($temp as $column){
if($column == "type")
continue;
$th .= str_replace(array("%number%","%text%","%type%"),array(0,$column,""),$this->aMessages["th"]);
}
$tr = str_replace(array("%number%","%text%","%type%"),array(0,$th,""),$this->aMessages["tr"]);
foreach($array as $row) {
$j = 0;
$td = "";
if(!isset($row["type"]))
$row["type"] = $this->aMessages["same"];
foreach($row as $key => $Value){
if($key == "type")
continue;
$td .= str_replace(array("%number%","%text%","%type%"),array($j,$Value,$row["type"]),$this->aMessages["td"]);
$j++;
}
$tr .= str_replace(array("%number%","%text%","%type%"),array($i,$td,$row["type"]),$this->aMessages["tr"]);
$i++;
}
$sResponse = $this->aMessages["pre"];
$sResponse .= $tr;
$sResponse .= $this->aMessages["post"];
return $sResponse;
}
function _difference($Cache,$New){
if($New == $Cache){
return array($this->_print($New),"");
return array($this->_print($New),$this->_message($this->aString["same"]));
}
if(!isset($New) && isset($Cache))
return array($this->_print($Cache),$this->_message($this->aString["difference"]));
if(isset($New) && !isset($Cache))
return array($this->_print($New),$this->_message($this->aString["first"]));
if(count($New) <= 0)
return array($this->_print($Cache),$this->_message($this->aString["connection"]));
$Max = count($Cache);
if(count($New) > count($Cache))
$Max = count($New);
$PrintArray = array();
for($i=0; $i < $Max; $i++){
if(isset($Cache[$i]) && !isset($New[$i]))
$PrintArray[] = array_merge($Cache[$i],array("type" => $this->aMessages["deleted"]));
if(!isset($Cache[$i]) && isset($New[$i]))
$PrintArray[] = array_merge($New[$i],array("type" => $this->aMessages["new"]));
if(isset($Cache[$i]) && isset($New[$i])){
if($Cache[$i] != $New[$i]){
$PrintArray[] = array_merge($Cache[$i],array("type" => $this->aMessages["changed"]));
$PrintArray[] = array_merge($New[$i],array("type" => $this->aMessages["changed"]));
}else
$PrintArray[] = array_merge($New[$i],array("type" => $this->aMessages["same"]));
}
}
return array($this->_print($PrintArray),$this->_message($this->aString["difference"]));
}
function connectTo($mode) {
$this->Lexer->addSpecialPattern('\[\[mysql\:.*?\]\]', $mode, 'plugin_sqlcomp');
$this->Lexer->addSpecialPattern('\[\[mssql\:.*?\]\]', $mode, 'plugin_sqlcomp');
$this->Lexer->addSpecialPattern('\[\[oracle\:.*?\]\]', $mode, 'plugin_sqlcomp');
$this->Lexer->addSpecialPattern('\[\[sqlite\:.*?\]\]', $mode, 'plugin_sqlcomp');
$this->Lexer->addSpecialPattern('\[\[sqlaccess\:.*?\]\]', $mode, 'plugin_sqlcomp');
$this->Lexer->addSpecialPattern('\[\[postgresql\:.*?\]\]', $mode, 'plugin_sqlcomp');
$this->Lexer->addSpecialPattern('\[\[sqlcsv\:.*?\]\]', $mode, 'plugin_sqlcomp');
if(!file_exists($this->sConfig))
$this->_createConfig();
include($this->sConfig);
foreach($sqlcomp as $key => $value)
$this->Lexer->addSpecialPattern('\[\['.$key.'.*?\]\]', $mode, 'plugin_sqlcomp');
}
function _createConfig(){
$sContent = "";
$sContent .= "<?php\n";
$sContent .= "//Sample Configfile\n";
$sContent .= "//Add as many servers as you want here...\n";
$sContent .= '$sqlcomp["localhost"] = "mysql:localhost:root::information_schema";';
$sContent .= '$sqlcomp["sampleconnection"] = "sqltype:servername:username:password:database";';
$sContent .= "\n?>\n";
$handle = fopen($this->sConfig,"w");
fwrite($handle,$sContent);
fclose($handle);
}
function getType() { return 'substition'; }
function getSort() { return 267; }
function handle($match, $state, $pos, &$handler) {
$temp = $match;
$match = substr($match,2,-2);
$MyData = array();
$match = explode("|",$match);
if(file_exists($this->sConfig))
include($this->sConfig);
foreach($sqlcomp as $key => $value)
if($key == $match[0])
$match[0] = $value;
$MyData = explode(":",$match[0]);
$MyData[] = $match[1];
if(isset($match[2]))
$MyData[] = $match[2];
else
$MyData[] = $this->defaultRefresh;
for($i=0;$i < 5; $i++)
$MyData[$i] = str_replace(" ", ":",$MyData[$i]);
return $MyData;
}
function render($mode, &$renderer, $data) {
if ($mode == 'xhtml') {
$renderer->doc .= $this->_query($data);
return true;
}
return false;
}
}
行。它归结为这3行。
"th" => "<pre><th class=\"row%number%\" style=\"%type%\">%text%</th></pre>",
"td" => "<pre><td class=\"col%number%\" style=\"%type%\">%text%</td></pre>",
"tr" => "<pre><tr class=\"row%number%\" style=\"%type%\">%text%</tr>\</pre>n",
任何wiki wiki的人都知道如何将其变成样式文本吗?
答案 0 :(得分:0)
"td" => "<td class=\"col%number%\" style=\"%type%\"><code>%text%</code></td>",
我添加了标签。中提琴。