PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.84
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.84
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 5.5.41 5.5.42 All 160 releases
wp-data-access / WPDataAccess / Plugin_Table_Models / WPDP_Project_Design_Table_Model.php

WPDP_Project_Design_Table_Model.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.84, at WPDataAccess/Plugin_Table_Models/WPDP_Project_Design_Table_Model.php

854 lines 30.6 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\Plugin_Table_Models
7 */
8
9 // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- verified on page
10 namespace WPDataAccess\Plugin_Table_Models {
11
12 use WPDataAccess\Data_Dictionary\WPDA_List_Columns_Cache;
13 use WPDataAccess\Utilities\WPDA_Message_Box;
14 use WPDataAccess\WPDA;
15
16 /**
17 * Class WPDP_Project_Design_Table_Model extends WPDA_Plugin_Table_Base_Model
18 *
19 * @see WPDA_Plugin_Table_Base_Model
20 *
21 * @author Peter Schulz
22 * @since 2.0.0
23 */
24 class WPDP_Project_Design_Table_Model extends WPDA_Plugin_Table_Base_Model {
25
26 const BASE_TABLE_NAME = 'wpda_project_table';
27
28 /**
29 * Cached table options
30 *
31 * @var null|array
32 */
33 protected static $cache_table_options = null;
34
35 /**
36 * Requested action
37 *
38 * @var string
39 */
40 protected $action2;
41
42 /**
43 * Name of table where design is stored
44 *
45 * @var string|null
46 */
47 protected $table_name = null;
48
49 /**
50 * Design schema name
51 *
52 * @var string
53 */
54 protected $wpda_schema_name = '';
55
56 /**
57 * Design table name
58 *
59 * @var string|null
60 */
61 protected $wpda_table_name = null;
62
63 /**
64 * Options set name (to allow multiple table definitions)
65 *
66 * @var string
67 */
68 protected $wpda_table_setname = null;
69
70 /**
71 * Check if options set name was changed
72 *
73 * @var string
74 */
75 protected $wpda_table_setname_old = null;
76
77 /**
78 * The actual table design
79 *
80 * @var string|null
81 */
82 protected $wpda_table_design = null;
83
84 /**
85 * WPDP_Project_Design_Table_Model constructor
86 *
87 * Get action2 arguments
88 */
89 public function __construct() {
90 $this->table_name = self::get_base_table_name();
91
92 if ( isset( $_REQUEST['wpda_schema_name'] ) ) { // phpcs:ignore
93 $this->wpda_schema_name = sanitize_text_field( wp_unslash( $_REQUEST['wpda_schema_name'] ) ); // phpcs:ignore
94 }
95
96 // Watch out for arrays! (array = starting export)
97 if ( isset( $_REQUEST['wpda_table_name'] ) && ! is_array( $_REQUEST['wpda_table_name'] ) ) { // phpcs:ignore
98 $this->wpda_table_name = sanitize_text_field( wp_unslash( $_REQUEST['wpda_table_name'] ) ); // phpcs:ignore
99 }
100
101 if ( isset( $_REQUEST['wpda_table_setname'] ) ) { // phpcs:ignore
102 $this->wpda_table_setname = sanitize_text_field( wp_unslash( $_REQUEST['wpda_table_setname'] ) ); // phpcs:ignore
103 }
104
105 if ( isset( $_REQUEST['wpda_table_setname_old'] ) ) { // phpcs:ignore
106 $this->wpda_table_setname_old = sanitize_text_field( wp_unslash( $_REQUEST['wpda_table_setname_old'] ) ); // phpcs:ignore
107 }
108
109 if ( isset( $_REQUEST['action2'] ) ) { // phpcs:ignore
110 $this->action2 = sanitize_text_field( wp_unslash( $_REQUEST['action2'] ) ); // phpcs:ignore
111 }
112 }
113
114 /**
115 * Prepare query to use setname (after reverse engineering)
116 *
117 * @param $wpda_table_setname
118 */
119 public function prepare_query( $wpda_table_setname ) {
120 $this->wpda_table_setname = $wpda_table_setname;
121 }
122
123 /**
124 * Get design for a specific table name
125 *
126 * @return int Number of rows.
127 */
128 public function query() {
129 if ( null === $this->wpda_table_name ) {
130 return false;
131 }
132
133 global $wpdb;
134 $wpda_table_design_raw = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin table
135 $wpdb->prepare(
136 'SELECT wpda_table_design FROM `%1s` WHERE wpda_schema_name = %s AND wpda_table_name = %s AND wpda_table_setname = %s', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
137 array(
138 WPDA::remove_backticks( $this->table_name ),
139 $this->wpda_schema_name,
140 $this->wpda_table_name,
141 null === $this->wpda_table_setname_old ? $this->wpda_table_setname : $this->wpda_table_setname_old,
142 )
143 ),
144 'ARRAY_A'
145 );
146 if ( $wpdb->num_rows > 0 ) {
147 $this->wpda_table_design = json_decode( $wpda_table_design_raw[0]['wpda_table_design'] );
148 }
149
150 return $wpdb->num_rows;
151 }
152
153 /**
154 * Return table design
155 *
156 * @return null|array
157 */
158 public function get_table_design() {
159 return $this->wpda_table_design;
160 }
161
162 /**
163 * Return table design
164 *
165 * @return null|array
166 */
167 public function get_table_setname() {
168 return $this->wpda_table_setname;
169 }
170
171 /**
172 * Overwrite method validate to add table options validation
173 *
174 * @return array
175 */
176 public function validate() {
177 $structure_messages = array();
178
179 if ( ! isset( $this->wpda_table_design->design_mode ) ) {
180 $structure_messages[] = array( 'ERR', 'Invalid structure [missing element design_mode]' );
181 }
182
183 if ( ! isset( $this->wpda_table_design->engine )
184 && (
185 ! isset( $this->wpda_table_design->table_type )
186 ||
187 ( isset( $this->wpda_table_design->table_type ) && 'TABLE' === $this->wpda_table_design->table_type )
188 )
189 ) {
190 $structure_messages[] = array( 'ERR', 'Invalid structure [missing element engine]' );
191 }
192
193 if ( ! isset( $this->wpda_table_design->collation )
194 && (
195 ! isset( $this->wpda_table_design->table_type )
196 ||
197 ( isset( $this->wpda_table_design->table_type ) && 'TABLE' === $this->wpda_table_design->table_type )
198 )
199 ) {
200 $structure_messages[] = array( 'ERR', 'Invalid structure [missing element collation]' );
201 }
202
203 if ( ! isset( $this->wpda_table_design->table ) ) {
204 $structure_messages[] = array( 'ERR', 'Invalid structure [missing element table]' );
205 } else {
206 $unique_column_names = array();
207 foreach ( $this->wpda_table_design->table as $column ) {
208 $unique_column_names[ $column->column_name ] = true;
209 }
210 if ( count( $unique_column_names ) !== count( $this->wpda_table_design->table ) ) { // phpcs:ignore -- 8.1 proof
211 $structure_messages[] = array( 'ERR', 'Column name must be unique within a table' );
212 }
213 }
214
215 if ( ! isset( $this->wpda_table_design->indexes ) ) {
216 $structure_messages[] = array( 'ERR', 'Invalid structure [missing element indexes]' );
217 } else {
218 $unique_index_names = array();
219 foreach ( $this->wpda_table_design->indexes as $index ) {
220 $unique_index_names[ $index->index_name ] = true;
221 }
222 if ( count( $unique_index_names ) !== count( $this->wpda_table_design->indexes ) ) { // phpcs:ignore -- 8.1 proof
223 $structure_messages[] = array( 'ERR', 'Index name must be unique within a table' );
224 }
225 }
226
227 if ( isset( $this->wpda_table_design->tableform_column_options ) ) {
228 // phpcs:ignore -- 8.1 proof
229 if ( count( $this->wpda_table_design->table ) !== count( $this->wpda_table_design->tableform_column_options ) ) {
230 $structure_messages[] = array( 'ERR', 'Invalid structure [run reconcile]' );
231 }
232 }
233
234 return $structure_messages;
235 }
236
237 /**
238 * Overwrite method prepare_update to prepare table options
239 */
240 public function prepare_update() {
241 $this->query();
242
243 if ( isset( $_REQUEST['design_mode'] ) ) { // phpcs:ignore
244 $this->wpda_table_design->design_mode = sanitize_text_field( wp_unslash( $_REQUEST['design_mode'] ) ); // phpcs:ignore
245 }
246
247 if ( isset( $_REQUEST['engine'] ) ) { // phpcs:ignore
248 $this->wpda_table_design->engine = sanitize_text_field( wp_unslash( $_REQUEST['engine'] ) ); // phpcs:ignore
249 }
250
251 if ( isset( $_REQUEST['collation'] ) ) { // phpcs:ignore
252 $this->wpda_table_design->collation = sanitize_text_field( wp_unslash( $_REQUEST['collation'] ) ); // phpcs:ignore
253 }
254
255 if ( isset( $_REQUEST['column_name'] ) ) { // phpcs:ignore
256 $this->wpda_table_design->table = $this->get_table_structure();
257 } else {
258 if ( isset( $_REQUEST['submitted_changes'] ) && 'table' === $_REQUEST['submitted_changes'] ) { // phpcs:ignore
259 $this->wpda_table_design->table = array();
260 }
261 }
262
263 if ( isset( $_REQUEST['column_names'] ) ) { // phpcs:ignore
264 $this->wpda_table_design->indexes = $this->get_indexes();
265 } else {
266 if ( isset( $_REQUEST['submitted_changes'] ) && 'indexes' === $_REQUEST['submitted_changes'] ) { // phpcs:ignore
267 $this->wpda_table_design->indexes = array();
268 }
269 }
270
271 switch ( $this->action2 ) {
272 case 'relation':
273 $this->prepare_update_relation();
274 break;
275 case 'listtable':
276 $this->prepare_update_listtable();
277 break;
278 case 'tableform':
279 $this->prepare_update_tableform();
280 break;
281 case 'tableinfo':
282 $this->prepare_update_tableinfo();
283 }
284 }
285
286 /**
287 * Set relationships to prepare update
288 */
289 protected function prepare_update_relation() {
290 unset( $this->wpda_table_design->relationships );
291 /**
292 * CWG cleared these as being future proof on the assumption that the fields in $_REQUEST are all arrays
293 * If that is not a safe assumption, this needs to be heavily revised
294 */
295 // phpcs:ignore -- 8.1 proof
296 if ( isset( $_REQUEST['row_num'] ) ) {
297 $no_columns = count( $_REQUEST['row_num'] ); // phpcs:ignore
298 if (
299 isset( $_REQUEST['relation_type'] ) && $no_columns === count( $_REQUEST['relation_type'] ) && // phpcs:ignore
300 isset( $_REQUEST['source_column_name'] ) && $no_columns === count( $_REQUEST['source_column_name'] ) && // phpcs:ignore
301 isset( $_REQUEST['target_table_name'] ) && $no_columns === count( $_REQUEST['target_table_name'] ) && // phpcs:ignore
302 isset( $_REQUEST['target_column_name'] ) && $no_columns === count( $_REQUEST['target_column_name'] ) // phpcs:ignore
303 ) {
304 for ( $i = 0; $i < $no_columns; $i ++ ) {
305 // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
306 $relation_type = sanitize_text_field( wp_unslash( $_REQUEST['relation_type'][ $i ] ) );
307 $source_column_name = sanitize_text_field( wp_unslash( $_REQUEST['source_column_name'][ $i ] ) );
308 $target_table_name = sanitize_text_field( wp_unslash( $_REQUEST['target_table_name'][ $i ] ) );
309 $target_column_name = sanitize_text_field( wp_unslash( $_REQUEST['target_column_name'][ $i ] ) );
310 // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
311 if ( isset( $_REQUEST['target_schema_name'][ $i ] ) ) {
312 $target_schema_name = sanitize_text_field( wp_unslash( $_REQUEST['target_schema_name'][ $i ] ) );
313 } else {
314 $target_schema_name = '';
315 }
316
317 if ( 'nm' === $relation_type ) {
318 if ( isset( $_REQUEST[ 'relation_table_name_' . $i ] ) ) { // phpcs:ignore
319 $relation_table_name = sanitize_text_field( wp_unslash( $_REQUEST[ 'relation_table_name_' . $i ] ) ); // phpcs:ignore
320 } else {
321 $relation_table_name = '';
322 }
323 if ( trim( $relation_table_name ) === '' ) {
324 $msg = new WPDA_Message_Box(
325 array(
326 'message_text' => __( 'Invalid array [missing required fields]', 'wp-data-access' ),
327 'message_type' => 'error',
328 'message_is_dismissible' => false,
329 )
330 );
331 $msg->box();
332
333 return;
334 }
335 }
336
337 if (
338 trim( $relation_type ) !== '' &&
339 trim( $source_column_name ) !== '' &&
340 trim( $target_table_name ) !== '' &&
341 trim( $target_column_name ) !== ''
342 ) {
343 $source_column_name_array = array();
344 $target_column_name_array = array();
345
346 array_push( $source_column_name_array, $source_column_name ); // phpcs:ignore -- 8.1 proof
347 array_push( $target_column_name_array, $target_column_name ); // phpcs:ignore -- 8.1 proof
348
349 if ( isset( $_REQUEST['num_source_column_name'][ $i ] ) ) { // phpcs:ignore
350 $num_source_column_name = sanitize_text_field( wp_unslash( $_REQUEST['num_source_column_name'][ $i ] ) ); // phpcs:ignore
351 if ( is_numeric( $num_source_column_name ) ) {
352 for ( $j = 1; $j <= $num_source_column_name; $j ++ ) {
353 if (isset( $_REQUEST[ 'source_column_name_' . $i . '_' . $j ] ) && isset( $_REQUEST[ 'target_column_name_' . $i . '_' . $j ] )) {
354 array_push( $source_column_name_array, sanitize_text_field( wp_unslash( $_REQUEST[ 'source_column_name_' . $i . '_' . $j ] ) ) );
355 array_push( $target_column_name_array, sanitize_text_field( wp_unslash( $_REQUEST[ 'target_column_name_' . $i . '_' . $j ] ) ) );
356 }
357 }
358 }
359 }
360
361 $this->wpda_table_design->relationships[ $i ]['relation_type'] = $relation_type;
362 $this->wpda_table_design->relationships[ $i ]['source_column_name'] = $source_column_name_array;
363 $this->wpda_table_design->relationships[ $i ]['target_table_name'] = $target_table_name;
364 $this->wpda_table_design->relationships[ $i ]['target_column_name'] = $target_column_name_array;
365 if ( 'nm' === $relation_type ) {
366 $this->wpda_table_design->relationships[ $i ]['relation_table_name'] = $relation_table_name;
367 } elseif ( 'lookup' === $relation_type || 'autocomplete' === $relation_type ) {
368 $this->wpda_table_design->relationships[ $i ]['target_schema_name'] = $target_schema_name;
369 }
370 }
371 }
372 } else {
373 $msg = new WPDA_Message_Box(
374 array(
375 'message_text' => __( 'Invalid array [missing required fields]', 'wp-data-access' ),
376 'message_type' => 'error',
377 'message_is_dismissible' => false,
378 )
379 );
380 $msg->box();
381 }
382 }
383 }
384
385 /**
386 * Set table options for list table to prepare update
387 */
388 protected function prepare_update_listtable() {
389 $column_options = $this->get_column_options_from_request();
390 if ( null !== $column_options ) {
391 $this->wpda_table_design->listtable_column_options = $column_options;
392 }
393 }
394
395 /**
396 * Set table options for data entry form to prepare update
397 */
398 protected function prepare_update_tableform() {
399 $column_options = $this->get_column_options_from_request();
400 if ( null !== $column_options ) {
401 $this->wpda_table_design->tableform_column_options = $column_options;
402 }
403 }
404
405 /**
406 * Set table level options to prepare update
407 */
408 protected function prepare_update_tableinfo() {
409 if ( isset( $_REQUEST['table_setname'] ) ) {
410 $this->wpda_table_setname = sanitize_text_field( wp_unslash( $_REQUEST['table_setname'] ) );
411 }
412
413 if ( isset( $_REQUEST['tab_label'] ) ) {
414 $this->wpda_table_design->tableinfo->tab_label = sanitize_text_field( wp_unslash( $_REQUEST['tab_label'] ) );
415 }
416
417 if ( isset( $_REQUEST['default_where'] ) ) {
418 $this->wpda_table_design->tableinfo->default_where = sanitize_text_field( wp_unslash( $_REQUEST['default_where'] ) );
419 }
420
421 if ( isset( $_REQUEST['default_orderby'] ) ) {
422 $this->wpda_table_design->tableinfo->default_orderby = sanitize_text_field( wp_unslash( $_REQUEST['default_orderby'] ) );
423 }
424
425 $settings_db = WPDA_Table_Settings_Model::query( $this->wpda_table_name, $this->wpda_schema_name );
426 if ( isset( $settings_db[0]['wpda_table_settings'] ) && '' !== $settings_db[0]['wpda_table_settings'] ) {
427 $settings = json_decode( $settings_db[0]['wpda_table_settings'] );
428 if ( isset( $settings->hyperlinks ) && is_array( $settings->hyperlinks ) ) {
429 $hyperlinks = array();
430 $hyperlinks_child = array();
431 foreach ( $settings->hyperlinks as $hyperlink ) {
432 if ( isset( $hyperlink->hyperlink_label ) ) {
433 $hyperlink_label_replace_spaces = ucfirst( str_replace( ' ', '_', $hyperlink->hyperlink_label ) );
434
435 if ( isset( $_REQUEST[ "{$hyperlink_label_replace_spaces}_hyperlink" ] ) ) {
436 $hyperlinks[ $hyperlink->hyperlink_label ] = true;
437 } else {
438 $hyperlinks[ $hyperlink->hyperlink_label ] = false;
439 }
440
441 if ( isset( $_REQUEST[ "{$hyperlink_label_replace_spaces}_hyperlink_child" ] ) ) {
442 $hyperlinks_child[ $hyperlink->hyperlink_label ] = true;
443 } else {
444 $hyperlinks_child[ $hyperlink->hyperlink_label ] = false;
445 }
446 }
447 }
448 $this->wpda_table_design->tableinfo->hyperlinks_parent = $hyperlinks;
449 $this->wpda_table_design->tableinfo->hyperlinks_child = $hyperlinks_child;
450 }
451 }
452
453 if ( has_filter( 'wpda_data_projects_save_table_option' ) ) {
454 $this->wpda_table_design->tableinfo->custom_table_settings = apply_filters(
455 'wpda_data_projects_save_table_option',
456 '',
457 $this->wpda_schema_name,
458 $this->wpda_table_name
459 );
460 }
461 }
462
463 /**
464 * Get table column options
465 *
466 * @return array|null
467 */
468 protected function get_column_options_from_request() {
469 // phpcs:disable WordPress.Security.ValidatedSanitizedInput -- verified in page
470 if ( isset( $_REQUEST['list_item_name'] ) ) {
471 $tableform_column_options = array();
472 $i = 0;
473 foreach ( $_REQUEST['list_item_name'] as $column_name ) {
474 $tableform_column_options[] = array(
475 'column_name' => $column_name,
476 'label' => isset( $_REQUEST[ $column_name ] ) ?
477 sanitize_text_field( wp_unslash( $_REQUEST[ $column_name ] ) ) :
478 ucfirst( str_replace( '_', ' ', $column_name ) ),
479 'readonly' => isset( $_REQUEST[ "{$column_name}_readonly" ] ) ? 'on' : 'off',
480 'less' => isset( $_REQUEST[ "{$column_name}_less" ] ) ? 'on' : 'off',
481 'show' => isset( $_REQUEST[ "{$column_name}_show" ] ) ? 'on' : 'off',
482 'lookup' => isset( $_REQUEST[ "{$column_name}_lookup" ] ) ?
483 sanitize_text_field( wp_unslash( $_REQUEST[ "{$column_name}_lookup" ] ) ) :
484 false,
485 'hide_lookup_key' => isset( $_REQUEST[ "{$column_name}_hide_lookup_key" ] ) ? 'on' : 'off',
486 );
487 if ( isset( $_REQUEST[ "{$column_name}_default" ] ) && '' !== $_REQUEST[ "{$column_name}_default" ] ) {
488 $tableform_column_options[ $i ]['default'] =
489 sanitize_text_field( wp_unslash( $_REQUEST[ "{$column_name}_default" ] ) );
490 }
491 $i ++;
492 }
493
494 return $tableform_column_options;
495 } else {
496 return null;
497 }
498 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
499 }
500
501 /**
502 * Reconcile table
503 *
504 * @param object $table_structure Table structure
505 * @param string $param_keep_options Possible values: 'on' and 'off'
506 *
507 * @return mixed Result of SQL update
508 */
509 public function reconcile(
510 $table_structure,
511 $param_keep_options
512 ) {
513 if ( 1 === $this->query() ) {
514 // Table definition.
515 $this->wpda_table_design->design_mode = $table_structure['design_mode'];
516 $this->wpda_table_design->engine = $table_structure['engine'];
517 $this->wpda_table_design->collation = $table_structure['collation'];
518 // Table columns.
519 $this->wpda_table_design->table = $table_structure['table'];
520 // Table indexes.
521 $this->wpda_table_design->indexes = $table_structure['indexes'];
522
523 if ( 'on' !== $param_keep_options ) {
524 // Clear arrays.
525 $this->wpda_table_design->listtable_column_options = array();
526 $this->wpda_table_design->tableform_column_options = array();
527 $this->wpda_table_design->tableinfo = array(
528 'tab_label' => '',
529 'default_where' => '',
530 'default_orderby' => '',
531 'custom_table_settings' => '',
532 );
533 } else {
534 // Remove non existing columns from arrays.
535 $new_listtable_column_options = array();
536 foreach ( $this->wpda_table_design->listtable_column_options as $listtable_column_option ) {
537 $column_found = false;
538 foreach ( $this->wpda_table_design->table as $table_column ) {
539 if ( $table_column->column_name === $listtable_column_option->column_name ) {
540 $column_found = true;
541 }
542 }
543 if ( $column_found ) {
544 // Add only column to array that were found in the table definition.
545 array_push( $new_listtable_column_options, $listtable_column_option ); // phpcs:ignore -- 8.1 proof
546 }
547 }
548 $this->wpda_table_design->listtable_column_options = $new_listtable_column_options;
549 $new_tableform_column_options = array();
550 foreach ( $this->wpda_table_design->tableform_column_options as $tableform_column_option ) {
551 $column_found = false;
552 foreach ( $this->wpda_table_design->table as $table_column ) {
553 if ( $table_column->column_name === $tableform_column_option->column_name ) {
554 $column_found = true;
555 }
556 }
557 if ( $column_found ) {
558 // Add only column to array that were found in the table definition.
559 array_push( $new_tableform_column_options, $tableform_column_option ); // phpcs:ignore -- 8.1 proof
560 }
561 }
562 $this->wpda_table_design->tableform_column_options = $new_tableform_column_options;
563 }
564
565 $wpda_list_columns = WPDA_List_Columns_Cache::get_list_columns( $this->wpda_schema_name, $this->wpda_table_name );
566 $table_column_headers = $wpda_list_columns->get_table_column_headers();
567
568 foreach ( $this->wpda_table_design->table as $column ) {
569 if ( 'on' !== $param_keep_options ) {
570 // Every column must be added to array.
571 $this->reconcile_add_column(
572 $column,
573 $wpda_list_columns->get_column_label( $column->column_name ),
574 isset( $table_column_headers[ $column->column_name ] ) ?
575 $table_column_headers[ $column->column_name ] :
576 $wpda_list_columns::get_default_column_label( $column->column_name )
577 );
578 } else {
579 // Add only new columns to array.
580 $column_found = false;
581 foreach ( $this->wpda_table_design->listtable_column_options as $listtable_column_option ) {
582 if ( isset( $column->column_name ) && isset( $listtable_column_option->column_name ) ) {
583 if ( $column->column_name === $listtable_column_option->column_name ) {
584 $column_found = true;
585 break;
586 }
587 }
588 }
589 if ( ! $column_found ) {
590 // Add column to both arrays.
591 $this->reconcile_add_column(
592 $column,
593 $wpda_list_columns->get_column_label( $column->column_name ),
594 isset( $table_column_headers[ $column->column_name ] ) ?
595 $table_column_headers[ $column->column_name ] :
596 $wpda_list_columns::get_default_column_label( $column->column_name )
597 );
598 }
599 }
600 }
601 }
602 global $wpdb;
603
604 return $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin table
605 $this->table_name,
606 array(
607 'wpda_table_design' => json_encode( $this->wpda_table_design ),
608 ),
609 array(
610 'wpda_schema_name' => $this->wpda_schema_name,
611 'wpda_table_name' => $this->wpda_table_name,
612 'wpda_table_setname' => $this->wpda_table_setname,
613 )
614 );
615 }
616
617 /**
618 * Reconcile a columns
619 *
620 * @param object $column Column info
621 */
622 private function reconcile_add_column( $column, $label_list, $label_form ) {
623 $this->wpda_table_design->listtable_column_options[] =
624 array(
625 'column_name' => $column->column_name,
626 'label' => $label_list,
627 'show' => 'on',
628 );
629 $this->wpda_table_design->tableform_column_options[] =
630 array(
631 'column_name' => $column->column_name,
632 'label' => $label_form,
633 'show' => 'on',
634 );
635 }
636
637 /**
638 * Get column options for specific table name and label type
639 *
640 * @param string $table_name Database table name
641 * @param string $label_type Label type
642 * @param string $setname Options set name
643 *
644 * @return array|null
645 */
646 public static function get_column_options( $table_name, $label_type, $setname = 'default', $schema_name = '' ) {
647 if ( ! isset( self::$cache_table_options[ "$table_name.$setname" ] ) ) {
648 global $wpdb;
649 $table_json = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin table
650 $wpdb->prepare(
651 "SELECT wpda_table_design FROM `%1s` WHERE wpda_schema_name = %s AND wpda_table_name = %s AND ( wpda_table_setname = %s OR wpda_table_setname = 'default') ORDER BY IF( wpda_table_setname='default', 1 , 0 )", // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
652 array(
653 WPDA::remove_backticks( self::get_base_table_name() ),
654 $schema_name,
655 $table_name,
656 $setname,
657 )
658 ),
659 'ARRAY_A'
660 );
661
662 if ( $wpdb->num_rows > 0 ) {
663 if ( isset( $table_json[0]['wpda_table_design'] ) ) {
664 $table_obj = json_decode( $table_json[0]['wpda_table_design'] );
665 if ( isset( $table_obj->table ) ) {
666 self::$cache_table_options[ "$table_name.$setname" ]['table'] = $table_obj->table;
667 }
668 self::$cache_table_options[ "$table_name.$setname" ]['tableinfo'] = isset( $table_obj->tableinfo ) ? $table_obj->tableinfo : null;
669 if ( isset( $table_obj->tableform_column_options ) ) {
670 self::$cache_table_options[ "$table_name.$setname" ]['tableform'] = $table_obj->tableform_column_options;
671 }
672 if ( isset( $table_obj->listtable_column_options ) ) {
673 self::$cache_table_options[ "$table_name.$setname" ]['listtable'] = $table_obj->listtable_column_options;
674 }
675 if ( isset( $table_obj->relationships ) ) {
676 self::$cache_table_options[ "$table_name.$setname" ]['relationships'] = $table_obj->relationships;
677 }
678 }
679 }
680 }
681 if ( 'tableform' === $label_type && isset( self::$cache_table_options[ "$table_name.$setname" ]['tableform'] ) ) {
682 return self::$cache_table_options[ "$table_name.$setname" ]['tableform'];
683 }
684 if ( 'listtable' === $label_type && isset( self::$cache_table_options[ "$table_name.$setname" ]['listtable'] ) ) {
685 return self::$cache_table_options[ "$table_name.$setname" ]['listtable'];
686 }
687 if ( 'relationships' === $label_type && isset( self::$cache_table_options[ "$table_name.$setname" ]['relationships'] ) ) {
688 return array(
689 'table' => isset( self::$cache_table_options[ "$table_name.$setname" ]['table'] ) ? self::$cache_table_options[ "$table_name.$setname" ]['table'] : null,
690 'tableinfo' => isset( self::$cache_table_options[ "$table_name.$setname" ]['tableinfo'] ) ? self::$cache_table_options[ "$table_name.$setname" ]['tableinfo'] : null,
691 'relationships' => self::$cache_table_options[ "$table_name.$setname" ]['relationships'],
692 );
693 }
694 if ( 'tableinfo' === $label_type ) {
695 return isset( self::$cache_table_options[ "$table_name.$setname" ]['tableinfo'] ) ? self::$cache_table_options[ "$table_name.$setname" ]['tableinfo'] : null;
696 }
697
698 return null;
699 }
700
701 /**
702 * Overwrites method insert_reverse_engineered to add table options
703 *
704 * @param $wpda_table_name
705 * @param $wpda_table_setname
706 * @param $wpda_table_design
707 *
708 * @return bool
709 */
710 public static function insert_reverse_engineered( $wpda_table_name, $wpda_table_setname, $wpda_table_design, $wpda_schema_name = '' ) {
711 global $wpdb;
712
713 $table_name = self::get_base_table_name();
714
715 $wpda_table_design['table_type'] = WPDA_Design_Table_Model::get_table_type( $wpda_table_name, $wpda_schema_name );
716
717 $wpda_table_design['listtable_column_options'] = array();
718 $wpda_table_design['tableform_column_options'] = array();
719 $wpda_table_design['tableinfo'] = array(
720 'tab_label' => '',
721 'default_where' => '',
722 'default_orderby' => '',
723 'custom_table_settings' => '',
724 );
725
726 $wpda_list_columns = WPDA_List_Columns_Cache::get_list_columns( $wpda_schema_name, $wpda_table_name );
727 $table_column_headers = $wpda_list_columns->get_table_column_headers();
728
729 foreach ( $wpda_table_design['table'] as $column ) {
730 $label = $wpda_list_columns->get_column_label( $column->column_name );
731 $wpda_table_design['listtable_column_options'][] =
732 array(
733 'column_name' => $column->column_name,
734 'label' => $label,
735 'show' => 'on',
736 );
737
738 $label = isset( $table_column_headers[ $column->column_name ] ) ?
739 $table_column_headers[ $column->column_name ] : $wpda_list_columns::get_default_column_label( $column->column_name );
740 $wpda_table_design['tableform_column_options'][] =
741 array(
742 'column_name' => $column->column_name,
743 'label' => $label,
744 'show' => 'on',
745 );
746 }
747
748 return (
749 1 === $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- plugin table
750 $table_name,
751 array(
752 'wpda_schema_name' => $wpda_schema_name,
753 'wpda_table_name' => $wpda_table_name,
754 'wpda_table_setname' => $wpda_table_setname,
755 'wpda_table_design' => json_encode( $wpda_table_design ),
756 )
757 )
758 );
759 }
760
761 /**
762 * Update table design
763 *
764 * @return bool TRUE = update successful, FALSE ; update failed.
765 */
766 public function update() {
767 if ( null === $this->wpda_table_name ) {
768 return false;
769 }
770
771 $this->prepare_update();
772
773 $setname_old =
774 $this->wpda_table_setname !== $this->wpda_table_setname_old ?
775 $this->wpda_table_setname_old :
776 $this->wpda_table_setname;
777
778 global $wpdb;
779 $result_update = $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin table
780 $this->table_name,
781 array(
782 'wpda_table_setname' => $this->wpda_table_setname,
783 'wpda_table_design' => json_encode( $this->wpda_table_design ),
784 ),
785 array(
786 'wpda_schema_name' => $this->wpda_schema_name,
787 'wpda_table_name' => $this->wpda_table_name,
788 'wpda_table_setname' => $setname_old,
789 )
790 );
791
792 if ( '' !== $wpdb->last_error ) {
793 $msg = new WPDA_Message_Box(
794 array(
795 'message_text' => $wpdb->last_error,
796 'message_type' => 'error',
797 'message_is_dismissible' => false,
798 )
799 );
800 $msg->box();
801 }
802
803 if ( ! $result_update && $this->wpda_table_setname !== $this->wpda_table_setname_old ) {
804 $this->wpda_table_setname = $this->wpda_table_setname_old;
805 }
806
807 return $result_update;
808 }
809
810 /**
811 * Get table design from function arguments instead of HTTP arguments
812 *
813 * @param $wpda_schema_name
814 * @param $wpda_table_name
815 * @param $wpda_set_name
816 *
817 * @return mixed|null
818 */
819 public static function static_query( $wpda_schema_name, $wpda_table_name, $wpda_set_name ) {
820 $wpda_table_design_raw = self::do_static_query( $wpda_schema_name, $wpda_table_name, $wpda_set_name );
821
822 global $wpdb;
823 if ( $wpdb->num_rows === 0 && $wpda_set_name !== 'default' ) {
824 $wpda_table_design_raw = self::do_static_query( $wpda_schema_name, $wpda_table_name, 'default' );
825 }
826
827 if ( $wpdb->num_rows > 0 ) {
828 return json_decode( $wpda_table_design_raw[0]['wpda_table_design'] );
829 } else {
830 return null;
831 }
832 }
833
834 protected static function do_static_query( $wpda_schema_name, $wpda_table_name, $wpda_set_name ) {
835 global $wpdb;
836
837 return $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin table
838 $wpdb->prepare(
839 'SELECT wpda_table_design FROM `%1s` WHERE wpda_schema_name = %s AND wpda_table_name = %s AND wpda_table_setname = %s', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
840 array(
841 WPDA::remove_backticks( self::get_base_table_name() ),
842 $wpda_schema_name,
843 $wpda_table_name,
844 $wpda_set_name,
845 )
846 ),
847 'ARRAY_A'
848 );
849 }
850
851 }
852
853 }
854 // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing