PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.1.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.1.1
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | classes/Visualizer/Source/Query.php +44 -145 4.0.63.1.1 View file →
@@ -35,188 +35,76 @@
35 35 */
36 36 protected $_query;
37 37
38 38 /**
39 - * The chart id.
39 + * The error message.
40 40 *
41 41 * @access protected
42 - * @var int
42 + * @var string
43 43 */
44 - protected $_chart_id;
44 + protected $_error;
45 45
46 46 /**
47 - * Any additional parameters (e.g. for connecting to a remote db).
48 - *
49 - * @access protected
50 - * @var array
51 - */
52 - protected $_params;
53 -
54 - /**
55 47 * Constructor.
56 48 *
57 49 * @access public
58 50 * @param string $query The query.
59 - * @param int $chart_id The chart id.
60 - * @param array $params Any additional parameters (e.g. for connecting to a remote db).
61 51 */
62 - public function __construct( $query = null, $chart_id = null, $params = null ) {
63 - $this->_query = $this->strip_sql_comments( $query );
64 - $this->_chart_id = $chart_id;
65 - $this->_params = $params;
52 + public function __construct( $query = null ) {
53 + $this->_query = $query;
66 54 }
67 55
68 56 /**
69 - * Strips SQL comments from the query.
70 - *
71 - * @param string $query The query.
72 - *
73 - * @return string
74 - */
75 - private function strip_sql_comments( $query = '' ) {
76 - if ( empty( $query ) ) {
77 - return $query;
78 - }
79 -
80 - // Regex https://regex101.com/r/xd5Vrg/1
81 - $sql_comments_regex = '@(--[^\r\n]*)|(\#[^\r\n]*)|(/\*[\w\W]*?(?=\*/)\*/)@ms';
82 - return trim( preg_replace( $sql_comments_regex, '', $query ) );
83 - }
84 -
85 - /**
86 57 * Fetches information from source, parses it and builds series and data arrays.
87 58 *
88 59 * @param bool $as_html Should the result be fetched as an HTML table or as an object.
89 - * @param bool $results_as_numeric_array Should the result be fetched as ARRAY_N instead of ARRAY_A.
90 - * @param bool $raw_results Should the result be returned without processing.
91 60 * @access public
92 61 * @return boolean TRUE on success, otherwise FALSE.
93 62 */
94 - public function fetch( $as_html = false, $results_as_numeric_array = false, $raw_results = false ) {
63 + public function fetch( $as_html = false ) {
95 64 if ( empty( $this->_query ) ) {
96 65 return false;
97 66 }
98 67
99 - // only select queries allowed. must start with SELECT keyword.
100 - if ( ! preg_match( '/^(\bselect\b)\s/i', $this->_query ) ) {
101 - $this->_error = __( 'Only SELECT queries are allowed', 'visualizer' );
102 - return false;
103 - }
104 -
105 - // if previous check passed, check for disallowed query parts to prevent subqueries and other harmful queries.
106 - $disallow_query_parts = array(
107 - 'CREATE',
108 - 'ALTER',
109 - 'TRUNCATE',
110 - 'DROP',
111 -
112 - 'INSERT',
113 - 'DELETE',
114 - 'UPDATE',
115 - 'REPLACE',
116 -
117 - 'RENAME',
118 - 'COMMIT',
119 - 'ROLLBACK',
120 - 'MERGE',
121 - 'CALL',
122 - 'EXPLAIN',
123 - 'LOCK',
124 - 'GRANT',
125 - 'REVOKE',
126 - 'SAVEPOINT',
127 - 'TRANSACTION',
128 - 'SET',
129 - );
130 - $disallow_regex = implode(
131 - '|',
132 - array_map(
133 - function ( $value ) {
134 - return '\b' . $value . '\b';
135 - }, $disallow_query_parts
136 - )
137 - );
138 -
139 - if ( preg_match( '/(' . $disallow_regex . ')/i', $this->_query) !== 0 ) {
140 - $this->_error = __( 'Only SELECT queries are allowed', 'visualizer' );
141 - return false;
142 - }
143 -
144 68 // impose a limit if no limit clause is provided.
145 69 if ( strpos( strtolower( $this->_query ), ' limit ' ) === false ) {
146 - $this->_query .= ' LIMIT ' . apply_filters( 'visualizer_sql_query_limit', 1000, $this->_chart_id );
70 + $this->_query .= ' LIMIT ' . apply_filters( 'visualizer_sql_query_limit', 300 );
147 71 }
148 72
149 - $this->_query = apply_filters( 'visualizer_db_query', $this->_query, $this->_chart_id, $this->_params );
73 + global $wpdb;
74 + $wpdb->hide_errors();
75 + // @codingStandardsIgnoreStart
76 + $rows = $wpdb->get_results( $this->_query, ARRAY_A );
77 + // @codingStandardsIgnoreEnd
78 + $wpdb->show_errors();
150 79
151 - $results = array();
152 - $headers = array();
153 -
154 - // short circuit results for remote dbs.
155 - $remote_results = apply_filters( 'visualizer_db_query_execute', false, $this->_query, $as_html, $results_as_numeric_array, $raw_results, $this->_chart_id, $this->_params );
156 - if ( false !== $remote_results ) {
157 - $error = $remote_results['error'];
158 - if ( empty( $error ) ) {
159 - $results = $remote_results['results'];
160 - $headers = $remote_results['headers'];
161 - }
162 -
163 - $this->_error = $error;
164 -
165 - if ( $raw_results ) {
166 - return $results;
167 - }
168 - }
169 -
170 - if ( ! ( $results && $headers ) ) {
171 - global $wpdb;
172 - $wpdb->hide_errors();
173 - // @codingStandardsIgnoreStart
174 - $rows = $wpdb->get_results( $this->_query, $results_as_numeric_array ? ARRAY_N : ARRAY_A );
175 - // @codingStandardsIgnoreEnd
176 - $wpdb->show_errors();
177 -
178 - if ( $raw_results ) {
179 - return $rows;
180 - }
181 -
182 - if ( $wpdb->last_error ) {
183 - $this->_error = $wpdb->last_error;
184 - return array();
185 - }
186 -
80 + if ( $rows ) {
81 + $results = array();
82 + $headers = array();
187 83 if ( $rows ) {
188 - $results = array();
189 - $headers = array();
190 - if ( $rows ) {
191 - $row_num = 0;
192 - foreach ( $rows as $row ) {
193 - $result = array();
194 - $col_num = 0;
195 - foreach ( $row as $k => $v ) {
196 - $result[] = $v;
197 - if ( 0 === $row_num ) {
198 - $headers[] = array( 'type' => $this->get_col_type( $col_num++ ), 'label' => $k );
199 - }
84 + $row_num = 0;
85 + foreach ( $rows as $row ) {
86 + $result = array();
87 + $col_num = 0;
88 + foreach ( $row as $k => $v ) {
89 + $result[] = $v;
90 + if ( 0 === $row_num ) {
91 + $headers[] = array( 'type' => $this->get_col_type( $col_num++ ), 'label' => $k );
200 92 }
201 - $results[] = $result;
202 - ++$row_num;
203 93 }
94 + $results[] = $result;
95 + $row_num++;
204 96 }
97 + }
205 98
206 - $this->_error = $wpdb->last_error;
99 + if ( $as_html ) {
100 + return $this->html( $headers, $results );
207 101 }
102 + return $this->object( $headers, $results );
208 103 }
209 - // Query log.
210 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Firing query %s to get results %s with error %s', $this->_query, print_r( $rows, true ), print_r( $wpdb->last_error, true ) ), 'debug', __FILE__, __LINE__ );
211 104
212 - if ( $as_html ) {
213 - $results = $this->html( $headers, $results );
214 - } else {
215 - $results = $this->object( $headers, $results );
216 - }
217 -
218 - return apply_filters( 'visualizer_db_query_results', $results, $headers, $as_html, $results_as_numeric_array, $raw_results, $this->_query, $this->_chart_id, $this->_params );
105 + $this->_error = $wpdb->last_error;
106 + return null;
219 107 }
220 108
221 109 /**
222 110 * Get the data type of the column.
@@ -278,9 +166,20 @@
278 166 foreach ( $results as $row ) {
279 167 $data[] = $this->_normalizeData( $row );
280 168 }
281 169 $this->_data = $data;
282 - return $this->_data;
170 +
171 + return true;
172 + }
173 +
174 + /**
175 + * Returns the error, if any.
176 + *
177 + * @access public
178 + * @return string
179 + */
180 + public function get_error() {
181 + return $this->_error;
283 182 }
284 183
285 184 /**
286 185 * Returns the final query.