summaryrefslogtreecommitdiff
path: root/liberty_plugins
diff options
context:
space:
mode:
authorLester Caine <lester@lsces.co.uk>2009-02-21 10:24:13 +0000
committerLester Caine <lester@lsces.co.uk>2009-02-21 10:24:13 +0000
commit44488e255f316eed2b8da4114dfcb49e3ca2b9b5 (patch)
treedf4694e76cc481723ae0dddc99086bec00b1382e /liberty_plugins
parent7ab38ff4ca56e6d48d5f5e792941a85a485c3188 (diff)
downloadwiki-44488e255f316eed2b8da4114dfcb49e3ca2b9b5.tar.gz
wiki-44488e255f316eed2b8da4114dfcb49e3ca2b9b5.tar.bz2
wiki-44488e255f316eed2b8da4114dfcb49e3ca2b9b5.zip
Port of dbreport from tikiwiki - modified to allow display_errors=on
See DataPluginDBReport page for status report
Diffstat (limited to 'liberty_plugins')
-rw-r--r--liberty_plugins/data.dbreport.php1643
1 files changed, 1643 insertions, 0 deletions
diff --git a/liberty_plugins/data.dbreport.php b/liberty_plugins/data.dbreport.php
new file mode 100644
index 0000000..5f36809
--- /dev/null
+++ b/liberty_plugins/data.dbreport.php
@@ -0,0 +1,1643 @@
+<?php
+/**
+ * $Header: /cvsroot/bitweaver/_bit_wiki/liberty_plugins/Attic/data.dbreport.php,v 1.1 2009/02/21 10:24:13 lsces Exp $
+ * @package liberty
+ * @subpackage plugins_data
+ *
+ * Generates a html report from a database query.
+ * Jeremy Lee 2009-02-16
+ */
+
+/**
+ * definitions
+ */
+define( 'PLUGIN_GUID_DATADBREPORT', 'datadbreport' );
+global $gLibertySystem;
+$pluginParams = array (
+ 'tag' => 'dbreport',
+ 'title' => 'DBReport',
+ 'description' => tra( "Generates a html report from a database query" ),
+ 'help_page' => 'DataPluginDBReport',
+
+ 'auto_activate' => FALSE,
+ 'requires_pair' => TRUE,
+ 'syntax' => '{dbreport dsn=dsnname db=dbname wiki=0|1 debug=0|1 }',
+ 'plugin_type' => DATA_PLUGIN,
+
+ // display icon in quicktags bar
+ 'biticon' => '{biticon ilocation=quicktag iname=image-x-generic iexplain="DBReport"}',
+ 'taginsert' => '{dbreport dsn db= wiki= debug= }',
+
+ // functions
+ 'help_function' => 'data_dbreport_help',
+ 'load_function' => 'wikiplugin_dbreport',
+);
+$gLibertySystem->registerPlugin( PLUGIN_GUID_DATADBREPORT, $pluginParams );
+$gLibertySystem->registerDataTag( $pluginParams['tag'], PLUGIN_GUID_DATADBREPORT );
+
+// plugin globals
+$wikiplugin_dbreport_errors;
+$wikiplugin_dbreport_fields;
+$wikiplugin_dbreport_fields_allowed;
+$wikiplugin_dbreport_record;
+
+class WikipluginDBReportToken {
+ var $type; // key=keyword, fld=field, str=string, var=variable, sty=style, eof=end of file
+ var $content;
+ var $start;
+ var $after;
+ var $code;
+ function type_name() {
+ switch($this->type) {
+ case 'key': return 'Keyword';
+ case 'txt': return 'Text';
+ case 'sty': return 'Style';
+ case 'fld': return 'Field';
+ case 'var': return 'Variable';
+ case 'str': return 'String';
+ case 'bra': return 'Brackets';
+ case 'eof': return 'End';
+ default: return $token->type;
+ }
+ }
+ function WikipluginDBReportToken($content=NULL) {
+ $this->content = $content;
+ }
+}
+
+class WikipluginDBReportField {
+ var $name;
+ var $variable;
+ var $break;
+ var $index;
+ function WikipluginDBReportField($text) {
+ global $wikiplugin_dbreport_fields, $wikiplugin_dbreport_fields_allowed;
+ $this->name = stripcslashes($text);
+ if($text[0]=='$') {
+ $this->variable = substr($this->name,1);
+ // print("new variable $this->variable ");
+ } else {
+ // add to the list of parsed fields
+ // if($wikiplugin_dbreport_fields_allowed)
+ $wikiplugin_dbreport_fields[] =& $this;
+ }
+ }
+ function text() {
+ global $wikiplugin_dbreport_record;
+ if(isset($this->index)) {
+ // indexed field
+ return (string)($wikiplugin_dbreport_record[$this->index]);
+ } else if(isset($this->variable)) {
+ // PHP variable
+ if(isset($GLOBALS[$this->variable])) {
+ return (string)$GLOBALS[$this->variable];
+ } else if(isset($_SESSION[$this->variable])) {
+ return (string)$_SESSION[$this->variable];
+ } else if(isset($_REQUEST[$this->variable])) {
+ return (string)$_REQUEST[$this->variable];
+ }
+ } else {
+ return "[$this->name]";
+ }
+ }
+ function code() {
+ if(isset($this->variable)) {
+ return '[$' . addcslashes($this->variable,"\0..\37[]$\\") . ']';
+ } else {
+ return '[' . addcslashes($this->name,"\0..\37[]$\\") . ']';
+ }
+ }
+ function html() {
+ return htmlentities($this->text());
+ }
+ function uri() {
+ return urlencode($this->text());
+ }
+}
+
+class WikipluginDBReportString {
+ var $literal;
+ function WikipluginDBReportString($text) {
+ $this->literal = stripcslashes($text);
+ }
+ function text() {
+ return $this->literal;
+ }
+ function code() {
+ return addcslashes($this->literal,"\0..\37[]\\");
+ }
+ function html() {
+ return htmlentities($this->text());
+ }
+ function uri() {
+ return $this->text();
+ }
+}
+
+class WikipluginDBReportContent {
+ var $elements;
+ function parse_text(&$text) {
+ $parse_state = 0;
+ $parse_text = '';
+ $pos = 0;
+ $len = strlen($text);
+ while($pos < $len) {
+ $char = $text[$pos++];
+ switch($parse_state) {
+ case 0: // start of next token
+ switch($char) {
+ case '[':
+ $parse_state = 3;
+ break;
+ case '\\':
+ $parse_state = 2;
+ $parse_text .= $char;
+ break;
+ default:
+ $parse_state = 1;
+ $parse_text .= $char;
+ }
+ break;
+ case 1: // text string
+ switch($char) {
+ case '[':
+ $this->elements[] =& new WikipluginDBReportString($parse_text);
+ $parse_text = '';
+ $parse_state = 3;
+ break;
+ case '\\':
+ $parse_state = 2;
+ $parse_text .= $char;
+ break;
+ default:
+ $parse_text .= $char;
+ }
+ break;
+ case 2: // literal escape
+ $parse_text .= $char;
+ $parse_state = 1;
+ break;
+ case 3: // field text
+ switch($char) {
+ case '[':
+ break;
+ case ']':
+ $this->elements[] =& new WikipluginDBReportField($parse_text);
+ $parse_text = '';
+ $parse_state = 0;
+ break;
+ case '\\':
+ $parse_state = 4;
+ $parse_text .= $char;
+ break;
+ default:
+ $parse_text .= $char;
+ }
+ break;
+ case 4: // field escape
+ $parse_text .= $char;
+ $parse_state = 3;
+ break;
+ }
+ }
+ // hanging text is parsed as a string
+ if($parse_state!=0) {
+ $this->elements[] =& new WikipluginDBReportString($parse_text);
+ }
+ }
+ function append_field($name) {
+ $this->elements[] =& new WikipluginDBReportField($name);
+ }
+ function append_variable($name) {
+ $this->elements[] =& new WikipluginDBReportField('$'.$name);
+ }
+ function append_string($text) {
+ $this->elements[] =& new WikipluginDBReportString($text);
+ }
+ function append($text) {
+ $this->parse_text($text);
+ }
+ function WikipluginDBReportContent(&$token) {
+ switch($token->type) {
+ case 'txt':
+ $this->parse_text($token->content);
+ break;
+ case 'fld':
+ $this->append_field($token->content);
+ break;
+ case 'var':
+ $this->append_variable($token->content);
+ break;
+ }
+ }
+ function text() {
+ $result = '';
+ if(isset($this->elements)) foreach($this->elements as $element) $result .= $element->text();
+ return $result;
+ }
+ function code() {
+ $result = '';
+ if(isset($this->elements)) foreach($this->elements as $element) $result .= $element->code();
+ return $result;
+ }
+ function html() {
+ $result = '';
+ if(isset($this->elements)) foreach($this->elements as $element) $result .= $element->html();
+ return $result;
+ }
+ function uri() {
+ $result = '';
+ if(isset($this->elements)) foreach($this->elements as $element) $result .= $element->uri();
+ return $result;
+ }
+}
+
+class WikipluginDBReportText extends WikipluginDBReportContent {
+ var $link;
+ var $style;
+ function code() {
+ $result = '"' . addcslashes(parent::code(),'"') . '"';
+ if(isset($this->style)) $result .= $this->style->code();
+ if(isset($this->link)) $result .= ' '.$this->link->code();
+ return $result;
+ }
+ function html() {
+ $html = parent::html();
+ if(isset($this->style)) {
+ $html = $this->style->html_start() . $html . $this->style->html_end();
+ }
+ if(isset($this->link)) {
+ $html = $this->link->html_start() . $html . $this->link->html_end();
+ }
+ return $html;
+ }
+}
+
+class WikipluginDBReportStyle {
+ var $tag;
+ var $class;
+ var $style;
+ function WikipluginDBReportStyle(&$token) {
+ if(is_object($token)) {
+ if( isset($token->content['class']) ) {
+ $subtoken =& $token->content['class'];
+ $this->class =& new WikipluginDBReportContent($subtoken);
+ }
+ if( isset($token->content['style']) ) {
+ $subtoken =& $token->content['style'];
+ $this->style =& new WikipluginDBReportContent($subtoken);
+ }
+ } else if(is_string($token)) {
+ $subtoken =& new WikipluginDBReportToken($token);
+ $subtoken->type = 'txt';
+ $this->class =& new WikipluginDBReportContent($subtoken);
+ }
+ }
+ function code() {
+ $code = ':';
+ if(isset($this->class)) {
+ $code .= addcslashes($this->class->code(),' ');
+ } else if($this->tag!='span') {
+ $code .= $this->tag;
+ }
+ // if(isset($this->class)) $code .= $this->class->code();
+ if(isset($this->style)) $code .= "{" . $this->style->code() . "}";
+ return $code;
+ }
+ function attributes() {
+ $html = '';
+ if(isset($this->class)) $html .= ' class="' . $this->class->html() . '"';
+ if(isset($this->style)) $html .= ' style="' . $this->style->html() . '"';
+ return $html;
+ }
+ function html_start() {
+ if(isset($this->class)) {
+ $class = $this->class->html();
+ switch(strtolower($class)) {
+ case 'u':
+ case 'b':
+ case 'i':
+ case 'h1':
+ case 'h2':
+ case 'h3':
+ case 'h4':
+ case 'h5':
+ case 'h6':
+ $this->tag = $class;
+ $html = '<' . $class;
+ break;
+ default:
+ $this->tag = 'span';
+ $html = '<span class="' . $class . '"';
+ }
+ } else {
+ $this->tag = 'span';
+ $html = '<span';
+ }
+ if(isset($this->style)) $html .= ' style="' . $this->style->html() . '"';
+ $html .= '>';
+ return $html;
+ }
+ function html_end() {
+ return '</'.$this->tag.'>';
+ }
+}
+
+class WikipluginDBReportLink {
+ var $style;
+ var $contents;
+ function code() {
+ $result = '<';
+ if(isset($this->contents)) foreach($this->contents as $content) {
+ if(is_a($content,'WikipluginDBReportContent')) {
+ $result .= '"'.$content->code().'"';
+ } else if(is_a($content,'WikipluginDBReportField')) {
+ $result .= $content->code();
+ }
+ }
+ if(isset($this->style)) $result .= $this->style->code();
+ $result .= '>';
+ return $result;
+ }
+ function uri() {
+ $uri = '';
+ if(isset($this->contents)) foreach($this->contents as $content) {
+ if(is_a($content,'WikipluginDBReportContent')) {
+ $uri .= $content->html();
+ } else if(is_a($content,'WikipluginDBReportField')) {
+ $uri .= $content->uri();
+ }
+ }
+ return $uri;
+ }
+ function html_start() {
+ $html = '<a href="' . $this->uri() . '"';
+ if($this->style) $html .= $this->style->attributes();
+ $html .= '>';
+ return $html;
+ }
+ function html_end() {
+ return '</a>';
+ }
+ function html_onclick() {
+ return 'onclick="document.location.href=&quot;' . $this->uri() . '&quot;"';
+ }
+}
+
+class WikipluginDBReportCell {
+ var $link;
+ var $style;
+ var $colspan;
+ var $rowspan;
+ var $contents;
+ function code($mode) {
+ $result = 'CELL';
+ if(isset($this->colspan) && isset($this->rowspan)) {
+ if($this->rowspan!=1) $result .= ' ROWSPAN '.$this->rowspan;
+ if($this->colspan!=1) $result .= ' COLSPAN '.$this->colspan;
+ } else if(isset($this->colspan)) {
+ if($this->colspan!=1) if($mode=='ROW') {
+ $result .= ' SPAN '.$this->colspan;
+ } else {
+ $result .= ' COLSPAN '.$this->colspan;
+ }
+ } else if(isset($this->rowspan)) {
+ if($this->rowspan!=1) if($mode=='ROW') {
+ $result .= ' ROWSPAN '.$this->rowspan;
+ } else {
+ $result .= ' SPAN '.$this->rowspan;
+ }
+ }
+ if(isset($this->style)) $result .= ' ' . $this->style->code();
+ if(isset($this->link)) $result .= ' ' . $this->link->code();
+ if(isset($this->contents)) foreach($this->contents as $content) $result .= ' '.$content->code();
+ return $result;
+ }
+ function html($heading=false) {
+ if($heading) {
+ $html = '<th';
+ } else {
+ $html = '<td';
+ }
+ if(isset($this->style)) $html .= $this->style->attributes();
+ if(isset($this->rowspan)) $html .= ' rowspan="' . $this->rowspan . '"';
+ if(isset($this->colspan)) $html .= ' colspan="' . $this->colspan . '"';
+ if(isset($this->link)) $html .= ' ' . $this->link->html_onclick();
+ $html .= '>';
+ if(isset($this->contents)) foreach($this->contents as $content) $html .= $content->html();
+ $html .= '</td>';
+ return $html;
+ }
+}
+
+class WikipluginDBReportLine {
+ var $link;
+ var $styles;
+ var $cells;
+ function code($indent='',$rtype='ROW',$cellmode='ROW') {
+ $result = $indent.$rtype;
+ if(isset($this->styles)) foreach($this->styles as $style) $result .= ' '.$style->code();
+ if(isset($this->link)) $result .= ' '.$this->link->code();
+ $result .= "\n";
+ foreach($this->cells as $cell) $result .= $indent.' '.$cell->code($cellmode)."\n";
+ return $result;
+ }
+ function row_html($data,$style,$heading=false) {
+ // set the global report row
+ global $wikiplugin_dbreport_record;
+ $wikiplugin_dbreport_record = $data;
+ // generate HTML
+ $html = '<tr';
+ if(isset($style)) $html .= $style->attributes();
+ if(isset($this->link)) $html .= ' ' . $this->link->html_onclick();
+ $html .= '>';
+ foreach($this->cells as $cell) $html .= $cell->html($heading);
+ $html .= '</tr>' . "\n";
+ return $html;
+ }
+}
+
+class WikipluginDBReportTable {
+ var $style;
+ var $headers;
+ var $rows;
+ var $footers;
+ var $style_index;
+ function code($indent='') {
+ $result = $indent.'TABLE';
+ if(isset($this->style)) $result .= ' '.$this->style->code();
+ $result .= "\n";
+ if(isset($this->headers)) foreach($this->headers as $line) {
+ $result .= $line->code($indent.' ','HEADER');
+ }
+ if(isset($this->rows)) foreach($this->rows as $line) {
+ $result .= $line->code($indent.' ','ROW');
+ }
+ if(isset($this->footers)) foreach($this->footers as $line) {
+ $result .= $line->code($indent.' ','FOOTER');
+ }
+ return $result;
+ }
+ function line_row_html($list,$data,$heading=false) {
+ $html = '';
+ foreach($list as $line) {
+ $style = null;
+ if(isset($line->styles)) {
+ $style_count = count($line->styles);
+ $style = $line->styles[$this->style_index % $style_count];
+ }
+ $html .= $line->row_html($data,$style,$heading);
+ }
+ return $html;
+ }
+ function header_row_html($data) {
+ $html = '';
+ // generate a new table
+ if(isset($this->style)) {
+ $html .= '<table' . $this->style->attributes() . '>' . "\n";
+ } else {
+ $html .= '<table>' . "\n";
+ }
+ // write headers
+ $style_index = 0;
+ if(isset($this->headers)) $html .= $this->line_row_html($this->headers,$data,true);
+ return $html;
+ }
+ function record_row_html($data) {
+ $html = '';
+ if(isset($this->rows)) $html .= $this->line_row_html($this->rows,$data);
+ $this->style_index++;
+ return $html;
+ }
+ function footer_row_html($data) {
+ $html = '';
+ // write footers
+ $this->style_index = 0;
+ if(isset($this->footers)) $html .= $this->line_row_html($this->footers,$data,true);
+ // close the table
+ $html .= '</table>';
+ return $html;
+ }
+}
+
+class WikipluginDBReportGroup {
+ var $link;
+ var $style;
+ var $fields;
+ var $field_count;
+ var $contents;
+ function __toString() {
+ $result = '';
+ foreach($this->contents as $entry) $result .= $entry;
+ return $result;
+ }
+ function code($indent='') {
+ $result = $indent.'GROUP';
+ if(isset($this->style)) $result .= ' '.$this->style->code();
+ if(isset($this->fields)) foreach($this->fields as $field) $result .= ' '.$field->code();
+ if(isset($this->link)) $result .= ' '.$this->link->code();
+ if(isset($this->contents)) foreach($this->contents as $content) $result .= ' '.$content->code();
+ $result .= "\n";
+ return $result;
+ }
+ function check_break(&$row) {
+ $ret = false;
+ // compare the field values against the break values
+ for($i=0; $i<$this->field_count; $i++) {
+ $field =& $this->fields[$i];
+ $value =& $row[$field->index];
+ if($value !== $field->break) {
+ $ret = true;
+ $field->break =& $value;
+ }
+ }
+ return $ret;
+ }
+ function start_html($row) {
+ global $wikiplugin_dbreport_record;
+ $wikiplugin_dbreport_record = $row;
+ $html = '';
+ // generate a new <div> with the report content at the top
+ if(isset($this->style)) {
+ $html .= '<div' . $this->style->attributes() . '>' . "\n";
+ } else {
+ $html .= '<div>' . "\n";
+ }
+ if(isset($this->contents)) foreach($this->contents as $content) $html.= $content->html();
+ return $html;
+ }
+ function end_html(&$row) {
+ $html = '';
+ // close the <div>
+ $html .= '</div>';
+ return $html;
+ }
+}
+
+class WikipluginDBReportParameter extends WikipluginDBReportContent {
+ var $name;
+ function code($indent='') {
+ $result = $indent.'PARAM';
+ // if(isset($this->name)) $result .= ' :'.$this->name;
+ if(isset($this->elements)) foreach($this->elements as $element) $result .= ' ' . $element->code();
+ $result .= "\n";
+ // $result .= ' "' . parent::code() . "\"\n";
+ return $result;
+ }
+}
+
+class WikipluginDBReportFail {
+ var $link;
+ var $style;
+ var $contents;
+ function code($mode) {
+ $result = 'FAIL';
+ if(isset($this->style)) $result .= ' ' . $this->style->code();
+ if(isset($this->link)) $result .= ' ' . $this->link->code();
+ if(isset($this->contents)) foreach($this->contents as $content) $result .= ' '.$content->code();
+ return $result;
+ }
+ function html($heading=false) {
+ $html = '<div';
+ if(isset($this->style)) $html .= $this->style->attributes();
+ if(isset($this->link)) $html .= ' ' . $this->link->html_onclick();
+ $html .= '>';
+ if(isset($this->contents)) foreach($this->contents as $content) $html .= $content->html();
+ $html .= '</div>';
+ return $html;
+ }
+}
+
+class WikipluginDBReport {
+ var $sql;
+ var $params;
+ var $groups;
+ var $table;
+ var $columns;
+ var $fail;
+ function code($indent='') {
+ // write the report in cannonical form.
+ $result = $indent.'SQL {' . $this->sql . '}'."\n";
+ if(isset($this->params)) foreach($this->params as $param) $result .= $param->code($indent.' ');
+ if(isset($this->groups)) foreach($this->groups as $group) $result .= $group->code($indent);
+ if(isset($this->table)) $result .= $this->table->code($indent);
+ if(isset($this->fail)) $result .= $this->fail->code($indent);
+ return $result;
+ }
+}
+
+function wikiplugin_dbreport_parse_error(&$token, $msg) {
+ global $wikiplugin_dbreport_errors;
+ // find the line relating to the token in the code
+ $pos = 0; $line = 0;
+ $code =& $token->code;
+ $len = strlen($code);
+ while($pos<$len) {
+ // find the next line break
+ $line++;
+ $break = strpos($code,"\n",$pos);
+ if($break===false) $break = $len;
+ // was the token in this line?
+ if($token->start < $break) {
+ // format the line with the token highlighted
+ $err_line = '<i>line '.$line.'</i>: ';
+ $err_line .= substr($code,$pos,$token->start-$pos);
+ $err_line .= '<span style="font-weight:bold;color:DarkRed;">'.substr($code,$token->start,$token->after-$token->start).'</span>';
+ if($token->after<$break) $err_line .= substr($code,$token->after,$break-$token->after);
+ $wikiplugin_dbreport_errors[] = $err_line;
+ $pos = $len;
+ } else {
+ // update position and loop
+ $pos = $break + 1;
+ }
+ }
+ // add the message to the errors
+ $wikiplugin_dbreport_errors[] = $msg;
+}
+
+function wikiplugin_dbreport_next_token(&$code, $len, $pos) {
+ global $wikiplugin_dbreport_errors, $wikiplugin_dbreport_fields_allowed;
+ $whitespace = " \n\r\t\v\f";
+ $tokenstop = " :<>[$\"\n\r\t\v\f";
+ // create a token object to return
+ $token =& new WikipluginDBReportToken();
+ $token->code =& $code;
+ // find the next non-whitespace character in the code
+ while( ($pos < $len) && (strpos($whitespace,$code[$pos])!==false) ) $pos++;
+ if( $pos >= $len ) {
+ $token->type = 'eof';
+ $token->start = $len - 1;
+ $token->after = $pos;
+ return $token;
+ }
+ // what did we find?
+ switch($code[$pos]) {
+ case '[':
+ // field token
+ $token->start = $pos;
+ // parse to closing ']'
+ while( ($pos < $len) && ($code[$pos]!=']') ) {
+ if($code[$pos]=='\\') $pos++;
+ $pos++;
+ }
+ if($pos < $len) {
+ $token->after = ++$pos;
+ $token->type = 'fld';
+ $token->content = substr($code, $token->start+1, $pos-$token->start-2);
+ return $token;
+ } else {
+ $token->after = ++$pos;
+ $token->type = 'eof';
+ wikiplugin_dbreport_parse_error($token, "Unclosed Field. ] expected.");
+ return $token;
+ }
+ break;
+ case '{':
+ // brackets token
+ $token->type = 'bra';
+ $token->start = $pos;
+ // parse until we find the closing bracket.
+ $pos++;
+ $state = 0;
+ while( ($pos < $len) && ($state<4) ) {
+ $c = $code[$pos++];
+ switch($state) {
+ case 0: // normal content
+ switch($c) {
+ case '}': $state = 4; break;
+ case '`': $state = 1; $token->content .= $c; break;
+ case "'": $state = 2; $token->content .= $c; break;
+ case '"': $state = 3; $token->content .= $c; break;
+ default: $token->content .= $c;
+ }
+ break;
+ case 1: // backtick-quoted
+ switch($c) {
+ case '`': $state = 0;
+ default: $token->content .= $c;
+ }
+ break;
+ case 2: // single-quoted
+ switch($c) {
+ case '\\': $token->content .= $c . $code[$pos++]; break;
+ case '\'': $state = 0;
+ default: $token->content .= $c;
+ }
+ break;
+ case 3: // double-quoted
+ switch($c) {
+ case '\\': $token->content .= $c . $code[$pos++]; break;
+ case '"': $state = 0;
+ default: $token->content .= $c;
+ }
+ break;
+ }
+ }
+ $token->after = $pos;
+ switch($state) {
+ case 0: // unclosed brackets
+ wikiplugin_dbreport_parse_error($token, "Unclosed brackets. } expected");
+ $token->type = 'eof';
+ break;
+ case 1: // unclosed backtick-quoted content
+ wikiplugin_dbreport_parse_error($token, "Unclosed backtick-quoted content in brackets. ` then } expected");
+ $token->type = 'eof';
+ break;
+ case 2: // unclosed single-quoted content
+ wikiplugin_dbreport_parse_error($token, "Unclosed single-quoted content in brackets. ' then } expected");
+ $token->type = 'eof';
+ break;
+ case 3: // unclosed double-quoted content
+ wikiplugin_dbreport_parse_error($token, "Unclosed double-quoted content in brackets. \" then } expected");
+ $token->type = 'eof';
+ break;
+ }
+ return $token;
+ break;
+ case ':':
+ // style token
+ $token->type = 'sty';
+ $token->start = $pos;
+ $token->content = array();
+ // create content sub-tokens
+ $class =& new WikipluginDBReportToken();
+ $class->code =& $code;
+ $class->type = 'txt';
+ $class->start = $pos;
+ $style =& new WikipluginDBReportToken();
+ $style->code =& $code;
+ $style->type = 'txt';
+ // parse until we find the closing space.
+ $pos++;
+ $state = 0;
+ while( ($pos < $len) && ($state<6) ) {
+ $c = $code[$pos++];
+ if($c=='\\') {
+ $c .= $code[$pos++];
+ $tc = $c;
+ } else {
+ $tc = strpos($whitespace,$c)!==false ? ' ': $c;
+ }
+ switch($state) {
+ case 0: // class content
+ switch($tc) {
+ case '<':
+ case '>':
+ case '"':
+ case ' ': $state = 6; $class->after = $pos; break;
+ case '{': $state = 1; $class->after = $pos; $style->start = $pos-1; break;
+ case '[': $state = 2;
+ default: $class->content .= $c;
+ }
+ break;
+ case 1: // inline style content
+ switch($tc) {
+ case '}': $state = 6; $style->after = $pos; break;
+ case '[': $state = 3; $style->content .= $c; break;
+ case "'": $state = 4; $style->content .= $c; break;
+ case '"': $state = 5; $style->content .= $c; break;
+ default: $style->content .= $c;
+ }
+ break;
+ case 2: // class field
+ switch($tc) {
+ case ']': $state = 0;
+ default: $class->content .= $c;
+ }
+ break;
+ case 3: // inline style field
+ switch($tc) {
+ case ']': $state = 1;
+ default: $style->content .= $c;
+ }
+ break;
+ case 4: // single-quoted inline style
+ switch($tc) {
+ case '\'': $state = 1;
+ default: $style->content .= $c;
+ }
+ break;
+ case 5: // double-quoted inline style
+ switch($tc) {
+ case '"': $state = 1;
+ default: $style->content .= $c;
+ }
+ break;
+ }
+ }
+ switch($state) {
+ case 0: // end of file
+ $class->after = $pos;
+ break;
+ case 1: // inline style content
+ $style->after = $pos;
+ wikiplugin_dbreport_parse_error($style, "Unclosed style CSS. } expected");
+ $token->type = 'eof';
+ break;
+ case 2: // class field
+ $class->after = $pos;
+ wikiplugin_dbreport_parse_error($class, "Unclosed field in style class. ] expected");
+ $token->type = 'eof';
+ break;
+ case 3: // inline style field
+ $style->after = $pos;
+ wikiplugin_dbreport_parse_error($style, "Unclosed field in style CSS. ] then } expected");
+ $token->type = 'eof';
+ break;
+ case 4: // single-quoted inline style
+ $style->after = $pos;
+ wikiplugin_dbreport_parse_error($style, "Unclosed single-quoted content in style CSS. ' then } expected");
+ $token->type = 'eof';
+ break;
+ case 5: // double-quoted inline style
+ $style->after = $pos;
+ wikiplugin_dbreport_parse_error($style, "Unclosed double-quoted content in style CSS. \" then } expected");
+ $token->type = 'eof';
+ break;
+ }
+ if($class->content) $token->content['class'] = $class;
+ if($style->content) $token->content['style'] = $style;
+ $token->after = $pos;
+ return $token;
+ break;
+ case '$':
+ // variable token
+ $token->type = 'var';
+ $token->start = $pos;
+ $pos++;
+ // parse to end of token
+ while( ($pos < $len) && (strpos($tokenstop,$code[$pos])===false) ) {
+ if($code[$pos]=='\\') $pos++;
+ $pos++;
+ }
+ $token->content = substr($code, $token->start+1, $pos-$token->start-1);
+ $token->after = $pos;
+ return $token;
+ break;
+ case '"':
+ // string token
+ $token->type = 'txt';
+ $token->start = $pos;
+ $token->content = '';
+ // parse until we find the closing quote.
+ $pos++;
+ while( $pos < $len ) {
+ // what is it?
+ $c = $code[$pos++];
+ switch($c) {
+ case '"':
+ $token->after = $pos;
+ return $token;
+ break;
+ case '\\':
+ $token->content .= $c;
+ if( ($pos < $len) ) {
+ $c = $code[$pos++];
+ $token->content .= $c;
+ } else {
+ wikiplugin_dbreport_parse_error($token, "Unclosed escaped string. \" expected.");
+ $token->type = 'eof';
+ return $token;
+ }
+ break;
+ default:
+ $token->content .= $c;
+ break;
+ }
+ }
+ // didn't find closing quotes
+ $token->type = 'txt';
+ wikiplugin_dbreport_parse_error($token, "Unterminated string. \" expected.");
+ $token->type = 'eof';
+ return $token;
+ break;
+ case '<':
+ case '>':
+ // link keywords
+ $token->type = 'key';
+ $token->content = $code[$pos];
+ $token->start = $pos;
+ $token->after = ++$pos;
+ return $token;
+ break;
+ default:
+ // keyword token
+ $token->start = $pos;
+ // parse to end of token
+ while( ($pos < $len) && (strpos($tokenstop,$code[$pos])===false) ) $pos++;
+ $token->type = 'key';
+ $token->content = substr($code, $token->start, $pos - $token->start);
+ $token->after = $pos;
+ return $token;
+ }
+}
+
+function wikiplugin_dbreport_parse(&$code) {
+ global $debug, $wikiplugin_dbreport_fields_allowed;
+ // code properties
+ $len = strlen($code);
+ $pos = 0;
+ // FSM state
+ $parse_state = 0;
+ $parse_link_return = 0;
+ $parse_line_return = 0;
+ $parse_cell_return = 0;
+ $parse_object;
+ $parse_text;
+ $parse_line;
+ $parse_cell;
+ $span_mode;
+ $parse_report =& new WikipluginDBReport();
+ // parse the code
+ while(true) {
+ // get the next token
+ $token = wikiplugin_dbreport_next_token($code, $len, $pos);
+ $pos = $token->after;
+ // repeat while we have an unconsumed token
+ while(isset($token)) {
+ $next_token = $token;
+ switch($parse_state) {
+ case 0: // next keyword
+ switch($token->type) {
+ case 'eof':
+ if(!isset($parse_report->sql)) return wikiplugin_dbreport_parse_error($token, "Unexpected End.");
+ return $parse_report;
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case 'SQL':
+ $parse_state = 1; // switch state
+ unset($next_token); // consume the token
+ $wikiplugin_dbreport_fields_allowed = false; // no fields in sql
+ break;
+ case 'PARAM':
+ // create the parameter object
+ $parse_object =& new WikipluginDBReportParameter($token);
+ $parse_report->params[] =& $parse_object;
+ $parse_state = 2; // switch state
+ unset($next_token); // consume the token
+ $wikiplugin_dbreport_fields_allowed = false; // no fields in sql params
+ break;
+ case 'GROUP':
+ // create the group object
+ $parse_object =& new WikipluginDBReportGroup();
+ $parse_report->groups[] =& $parse_object;
+ $parse_state = 3; // switch state
+ unset($next_token); // consume the token
+ $wikiplugin_dbreport_fields_allowed = true; // we can now parse fields
+ break;
+ case 'TABLE':
+ // create the table object
+ $parse_object =& new WikipluginDBReportTable();
+ $parse_report->table =& $parse_object;
+ $parse_state = 4; // switch state
+ unset($next_token); // consume the token
+ $wikiplugin_dbreport_fields_allowed = true; // we can now parse fields
+ break;
+ case 'FAIL':
+ // create the fail object
+ $parse_object =& new WikipluginDBReportFail();
+ $parse_report->fail =& $parse_object;
+ $parse_state = 10; // switch state
+ unset($next_token); // consume the token
+ $wikiplugin_dbreport_fields_allowed = false; // no fields in fail message
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Invalid keyword '$token->content'");
+ }
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected ".$token->type." '".$token->content."' at ".$token->start);
+ }
+ break;
+ case 1: // SQL content
+ switch($token->type) {
+ case 'eof':
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ case 'bra':
+ $parse_report->sql .= $token->content;
+ unset($next_token); // consume the token
+ break;
+ case 'txt':
+ $parse_report->sql .= stripcslashes($token->content);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected " . $token->type_name() . " '$token->content' after 'SQL'. String expected.");
+ }
+ break;
+ case 2: // PARAM content
+ switch($token->type) {
+ case 'eof':
+ $parse_state = 0; // switch parse state
+ break;
+ /* case 'sty':
+ $parse_object->name = $token->content;
+ unset($next_token); // consume the token
+ break; */
+ case 'fld':
+ $parse_object->append_field($token->content);
+ unset($next_token); // consume the token
+ break;
+ case 'var':
+ $parse_object->append_variable($token->content);
+ unset($next_token); // consume the token
+ break;
+ case 'txt':
+ $parse_object->elements[] =& new WikipluginDBReportText($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ unset($parse_object);
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected " . $token->type_name() . " '$token->content' after 'PARAM'. Name, Field, String or Variable expected.");
+ }
+ break;
+ case 3: // GROUP content
+ switch($token->type) {
+ case 'eof':
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ case 'fld':
+ $parse_object->fields[] =& new WikipluginDBReportField($token->content);
+ $parse_object->field_count++;
+ unset($next_token); // consume the token
+ break;
+ case 'txt':
+ case 'var':
+ $parse_text =& new WikipluginDBReportText($token);
+ $parse_object->contents[] =& $parse_text;
+ $parse_text_return = $parse_state; // return to this state
+ $parse_state = 9; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'sty':
+ $parse_object->style =& new WikipluginDBReportStyle($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case '<':
+ $parse_link =& new WikipluginDBReportLink($token); // create the link object
+ $parse_object->link =& $parse_link;
+ $parse_link_return = $parse_state; // return to this state
+ $parse_state = 5; // switch state
+ unset($next_token); // consume the token
+ break;
+ default:
+ unset($parse_object); // we are finished parsing the group
+ $wikiplugin_dbreport_fields_allowed = false; // we cannot parse fields anymore
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ }
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected " . $token->type_name() . " '$token->content' after '<'. Field, String or Style expected.");
+ }
+ break;
+ case 4: // TABLE content
+ switch($token->type) {
+ case 'eof':
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ case 'sty':
+ $parse_object->style =& new WikipluginDBReportStyle($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case 'HEADER':
+ $parse_line =& new WikipluginDBReportLine();
+ $parse_object->headers[] =& $parse_line;
+ $parse_line_return = $parse_state; // return to this state
+ $parse_state = 6; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'FOOTER':
+ $parse_line =& new WikipluginDBReportLine();
+ $parse_object->footers[] =& $parse_line;
+ $parse_line_return = $parse_state; // return to this state
+ $parse_state = 6; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'ROW':
+ case 'ROWS':
+ $parse_line =& new WikipluginDBReportLine();
+ $parse_object->rows[] =& $parse_line;
+ $parse_line_return = $parse_state; // return to this state
+ $parse_state = 6; // switch state
+ unset($next_token); // consume the token
+ break;
+ default:
+ unset($parse_object); // we are finished parsing the table
+ $wikiplugin_dbreport_fields_allowed = false; // we cannot parse fields anymore
+ $parse_state = 0; // switch state and reparse the token
+ }
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected " . $token->type_name() . " '$token->content' after 'TABLE'. HEADER, FOOTER, ROWS, <, or Style expected.");
+ }
+ break;
+ case 5: // Link content
+ switch($token->type) {
+ case 'eof':
+ return wikiplugin_dbreport_parse_error($token, "Unexpected EOF in WikipluginDBReportLink. '>' expected.");
+ break;
+ case 'var':
+ case 'fld':
+ $parse_link->contents[] =& new WikipluginDBReportField($token->content);
+ unset($next_token); // consume the token
+ break;
+ case 'txt':
+ $parse_link->contents[] =& new WikipluginDBReportContent($token);
+ unset($next_token); // consume the token
+ break;
+ /*
+ case 'txt':
+ $parse_link->append($token->content);
+ unset($next_token); // consume the token
+ break;
+ case 'var':
+ $parse_link->append_variable($token->content);
+ unset($next_token); // consume the token
+ break;
+ case 'fld':
+ $parse_link->append_field($token->content);
+ unset($next_token); // consume the token
+ break;
+ */
+ case 'sty':
+ $parse_link->style =& new WikipluginDBReportStyle($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case '<':
+ return wikiplugin_dbreport_parse_error($token, "Unexpected '<' in Link. '>' expected.");
+ case '>':
+ unset($next_token); // consume the token
+ $parse_state = $parse_link_return; // return to previous state
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected Keyword '$token->content' in Link. '>' expected.");
+ }
+ default:
+ $parse_state = $parse_link_return; // switch state and reparse the token
+ }
+ break;
+ case 6: // HEADER, FOOTER, ROW content
+ switch($token->type) {
+ case 'eof':
+ $parse_state = $parse_line_return; // switch state and reparse the token
+ break;
+ case 'sty':
+ $parse_line->styles[] =& new WikipluginDBReportStyle($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case 'CELL':
+ $parse_cell =& new WikipluginDBReportCell();
+ $parse_line->cells[] =& $parse_cell;
+ $parse_cell_return = $parse_state; // return to this state
+ $parse_state = 7; // switch state
+ unset($next_token); // consume the token
+ break;
+ case '<':
+ $parse_link =& new WikipluginDBReportLink($token); // create the link object
+ $parse_line->link =& $parse_link;
+ $parse_link_return = $parse_state; // return to this state
+ $parse_state = 5; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'HEADER':
+ case 'ROW':
+ case 'FOOTER':
+ case 'FAIL':
+ $parse_state = $parse_line_return;
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Invalid keyword '$token->content' after row. CELL or Link expected.");
+ }
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected " . $token->type_name() . " '$token->content' in row.");
+ }
+ break;
+ case 7: // CELL content
+ switch($token->type) {
+ case 'eof':
+ $parse_state = $parse_cell_return; // switch state and reparse the token
+ break;
+ case 'fld':
+ case 'var':
+ case 'txt':
+ $parse_text =& new WikipluginDBReportText($token);
+ $parse_cell->contents[] =& $parse_text;
+ $parse_text_return = $parse_state; // return to this state
+ $parse_state = 9; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'sty':
+ $parse_cell->style =& new WikipluginDBReportStyle($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case '<':
+ $parse_link =& new WikipluginDBReportLink($token); // create the link object
+ $parse_cell->link =& $parse_link;
+ $parse_link_return = $parse_state; // return to this state
+ $parse_state = 5; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'SPAN':
+ $span_mode = 'COL';
+ $parse_state = 8; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'COLSPAN':
+ $span_mode = 'COL';
+ $parse_state = 8; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'ROWSPAN':
+ $span_mode = 'ROW';
+ $parse_state = 8; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'CELL':
+ case 'HEADER':
+ case 'ROW':
+ case 'COLUMN':
+ case 'FOOTER':
+ case 'FAIL':
+ $parse_state = $parse_cell_return; // switch state and reparse the token
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Invalid keyword '$token->content' in 'CELL'. Field, String, Style or Link expected.");
+ }
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected " . $token->type_name() . " '$token->content' after 'CELL'.");
+ }
+ break;
+ case 8: // SPAN content
+ switch($token->type) {
+ case 'key':
+ // try to parse the keyword as as number
+ $span = (int)$token->content;
+ if((string)$span == $token->content) {
+ if($span_mode=='ROW') {
+ $parse_cell->rowspan = $span;
+ } else {
+ $parse_cell->colspan = $span;
+ }
+ unset($next_token); // consume the token
+ }
+ $parse_state = 7; // switch state (and possibly reparse the token)
+ break;
+ default:
+ $parse_state = 7; // switch state and reparse the token
+ }
+ break;
+ case 9: // Text content
+ switch($token->type) {
+ case 'sty':
+ $parse_text->style =& new WikipluginDBReportStyle($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case '<':
+ $parse_link =& new WikipluginDBReportLink($token); // create the link object
+ $parse_text->link =& $parse_link;
+ $parse_link_return = $parse_state; // return to this state
+ $parse_state = 5; // switch state
+ unset($next_token); // consume the token
+ break;
+ default:
+ $parse_state = $parse_text_return; // return to the previous state
+ break;
+ }
+ break;
+ default:
+ $parse_state = $parse_text_return; // return to the previous state
+ break;
+ }
+ break;
+ case 10: // Fail content
+ switch($token->type) {
+ case 'eof':
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ case 'var':
+ case 'txt':
+ $parse_text =& new WikipluginDBReportText($token);
+ $parse_object->contents[] =& $parse_text;
+ $parse_text_return = $parse_state; // return to this state
+ $parse_state = 9; // switch state
+ unset($next_token); // consume the token
+ break;
+ case 'sty':
+ $parse_object->style =& new WikipluginDBReportStyle($token);
+ unset($next_token); // consume the token
+ break;
+ case 'key':
+ switch(strtoupper($token->content)) {
+ case '<':
+ $parse_link =& new WikipluginDBReportLink($token); // create the link object
+ $parse_object->link =& $parse_link;
+ $parse_link_return = $parse_state; // return to this state
+ $parse_state = 5; // switch state
+ unset($next_token); // consume the token
+ break;
+ default:
+ unset($parse_object); // we are finished parsing the fail
+ $parse_state = 0; // switch state and reparse the token
+ break;
+ }
+ break;
+ default:
+ return wikiplugin_dbreport_parse_error($token, "Unexpected " . $token->type_name() . " '$token->content' after 'FAIL'.");
+ }
+ break;
+ default:
+ $parse_state = 0;
+ }
+ $token = isset($next_token) ? $next_token : NULL;
+ }
+ }
+}
+
+function wikiplugin_dbreport_error_box($error) {
+ $return = '~np~<table style="border-width:1px; border-style:dashed; border-color:red; background:#FFE0E0;"><tr><td>';
+ switch(gettype($error)) {
+ case 'array':
+ foreach($error as $entry) $return .= $entry.'<br/>';
+ break;
+ case 'string':
+ case 'object':
+ $return .= (string)$error;
+ break;
+ default:
+ $return .= gettype($error).' ERROR!';
+ }
+ $return .= '</td></tr></table>~/np~';
+ return $return;
+}
+
+function wikiplugin_dbreport_message_box($msg) {
+ $return = '<table style="border-width:1px; border-style:dashed; border-color:silver; background:#E0E0FF;"><tr><td>';
+ switch(gettype($error)) {
+ case 'array':
+ foreach($msg as $entry) $return .= $entry.'<br/>';
+ break;
+ default:
+ $return .= (string)$msg;
+ }
+ $return .= '</td></tr></table>';
+ return $return;
+}
+
+function data_dbreport_help() {
+ $help =
+ '<table class="data help">'
+ .'<tr>'
+ .'<th>'.tra( "Key" ).'</th>'
+ .'<th>'.tra( "Type" ).'</th>'
+ .'<th>'.tra( "Comments" ).'</th>'
+ .'</tr>'
+ .'<tr class="odd">'
+ .'<td>dns</td>'
+ .'<td>'.tra( "string").'<br />'.tra( "(required)" ).'</td>'
+ .'<td>'.tra( "A full DSN (Data Source Name) connection string. eg: mysql://user:pass@server/database" ).'</td>'
+ .'</tr>'
+ .'<tr class="even">'
+ .'<td>title</td>'
+ .'<td>'.tra( "string").'<br />'.tra( "(required)" ).'</td>'
+ .'<td>'.tra( "The name of a DSN connection defined by the Wiki administrator.").'</td>'
+ .'</tr>'
+ .'<tr class="odd">'
+ .'<td>wiki</td>'
+ .'<td>'.tra( "numeric").'<br />'.tra( "(optional)" ).'</td>'
+ .'<td>'.tra( "0|1, parse wiki syntax within the report.").' '.tra( "Default").': 0</td>'
+ .'</tr>'
+ .'<tr class="even">'
+ .'<td>debug</td>'
+ .'<td>'.tra( "numeric").'<br />'.tra( "(optional)" ).'</td>'
+ .'<td>'.tra( "0|1, display the parsed report definition.").' '.tra( "Default").': 0</td>'
+ .'</tr>'
+ .'</table>'
+ .tra( "Example: " )."{dbreport dns=demo}SELECT * FROM DEMO{/dbreport}";
+ return $help;
+}
+
+function wikiplugin_dbreport($data, $params) {
+ // TikiWiki globals
+ global $tikilib, $user, $group, $page, $prefs;
+ global $wikiplugin_dbreport_errors, $wikiplugin_dbreport_fields;
+ // wikiplugin_dbreport globals
+ global $wikiplugin_dbreport_errors;
+ global $wikiplugin_dbreport_fields;
+ global $wikiplugin_dbreport_fields_allowed;
+ global $wikiplugin_dbreport_record;
+ // initialize globals
+ $wikiplugin_dbreport_errors = array();
+ $wikiplugin_dbreport_fields = array();
+ $wikiplugin_dbreport_fields_allowed = false;
+ $wikiplugin_dbreport_record = null;
+
+ $ret = '';
+ // extract parameters
+ extract ($params,EXTR_SKIP);
+ if ( !isset($wiki) ) $wiki = false;
+ if ( !isset($debug) ) $debug = false;
+ // debug plugin input
+ if( isset($debug_input) ) {
+ $msg = $_REQUEST['preview'] . ' ' . $_SESSION['s_prefs']['tiki_release'] . '<br/>';
+ $msg .= '~np~<pre>'.htmlspecialchars($data).'</pre>~/np~';
+ $ret .= wikiplugin_dbreport_message_box($msg);
+ }
+ // we need a dsn or db parameter
+ if (!isset($dsn) && !isset($db)) {
+ return tra('Missing db or dsn parameter');
+ }
+ // parse the report definition
+// $parse_fix = ($_REQUEST['preview']);
+// if($parse_fix) {
+ $report =& wikiplugin_dbreport_parse($data);
+// } else {
+// $report =& wikiplugin_dbreport_parse(html_entity_decode($data));
+// }
+ // were there errors?
+ if($wikiplugin_dbreport_errors) {
+ $ret .= wikiplugin_dbreport_error_box($wikiplugin_dbreport_errors);
+ return $ret;
+ }
+ // create the bind variables array
+ $bindvars = array();
+ if(isset($report->params)) foreach($report->params as $param) {
+ if(isset($param->name)) {
+ $bindvars[$param->name] = $param->text();
+ } else {
+ $bindvars[] = $param->text();
+ }
+ }
+ // translate db name into dsn
+//TODO - convert to bw permissions
+ if (isset($db)) {
+ $perm_name = 'tiki_p_dsn_' . $db;
+ global $$perm_name;
+ // check permissions
+ if ($$perm_name != 'y') {
+ return (tra('You do not have permission to use this DSN'));
+ }
+ // retrieve the dsn string
+ $dsn = $tikilib->get_dsn_by_name($db);
+ }
+
+ // open the database
+ if (isset($dsn)) {
+ // open database dsn connection
+ $ado =& ADONewConnection($dsn);
+ if (!$ado) {
+ $ret .= wikiplugin_dbreport_error_box($ado->ErrorMsg());
+ return $ret;
+ } else {
+ // execute sql query
+ $ado->SetFetchMode(ADODB_FETCH_NUM);
+ $query =& $ado->Execute($report->sql, $bindvars);
+ if (!$query) {
+ $ret .= wikiplugin_dbreport_error_box($ado->ErrorMsg());
+ return $ret;
+ }
+ }
+ } else {
+ return (tra('No DSN connection string found!'));
+ }
+ // create an array of field names and their index
+ $field_index = array();
+ $field_count = $query->FieldCount();
+ for($index = 0; $index<$field_count; $index++) {
+ $column =& $query->FetchField($index);
+ $field_index[$column->name] = $index;
+ }
+ // go through the parsed fields and assign indexes
+ foreach($wikiplugin_dbreport_fields as $key => $value) {
+ $parse_field =& $wikiplugin_dbreport_fields[$key];
+ $index = $field_index[$parse_field->name];
+ if(isset($index)) {
+ $parse_field->index = $index;
+ } else {
+ // not a valid field. log the message.
+ $ret .= wikiplugin_dbreport_error_box("The Field '$parse_field->name' was not returned by the SQL query.");
+ return $ret;
+ }
+ }
+ // does the report have a table definition?
+ if(!isset($report->table)) {
+ // create a default definition from the data
+ $report->table = new WikipluginDBReportTable();
+ $style = 'sortable';
+ $report->table->style =& new WikipluginDBReportStyle($style);
+ $header =& new WikipluginDBReportLine();
+ $style = 'heading';
+ $header->styles[] =& new WikipluginDBReportStyle($style);
+ $report->table->headers[] =& $header;
+ $row =& new WikipluginDBReportLine();
+ $style = 'even';
+ $row->styles[] =& new WikipluginDBReportStyle($style);
+ $style = 'odd';
+ $row->styles[] =& new WikipluginDBReportStyle($style);
+ $report->table->rows[] =& $row;
+ // fill in the cells
+ $field_count = $query->FieldCount();
+ for($index = 0; $index<$field_count; $index++) {
+ // get the query field
+ $column =& $query->FetchField($index);
+ // create the header cell
+ $text =& new WikipluginDBReportText(new WikipluginDBReportToken());
+ $text->append_string($column->name);
+ $cell =& new WikipluginDBReportCell();
+ // $style = 'heading';
+ // $cell->style =& new WikipluginDBReportStyle($style);
+ $cell->contents[] =& $text;
+ $header->cells[] =& $cell;
+ // create the rows cell
+ $cell =& new WikipluginDBReportCell();
+ $field =& new WikipluginDBReportField($column->name);
+ $field->index = $index;
+ $cell->contents[] =& $field;
+ $row->cells[] =& $cell;
+ }
+ }
+ // are we debugging?
+ if($debug) $ret .= wikiplugin_dbreport_message_box("~np~<pre>".htmlspecialchars($report->code())."</pre>~/np~");
+ // generate the report
+ if(!$wiki) $ret .= '~np~';
+ if(!$query->EOF) {
+ // get the first row
+ $current_row = $query->FetchRow();
+ // start the group breaks
+ if (isset($report->groups)) {
+ foreach($report->groups as $group) {
+ $group->check_break($current_row);
+ $ret .= $group->start_html($current_row);
+ }
+ }
+ // first row is always considered 'after a break'
+ $breaking = true;
+ // go through the rows
+ while ($current_row) {
+ // do we generate a table header?
+ if($breaking) $ret .= $report->table->header_row_html($current_row);
+ // write the table row
+ $ret .= $report->table->record_row_html($current_row);
+ // get the next row
+ if($query->EOF) {
+ unset($next_row);
+ $breaking = true;
+ } else {
+ $next_row = $query->FetchRow();
+ $breaking = false;
+ }
+ $break_end = '';
+ $break_start = '';
+ // check group breaks
+ if (isset($report->groups)) {
+ foreach($report->groups as $group) {
+ if(isset($next_row)) $breaking = ($group->check_break($next_row) || $breaking);
+ if($breaking) {
+ $break_end = $group->end_html($current_row) . $break_end;
+ if(isset($next_row)) $break_start .= $group->start_html($next_row);
+ }
+ }
+ }
+ if($breaking) {
+ $ret .= $report->table->footer_row_html($current_row);
+ $ret .= $break_end;
+ $ret .= $break_start;
+ }
+ // move to the next row
+ $current_row = isset($next_row) ? $next_row : NULL;
+ }
+ } else {
+ // no records returned. output the fail message
+ if($report->fail) $ret .= $report->fail->html();
+ }
+ if(!$wiki) $ret .= '~/np~';
+ // close the database connection
+ $query->Close();
+ $ado->Close();
+ // return the result
+ return $ret;
+}
+
+?> \ No newline at end of file