193d995e0SAndreas Gohr<?php 293d995e0SAndreas Gohr/** 393d995e0SAndreas Gohr * DokuWiki Plugin sqlite (Admin Component) 493d995e0SAndreas Gohr * 593d995e0SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 693d995e0SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 793d995e0SAndreas Gohr */ 893d995e0SAndreas Gohr 9af0e7691SSzymon Olewniczakuse dokuwiki\Form\Form; 10*ecc45fdcSSzymon Olewniczakuse dokuwiki\Form\InputElement; 11af0e7691SSzymon Olewniczak 1293d995e0SAndreas Gohr// must be run within Dokuwiki 1393d995e0SAndreas Gohrif(!defined('DOKU_INC')) die(); 1493d995e0SAndreas Gohr 1593d995e0SAndreas Gohrclass admin_plugin_sqlite extends DokuWiki_Admin_Plugin { 1693d995e0SAndreas Gohr 170542fc8eSKlap-in function getMenuSort() { 180542fc8eSKlap-in return 500; 190542fc8eSKlap-in } 200542fc8eSKlap-in 210542fc8eSKlap-in function forAdminOnly() { 220542fc8eSKlap-in return true; 230542fc8eSKlap-in } 2493d995e0SAndreas Gohr 2593d995e0SAndreas Gohr function handle() { 26a34ef333SKlap-in global $conf; 270dbd1d4cSSzymon Olewniczak global $INPUT; 280dbd1d4cSSzymon Olewniczak 29af0e7691SSzymon Olewniczak if($INPUT->bool('sqlite_rename') && checkSecurityToken()) { 30a34ef333SKlap-in 317431dc90SSzymon Olewniczak $path = $conf['metadir'].'/'.$INPUT->str('db'); 32a34ef333SKlap-in if(io_rename($path.'.sqlite', $path.'.sqlite3')) { 33a34ef333SKlap-in msg('Renamed database file succesfull!', 1); 34a34ef333SKlap-in //set to new situation 357431dc90SSzymon Olewniczak $INPUT->set('version', 'sqlite3'); 36a34ef333SKlap-in 37a34ef333SKlap-in } else { 38a34ef333SKlap-in msg('Renaming database file fails!', -1); 39a34ef333SKlap-in } 400dbd1d4cSSzymon Olewniczak } elseif($INPUT->bool('sqlite_export') && checkSecurityToken()) { 410dbd1d4cSSzymon Olewniczak 420dbd1d4cSSzymon Olewniczak /** @var $DBI helper_plugin_sqlite */ 430dbd1d4cSSzymon Olewniczak $DBI = plugin_load('helper', 'sqlite'); 440dbd1d4cSSzymon Olewniczak $dbname = $INPUT->str('db'); 450dbd1d4cSSzymon Olewniczak 460dbd1d4cSSzymon Olewniczak $dumpfile = $DBI->dumpDatabase($dbname, DOKU_EXT_PDO, true); 470dbd1d4cSSzymon Olewniczak if ($dumpfile) { 480dbd1d4cSSzymon Olewniczak header('Content-Type: text/sql'); 490dbd1d4cSSzymon Olewniczak header('Content-Disposition: attachment; filename="'.$dbname.'.sql";'); 500dbd1d4cSSzymon Olewniczak 510dbd1d4cSSzymon Olewniczak readfile($dumpfile); 520dbd1d4cSSzymon Olewniczak exit(0); 530dbd1d4cSSzymon Olewniczak } 540dbd1d4cSSzymon Olewniczak } elseif($INPUT->bool('sqlite_import') && checkSecurityToken()) { 550dbd1d4cSSzymon Olewniczak 560dbd1d4cSSzymon Olewniczak /** @var $DBI helper_plugin_sqlite */ 570dbd1d4cSSzymon Olewniczak $DBI = plugin_load('helper', 'sqlite'); 580dbd1d4cSSzymon Olewniczak $dbname = $INPUT->str('db'); 590dbd1d4cSSzymon Olewniczak $dumpfile = $_FILES['dumpfile']['tmp_name']; 600dbd1d4cSSzymon Olewniczak 610dbd1d4cSSzymon Olewniczak if (empty($dumpfile)) { 620dbd1d4cSSzymon Olewniczak msg($this->getLang('import_no_file'), -1); 630dbd1d4cSSzymon Olewniczak return; 640dbd1d4cSSzymon Olewniczak } 650dbd1d4cSSzymon Olewniczak 660dbd1d4cSSzymon Olewniczak if ($DBI->fillDatabaseFromDump($dbname, $dumpfile, true)) { 670dbd1d4cSSzymon Olewniczak msg($this->getLang('import_success'), 1); 680dbd1d4cSSzymon Olewniczak } 69*ecc45fdcSSzymon Olewniczak } elseif($INPUT->bool('sqlite_query_save') && checkSecurityToken()) { 70*ecc45fdcSSzymon Olewniczak if($INPUT->str('sql') === '') { 71*ecc45fdcSSzymon Olewniczak msg($this->getLang('validation query_required'), -1); 72*ecc45fdcSSzymon Olewniczak return; 73*ecc45fdcSSzymon Olewniczak } 74*ecc45fdcSSzymon Olewniczak if($INPUT->str('name') === '') { 75*ecc45fdcSSzymon Olewniczak msg($this->getLang('validation query_name_required'), -1); 76*ecc45fdcSSzymon Olewniczak return; 77*ecc45fdcSSzymon Olewniczak } 78*ecc45fdcSSzymon Olewniczak /** @var helper_plugin_sqlite_db $db_helper */ 79*ecc45fdcSSzymon Olewniczak $db_helper = $this->loadHelper('sqlite_db'); 80*ecc45fdcSSzymon Olewniczak $sqlite_db = $db_helper->getDB(); 81*ecc45fdcSSzymon Olewniczak $ok = $sqlite_db->storeEntry('queries', array( 82*ecc45fdcSSzymon Olewniczak 'db' => $INPUT->str('db'), 83*ecc45fdcSSzymon Olewniczak 'name' => $INPUT->str('name'), 84*ecc45fdcSSzymon Olewniczak 'sql' => $INPUT->str('sql') 85*ecc45fdcSSzymon Olewniczak )); 86*ecc45fdcSSzymon Olewniczak if ($ok) { 87*ecc45fdcSSzymon Olewniczak msg($this->getLang('success query_saved'), 1); 88*ecc45fdcSSzymon Olewniczak } 89*ecc45fdcSSzymon Olewniczak } elseif($INPUT->has('sqlite_query_delete') && checkSecurityToken()) { 90*ecc45fdcSSzymon Olewniczak /** @var helper_plugin_sqlite_db $db_helper */ 91*ecc45fdcSSzymon Olewniczak $db_helper = $this->loadHelper('sqlite_db'); 92*ecc45fdcSSzymon Olewniczak $sqlite_db = $db_helper->getDB(); 93*ecc45fdcSSzymon Olewniczak 94*ecc45fdcSSzymon Olewniczak $ok = $sqlite_db->query("DELETE FROM queries WHERE id=?;", $INPUT->int('sqlite_query_delete')); 95*ecc45fdcSSzymon Olewniczak if ($ok) { 96*ecc45fdcSSzymon Olewniczak msg($this->getLang('success query_deleted'), 1); 97*ecc45fdcSSzymon Olewniczak } 98a34ef333SKlap-in } 9993d995e0SAndreas Gohr } 10093d995e0SAndreas Gohr 10193d995e0SAndreas Gohr function html() { 10293d995e0SAndreas Gohr global $ID; 103a34ef333SKlap-in global $conf; 104271f9caeSSzymon Olewniczak global $INPUT; 10593d995e0SAndreas Gohr 10693d995e0SAndreas Gohr echo $this->locale_xhtml('intro'); 10793d995e0SAndreas Gohr 1087431dc90SSzymon Olewniczak if($INPUT->has('db') && checkSecurityToken()) { 10993d995e0SAndreas Gohr 1107431dc90SSzymon Olewniczak echo '<h2>'.$this->getLang('db').' "'.hsc($INPUT->str('db')).'"</h2>'; 11193d995e0SAndreas Gohr echo '<div class="level2">'; 11293d995e0SAndreas Gohr 113a34ef333SKlap-in $sqlcommandform = true; 114a34ef333SKlap-in /** @var $DBI helper_plugin_sqlite */ 11579288b58SGerrit Uitslag $DBI = plugin_load('helper', 'sqlite'); 1167431dc90SSzymon Olewniczak if($INPUT->str('version') == 'sqlite2') { 1177431dc90SSzymon Olewniczak if(helper_plugin_sqlite_adapter::isSqlite3db($conf['metadir'].'/'.$INPUT->str('db').'.sqlite')) { 118a34ef333SKlap-in 119a34ef333SKlap-in msg('This is a database in sqlite3 format.', 2); 120a34ef333SKlap-in msg( 121a34ef333SKlap-in 'This plugin needs your database file has the extension ".sqlite3" 122a34ef333SKlap-in instead of ".sqlite" before it will be recognized as sqlite3 database.', 2 123a34ef333SKlap-in ); 124*ecc45fdcSSzymon Olewniczak $action = wl($ID, [ 125*ecc45fdcSSzymon Olewniczak 'do' => 'admin', 126*ecc45fdcSSzymon Olewniczak 'page' => 'sqlite', 127*ecc45fdcSSzymon Olewniczak 'db' => $INPUT->str('db'), 128*ecc45fdcSSzymon Olewniczak 'version'=> $INPUT->str('version') 129*ecc45fdcSSzymon Olewniczak ], false, '&'); 130*ecc45fdcSSzymon Olewniczak $form = new Form(['action' => $action]); 131*ecc45fdcSSzymon Olewniczak $form->addButton('sqlite_rename', sprintf($this->getLang('rename2to3'), hsc($INPUT->str('db')))) 132af0e7691SSzymon Olewniczak ->attr('type', 'submit'); 133af0e7691SSzymon Olewniczak print $form->toHTML(); 134a34ef333SKlap-in 135a34ef333SKlap-in if($DBI->existsPDOSqlite()) $sqlcommandform = false; 136a34ef333SKlap-in 137a34ef333SKlap-in } else { 138a34ef333SKlap-in msg( 139a34ef333SKlap-in 'Before PDO sqlite can handle this format, it needs a conversion to the sqlite3 format. 140cd9d7ecbSSzymon Olewniczak Because PHP sqlite extension is no longer supported, 1417431dc90SSzymon Olewniczak you should manually convert "'.hsc($INPUT->str('db')).'.sqlite" in the meta directory to "'.hsc($INPUT->str('db')).'.sqlite3".<br /> 142a34ef333SKlap-in See for info about the conversion '.$this->external_link('http://www.sqlite.org/version3.html').'.', -1 143a34ef333SKlap-in ); 144*ecc45fdcSSzymon Olewniczak $sqlcommandform = false; 145a34ef333SKlap-in } 146a34ef333SKlap-in } else { 147a34ef333SKlap-in if(!$DBI->existsPDOSqlite()) { 148a34ef333SKlap-in $sqlcommandform = false; 149a34ef333SKlap-in msg('A database in sqlite3 format needs the PHP PDO sqlite plugin.', -1); 150a34ef333SKlap-in } 151a34ef333SKlap-in } 152a34ef333SKlap-in 153a34ef333SKlap-in if($sqlcommandform) { 15493d995e0SAndreas Gohr echo '<ul>'; 1557f5f9a98SAndreas Gohr echo '<li><div class="li"><a href="'. 156a34ef333SKlap-in wl( 157a34ef333SKlap-in $ID, array( 158a34ef333SKlap-in 'do' => 'admin', 1597f5f9a98SAndreas Gohr 'page' => 'sqlite', 1607431dc90SSzymon Olewniczak 'db' => $INPUT->str('db'), 1617431dc90SSzymon Olewniczak 'version'=> $INPUT->str('version'), 1627f5f9a98SAndreas Gohr 'sql' => 'SELECT name,sql FROM sqlite_master WHERE type=\'table\' ORDER BY name', 163a34ef333SKlap-in 'sectok' => getSecurityToken() 164a34ef333SKlap-in ) 165a34ef333SKlap-in ). 166ab6c40f9SAdrian Lang '">'.$this->getLang('table').'</a></div></li>'; 1677f5f9a98SAndreas Gohr echo '<li><div class="li"><a href="'. 168a34ef333SKlap-in wl( 169a34ef333SKlap-in $ID, array( 170a34ef333SKlap-in 'do' => 'admin', 1717f5f9a98SAndreas Gohr 'page' => 'sqlite', 1727431dc90SSzymon Olewniczak 'db' => $INPUT->str('db'), 1737431dc90SSzymon Olewniczak 'version'=> $INPUT->str('version'), 1747f5f9a98SAndreas Gohr 'sql' => 'SELECT name,sql FROM sqlite_master WHERE type=\'index\' ORDER BY name', 175a34ef333SKlap-in 'sectok' => getSecurityToken() 176a34ef333SKlap-in ) 177a34ef333SKlap-in ). 178ab6c40f9SAdrian Lang '">'.$this->getLang('index').'</a></div></li>'; 1790dbd1d4cSSzymon Olewniczak echo '<li><div class="li"><a href="'. 1800dbd1d4cSSzymon Olewniczak wl( 1810dbd1d4cSSzymon Olewniczak $ID, array( 1820dbd1d4cSSzymon Olewniczak 'do' => 'admin', 1830dbd1d4cSSzymon Olewniczak 'page' => 'sqlite', 1847431dc90SSzymon Olewniczak 'db' => $INPUT->str('db'), 1857431dc90SSzymon Olewniczak 'version'=> $INPUT->str('version'), 1860dbd1d4cSSzymon Olewniczak 'sqlite_export' => '1', 1870dbd1d4cSSzymon Olewniczak 'sectok' => getSecurityToken() 1880dbd1d4cSSzymon Olewniczak ) 1890dbd1d4cSSzymon Olewniczak ). 1900dbd1d4cSSzymon Olewniczak '">'.$this->getLang('export').'</a></div></li>'; 1910dbd1d4cSSzymon Olewniczak 1920dbd1d4cSSzymon Olewniczak 193*ecc45fdcSSzymon Olewniczak $action = wl($ID, [ 194*ecc45fdcSSzymon Olewniczak 'do' => 'admin', 195*ecc45fdcSSzymon Olewniczak 'page' => 'sqlite', 196*ecc45fdcSSzymon Olewniczak 'db' => $INPUT->str('db'), 197*ecc45fdcSSzymon Olewniczak 'version'=> $INPUT->str('version') 198*ecc45fdcSSzymon Olewniczak ], false, '&'); 199*ecc45fdcSSzymon Olewniczak $form = new Form(['action' => $action, 'enctype' => 'multipart/form-data']); 200*ecc45fdcSSzymon Olewniczak $form->addElement(new InputElement('file', 'dumpfile')); 2010dbd1d4cSSzymon Olewniczak $form->addButton('sqlite_import', $this->getLang('import')); 2020dbd1d4cSSzymon Olewniczak echo '<li>' . $form->toHTML() . '</li>'; 20393d995e0SAndreas Gohr echo '</ul>'; 20493d995e0SAndreas Gohr 205*ecc45fdcSSzymon Olewniczak $action = wl($ID, [ 206*ecc45fdcSSzymon Olewniczak 'do' => 'admin', 207*ecc45fdcSSzymon Olewniczak 'page' => 'sqlite', 2087431dc90SSzymon Olewniczak 'db' => $INPUT->str('db'), 209*ecc45fdcSSzymon Olewniczak 'version'=> $INPUT->str('version') 210*ecc45fdcSSzymon Olewniczak ], false, '&'); 211*ecc45fdcSSzymon Olewniczak $form = (new Form(['action' => $action]))->addClass('sqliteplugin'); 212*ecc45fdcSSzymon Olewniczak $form->addFieldsetOpen('SQL Command'); 213*ecc45fdcSSzymon Olewniczak $form->addTextarea('sql')->addClass('edit')->val(hsc($INPUT->str('sql'))); 214*ecc45fdcSSzymon Olewniczak $form->addElement(new InputElement('submit', '')); 215*ecc45fdcSSzymon Olewniczak $form->addTextInput('name', $this->getLang('query_name')); 216*ecc45fdcSSzymon Olewniczak $form->addButton('sqlite_query_save', $this->getLang('save_query')); 217*ecc45fdcSSzymon Olewniczak $form->addFieldsetClose(); 218*ecc45fdcSSzymon Olewniczak print $form->toHTML(); 21993d995e0SAndreas Gohr 220271f9caeSSzymon Olewniczak // List saved queries 221*ecc45fdcSSzymon Olewniczak /** @var helper_plugin_sqlite_db $db_helper */ 222*ecc45fdcSSzymon Olewniczak $db_helper = $this->loadHelper('sqlite_db'); 223*ecc45fdcSSzymon Olewniczak $sqlite_db = $db_helper->getDB(); 2247431dc90SSzymon Olewniczak $res = $sqlite_db->query("SELECT id, name, sql FROM queries WHERE db=?", $INPUT->str('db')); 22509a0e52bSSzymon Olewniczak $result = $sqlite_db->res2arr($res); 22609a0e52bSSzymon Olewniczak if(count($result) > 0) { 22774f97ccfSSzymon Olewniczak echo '<h3>' . $this->getLang('saved_queries') . '</h3>'; 228271f9caeSSzymon Olewniczak echo '<div>'; 229271f9caeSSzymon Olewniczak echo '<table class="inline">'; 230271f9caeSSzymon Olewniczak echo '<tr>'; 231271f9caeSSzymon Olewniczak echo '<th>name</th>'; 232271f9caeSSzymon Olewniczak echo '<th>sql</th>'; 233271f9caeSSzymon Olewniczak echo '<th></th>'; 234271f9caeSSzymon Olewniczak echo '</tr>'; 235271f9caeSSzymon Olewniczak foreach($result as $row) { 236271f9caeSSzymon Olewniczak echo '<tr>'; 237271f9caeSSzymon Olewniczak echo '<td>'.hsc($row['name']).'</td>'; 238271f9caeSSzymon Olewniczak $link = wl($ID, array( 'do'=> 'admin', 239271f9caeSSzymon Olewniczak 'page'=> 'sqlite', 2407431dc90SSzymon Olewniczak 'db'=> $INPUT->str('db'), 2417431dc90SSzymon Olewniczak 'version'=> $INPUT->str('version'), 242271f9caeSSzymon Olewniczak 'sql' => $row['sql'], 243271f9caeSSzymon Olewniczak 'sectok'=> getSecurityToken())); 244271f9caeSSzymon Olewniczak echo '<td><a href="'.$link.'">'.hsc($row['sql']).'</a></td>'; 245271f9caeSSzymon Olewniczak 246271f9caeSSzymon Olewniczak $link = wl($ID, array( 'do'=> 'admin', 247271f9caeSSzymon Olewniczak 'page'=> 'sqlite', 2487431dc90SSzymon Olewniczak 'db'=> $INPUT->str('db'), 2497431dc90SSzymon Olewniczak 'version'=> $INPUT->str('version'), 250*ecc45fdcSSzymon Olewniczak 'sqlite_query_delete' => $row['id'], 251271f9caeSSzymon Olewniczak 'sectok'=> getSecurityToken())); 252271f9caeSSzymon Olewniczak echo '<td><a href="'.$link.'">delete</a></td>'; 253271f9caeSSzymon Olewniczak echo '</tr>'; 254271f9caeSSzymon Olewniczak } 255271f9caeSSzymon Olewniczak echo '</table>'; 256271f9caeSSzymon Olewniczak echo '</div>'; 257271f9caeSSzymon Olewniczak } 258271f9caeSSzymon Olewniczak 2597431dc90SSzymon Olewniczak if($INPUT->has('sql')) { 2607431dc90SSzymon Olewniczak if(!$DBI->init($INPUT->str('db'), '')) return; 26109a0e52bSSzymon Olewniczak 262271f9caeSSzymon Olewniczak print '<h3>Query results</h3>'; 2637431dc90SSzymon Olewniczak $sql = $DBI->SQLstring2array($INPUT->str('sql')); 26493d995e0SAndreas Gohr foreach($sql as $s) { 26593d995e0SAndreas Gohr $s = preg_replace('!^\s*--.*$!m', '', $s); 26693d995e0SAndreas Gohr $s = trim($s); 26793d995e0SAndreas Gohr if(!$s) continue; 26884041991SKlap-in 26984041991SKlap-in $time_start = microtime(true); 27084041991SKlap-in 27193d995e0SAndreas Gohr $res = $DBI->query("$s;"); 27293d995e0SAndreas Gohr if($res === false) continue; 27393d995e0SAndreas Gohr 27493d995e0SAndreas Gohr $result = $DBI->res2arr($res); 27584041991SKlap-in 27684041991SKlap-in $time_end = microtime(true); 27784041991SKlap-in $time = $time_end - $time_start; 27884041991SKlap-in 27984041991SKlap-in $cnt = $DBI->res2count($res); 28084041991SKlap-in msg($cnt.' affected rows in '.($time < 0.0001 ? substr($time, 0, 5).substr($time, -3) : substr($time, 0, 7)).' seconds', 1); 28184041991SKlap-in if(!$cnt) continue; 28293d995e0SAndreas Gohr 283f57002afSPPPCR echo '<div>'; 28493d995e0SAndreas Gohr $ths = array_keys($result[0]); 28593d995e0SAndreas Gohr echo '<table class="inline">'; 28693d995e0SAndreas Gohr echo '<tr>'; 28793d995e0SAndreas Gohr foreach($ths as $th) { 28893d995e0SAndreas Gohr echo '<th>'.hsc($th).'</th>'; 28993d995e0SAndreas Gohr } 29093d995e0SAndreas Gohr echo '</tr>'; 29193d995e0SAndreas Gohr foreach($result as $row) { 29293d995e0SAndreas Gohr echo '<tr>'; 29393d995e0SAndreas Gohr $tds = array_values($row); 29493d995e0SAndreas Gohr foreach($tds as $td) { 2955eb2cff1SAndreas Gohr if($td === null) $td='␀'; 29693d995e0SAndreas Gohr echo '<td>'.hsc($td).'</td>'; 29793d995e0SAndreas Gohr } 29893d995e0SAndreas Gohr echo '</tr>'; 29993d995e0SAndreas Gohr } 30093d995e0SAndreas Gohr echo '</table>'; 301f57002afSPPPCR echo '</div>'; 30293d995e0SAndreas Gohr } 30393d995e0SAndreas Gohr } 30493d995e0SAndreas Gohr 305a34ef333SKlap-in } 30693d995e0SAndreas Gohr echo '</div>'; 30793d995e0SAndreas Gohr } 30893d995e0SAndreas Gohr } 30993d995e0SAndreas Gohr 31093d995e0SAndreas Gohr function getTOC() { 31193d995e0SAndreas Gohr global $conf; 31293d995e0SAndreas Gohr global $ID; 31393d995e0SAndreas Gohr 31493d995e0SAndreas Gohr $toc = array(); 31540698f67SKlap-in $fileextensions = array('sqlite2'=> '.sqlite', 'sqlite3'=> '.sqlite3'); 31693d995e0SAndreas Gohr 31740698f67SKlap-in foreach($fileextensions as $dbformat => $fileextension) { 31893d995e0SAndreas Gohr $toc[] = array( 3190542fc8eSKlap-in 'link' => wl($ID, array('do'=> 'admin', 'page'=> 'sqlite')), 32040698f67SKlap-in 'title' => $dbformat.':', 32193d995e0SAndreas Gohr 'level' => 1, 32293d995e0SAndreas Gohr 'type' => 'ul', 32393d995e0SAndreas Gohr ); 32440698f67SKlap-in 32540698f67SKlap-in $dbfiles = glob($conf['metadir'].'/*'.$fileextension); 32640698f67SKlap-in 32740698f67SKlap-in if(is_array($dbfiles)) foreach($dbfiles as $file) { 32840698f67SKlap-in $db = basename($file, $fileextension); 32940698f67SKlap-in $toc[] = array( 33084041991SKlap-in 'link' => wl($ID, array('do'=> 'admin', 'page'=> 'sqlite', 'db'=> $db, 'version'=> $dbformat, 'sectok'=> getSecurityToken())), 33140698f67SKlap-in 'title' => $this->getLang('db').' '.$db, 33240698f67SKlap-in 'level' => 2, 33340698f67SKlap-in 'type' => 'ul', 33440698f67SKlap-in ); 33540698f67SKlap-in } 33693d995e0SAndreas Gohr } 33793d995e0SAndreas Gohr 33893d995e0SAndreas Gohr return $toc; 33993d995e0SAndreas Gohr } 34093d995e0SAndreas Gohr} 34193d995e0SAndreas Gohr 342dd79791bSAndreas Gohr// vim:ts=4:sw=4:et: 343