1<?php 2/** 3 * DokuWiki Plugin sqlite (Admin Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12class admin_plugin_sqlite extends DokuWiki_Admin_Plugin { 13 14 function getMenuSort() { 15 return 500; 16 } 17 18 function forAdminOnly() { 19 return true; 20 } 21 22 function handle() { 23 global $conf; 24 global $INPUT; 25 26 if(isset($_POST['sqlite_rename'])) { 27 28 $path = $conf['metadir'].'/'.$_REQUEST['db']; 29 if(io_rename($path.'.sqlite', $path.'.sqlite3')) { 30 msg('Renamed database file succesfull!', 1); 31 //set to new situation 32 $_REQUEST['version'] = 'sqlite3'; 33 34 } else { 35 msg('Renaming database file fails!', -1); 36 } 37 38 } elseif(isset($_POST['sqlite_convert'])) { 39 40 /** @var $DBI helper_plugin_sqlite */ 41 $DBI = plugin_load('helper', 'sqlite'); 42 $time_start = microtime(true); 43 44 if($dumpfile = $DBI->dumpDatabase($_REQUEST['db'], DOKU_EXT_SQLITE)) { 45 msg('Database temporary dumped to file: '.hsc($dumpfile).'. Now loading in new database...', 1); 46 47 if(!$DBI->fillDatabaseFromDump($_REQUEST['db'], $dumpfile)) { 48 msg('Conversion failed!', -1); 49 return false; 50 } 51 52 //TODO delete dumpfile 53 //return @unlink($dumpfile); 54 //TODO delete old sqlite2-db 55 // return @unlink($conf['metadir'].'/'.$_REQUEST['db'].'.sqlite'); 56 57 msg('Conversion succeed!', 1); 58 //set to new situation 59 $_REQUEST['version'] = 'sqlite3'; 60 } 61 $time_end = microtime(true); 62 $time = $time_end - $time_start; 63 msg('Database "'.hsc($_REQUEST['db']).'" converted from sqlite 2 to 3 in '.$time.' seconds.', 0); 64 65 } elseif($INPUT->bool('sqlite_export') && checkSecurityToken()) { 66 67 /** @var $DBI helper_plugin_sqlite */ 68 $DBI = plugin_load('helper', 'sqlite'); 69 $dbname = $INPUT->str('db'); 70 71 $dumpfile = $DBI->dumpDatabase($dbname, DOKU_EXT_PDO, true); 72 if ($dumpfile) { 73 header('Content-Type: text/sql'); 74 header('Content-Disposition: attachment; filename="'.$dbname.'.sql";'); 75 76 readfile($dumpfile); 77 exit(0); 78 } 79 } elseif($INPUT->bool('sqlite_import') && checkSecurityToken()) { 80 global $conf; 81 82 /** @var $DBI helper_plugin_sqlite */ 83 $DBI = plugin_load('helper', 'sqlite'); 84 $dbname = $INPUT->str('db'); 85 $dumpfile = $_FILES['dumpfile']['tmp_name']; 86 87 if (empty($dumpfile)) { 88 msg($this->getLang('import_no_file'), -1); 89 return; 90 } 91 92 if ($DBI->fillDatabaseFromDump($dbname, $dumpfile, true)) { 93 msg($this->getLang('import_success'), 1); 94 } 95 } 96 } 97 98 function html() { 99 global $ID; 100 global $conf; 101 102 echo $this->locale_xhtml('intro'); 103 104 if(isset($_REQUEST['db']) && checkSecurityToken()) { 105 106 echo '<h2>'.$this->getLang('db').' "'.hsc($_REQUEST['db']).'"</h2>'; 107 echo '<div class="level2">'; 108 109 $sqlcommandform = true; 110 /** @var $DBI helper_plugin_sqlite */ 111 $DBI = plugin_load('helper', 'sqlite'); 112 if($_REQUEST['version'] == 'sqlite2') { 113 if(helper_plugin_sqlite_adapter::isSqlite3db($conf['metadir'].'/'.$_REQUEST['db'].'.sqlite')) { 114 115 msg('This is a database in sqlite3 format.', 2); 116 msg( 117 'This plugin needs your database file has the extension ".sqlite3" 118 instead of ".sqlite" before it will be recognized as sqlite3 database.', 2 119 ); 120 $form = new Doku_Form(array('method'=> 'post')); 121 $form->addHidden('page', 'sqlite'); 122 $form->addHidden('sqlite_rename', 'go'); 123 $form->addHidden('db', $_REQUEST['db']); 124 $form->addElement(form_makeButton('submit', 'admin', sprintf($this->getLang('rename2to3'), hsc($_REQUEST['db'])))); 125 $form->printForm(); 126 127 if($DBI->existsPDOSqlite()) $sqlcommandform = false; 128 129 } else { 130 if($DBI->existsPDOSqlite()) { 131 $sqlcommandform = false; 132 msg('This is a database in sqlite2 format.', 2); 133 134 if($DBI->existsSqlite2()) { 135 $form = new Doku_Form(array('method'=> 'post')); 136 $form->addHidden('page', 'sqlite'); 137 $form->addHidden('sqlite_convert', 'go'); 138 $form->addHidden('db', $_REQUEST['db']); 139 $form->addElement(form_makeButton('submit', 'admin', sprintf($this->getLang('convert2to3'), hsc($_REQUEST['db'])))); 140 $form->printForm(); 141 } else { 142 msg( 143 'Before PDO sqlite can handle this format, it needs a conversion to the sqlite3 format. 144 Because PHP sqlite extension is not available, 145 you should manually convert "'.hsc($_REQUEST['db']).'.sqlite" in the meta directory to "'.hsc($_REQUEST['db']).'.sqlite3".<br /> 146 See for info about the conversion '.$this->external_link('http://www.sqlite.org/version3.html').'.', -1 147 ); 148 } 149 } 150 } 151 } else { 152 if(!$DBI->existsPDOSqlite()) { 153 $sqlcommandform = false; 154 msg('A database in sqlite3 format needs the PHP PDO sqlite plugin.', -1); 155 } 156 } 157 158 if($sqlcommandform) { 159 echo '<ul>'; 160 echo '<li><div class="li"><a href="'. 161 wl( 162 $ID, array( 163 'do' => 'admin', 164 'page' => 'sqlite', 165 'db' => $_REQUEST['db'], 166 'version'=> $_REQUEST['version'], 167 'sql' => 'SELECT name,sql FROM sqlite_master WHERE type=\'table\' ORDER BY name', 168 'sectok' => getSecurityToken() 169 ) 170 ). 171 '">'.$this->getLang('table').'</a></div></li>'; 172 echo '<li><div class="li"><a href="'. 173 wl( 174 $ID, array( 175 'do' => 'admin', 176 'page' => 'sqlite', 177 'db' => $_REQUEST['db'], 178 'version'=> $_REQUEST['version'], 179 'sql' => 'SELECT name,sql FROM sqlite_master WHERE type=\'index\' ORDER BY name', 180 'sectok' => getSecurityToken() 181 ) 182 ). 183 '">'.$this->getLang('index').'</a></div></li>'; 184 echo '<li><div class="li"><a href="'. 185 wl( 186 $ID, array( 187 'do' => 'admin', 188 'page' => 'sqlite', 189 'db' => $_REQUEST['db'], 190 'version'=> $_REQUEST['version'], 191 'sqlite_export' => '1', 192 'sectok' => getSecurityToken() 193 ) 194 ). 195 '">'.$this->getLang('export').'</a></div></li>'; 196 197 198 $form = new \dokuwiki\Form\Form(array('enctype' => 'multipart/form-data')); 199 $form->setHiddenField('id', $ID); 200 $form->setHiddenField('do', 'admin'); 201 $form->setHiddenField('page', 'sqlite'); 202 $form->setHiddenField('db', $_REQUEST['db']); 203 $form->setHiddenField('version', $_REQUEST['version']); 204 $form->addElement(new dokuwiki\Form\InputElement('file', 'dumpfile')); 205 $form->addButton('sqlite_import', $this->getLang('import')); 206 echo '<li>' . $form->toHTML() . '</li>'; 207 echo '</ul>'; 208 209 $form = new Doku_Form(array('class'=> 'sqliteplugin')); 210 $form->startFieldset('SQL Command'); 211 $form->addHidden('id', $ID); 212 $form->addHidden('do', 'admin'); 213 $form->addHidden('page', 'sqlite'); 214 $form->addHidden('db', $_REQUEST['db']); 215 $form->addHidden('version', $_REQUEST['version']); 216 if(isset($_REQUEST['sql'])) $form->addElement('<textarea name="sql" class="edit">'.hsc($_REQUEST['sql']).'</textarea>'); 217 $form->addElement('<input type="submit" class="button" />'); 218 $form->endFieldset(); 219 $form->printForm(); 220 221 if(isset($_REQUEST['sql'])) { 222 223 if(!$DBI->init($_REQUEST['db'], '')) return; 224 225 $sql = $DBI->SQLstring2array($_REQUEST['sql']); 226 foreach($sql as $s) { 227 $s = preg_replace('!^\s*--.*$!m', '', $s); 228 $s = trim($s); 229 if(!$s) continue; 230 231 $time_start = microtime(true); 232 233 $res = $DBI->query("$s;"); 234 if($res === false) continue; 235 236 $result = $DBI->res2arr($res); 237 238 $time_end = microtime(true); 239 $time = $time_end - $time_start; 240 241 $cnt = $DBI->res2count($res); 242 msg($cnt.' affected rows in '.($time < 0.0001 ? substr($time, 0, 5).substr($time, -3) : substr($time, 0, 7)).' seconds', 1); 243 if(!$cnt) continue; 244 245 echo '<div>'; 246 $ths = array_keys($result[0]); 247 echo '<table class="inline">'; 248 echo '<tr>'; 249 foreach($ths as $th) { 250 echo '<th>'.hsc($th).'</th>'; 251 } 252 echo '</tr>'; 253 foreach($result as $row) { 254 echo '<tr>'; 255 $tds = array_values($row); 256 foreach($tds as $td) { 257 if($td === null) $td='␀'; 258 echo '<td>'.hsc($td).'</td>'; 259 } 260 echo '</tr>'; 261 } 262 echo '</table>'; 263 echo '</div>'; 264 } 265 } 266 267 } 268 echo '</div>'; 269 } 270 } 271 272 function getTOC() { 273 global $conf; 274 global $ID; 275 276 $toc = array(); 277 $fileextensions = array('sqlite2'=> '.sqlite', 'sqlite3'=> '.sqlite3'); 278 279 foreach($fileextensions as $dbformat => $fileextension) { 280 $toc[] = array( 281 'link' => wl($ID, array('do'=> 'admin', 'page'=> 'sqlite')), 282 'title' => $dbformat.':', 283 'level' => 1, 284 'type' => 'ul', 285 ); 286 287 $dbfiles = glob($conf['metadir'].'/*'.$fileextension); 288 289 if(is_array($dbfiles)) foreach($dbfiles as $file) { 290 $db = basename($file, $fileextension); 291 $toc[] = array( 292 'link' => wl($ID, array('do'=> 'admin', 'page'=> 'sqlite', 'db'=> $db, 'version'=> $dbformat, 'sectok'=> getSecurityToken())), 293 'title' => $this->getLang('db').' '.$db, 294 'level' => 2, 295 'type' => 'ul', 296 ); 297 } 298 } 299 300 return $toc; 301 } 302} 303 304// vim:ts=4:sw=4:et: 305