1<?php 2/** 3 * Plugin SQL: executes SQL queries 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Slim Amamou <slim.amamou@gmail.com> 7 */ 8 9if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 10if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 11require_once(DOKU_PLUGIN.'syntax.php'); 12require_once(DOKU_INC.'inc/parserutils.php'); 13require_once('DB.php'); 14 15function property($prop, $xml) 16{ 17 $pattern = '/'.$prop ."='([^']*)')/"; 18 if (preg_match($pattern, $xml, $matches)) { 19 return $matches[1]; 20 } 21 $pattern = '/'.$prop .'="([^"]*)"/'; 22 if (preg_match($pattern, $xml, $matches)) { 23 return $matches[1]; 24 } 25 return FALSE; 26} 27 28/** 29 * All DokuWiki plugins to extend the parser/rendering mechanism 30 * need to inherit from this class 31 */ 32class syntax_plugin_sql extends DokuWiki_Syntax_Plugin { 33 var $databases = array(); 34 var $wikitext_enabled = TRUE; 35 var $display_inline = FALSE; 36 var $vertical_position = FALSE; 37 38 /** 39 * What kind of syntax are we? 40 */ 41 function getType(){ 42 return 'substition'; 43 } 44 45 /** 46 * Where to sort in? 47 */ 48 function getSort(){ 49 return 555; 50 } 51 52 53 /** 54 * Connect pattern to lexer 55 */ 56 function connectTo($mode) { 57 $this->Lexer->addEntryPattern('<sql [^>]*>',$mode,'plugin_sql'); 58 } 59 60 function postConnect() { 61 $this->Lexer->addExitPattern('</sql>','plugin_sql'); 62 } 63 64 65 /** 66 * Handle the match 67 */ 68 function handle($match, $state, $pos, Doku_Handler $handler){ 69 switch ($state) { 70 case DOKU_LEXER_ENTER : 71 $urn = property('db',$match); 72 $wikitext = property('wikitext', $match); 73 $display = property('display', $match); 74 $position = property('position', $match); 75 return array('urn' => $urn, 'wikitext' => $wikitext, 'display' => $display, 'position' => $position); 76 break; 77 case DOKU_LEXER_UNMATCHED : 78 $queries = explode(';', $match); 79 if (trim(end($queries)) == "") { 80 array_pop($queries); 81 } 82 return array('sql' => $queries); 83 break; 84 case DOKU_LEXER_EXIT : 85 $this->wikitext_enabled = TRUE; 86 $this->display_inline = FALSE; 87 $this->vertical_position = FALSE; 88 return array('wikitext' => 'enable', 'display' => 'block', 'position' => 'horizontal'); 89 break; 90 } 91 return array(); 92 } 93 94 /** 95 * Create output 96 */ 97 function render($mode, Doku_Renderer $renderer, $data) { 98 $renderer->info['cache'] = false; 99 100 if($mode == 'xhtml'){ 101 102 if ($data['wikitext'] == 'disable') { 103 $this->wikitext_enabled = FALSE; 104 } else if ($data['wikitext'] == 'enable') { 105 $this->wikitext_enabled = TRUE; 106 } 107 if ($data['display'] == 'inline') { 108 $this->display_inline = TRUE; 109 } else if ($data['display'] == 'block') { 110 $this->display_inline = FALSE; 111 } 112 if ($data['position'] == 'vertical') { 113 $this->vertical_position = TRUE; 114 } else if ($data['position'] == 'horizontal') { 115 $this->vertical_position = FALSE; 116 } 117 if ($data['urn'] != "") { 118 try { 119 $db =& DB::connect($data['urn']); 120 } catch(Exception $e) { 121 $error = $e->getMessage(); 122 $renderer->doc .= '<div class="error">Plugin SQL Error '. $error .'</div>'; 123 return TRUE; 124 } 125 array_push($this->databases, $db); 126 } 127 elseif (!empty($data['sql'])) { 128 $db =& array_pop($this->databases); 129 if (!empty($db)) { 130 foreach ($data['sql'] as $query) { 131 try { 132 $result =& $db->getAll($query); 133 } catch(Exception $e) { 134 $error = $e->getMessage(); 135 $renderer->doc .= '<div class="error">Plugin SQL Error '. $error .'</div>'; 136 return TRUE; 137 } 138 139 if (! $this->vertical_position) { 140 if ($this->display_inline) { 141 $renderer->doc .= '<table class="inline" style="display:inline"><tbody>'; 142 } else { 143 $renderer->doc .= '<table class="inline"><tbody>'; 144 } 145 $renderer->doc .= '<tr>'; 146 foreach (array_keys($result[0]) as $header) { 147 $renderer->doc .= '<th>'; 148 if ($this->wikitext_enabled) { 149 $renderer->nest(p_get_instructions($header)); 150 } else { 151 $renderer->cdata($header); 152 } 153 $renderer->doc .= '</th>'; 154 } 155 $renderer->doc .= '</tr>'; 156 foreach ($result as $row) { 157 $renderer->doc .= '<tr>'; 158 foreach ($row as $cell) { 159 $renderer->doc .= '<td>'; 160 if ($this->wikitext_enabled) { 161 $renderer->nest(p_get_instructions($cell)); 162 } else { 163 $renderer->cdata($cell); 164 } 165 $renderer->doc .= '</td>'; 166 } 167 $renderer->doc .= '</td>'; 168 $renderer->doc .= '</tr>'; 169 } 170 $renderer->doc .= '</tbody></table>'; 171 } else { 172 foreach ($result as $row) { 173 $renderer->doc .= '<table class="inline"><tbody>'; 174 foreach ($row as $name => $cell) { 175 $renderer->doc .= '<tr>'; 176 $renderer->doc .= "<th>$name</th>"; 177 $renderer->doc .= '<td>'; 178 if ($this->wikitext_enabled) { 179 $renderer->nest(p_get_instructions($cell)); 180 } else { 181 $renderer->cdata($cell); 182 } 183 $renderer->doc .= '</td>'; 184 $renderer->doc .= '</tr>'; 185 } 186 $renderer->doc .= '</tbody></table>'; 187 } 188 } 189 } 190 } 191 } 192 return true; 193 } 194 return false; 195 } 196} 197