Merge remote-tracking branch 'origin/master'
[phpmyadmin.git] / libraries / Console.php
bloba5a814258815c16125ff8a144ce37121603855eb
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Used to render the console of PMA's pages
6 * @package PhpMyAdmin
7 */
8 namespace PMA\libraries;
10 if (! defined('PHPMYADMIN')) {
11 exit;
14 require_once 'libraries/bookmark.lib.php';
16 /**
17 * Class used to output the console
19 * @package PhpMyAdmin
21 class Console
23 /**
24 * Whether to display anything
26 * @access private
27 * @var bool
29 private $_isEnabled;
31 /**
32 * Creates a new class instance
34 public function __construct()
36 $this->_isEnabled = true;
39 /**
40 * Whether we are servicing an ajax request.
41 * We can't simply use $GLOBALS['is_ajax_request']
42 * here since it may have not been initialised yet.
44 * @access private
45 * @var bool
47 private $_isAjax;
49 /**
50 * Set the ajax flag to indicate whether
51 * we are servicing an ajax request
53 * @param bool $isAjax Whether we are servicing an ajax request
55 * @return void
57 public function setAjax($isAjax)
59 $this->_isAjax = !!$isAjax;
62 /**
63 * Disables the rendering of the footer
65 * @return void
67 public function disable()
69 $this->_isEnabled = false;
72 /**
73 * Renders the bookmark content
75 * @access public
76 * @return string
78 public static function getBookmarkContent()
80 $output = '';
81 $cfgBookmark = PMA_Bookmark_getParams();
82 if ($cfgBookmark) {
84 $tpl_bookmark_actions
85 = '<span class="action collapse">' . __('Collapse') . '</span> '
86 . '<span class="action expand">' . __('Expand') . '</span> '
87 . '<span class="action requery">' . __('Requery') . '</span> '
88 . '<span class="action edit_bookmark">' . __('Edit') . '</span> '
89 . '<span class="action delete_bookmark">' . __('Delete')
90 . '</span> '
91 . '<span class="text targetdb">' . __('Database')
92 . ': <span>%s</span></span>';
94 $bookmarks = PMA_Bookmark_getList();
95 $output .= '<div class="message welcome"><span>';
96 $count_bookmarks = count($bookmarks);
97 if ($count_bookmarks > 0) {
98 $bookmarks_message = sprintf(
99 _ngettext(
100 'Total %d bookmark',
101 'Total %d bookmarks',
102 $count_bookmarks
104 $count_bookmarks
106 $private_message = sprintf(
107 '<span class="bookmark_label">%1$s</span>',
108 __('private')
110 $shared_message = sprintf(
111 '<span class="bookmark_label shared">%1$s</span>',
112 __('shared')
114 $output .= sprintf(
115 /* l10n: First parameter will be replaced with the translation
116 for Total and the number of bookmarks, second one with the
117 translation for private and the third one, with the translation
118 for shared */
119 __('%1$s, %2$s and %3$s bookmarks included'),
120 $bookmarks_message,
121 $private_message,
122 $shared_message
124 } else {
125 $output .= __('No bookmarks');
127 unset($count_bookmarks, $private_message, $shared_message);
128 $output .= '</span></div>';
129 foreach ($bookmarks as $val) {
130 $output .= '<div class="message collapsed bookmark" bookmarkid="'
131 . $val['id'] . '" targetdb="' . htmlspecialchars($val['db'])
132 . '"><div class="action_content">'
133 . sprintf($tpl_bookmark_actions, htmlspecialchars($val['db']))
134 . '</div><span class="bookmark_label '
135 . ($val['shared'] ? 'shared' : '') . '">'
136 . htmlspecialchars($val['label'])
137 . '</span> <span class="query">'
138 . htmlspecialchars($val['query'])
139 . '</span></div>';
142 return $output;
146 * Returns the list of JS scripts required by console
148 * @return array list of scripts
150 public function getScripts()
152 return array('console.js');
156 * Gets the history
158 * @param string $tpl_query_actions the template for query actions
160 * @return string $output the generated HTML for history
162 * @access private
165 private function _getHistory($tpl_query_actions)
167 $output = '';
169 $_sql_history = PMA_getHistory($GLOBALS['cfg']['Server']['user']);
170 if (! empty($_sql_history)) {
171 foreach (array_reverse($_sql_history) as $record) {
172 $isSelect = preg_match(
173 '@^SELECT[[:space:]]+@i', $record['sqlquery']
175 $output .= '<div class="message history collapsed hide'
176 . ($isSelect ? ' select' : '')
177 . '" targetdb="'
178 . htmlspecialchars($record['db'])
179 . '" targettable="' . htmlspecialchars($record['table'])
180 . '"><div class="action_content">'
181 . sprintf(
182 $tpl_query_actions,
183 htmlspecialchars($record['db']),
184 (isset($record['timevalue'])
185 ? $record['timevalue']
186 : __('During current session')
189 . '</div><span class="query">'
190 . htmlspecialchars($record['sqlquery'])
191 . '</span></div>';
194 return $output;
198 * Renders the console
200 * @access public
201 * @return string
203 public function getDisplay()
205 $output = '';
206 if ((! $this->_isAjax) && $this->_isEnabled) {
207 $cfgBookmark = PMA_Bookmark_getParams();
208 $output .= '<div id="pma_console_container"><div id="pma_console">';
210 // The templates, use sprintf() to output them
211 // There're white space at the end of every <span>,
212 // for double-click selection
213 $tpl_query_actions = '<span class="action collapse">' . __('Collapse')
214 . '</span> '
215 . '<span class="action expand">' . __('Expand') . '</span> '
216 . '<span class="action requery">' . __('Requery') . '</span> '
217 . '<span class="action edit">' . __('Edit') . '</span> '
218 . '<span class="action explain">' . __('Explain') . '</span> '
219 . '<span class="action profiling">' . __('Profiling') . '</span> '
220 . ($cfgBookmark ? '<span class="action bookmark">'
221 . __('Bookmark') . '</span> ' : '')
222 . '<span class="text failed">' . __('Query failed') . '</span> '
223 . '<span class="text targetdb">' . __('Database')
224 . ': <span>%s</span></span> '
225 . '<span class="text query_time">' . __(
226 'Queried time'
227 ) . ': <span>%s</span></span> ';
229 // Console toolbar
230 $output .= '<div class="toolbar collapsed">';
232 $output .= '<div class="switch_button console_switch">';
233 $output .= Util::getImage('console.png', __('SQL Query Console'));
234 $output .= '<span>' . __('Console') . '</span></div>';
236 $output .= '<div class="button clear"><span>'
237 . __('Clear') . '</span></div>';
239 $output .= '<div class="button history"><span>'
240 . __('History') . '</span></div>';
242 $output .= '<div class="button options"><span>'
243 . __('Options') . '</span></div>';
245 if ($cfgBookmark) {
246 $output .= '<div class="button bookmarks"><span>'
247 . __('Bookmarks') . '</span></div>';
250 $output .= '<div class="button debug hide"><span>'
251 . __('Debug SQL') . '</span></div>';
253 $output .= '</div>'; // Toolbar end
255 // Console messages
256 $output .= '<div class="content">';
257 $output .= '<div class="console_message_container">'
258 . '<div class="message welcome"><span>'
259 . '<span id="instructions-0">'
260 . __('Press Ctrl+Enter to execute query') . '</span>'
261 . '<span class="hide" id="instructions-1">'
262 . __('Press Enter to execute query') . '</span>'
263 . '</span></div>';
265 $output .= $this->_getHistory($tpl_query_actions);
267 $output .= '</div>'; // .console_message_container
268 $output .= '<div class="query_input">'
269 . '<span class="console_query_input"></span>'
270 . '</div>';
271 $output .= '</div>'; // Messages end
273 // Dark the console while other cards cover it
274 $output .= '<div class="mid_layer"></div>';
276 // Debug SQL card
277 $output .= '<div class="card" id="debug_console">';
278 $output .= '<div class="toolbar">'
279 . '<div class="button order order_asc">'
280 . '<span>' . __('ascending') . '</span>'
281 . '</div>'
282 . '<div class="button order order_desc">'
283 . '<span>' . __('descending') . '</span>'
284 . '</div>'
285 . '<div class="text">'
286 . '<span>' . __('Order:') . '</span>'
287 . '</div>'
288 . '<div class="switch_button">'
289 . '<span>' . __('Debug SQL') . '</span>'
290 . '</div>'
291 . '<div class="button order_by sort_count">'
292 . '<span>' . __('Count') . '</span>'
293 . '</div>'
294 . '<div class="button order_by sort_exec">'
295 . '<span>' . __('Execution order') . '</span>'
296 . '</div>'
297 . '<div class="button order_by sort_time">'
298 . '<span>' . __('Time taken') . '</span>'
299 . '</div>'
300 . '<div class="text">'
301 . '<span>' . __('Order by:') . '</span>'
302 . '</div>'
303 . '<div class="button group_queries">'
304 . '<span>' . __('Group queries') . '</span>'
305 . '</div>'
306 . '<div class="button ungroup_queries">'
307 . '<span>' . __('Ungroup queries') . '</span>'
308 . '</div>'
309 . '</div>'; // Toolbar
310 $output .= '<div class="content debug">';
311 $output .= '<div class="message welcome"></div>';
312 $output .= '<div class="debugLog"></div>';
313 $output .= '</div>'; // Content
314 $output .= '<div class="templates">'
315 . '<div class="debug_query action_content">'
316 . '<span class="action collapse">' . __('Collapse') . '</span> '
317 . '<span class="action expand">' . __('Expand') . '</span> '
318 . '<span class="action dbg_show_trace">' . __('Show trace')
319 . '</span> '
320 . '<span class="action dbg_hide_trace">' . __('Hide trace')
321 . '</span> '
322 . '<span class="text count hide">' . __('Count:')
323 . ' <span></span></span>'
324 . '<span class="text time">' . __('Time taken:')
325 . ' <span></span></span>'
326 . '</div>'
327 . '</div>'; // Template
328 $output .= '</div>'; // Debug SQL card
330 // Bookmarks card:
332 if ($cfgBookmark) {
333 $output .= '<div class="card" id="pma_bookmarks">';
334 $output .= '<div class="toolbar">'
335 . '<div class="switch_button"><span>' . __('Bookmarks')
336 . '</span></div>';
338 $output .= '<div class="button refresh"><span>'
339 . __('Refresh') . '</span></div>';
341 $output .= '<div class="button add"><span>'
342 . __('Add') . '</span></div>';
344 $output .= '</div><div class="content bookmark">';
345 $output .= static::getBookmarkContent();
346 $output .= '</div>';
347 $output .= '<div class="mid_layer"></div>';
348 $output .= '<div class="card add">';
349 $output .= '<div class="toolbar">'
350 . '<div class="switch_button"><span>'
351 . __('Add bookmark')
352 . '</span></div>';
353 $output .= '</div><div class="content add_bookmark">'
354 . '<div class="options">'
355 . '<label>' . __('Label')
356 . ': <input type="text" name="label"></label> '
357 . '<label>' . __('Target database')
358 . ': <input type="text" name="targetdb"></label> '
359 . '<label><input type="checkbox" name="shared">'
360 . __('Share this bookmark') . '</label>'
361 . '<button type="submit" name="submit">Ok</button>'
362 . '</div>' // .options
363 . '<div class="query_input">'
364 . '<span class="bookmark_add_input"></span></div>';
365 $output .= '</div>';
366 $output .= '</div>'; // Add bookmark card
367 $output .= '</div>'; // Bookmarks card
370 // Options card:
371 $output .= '<div class="card" id="pma_console_options">';
372 $output .= '<div class="toolbar">'
373 . '<div class="switch_button"><span>' . __('Options')
374 . '</span></div>';
376 $output .= '<div class="button default"><span>'
377 . __('Set default') . '</span></div>';
379 $output .= '</div><div class="content">'
380 . '<label><input type="checkbox" name="always_expand">'
381 . __('Always expand query messages') . '</label><br>'
382 . '<label><input type="checkbox" name="start_history">'
383 . __('Show query history at start') . '</label><br>'
384 . '<label><input type="checkbox" name="current_query">'
385 . __('Show current browsing query') . '</label><br>'
386 . '<label><input type="checkbox" name="enter_executes">'
387 . __(
388 'Execute queries on Enter and insert new line with Shift + '
389 . 'Enter. To make this permanent, view settings.'
390 ) . '</label><br>'
391 . '<label><input type="checkbox" name="dark_theme">'
392 . __('Switch to dark theme') . '</label><br>'
393 . '</div>';
394 $output .= '</div>'; // Options card
396 $output .= '<div class="templates">'
397 // Templates for console message actions
398 . '<div class="query_actions">'
399 . sprintf($tpl_query_actions, '', '')
400 . '</div>'
401 . '</div>';
402 $output .= '</div></div>'; // #console and #pma_console_container ends
404 return $output;