PluginProbe
WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps / 5.2
WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps v5.2
5.5.87 5.5.85 5.5.84 5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 All 162 releases
wp-data-access / WPDataAccess / Data_Dictionary / WPDA_List_Columns.php

WPDA_List_Columns.php in WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps 5.2, at WPDataAccess/Data_Dictionary/WPDA_List_Columns.php

470 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
5 *
6 * @package WPDataAccess\Data_Dictionary
7 */
8
9 namespace WPDataAccess\Data_Dictionary {
10
11 use WPDataAccess\Connection\WPDADB;
12 use WPDataAccess\Plugin_Table_Models\WPDA_Table_Settings_Model;
13
14 /**
15 * Class WPDA_List_Columns
16 *
17 * @author Peter Schulz
18 * @since 1.0.0
19 */
20 class WPDA_List_Columns {
21
22 /**
23 * Database connection
24 *
25 * @var null
26 */
27 protected $wpdadb = null;
28
29 /**
30 * Database schema name
31 *
32 * @var string
33 */
34 protected $schema_name;
35
36 /**
37 * Database table name
38 *
39 * @var string
40 */
41 protected $table_name;
42
43 /**
44 * Columns of $this->table_name
45 *
46 * @var array
47 */
48 protected $table_columns = array();
49
50 /**
51 * Columns of $this->searchable_table_columns
52 *
53 * @var array
54 */
55 protected $searchable_table_columns = array();
56
57 /**
58 * Column data type sorted on column name
59 *
60 * @var array
61 */
62 protected $table_column_data_type = array();
63
64 /**
65 * Column type sorted on column name
66 *
67 * @var array
68 */
69 protected $table_column_type = array();
70
71 /**
72 * Primary key columns of $this->table_name
73 *
74 * @var array
75 */
76 protected $table_primary_key = array();
77
78 /**
79 * Primary key columns of $this->table_name (named)
80 *
81 * @var array
82 */
83 protected $table_primary_key_check = array();
84
85 /**
86 * Auto increment column name of $this->table_name or false
87 *
88 * @var bool|string
89 */
90 protected $auto_increment_column_name = false;
91
92 /**
93 * Column headers for $this->table_name
94 *
95 * @var array
96 */
97 protected $table_column_headers = array();
98
99 /**
100 * Table settings as define in Data Explorer
101 *
102 * @var null||Object
103 */
104 protected $table_settings = null;
105
106 /**
107 * WPDA_List_Columns constructor
108 *
109 * @param string $schema_name Database schema name.
110 * @param string $table_name Database table name.
111 *
112 * @since 1.0.0
113 */
114 public function __construct( $schema_name, $table_name ) {
115 // Set schema and table name.
116 if ( '' === $schema_name ) {
117 global $wpdb;
118 $this->schema_name = $wpdb->dbname;
119 } else {
120 $this->schema_name = $schema_name;
121 }
122
123 $this->wpdadb = WPDADB::get_db_connection( $this->schema_name );
124 if ( null === $this->wpdadb ) {
125 if ( is_admin() ) {
126 wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name) ) );
127 } else {
128 die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
129 }
130 }
131
132 if ( '' !== $table_name ) {
133 $this->table_name = $table_name;
134
135 // Get table settings
136 $table_settings_db = WPDA_Table_Settings_Model::query( $this->table_name, $this->schema_name );
137 if ( isset( $table_settings_db[0]['wpda_table_settings'] ) ) {
138 $this->table_settings = json_decode( $table_settings_db[0]['wpda_table_settings'] );
139 }
140
141 // Get dictionary info
142 $this->set_table_columns();
143 $this->set_table_primary_key();
144 $this->set_table_column_headers();
145 }
146 }
147
148 /**
149 * Get column label for list table
150 *
151 * Returns the label of a column according to a pre defined format. Call must contain column name.
152 * Column must be in $this->table_name.
153 *
154 * @param string $column_name Column name as defined in the data dictionary.
155 *
156 * @return string Label for $column_name.
157 * @since 1.0.0
158 */
159 public function get_column_label( $column_name ) {
160
161 if ( isset( $this->table_settings->list_labels->$column_name ) ) {
162 return $this->table_settings->list_labels->$column_name;
163 } else {
164 return $this->get_default_column_label( $column_name );
165 }
166
167 }
168
169 /**
170 * Return column data type
171 *
172 * @param $column_name Database column name
173 *
174 * @return string|null
175 * @since 2.7.2
176 */
177 public function get_column_data_type( $column_name ) {
178 return isset( $this->table_column_data_type[ $column_name ] ) ? $this->table_column_data_type[ $column_name ] : null;
179 }
180
181 /**
182 * Return column type
183 *
184 * @param $column_name Database column name
185 *
186 * @return string|null
187 * @since 2.7.2
188 */
189 public function get_column_type( $column_name ) {
190 return isset( $this->table_column_type[ $column_name ] ) ? $this->table_column_type[ $column_name ] : null;
191 }
192
193 /**
194 * Get default column label
195 *
196 * Returns the default label of a column according to a pre defined format. Call must contain column name.
197 * Column must be in $this->table_name.
198 *
199 * @param string $column_name Column name as defined in the data dictionary.
200 *
201 * @return string Default label for $column_name.
202 * @since 1.0.0
203 */
204 public function get_default_column_label( $column_name ) {
205
206 return ucwords( str_replace( '_', ' ', $column_name ) );
207
208 }
209
210 /**
211 * Check if column is part of primary key
212 *
213 * @param string $column_name Column name as defined in the data dictionary.
214 *
215 * @return bool TRUE = column is part of primary key, FALSE = column is not part of primary key.
216 * @since 1.0.0
217 */
218 public function is_primary_key_column( $column_name ) {
219
220 return ( isset( $this->table_primary_key_check[ $column_name ] ) );
221
222 }
223
224 /**
225 * Get columns
226 *
227 * @return array Column of $this->table_name.
228 * @since 1.0.0
229 */
230 public function get_table_columns() {
231
232 return $this->table_columns;
233
234 }
235
236 /**
237 * Get searchable columns
238 *
239 * @return array Column of $this->table_name.
240 * @since 1.0.0
241 */
242 public function get_searchable_table_columns() {
243
244 return $this->searchable_table_columns;
245
246 }
247
248 /**
249 * Set table columns
250 *
251 * Column info is taken from the MySQL data dictionary. For each column in $this->table_name the following
252 * column info is stored:
253 * + Column name
254 * + Data type (MySQL data type)
255 * + Extra (needed to find auto increment columns)
256 * + Column type (needed for columns with data type enum: column type holds allowed values)
257 * + Null values allowed?
258 *
259 * Since MariaDB 10.2.7 and higher handles default values different than other DBMSs we have to take care of
260 * the quotes it places at the beginning and the end. This involves the implication that users cannot use
261 * default values that start and end with a single quote. Which seems common sense for me.
262 *
263 * @since 1.0.0
264 */
265 protected function set_table_columns() {
266 $query = $this->wpdadb->prepare(
267 '
268 SELECT column_name AS column_name,
269 data_type AS data_type,
270 extra AS extra,
271 column_type AS column_type,
272 is_nullable AS is_nullable,
273 IF(LEFT(column_default,1)=\'\'\'\' AND RIGHT(column_default,1)=\'\'\'\', SUBSTR(column_default,2,LENGTH(column_default)-2), column_default) AS column_default,
274 character_maximum_length AS character_maximum_length,
275 numeric_scale AS numeric_scale,
276 numeric_precision AS numeric_precision
277 FROM information_schema.columns
278 WHERE table_schema = %s
279 AND table_name = %s
280 ORDER BY ordinal_position
281 ',
282 array(
283 $this->wpdadb->dbname,
284 $this->table_name,
285 )
286 );
287
288 $this->table_columns = $this->wpdadb->get_results( $query, 'ARRAY_A' ); // phpcs:ignore Standard.Category.SniffName.ErrorCode
289 $this->searchable_table_columns = $this->table_columns; // Contains all columns and is not modified
290
291 foreach ( $this->table_columns as $column ) {
292 if ( isset( $column['column_name'] ) && isset( $column['data_type'] ) ) {
293 $this->table_column_data_type[ $column['column_name'] ] = $column['data_type'];
294 }
295
296 if ( isset( $column['column_name'] ) && isset( $column['column_type'] ) ) {
297 $this->table_column_type[ $column['column_name'] ] = $column['column_type'];
298 }
299 }
300
301 }
302
303 /**
304 * Get primary key columns
305 *
306 * @return array Primary key columns of $this->table_name.
307 * @since 1.0.0
308 */
309 public function get_table_primary_key() {
310 return $this->table_primary_key;
311 }
312
313 /**
314 * Set primary key columns
315 *
316 * Primary key columns are taken from the MySQL data dictionary.
317 *
318 * Newer versions of MariaDB no longer seem to support JOIN USING. Rewritten to old school join. MySQL supports
319 * both types of joins.
320 *
321 * @since 1.0.0
322 */
323 protected function set_table_primary_key() {
324 $result = $this->get_table_unique_indexes();
325
326 if ( 0 < $this->wpdadb->num_rows ) {
327 // Check if there is a primary key
328 $has_primary_key = false;
329 foreach ( $result as $row ) {
330 if ( 'PRIMARY' === $row['Key_name'] ) {
331 $this->table_primary_key[] = $row['Column_name'];
332 $this->table_primary_key_check[ $row['Column_name'] ] = true;
333
334 foreach ( $this->table_columns as $table_column ) {
335 if ( $table_column['column_name'] === $row['Column_name'] &&
336 'auto_increment' === $table_column['extra']
337 ) {
338 // Save auto_increment column name.
339 $this->auto_increment_column_name = $row['Column_name'];
340 }
341 }
342
343 $has_primary_key = true;
344 }
345 }
346
347 if ( ! $has_primary_key ) {
348 // Use non unique index as an alternative
349 $key_name = $result[0]['Key_name'];
350 $this->table_primary_key[] = $result[0]['Column_name'];
351 $this->table_primary_key_check[ $key_name ] = true;
352 $i = 1;
353 while ( $i < sizeof( $result ) ) {
354 if ( $key_name === $result[ $i ]['Key_name'] ) {
355 $this->table_primary_key[] = $result[ $i ]['Column_name'];
356 $this->table_primary_key_check[ $result[ $i ]['Column_name'] ] = true;
357 }
358 $i ++;
359 }
360 }
361 }
362 }
363
364 protected function get_table_unique_indexes() {
365 $suppress = $this->wpdadb->suppress_errors( true );
366 $query =
367 sprintf(
368 'SHOW INDEX FROM `%s`.`%s` WHERE non_unique = 0',
369 $this->wpdadb->dbname,
370 str_replace( '`', '', $this->table_name )
371 );
372 $result = $this->wpdadb->get_results( $query, 'ARRAY_A' );
373 $this->wpdadb->suppress_errors( $suppress );
374
375 return $result;
376 }
377
378 public function get_table_alternative_keys() {
379 $result = $this->get_table_unique_indexes();
380 $return = array();
381
382 if ( 0 < $this->wpdadb->num_rows ) {
383 $index_name = '';
384 $index = array();
385 foreach ( $result as $row ) {
386 if ( $index_name !== $row['Key_name'] ) {
387 if ( '' !== $index_name ) {
388 array_push( $return, $row['Column_name'] );
389 $index = array();
390 }
391 $index_name = $row['Key_name'];
392 }
393 array_push( $index, $row['Column_name'] );
394 }
395 array_push( $return, $index );
396 }
397
398 return $return;
399 }
400
401 /**
402 * Get column headers
403 *
404 * @return array
405 * @since 1.0.0
406 */
407 public function get_table_column_headers() {
408
409 return $this->table_column_headers;
410
411 }
412
413 /**
414 * Set column headers (= column labels in data entry forms)
415 *
416 * For now column headers are defined equal to their names. If a column is part of the primary key, this is
417 * reflected in the column header.
418 *
419 * @since 1.0.0
420 */
421 protected function set_table_column_headers() {
422
423 if ( ! isset( $this->table_columns ) ) {
424 wp_die( __( 'ERROR: Wrong arguments [no columns found]', 'wp-data-access' ) );
425 }
426
427 $primary_nr = 0;
428 $this->table_column_headers = array();
429 foreach ( $this->table_columns as $key => $value ) {
430
431 if ( isset( $this->table_settings->form_labels ) ) {
432 if ( isset( $this->table_settings->form_labels->{$value['column_name']} ) ) {
433 $label = $this->table_settings->form_labels->{$value['column_name']};
434 } else {
435 $label = $this->get_default_column_label( $value['column_name'] );
436 }
437 } else {
438 $label = $this->get_default_column_label( $value['column_name'] );
439
440 if ( $this->is_primary_key_column( $value['column_name'] ) ) {
441 $key_text = __( 'key', 'wp-data-access' );
442 if ( count( $this->table_primary_key ) > 1 ) {
443 $label .= " ($key_text #" . ( ++ $primary_nr ) . ')';
444 } else {
445 $label .= " ($key_text)";
446 }
447 }
448 }
449
450 $this->table_column_headers[ $value['column_name'] ] = $label;
451 }
452
453 }
454
455 /**
456 * Get name of auto increment column
457 *
458 * @return bool|string Name of auto increment column or false if no auto increment column exists
459 * @since 1.0.0
460 */
461 public function get_auto_increment_column_name() {
462
463 return $this->auto_increment_column_name;
464
465 }
466
467 }
468
469 }
470