2 declare(strict_types
=1);
4 namespace PhpMyAdmin\Controllers\Table
;
7 use PhpMyAdmin\Message
;
8 use PhpMyAdmin\SqlParser\Components\Limit
;
9 use PhpMyAdmin\SqlParser\Parser
;
10 use PhpMyAdmin\SqlParser\Statements\SelectStatement
;
13 use function array_keys
;
14 use function htmlspecialchars
;
15 use function in_array
;
16 use function json_encode
;
21 * Handles creation of the chart.
23 class ChartController
extends AbstractController
26 * Execute the query and return the result
28 public function index(): void
30 global $db, $table, $cfg, $sql_query, $url_query;
32 if (isset($_REQUEST['pos'], $_REQUEST['session_max_rows']) && $this->response
->isAjax()
38 // Throw error if no sql query is set
39 if (! isset($sql_query) ||
$sql_query == '') {
40 $this->response
->setRequestStatus(false);
41 $this->response
->addHTML(
42 Message
::error(__('No SQL query was set to fetch data.'))
47 $this->response
->getHeader()->getScripts()->addFiles(
51 'vendor/jqplot/jquery.jqplot.js',
52 'vendor/jqplot/plugins/jqplot.barRenderer.js',
53 'vendor/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js',
54 'vendor/jqplot/plugins/jqplot.canvasTextRenderer.js',
55 'vendor/jqplot/plugins/jqplot.categoryAxisRenderer.js',
56 'vendor/jqplot/plugins/jqplot.dateAxisRenderer.js',
57 'vendor/jqplot/plugins/jqplot.pointLabels.js',
58 'vendor/jqplot/plugins/jqplot.pieRenderer.js',
59 'vendor/jqplot/plugins/jqplot.enhancedPieLegendRenderer.js',
60 'vendor/jqplot/plugins/jqplot.highlighter.js',
69 if (strlen($table) > 0) {
70 $url_params['goto'] = Util
::getScriptNameForOption(
71 $cfg['DefaultTabTable'],
74 $url_params['back'] = Url
::getFromRoute('/table/sql');
76 $this->dbi
->selectDb($db);
77 } elseif (strlen($db) > 0) {
78 $url_params['goto'] = Util
::getScriptNameForOption(
79 $cfg['DefaultTabDatabase'],
82 $url_params['back'] = Url
::getFromRoute('/sql');
85 $url_params['goto'] = Util
::getScriptNameForOption(
86 $cfg['DefaultTabServer'],
89 $url_params['back'] = Url
::getFromRoute('/sql');
95 $result = $this->dbi
->tryQuery($sql_query);
96 $fields_meta = $this->dbi
->getFieldsMeta($result);
97 while ($row = $this->dbi
->fetchAssoc($result)) {
101 $keys = array_keys($data[0]);
107 $numeric_column_count = 0;
108 foreach ($keys as $idx => $key) {
109 if (in_array($fields_meta[$idx]->type
, $numeric_types)) {
110 $numeric_column_count++
;
114 if ($numeric_column_count == 0) {
115 $this->response
->setRequestStatus(false);
116 $this->response
->addJSON(
118 __('No numeric columns present in the table to plot.')
123 $url_params['db'] = $db;
124 $url_params['reload'] = 1;
129 $this->render('table/chart/tbl_chart', [
130 'url_query' => $url_query,
131 'url_params' => $url_params,
133 'fields_meta' => $fields_meta,
134 'numeric_types' => $numeric_types,
135 'numeric_column_count' => $numeric_column_count,
136 'sql_query' => $sql_query,
141 * Handle ajax request
143 public function ajax(): void
145 global $db, $table, $sql_query;
147 if (strlen($table) > 0 && strlen($db) > 0) {
151 $parser = new Parser($sql_query);
153 * @var SelectStatement $statement
155 $statement = $parser->statements
[0];
156 if (empty($statement->limit
)) {
157 $statement->limit
= new Limit(
158 $_REQUEST['session_max_rows'],
162 $start = $statement->limit
->offset +
$_REQUEST['pos'];
164 $_REQUEST['session_max_rows'],
165 $statement->limit
->rowCount
- $_REQUEST['pos']
167 $statement->limit
= new Limit($rows, $start);
169 $sql_with_limit = $statement->build();
172 $result = $this->dbi
->tryQuery($sql_with_limit);
173 while ($row = $this->dbi
->fetchAssoc($result)) {
178 $this->response
->setRequestStatus(false);
179 $this->response
->addJSON('message', __('No data to display'));
182 $sanitized_data = [];
184 foreach ($data as $data_row_number => $data_row) {
186 foreach ($data_row as $data_column => $data_value) {
187 $escaped_value = $data_value === null ?
null : htmlspecialchars($data_value);
188 $tmp_row[htmlspecialchars($data_column)] = $escaped_value;
190 $sanitized_data[] = $tmp_row;
192 $this->response
->setRequestStatus(true);
193 $this->response
->addJSON('message', null);
194 $this->response
->addJSON('chartData', json_encode($sanitized_data));