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( '<' => '&lt;' ) );
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( '<' => '&lt;' ) );
152						$q    = strtr( $q, array( '"' => '&quot;' ) );
153						$history[] = '<option value="' . $q . '">' . $qesc . '&nbsp;&nbsp;</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