|
|
|
@ -4,26 +4,29 @@ |
|
|
|
|
* |
|
|
|
|
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html |
|
|
|
|
* @author George Pirogov <i1557@yandex.ru> |
|
|
|
|
* @author Thomas Hooge <hooge@rowa-group.com> |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
// must be run within Dokuwiki |
|
|
|
|
if (!defined('DOKU_INC')) die(); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* All DokuWiki plugins to extend the parser/rendering mechanism |
|
|
|
|
* need to inherit from this class |
|
|
|
|
*/ |
|
|
|
|
class syntax_plugin_sqlquery extends DokuWiki_Syntax_Plugin { |
|
|
|
|
|
|
|
|
|
public function getType() { return 'substition'; } |
|
|
|
|
public function getSort() { return 666; } |
|
|
|
|
public function getPType() { return 'block'; } |
|
|
|
|
public function getType() { |
|
|
|
|
return 'substition'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public function getSort() { |
|
|
|
|
return 666; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public function connectTo($mode) |
|
|
|
|
{ |
|
|
|
|
$this->Lexer->addSpecialPattern('<sql\b(?:\s+(?:host|db|type)=[\w\-\.$]+?)*\s*>(?:.*?</sql>)', $mode, 'plugin_sqlquery'); |
|
|
|
|
$this->Lexer->addEntryPattern('<sql>', $mode, 'plugin_sqlquery'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public function postConnect() |
|
|
|
|
{ |
|
|
|
|
$this->Lexer->addExitPattern('</sql>','plugin_sqlquery'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -33,36 +36,29 @@ class syntax_plugin_sqlquery extends DokuWiki_Syntax_Plugin { |
|
|
|
|
* @param int $state The state of the handler |
|
|
|
|
* @param int $pos The position in the document |
|
|
|
|
* @param Doku_Handler $handler The handler |
|
|
|
|
* |
|
|
|
|
* @return array Data for the renderer |
|
|
|
|
*/ |
|
|
|
|
public function handle($match, $state, $pos, Doku_Handler $handler) { |
|
|
|
|
$data = array('state' => $state); |
|
|
|
|
if ($state == DOKU_LEXER_SPECIAL) { |
|
|
|
|
# get type (DSN prefix) |
|
|
|
|
if (preg_match('/<sql\b.*type=(mysql|dblib)/', $match, $result)) { |
|
|
|
|
$data['type'] = $result[1]; |
|
|
|
|
} else { |
|
|
|
|
$data['type'] = $this->getConf('type'); |
|
|
|
|
} |
|
|
|
|
# get host |
|
|
|
|
if (preg_match('/<sql\b.*host=([\w\-\.$]+)/', $match, $result)) { |
|
|
|
|
$data['host'] = $result[1]; |
|
|
|
|
} else { |
|
|
|
|
$data['host'] = $this->getConf('Host'); |
|
|
|
|
} |
|
|
|
|
# get database |
|
|
|
|
if (preg_match('/<sql\b.*db=([\w\-\.$]+)/', $match, $result)) { |
|
|
|
|
$data['db'] = $result[1]; |
|
|
|
|
} else { |
|
|
|
|
$data['db'] = $this->getConf('DB'); |
|
|
|
|
} |
|
|
|
|
# get query |
|
|
|
|
$data['match'] = $match; |
|
|
|
|
if (preg_match('%<sql.*?>(.*)</sql>%s', $match, $result)) { |
|
|
|
|
$data['query'] = trim($result[1]); |
|
|
|
|
} |
|
|
|
|
public function handle($match, $state, $pos, Doku_Handler $handler) |
|
|
|
|
{ |
|
|
|
|
switch ( $state ) |
|
|
|
|
{ |
|
|
|
|
case DOKU_LEXER_ENTER: |
|
|
|
|
$data = array(); |
|
|
|
|
return $data; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case DOKU_LEXER_UNMATCHED: |
|
|
|
|
return array('sqlquery' => $match); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case DOKU_LEXER_EXIT: |
|
|
|
|
$data = array(); |
|
|
|
|
return $data; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$data = array(); |
|
|
|
|
return $data; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -72,73 +68,72 @@ class syntax_plugin_sqlquery extends DokuWiki_Syntax_Plugin { |
|
|
|
|
* @param string $mode Renderer mode (supported modes: xhtml) |
|
|
|
|
* @param Doku_Renderer $renderer The renderer |
|
|
|
|
* @param array $data The data from the handler() function |
|
|
|
|
* |
|
|
|
|
* @return bool If rendering was successful. |
|
|
|
|
*/ |
|
|
|
|
public function render($mode, Doku_Renderer $renderer, $data) |
|
|
|
|
{ |
|
|
|
|
if ( $mode != 'xhtml' ) return false; |
|
|
|
|
if (empty($data['query'])) return true; |
|
|
|
|
|
|
|
|
|
// get configuration |
|
|
|
|
if ( !empty( $data['sqlquery'] ) ) |
|
|
|
|
{ |
|
|
|
|
// получаем параметры конфигурации |
|
|
|
|
$host = $this->getConf('Host'); |
|
|
|
|
$DB = $this->getConf('DB'); |
|
|
|
|
$user = $this->getConf('user'); |
|
|
|
|
$password = $this->getConf('password'); |
|
|
|
|
|
|
|
|
|
// connect to database |
|
|
|
|
$dsn = "{$data['type']}:host={$data['host']};dbname={$data[db]};charset=UTF-8;"; |
|
|
|
|
try { |
|
|
|
|
$dbh = new PDO($dsn, $user, $password); |
|
|
|
|
} catch (PDOException $e) { |
|
|
|
|
$renderer->doc .= "<pre>Unable to connect ro database:" . $e->getMessage() . "</pre>\n"; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
|
|
|
|
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_NUM); |
|
|
|
|
|
|
|
|
|
// run query |
|
|
|
|
try { |
|
|
|
|
$result = $dbh->query($data['query']); |
|
|
|
|
} catch (PDOException $e) { |
|
|
|
|
$renderer->doc .= "<pre>Error in query:" . $e->getMessage() . "</pre>\n"; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
// получаем запрос |
|
|
|
|
$querystring = $data['sqlquery']; |
|
|
|
|
|
|
|
|
|
// get the number of fields in the table |
|
|
|
|
$fieldcount = $result->columnCount(); |
|
|
|
|
// подключаемся к базе |
|
|
|
|
$link = mysqli_connect($host, $user, $password, $DB); |
|
|
|
|
mysqli_set_charset($link, "utf8"); |
|
|
|
|
|
|
|
|
|
// build a table |
|
|
|
|
$renderer->doc .= '<table id="sqlquerytable" class="inline">' . "\n"; |
|
|
|
|
// подключились |
|
|
|
|
if ( $link ) |
|
|
|
|
{ |
|
|
|
|
$result = mysqli_query($link, $querystring); |
|
|
|
|
if ( $result ) |
|
|
|
|
{ |
|
|
|
|
// получаем кол-во полей в таблице |
|
|
|
|
$fieldcount = mysqli_num_fields($result); |
|
|
|
|
|
|
|
|
|
// build the header section of the table |
|
|
|
|
$renderer->doc .= "<thead><tr>"; |
|
|
|
|
// строим таблицу |
|
|
|
|
$renderer->doc .= "<table id=\"sqlquerytable\" class=\"inline\">"; |
|
|
|
|
|
|
|
|
|
for ($i = 0; $i < $fieldcount; $i++) { |
|
|
|
|
$meta = $result->getColumnMeta($i); |
|
|
|
|
// строим заголовок |
|
|
|
|
$renderer->doc .= "<thead><tr>"; |
|
|
|
|
while ($fieldinfo = mysqli_fetch_field($result)) |
|
|
|
|
{ |
|
|
|
|
$renderer->doc .= "<th>"; |
|
|
|
|
$renderer->doc .= $meta['name']; |
|
|
|
|
$renderer->doc .= $fieldinfo->name; |
|
|
|
|
$renderer->doc .= "</th>"; |
|
|
|
|
} |
|
|
|
|
$renderer->doc .= "</tr></thead>\n"; |
|
|
|
|
$renderer->doc .= "</tr></thead>"; |
|
|
|
|
|
|
|
|
|
// build the contents of the table |
|
|
|
|
$renderer->doc .= "<tbody>\n"; |
|
|
|
|
foreach ($result as $row) { |
|
|
|
|
// строим содержимое таблицы |
|
|
|
|
$renderer->doc .= "<tbody>"; |
|
|
|
|
while ($row = mysqli_fetch_row($result)) |
|
|
|
|
{ |
|
|
|
|
$renderer->doc .= "<tr>"; |
|
|
|
|
for ( $i = 0; $i < $fieldcount; $i++ ) { |
|
|
|
|
|
|
|
|
|
// строим строку |
|
|
|
|
for ( $i = 0; $i < $fieldcount; $i++ ) |
|
|
|
|
{ |
|
|
|
|
$renderer->doc .= "<td>"; |
|
|
|
|
$renderer->doc .= htmlentities($row[$i]); |
|
|
|
|
$renderer->doc .= $row[$i]; |
|
|
|
|
$renderer->doc .= "</td>"; |
|
|
|
|
} |
|
|
|
|
$renderer->doc .= "</tr>\n"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// finish the table |
|
|
|
|
$renderer->doc .= "</tbody>\n</table>\n"; |
|
|
|
|
|
|
|
|
|
// Close connection, there is no close() method with PDO :-( |
|
|
|
|
$result = null; |
|
|
|
|
$dbh = null; |
|
|
|
|
|
|
|
|
|
$renderer->doc .= "</tr>"; |
|
|
|
|
} // of while fetch_row |
|
|
|
|
// закрываем таблицу |
|
|
|
|
$renderer->doc .= "</tbody></table>"; |
|
|
|
|
} // of mysqli_query |
|
|
|
|
mysqli_close($link); |
|
|
|
|
} // of mysqli link |
|
|
|
|
} // of sqlquery not empty |
|
|
|
|
return true; |
|
|
|
|
} // of render function |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// vim:ts=4:sw=4:et: |
|
|
|
|