1<?php 2 3 4if ( !defined( 'DOKU_INC' ) ) 5 define( 'DOKU_INC', realpath( dirname( __FILE__ ) . '/../../' ) . '/' ); 6 7if ( !defined( 'DOKU_PLUGIN' ) ) 8 define( 'DOKU_PLUGIN', DOKU_INC . 'lib/plugins/' ); 9 10require_once( DOKU_PLUGIN . 'admin.php' ); 11 12 13 14/** 15 * All DokuWiki plugins to extend the admin function 16 * need to inherit from this class 17 */ 18 19class admin_plugin_database2 extends DokuWiki_Admin_Plugin 20{ 21 22 23 /** 24 * instance providing functionality stuff. 25 * 26 * @var Database2_Admin 27 */ 28 29 protected $db; 30 31 32 33 /** 34 * return some info 35 */ 36 37 public function getInfo() 38 { 39 return array( 40 'author' => 'Thomas Urban', 41 'email' => 'soletan@nihilum.de', 42 'date' => '2009-11-18', 43 'name' => 'database2', 44 'desc' => 'Provides console for querying SQL commands ' . 45 'to local SQLite database file', 46 'url' => 'http://wiki.nihilum.de/software:database2', 47 ); 48 } 49 50 51 /** 52 * handle user request 53 */ 54 55 public function handle() 56 { 57 } 58 59 60 /** 61 * output appropriate html 62 */ 63 64 public function html() 65 { 66 67 if ( !$this->getConf( 'console' ) ) 68 { 69 ptln( $this->getLang( 'consoleoff' ) ); 70 return; 71 } 72 73 74 75 if ( $this->getConf( 'consoleforcehistory') ) 76 { 77 @session_start(); 78 $useHistory = true; 79 } 80 else if ( $useHistory = !headers_sent() ) 81 session_start(); 82 else 83 ptln( $this->getLang( 'consolesession' ) ); 84 85 86 87 $db = $this->connect( $_REQUEST['dbfile'] ); 88 if ( $db ) 89 { 90 91 if ( $_GET['sectok'] != getSecurityToken() ) 92 $query = ''; 93 else 94 $query = trim( $_GET['q'] ); 95 96 $queryEsc = strtr( $query, array( '<' => '<' ) ); 97 98 99 if ( $useHistory && ( $query !== '' ) ) 100 { 101 102 if ( !is_array( $_SESSION['DATABASE2_CONSOLE_HISTORY'] ) ) 103 $_SESSION['DATABASE2_CONSOLE_HISTORY'] = array(); 104 105 $HISTORY =& $_SESSION['DATABASE2_CONSOLE_HISTORY']; 106 107 108 $index = array_search( $query, $HISTORY ); 109 if ( $index !== false ) 110 unset( $HISTORY[$index] ); 111 112 array_unshift( $HISTORY, $query ); 113 114 $HISTORY = array_slice( $HISTORY, 0, 20 ); 115 116 } 117 118 119 120 $btn = $this->getLang( 'consolebtn' ); 121 $sqliteLabel = $this->getLang( 'consolesqlitedoc' ); 122 123 $dbSelectorLabel = $this->getLang( 'consoledbselector' ); 124 125 $helperShortcutsLabel = $this->getLang( 'consolehelpershortcuts' ); 126 $helperKeys = $this->getLang( 'consolehelperkeys' ); 127 $helperLocks = $this->getLang( 'consolehelperlocks' ); 128 $helperLog = $this->getLang( 'consolehelperlog' ); 129 $helperTables = $this->getLang( 'consolehelpertables' ); 130 $helperVac = $this->getLang( 'consolehelpervac' ); 131 132 $helperTemplatesLabel = $this->getLang( 'consolehelpertemplates' ); 133 $helperRead = $this->getLang( 'consolehelperread' ); 134 $helperReadSQL = $this->getLang( 'consolehelperreadsql' ); 135 $helperEdit = $this->getLang( 'consolehelperedit' ); 136 $helperEditSQL = $this->getLang( 'consolehelpereditsql' ); 137 $helperDelete = $this->getLang( 'consolehelperdelete' ); 138 $helperDeleteSQL = $this->getLang( 'consolehelperdeletesql' ); 139 $helperAdd = $this->getLang( 'consolehelperadd' ); 140 $helperAddSQL = $this->getLang( 'consolehelperaddsql' ); 141 142 if ( $useHistory ) 143 { 144 145 $helperHistoryLabel = $this->getLang( 'consolehelperhistory' ); 146 147 $history = array(); 148 if ( is_array( $HISTORY ) ) 149 foreach ( $HISTORY as $q ) 150 { 151 $qesc = strtr( $q, array( '<' => '<' ) ); 152 $q = strtr( $q, array( '"' => '"' ) ); 153 $history[] = '<option value="' . $q . '">' . $qesc . ' </option>'; 154 } 155 156 $history = implode( "\n", $history ); 157 $history = <<<EOT 158 <div> 159 $helperHistoryLabel 160 <select name="history" onchange="return db2_console_load(this.options[this.selectedIndex].value);"> 161 $history 162 </select> 163 </div> 164EOT; 165 166 } 167 168 $sectok = getSecurityToken(); 169 170 171 172 echo <<<EOT 173<script type="text/javascript"><!-- 174function db2_console_load(query) 175{ 176 with ( document.database2_console.q ) 177 { 178 value = query; 179 focus(); 180 } 181 182 return false; 183} 184//--></script> 185<form action="$_SERVER[PHP_SELF]" method="GET" name="database2_console" id="database2_console"> 186 <input type="hidden" name="do" value="$_REQUEST[do]" /> 187 <input type="hidden" name="page" value="$_REQUEST[page]" /> 188 <input type="hidden" name="id" value="$_REQUEST[id]" /> 189 <input type="hidden" name="sectok" value="$sectok" /> 190 <div> 191 $dbSelectorLabel <input type="text" name="dbfile" id="dbfile" value="$_REQUEST[dbfile]" size="40" /> 192 </div> 193 <div> 194 $helperShortcutsLabel 195 <a href="" onclick="return db2_console_load('SELECT * FROM __keys');">$helperKeys</a> 196 | 197 <a href="" onclick="return db2_console_load('SELECT * FROM __locks');">$helperLocks</a> 198 | 199 <a href="" onclick="return db2_console_load('SELECT * FROM __log');">$helperLog</a> 200 | 201 <a href="" onclick="return db2_console_load('SELECT * FROM SQLITE_MASTER');">$helperTables</a> 202 | 203 <a href="" onclick="return db2_console_load('VACUUM');">$helperVac</a> 204 </div> 205 <div> 206 $helperTemplatesLabel 207 <a href="" onclick="return db2_console_load('$helperReadSQL');">$helperRead</a> 208 | 209 <a href="" onclick="return db2_console_load('$helperEditSQL');">$helperEdit</a> 210 | 211 <a href="" onclick="return db2_console_load('$helperDeleteSQL');">$helperDelete</a> 212 | 213 <a href="" onclick="return db2_console_load('$helperAddSQL');">$helperAdd</a> 214 </div> 215 $history 216 <textarea name="q" rows="3" cols="60" style="width: 100%;">$queryEsc</textarea> 217 <div> 218 <input type="submit" value="$btn" /> 219 | 220 <a href="http://sqlite.org/lang.html" target="sqliteLangDoc"> 221 $sqliteLabel 222 </a> 223 </div> 224</form> 225<script type="text/javascript"><!-- 226document.database2_console.q.select(); 227document.database2_console.q.focus(); 228//--></script> 229EOT; 230 231 if ( $query !== '' ) 232 { 233 234 echo <<<EOT 235<div style="padding-top: 1em; margin-top: 1em; border-top: 1px solid #888888;"> 236EOT; 237 238 try 239 { 240 241 $result = $db->getLink()->query( $query ); 242 243 if ( $result instanceof PDOStatement ) 244 { 245 246 $rows = $result->fetchAll( PDO::FETCH_ASSOC ); 247 248 if ( count( $rows ) ) 249 { 250 251 $first = array_slice( $rows, 0, 1 ); 252 $cols = empty( $first ) ? array() : array_keys( $first ); 253 254 echo $db->__renderTable( null, $cols, $rows, 255 count( $rows ), count( $rows ), 256 0, null, array(), false, 257 true ); 258 259 } 260 else 261 echo $this->getLang( 'consolegoodresult' ); 262 263 } 264 else 265 var_dump( $result ); 266 267 } 268 catch ( PDOException $e ) 269 { 270 echo '<div class="error">' . $e->getMessage() . '</div>'; 271 } 272 273 echo '</div>'; 274 275 } 276 } 277 } 278 279 280 /** 281 * Connects to local database. 282 * 283 * @return Database2_Admin 284 */ 285 286 public function connect( $explicitDBPathname = null ) 287 { 288 289 if ( !( $this->db instanceof Database2_Admin ) ) 290 { 291 292 self::includeLib(); 293 294 $db = new Database2_Admin( $this ); 295 296 $dbFile = trim( $explicitDBPathname ); 297 if ( $dbFile === '' ) 298 $dbFile = $_REQUEST['id']; 299 300 if ( $db->connect( $dbFile ) ) 301 $this->db = $db; 302 303 } 304 305 return $this->db; 306 307 } 308 309 310 public static function includeLib() 311 { 312 313 if ( !class_exists( 'Database2_Admin' ) ) 314 { 315 316 $libFile = dirname( __FILE__ ) . '/database2.php'; 317 318 // support working with development version if available and 319 // selected to enable development in a production wiki 320 // (as used on wiki.nihilum.de) 321 if ( is_file( dirname( __FILE__ ) . '/database2.dev.php' ) ) 322 { 323 324 @session_start(); 325 326 if ( $_GET['use_dev'] ) 327 $_SESSION['useDevIP'] = $_SERVER['REMOTE_ADDR']; 328 329 if ( $_GET['use_prod'] ) 330 unset( $_SESSION['useDevIP'] ); 331 332 if ( $_SESSION['useDevIP'] ) 333 if ( $_SESSION['useDevIP'] == $_SERVER['REMOTE_ADDR'] ) 334 $libFile = dirname( __FILE__ ) . '/database2.dev.php'; 335 336 } 337 338 { include_once( $libFile ); } 339 340 } 341 } 342} 343