TableChartController.class.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Holds the PMA\TableChartController
  5. *
  6. * @package PMA
  7. */
  8. namespace PMA\Controllers\Table;
  9. use PMA\DI\Container;
  10. use PMA_Util;
  11. use PMA_Message;
  12. use PMA\Template;
  13. use PMA\Controllers\TableController;
  14. require_once 'libraries/Util.class.php';
  15. require_once 'libraries/Message.class.php';
  16. require_once 'libraries/Template.class.php';
  17. require_once 'libraries/controllers/TableController.class.php';
  18. /**
  19. * Handles table related logic
  20. *
  21. * @package PhpMyAdmin
  22. */
  23. class TableChartController extends TableController
  24. {
  25. /**
  26. * @var string $sql_query
  27. */
  28. protected $sql_query;
  29. /**
  30. * @var string $url_query
  31. */
  32. protected $url_query;
  33. /**
  34. * @var array $cfg
  35. */
  36. protected $cfg;
  37. /**
  38. * Constructor
  39. *
  40. * @param string $sql_query Query
  41. * @param string $url_query Query URL
  42. * @param array $cfg Configuration
  43. */
  44. public function __construct($sql_query, $url_query, $cfg)
  45. {
  46. parent::__construct();
  47. $this->sql_query = $sql_query;
  48. $this->url_query = $url_query;
  49. $this->cfg = $cfg;
  50. }
  51. /**
  52. * Execute the query and return the result
  53. *
  54. * @return void
  55. */
  56. public function indexAction()
  57. {
  58. if (isset($_REQUEST['ajax_request'])
  59. && isset($_REQUEST['pos'])
  60. && isset($_REQUEST['session_max_rows'])
  61. ) {
  62. $this->ajaxAction();
  63. return;
  64. }
  65. // Throw error if no sql query is set
  66. if (!isset($this->sql_query) || $this->sql_query == '') {
  67. $this->response->isSuccess(false);
  68. $this->response->addHTML(
  69. PMA_Message::error(__('No SQL query was set to fetch data.'))
  70. );
  71. return;
  72. }
  73. $this->response->getHeader()->getScripts()->addFiles(
  74. array(
  75. 'chart.js',
  76. 'tbl_chart.js',
  77. 'jqplot/jquery.jqplot.js',
  78. 'jqplot/plugins/jqplot.barRenderer.js',
  79. 'jqplot/plugins/jqplot.canvasAxisLabelRenderer.js',
  80. 'jqplot/plugins/jqplot.canvasTextRenderer.js',
  81. 'jqplot/plugins/jqplot.categoryAxisRenderer.js',
  82. 'jqplot/plugins/jqplot.dateAxisRenderer.js',
  83. 'jqplot/plugins/jqplot.pointLabels.js',
  84. 'jqplot/plugins/jqplot.pieRenderer.js',
  85. 'jqplot/plugins/jqplot.highlighter.js'
  86. )
  87. );
  88. /**
  89. * Extract values for common work
  90. * @todo Extract common files
  91. */
  92. $db = &$this->db;
  93. $table = &$this->table;
  94. /**
  95. * Runs common work
  96. */
  97. if (/*overload*/ mb_strlen($this->table)) {
  98. $url_params['goto'] = PMA_Util::getScriptNameForOption(
  99. $this->cfg['DefaultTabTable'], 'table'
  100. );
  101. $url_params['back'] = 'tbl_sql.php';
  102. include 'libraries/tbl_common.inc.php';
  103. include 'libraries/tbl_info.inc.php';
  104. } elseif (/*overload*/ mb_strlen($this->db)) {
  105. $url_params['goto'] = PMA_Util::getScriptNameForOption(
  106. $this->cfg['DefaultTabDatabase'], 'database'
  107. );
  108. $url_params['back'] = 'sql.php';
  109. include 'libraries/db_common.inc.php';
  110. list(
  111. $tables,
  112. $num_tables,
  113. $total_num_tables,
  114. $sub_part,
  115. $is_show_stats,
  116. $db_is_system_schema,
  117. $tooltip_truename,
  118. $tooltip_aliasname,
  119. $pos
  120. ) = PMA_Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
  121. } else {
  122. $url_params['goto'] = PMA_Util::getScriptNameForOption(
  123. $this->cfg['DefaultTabServer'], 'server'
  124. );
  125. $url_params['back'] = 'sql.php';
  126. include 'libraries/server_common.inc.php';
  127. }
  128. $data = array();
  129. $result = $this->dbi->tryQuery($this->sql_query);
  130. $fields_meta = $this->dbi->getFieldsMeta($result);
  131. while ($row = $this->dbi->fetchAssoc($result)) {
  132. $data[] = $row;
  133. }
  134. $keys = array_keys($data[0]);
  135. $numeric_types = array('int', 'real');
  136. $numeric_column_count = 0;
  137. foreach ($keys as $idx => $key) {
  138. if (in_array($fields_meta[$idx]->type, $numeric_types)) {
  139. $numeric_column_count++;
  140. }
  141. }
  142. if ($numeric_column_count == 0) {
  143. $this->response->isSuccess(false);
  144. $this->response->addJSON(
  145. 'message',
  146. __('No numeric columns present in the table to plot.')
  147. );
  148. return;
  149. }
  150. $url_params['db'] = $this->db;
  151. $url_params['reload'] = 1;
  152. /**
  153. * Displays the page
  154. */
  155. $this->response->addHTML(
  156. Template::get('table/chart/tbl_chart')->render(
  157. array(
  158. 'url_query' => $this->url_query,
  159. 'url_params' => $url_params,
  160. 'keys' => $keys,
  161. 'fields_meta' => $fields_meta,
  162. 'numeric_types' => $numeric_types,
  163. 'numeric_column_count' => $numeric_column_count,
  164. 'sql_query' => $this->sql_query
  165. )
  166. )
  167. );
  168. }
  169. /**
  170. * Handle ajax request
  171. *
  172. * @return void
  173. */
  174. public function ajaxAction()
  175. {
  176. /**
  177. * Extract values for common work
  178. * @todo Extract common files
  179. */
  180. $db = &$this->db;
  181. $table = &$this->table;
  182. $tableLength = /*overload*/
  183. mb_strlen($this->table);
  184. $dbLength = /*overload*/
  185. mb_strlen($this->db);
  186. if ($tableLength && $dbLength) {
  187. include './libraries/tbl_common.inc.php';
  188. }
  189. $sql_with_limit = sprintf(
  190. 'SELECT * FROM(%s) AS `temp_res` LIMIT %s, %s',
  191. $this->sql_query,
  192. $_REQUEST['pos'],
  193. $_REQUEST['session_max_rows']
  194. );
  195. $data = array();
  196. $result = $this->dbi->tryQuery($sql_with_limit);
  197. while ($row = $this->dbi->fetchAssoc($result)) {
  198. $data[] = $row;
  199. }
  200. if (empty($data)) {
  201. $this->response->isSuccess(false);
  202. $this->response->addJSON('message', __('No data to display'));
  203. return;
  204. }
  205. $sanitized_data = array();
  206. foreach ($data as $data_row_number => $data_row) {
  207. $tmp_row = array();
  208. foreach ($data_row as $data_column => $data_value) {
  209. $tmp_row[htmlspecialchars($data_column)] = htmlspecialchars(
  210. $data_value
  211. );
  212. }
  213. $sanitized_data[] = $tmp_row;
  214. }
  215. $this->response->isSuccess(true);
  216. $this->response->addJSON('message', null);
  217. $this->response->addJSON('chartData', json_encode($sanitized_data));
  218. }
  219. }