PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.2
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.2
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 5.5.43 All 159 releases
wp-data-access / WPDataProjects / Project / WPDP_Project_Table_List.php

WPDP_Project_Table_List.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.2, at WPDataProjects/Project/WPDP_Project_Table_List.php

512 lines 16.5 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 WPDataProjects\Project
7 */
8
9 namespace WPDataProjects\Project {
10
11 use WPDataAccess\Dashboard\WPDA_Dashboard;
12 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Exist;
13 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Lists;
14 use WPDataAccess\List_Table\WPDA_List_Table;
15 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Design_Table_Model;
16 use WPDataAccess\Utilities\WPDA_Message_Box;
17 use WPDataAccess\WPDA;
18
19 /**
20 * Class WPDP_Project_Table_List extends WPDA_List_Table
21 *
22 * @see WPDA_List_Table
23 *
24 * @author Peter Schulz
25 * @since 2.0.0
26 */
27 class WPDP_Project_Table_List extends WPDA_List_Table {
28
29 /**
30 * WPDP_Project_Table_List constructor
31 *
32 * Get and sort list of all database tables
33 *
34 * @param array $args
35 */
36 public function __construct( array $args = array() ) {
37 $args['column_headers'] = self::column_headers_labels();
38 $args['title'] = '';
39 $args['allow_import'] = 'off';
40 $args['allow_insert'] = 'off';
41
42 parent::__construct( $args );
43 }
44
45 /**
46 * Overwrite method add_header_button to add reverse engineering
47 *
48 * @param string $add_param
49 */
50 protected function add_header_button( $add_param = '' ) {
51 global $wpdb;
52
53 // Get available databases
54 $schema_names = WPDA_Dictionary_Lists::get_db_schemas();
55 $database_tables = array();
56 foreach ( $schema_names as $schema_name ) {
57 // Check table access to prepare table listbox content
58 if ( $wpdb->dbname === $schema_name['schema_name'] ) {
59 $table_access = WPDA::get_option( WPDA::OPTION_BE_TABLE_ACCESS );
60 } else {
61 $table_access = get_option( WPDA::BACKEND_OPTIONNAME_DATABASE_ACCESS . $schema_name['schema_name'] );
62 if ( false === $table_access ) {
63 $table_access = 'show';
64 }
65 }
66 switch ( $table_access ) {
67 case 'show':
68 $tables = $this->get_all_db_tables( $schema_name['schema_name'] );
69 break;
70 case 'hide':
71 $tables = $this->get_all_db_tables( $schema_name['schema_name'] );
72 // Remove WordPress tables from listbox content
73 $tables_named = array();
74 foreach ( $tables as $table ) {
75 $tables_named[ $table ] = true;
76 }
77 foreach ( $wpdb->tables( 'all', true ) as $wp_table ) {
78 unset( $tables_named[ $wp_table ] );
79 }
80 $tables = array();
81 foreach ( $tables_named as $key => $value ) {
82 array_push( $tables, $key );
83 }
84 break;
85 default:
86 // Show only selected tables and views
87 if ( $wpdb->dbname === $schema_name['schema_name'] ) {
88 $tables = WPDA::get_option( WPDA::OPTION_BE_TABLE_ACCESS_SELECTED );
89 } else {
90 $tables = get_option( WPDA::BACKEND_OPTIONNAME_DATABASE_SELECTED . $schema_name['schema_name'] );
91 if ( false === $tables ) {
92 $tables = '';
93 }
94 }
95 }
96 $database_tables[ $schema_name['schema_name'] ] = $tables;
97 }
98
99 $tables = array();
100 $column_index = $this->get_item_index( 'page_schema_name' );
101 if ( false !== $column_index ) {
102 $pub_schema_name = $this->form_items[ $column_index ]->get_item_value();
103 if ( '' === $pub_schema_name || null === $pub_schema_name ) {
104 $pub_schema_name = $wpdb->dbname;
105 }
106
107 if ( isset( $database_tables[ $pub_schema_name ] ) ) {
108 $tables = $database_tables[ $pub_schema_name ];
109 }
110 }
111
112 $user_default_schema = WPDA::get_user_default_scheme();
113 $wpnonce = wp_create_nonce( WPDP_Project_Table_Form::WPNONCE_SEED . WPDP_Project_Design_Table_Model::get_base_table_name() );
114 if ( WPDA_Dashboard::add_actions_to_page_title() ) {
115 ?>
116 <div id="no_repository_buttons" style="display: inline-block; vertical-align: unset;">
117 <button type="button"
118 class="page-title-action wpda_tooltip"
119 title="Add project template to repository. The plugin needs to load the structure of a table into the repository to generate list table and data entry forms. If you update a table with another database tool, make sure to reconcile that table to update the repository and prevent the plugin using an old table structure."
120 onclick="jQuery('#no_repository_buttons').hide(); jQuery('#add_table_to_repository').show(); return false;">
121 <span class="material-icons wpda_icon_on_button">add_circle</span>
122 <?php echo __( 'Add Project Template To Repository', 'wp-data-access' ); ?>
123 </button>
124 </div>
125 <?php
126 }
127 ?>
128 <form
129 method="post"
130 action="?page=<?php echo esc_attr( $this->page ); ?>&tab=tables"
131 style="display: block"
132 >
133 <input type="hidden" name="action" value="reverse_engineering">
134 <div id="add_table_to_repository" style="display:none">
135 <select name="wpda_schema_name" id="wpda_schema_name">
136 <?php
137 foreach ( $schema_names as $schema_name ) {
138 $selected = $user_default_schema === $schema_name['schema_name'] ? ' selected' : '';
139 echo "<option value='{$schema_name['schema_name']}'{$selected}>{$schema_name['schema_name']}</option>"; // phpcs:ignore WordPress.Security.EscapeOutput
140 }
141 ?>
142 </select>
143 <select name="wpda_table_name" id="wpda_table_name">
144 <?php
145 global $wpdb;
146 if ( isset( $database_tables[ $user_default_schema ] ) ) {
147 foreach ( $database_tables[ $user_default_schema ] as $table ) {
148 ?>
149 <option value="<?php echo esc_attr( $table ); ?>"><?php echo esc_attr( $table ); ?></option>
150 <?php
151 }
152 }
153 ?>
154 </select>
155 <input type="hidden" name="wpnonce"
156 value="<?php echo esc_attr( $wpnonce ); ?>"/>
157 <input type="submit"
158 value="<?php echo __( 'Add Template For Selected Table To Repository', 'wp-data-access' ); ?>"
159 class="button button-secondary">
160 <input type="button"
161 value="<?php echo __( 'Cancel', 'wp-data-access' ); ?>"
162 class="button button-secondary"
163 onclick="jQuery('#no_repository_buttons').show(); jQuery('#add_table_to_repository').hide(); return false;">
164 </div>
165 </form>
166 <script type='text/javascript'>
167 var database_tables = new Object();
168 <?php
169 foreach ( $database_tables as $key => $value ) {
170 echo "database_tables['$key'] = " . json_encode( $value ) . ';'; // phpcs:ignore WordPress.Security.EscapeOutput
171 }
172 ?>
173
174 jQuery(function () {
175 jQuery('#wpda_schema_name').on('change', function () {
176 jQuery('#wpda_table_name').empty();
177 var tables = database_tables[jQuery(this).val()];
178 for ( var i = 0; i < tables.length; i++ ) {
179 jQuery('<option/>', {
180 value: tables[i],
181 html: tables[i]
182 }).appendTo('#wpda_table_name');
183 }
184 });
185 });
186 </script>
187 <?php
188 }
189
190 /**
191 * Get all db tables and views
192 *
193 * @param string $database Database schema name
194 *
195 * @return array
196 */
197 protected function get_all_db_tables( $database ) {
198 $tables = array();
199 $db_tables = WPDA_Dictionary_Lists::get_tables( true, $database ); // select all db tables and views
200 foreach ( $db_tables as $db_table ) {
201 array_push( $tables, $db_table['table_name'] ); // add table or view to array
202 }
203
204 return $tables;
205 }
206
207 /**
208 * Overwrites method get_columns to add checkbox
209 *
210 * @return array
211 */
212 public function get_columns() {
213 $columns = array();
214
215 if ( $this->bulk_actions_enabled ) {
216 $columns = array( 'cb' => '<input type="checkbox" />' );
217 }
218
219 return array_merge( $columns, $this->column_headers );
220 }
221
222 /**
223 * Overwrites method column_default
224 *
225 * @param array $item
226 * @param string $column_name
227 *
228 * @return mixed|string
229 */
230 public function column_default( $item, $column_name ) {
231 switch ( $column_name ) {
232 case 'table_found':
233 if ( 'rdb:' === substr( $item['wpda_schema_name'], 0, 4 ) ) {
234 return __( 'N/A', 'wp-data-access' );
235 }
236 $wpda_dictionary_exist = new WPDA_Dictionary_Exist( $item['wpda_schema_name'], $item['wpda_table_name'] );
237 if ( $wpda_dictionary_exist->table_exists() ) {
238 return __( 'Yes', 'wp-data-access' );
239 } else {
240 return __( 'No', 'wp-data-access' );
241 }
242 case 'table_has_relations':
243 $table_design = json_decode( $item['wpda_table_design'] );
244 if ( isset( $table_design->relationships ) ) {
245 return 'Yes';
246 } else {
247 return 'No';
248 }
249 case 'table_rows':
250 if ( 'rdb:' === substr( $item['wpda_schema_name'], 0, 4 ) ) {
251 return __( 'N/A', 'wp-data-access' );
252 }
253 global $wpdb;
254 $suppress = $wpdb->suppress_errors( true );
255 if ( '' === $item['wpda_schema_name'] || null === $item['wpda_schema_name'] ) {
256 $query = $wpdb->prepare(
257 'select count(*) from `%1s`', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
258 array(
259 WPDA::remove_backticks( $item['wpda_table_name'] ),
260 )
261 );
262 } else {
263 $query = $wpdb->prepare(
264 'select count(*) from `%1s`.`%1s`', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
265 array(
266 WPDA::remove_backticks( $item['wpda_schema_name'] ),
267 WPDA::remove_backticks( $item['wpda_table_name'] ),
268 )
269 );
270 }
271 $rows = $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.PreparedSQL
272 $wpdb->suppress_errors( $suppress );
273 return null === $rows ? '-' : $rows;
274 case 'wpda_table_name':
275 // Validate schema, table and column names
276 $warning = WPDA::validate_names( $item['wpda_schema_name'], $item['wpda_table_name'] );
277 if ( '' !== $warning ) {
278 $content = $item['wpda_table_name'] . $warning .
279 substr( parent::column_default( $item, $column_name ), strlen( $item['wpda_table_name'] ) );
280
281 return $content;
282 }
283 case 'wpda_schema_name':
284 global $wpdb;
285 if ( $wpdb->dbname === $item[ $column_name ] ) {
286 return "WordPress database ({$item[ $column_name ]})";
287 }
288 default:
289 return parent::column_default( $item, $column_name );
290 }
291 }
292
293 /**
294 * Overwrite method column_default_add_action to add tab argument
295 *
296 * @param array $item
297 * @param string $column_name
298 * @param array $actions
299 */
300 protected function column_default_add_action( $item, $column_name, &$actions ) {
301 parent::column_default_add_action( $item, $column_name, $actions );
302
303 // Add copy table options action.
304 $wp_nonce_action = "wpda-copy-{$this->table_name}";
305 $wp_nonce = esc_attr( wp_create_nonce( $wp_nonce_action ) );
306 $form_id = '_' . ( self::$list_number - 1 );
307 $copy_form =
308 '<form' .
309 " id='copy_form$form_id'" .
310 " action='?page=" . esc_attr( $this->page ) . '&wpdaschema_name=' . esc_attr( $this->schema_name ) . '&table_name=' . esc_attr( $this->table_name ) . "'" .
311 " method='post'>" .
312 $this->get_key_input_fields( $item ) .
313 $this->add_parent_args_as_string( $item ) .
314 "<input type='hidden' name='action' value='copy' />" .
315 "<input type='hidden' name='_wpnonce' value='$wp_nonce'>" .
316 $this->page_number_item .
317 '</form>'
318 ?>
319
320 <script type='text/javascript'>
321 jQuery("#wpda_invisible_container").append("<?php echo $copy_form; // phpcs:ignore WordPress.Security.EscapeOutput ?>");
322 </script>
323
324 <?php
325
326 // Add link to submit form.
327 $copy_warning = __( "Copy project template set?\\n\\'Cancel\\' to stop, \\'OK\\' to copy.", 'wp-data-access' );
328 $actions['copy'] = sprintf(
329 '<a href="javascript:void(0)"
330 class="edit wpda_tooltip"
331 title="Copy template set"
332 onclick="if (confirm(\'%s\')) jQuery(\'#%s\').submit()">
333 <span style="white-space:nowrap">
334 <span class="material-icons wpda_icon_on_button">content_copy</span>
335 %s
336 </span>
337 </a>
338 ',
339 $copy_warning,
340 "copy_form$form_id",
341 __( 'Copy', 'wp-data-access' )
342 );
343 }
344
345 /**
346 * Overwrite method to implement copy action
347 *
348 * @return array|void
349 */
350 public function process_bulk_action() {
351 if ( 'copy' === $this->current_action() ) {
352 $wp_nonce_action = "wpda-copy-{$this->table_name}";
353 $wp_nonce = isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : ''; // input var okay.
354 if ( ! wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
355 die( __( 'ERROR: Not authorized', 'wp-data-access' ) );
356 }
357
358 if ( isset( $_REQUEST['wpda_schema_name'] ) ) {
359 $wpda_schema_name = sanitize_text_field( wp_unslash( $_REQUEST['wpda_schema_name'] ) ); // input var okay.
360 }
361 if ( isset( $_REQUEST['wpda_table_name'] ) ) {
362 $wpda_table_name = sanitize_text_field( wp_unslash( $_REQUEST['wpda_table_name'] ) ); // input var okay.
363 }
364 if ( isset( $_REQUEST['wpda_table_setname'] ) ) {
365 $wpda_table_setname = sanitize_text_field( wp_unslash( $_REQUEST['wpda_table_setname'] ) ); // input var okay.
366 }
367
368 $unique_wpda_table_setname = $this->get_unique_setname( $wpda_schema_name, $wpda_table_name, $wpda_table_setname );
369
370 global $wpdb;
371 $wpda_table_design_raw = $wpdb->get_results(
372 $wpdb->prepare(
373 'SELECT * FROM `%1s` WHERE wpda_schema_name = %s AND wpda_table_name = %s AND wpda_table_setname = %s', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
374 array(
375 WPDA::remove_backticks( $this->table_name ),
376 $wpda_schema_name,
377 $wpda_table_name,
378 $wpda_table_setname,
379 )
380 ),
381 'ARRAY_A'
382 );
383 if ( $wpdb->num_rows > 0 ) {
384 $wpda_table_design_raw[0]['wpda_table_setname'] = $unique_wpda_table_setname;
385 $rows_inserted = $wpdb->insert(
386 $this->table_name,
387 $wpda_table_design_raw[0]
388 );
389 switch ( $rows_inserted ) {
390 case 0:
391 $msg = new WPDA_Message_Box(
392 array(
393 'message_text' => __( 'Could not copy table options [source not found]', 'wp-data-access' ),
394 'message_type' => 'error',
395 'message_is_dismissible' => false,
396 )
397 );
398 $msg->box();
399 break;
400 case 1:
401 $msg = new WPDA_Message_Box(
402 array(
403 'message_text' => __( 'Table options copied', 'wp-data-access' ),
404 )
405 );
406 $msg->box();
407 break;
408 default:
409 $msg = new WPDA_Message_Box(
410 array(
411 'message_text' => __( 'Could not copy table options [too many rows]', 'wp-data-access' ),
412 'message_type' => 'error',
413 'message_is_dismissible' => false,
414 )
415 );
416 $msg->box();
417 }
418 }
419 } else {
420 parent::process_bulk_action();
421 }
422 }
423
424 /**
425 * Create a unique setname for this table
426 *
427 * @param $wpda_schema_name
428 * @param $wpda_table_name
429 * @param $wpda_table_setname
430 *
431 * @return string
432 */
433 protected function get_unique_setname( $wpda_schema_name, $wpda_table_name, $wpda_table_setname ) {
434 global $wpdb;
435
436 $i = 2;
437 $query = "select 'x' from `%1s` where wpda_schema_name = %s and wpda_table_name = %s and wpda_table_setname = %s";
438
439 $unique_wpda_table_setname = "{$wpda_table_setname}_$i";
440 $wpdb->get_results(
441 $wpdb->prepare(
442 $query, // phpcs:ignore WordPress.DB.PreparedSQL
443 array(
444 WPDA::remove_backticks( WPDP_Project_Design_Table_Model::get_base_table_name() ),
445 $wpda_schema_name,
446 $wpda_table_name,
447 $unique_wpda_table_setname,
448 )
449 )
450 );
451 while ( $wpdb->num_rows > 0 ) {
452 // Search until a free options set is found
453 $i ++;
454 $unique_wpda_table_setname = "{$wpda_table_setname}_$i";
455 $wpdb->get_results(
456 $wpdb->prepare(
457 $query, // phpcs:ignore WordPress.DB.PreparedSQL
458 array(
459 WPDA::remove_backticks( WPDP_Project_Design_Table_Model::get_base_table_name() ),
460 $wpda_schema_name,
461 $wpda_table_name,
462 $unique_wpda_table_setname,
463 )
464 )
465 );
466 }
467
468 return $unique_wpda_table_setname;
469 }
470
471 /**
472 * Overwrite method show to add tab argument
473 */
474 public function show() {
475 parent::show();
476 ?>
477 <script type='text/javascript'>
478 var wpda_main_form_action = jQuery('#wpda_main_form').attr('action') + '&tab=tables';
479 jQuery('#wpda_main_form').attr('action', wpda_main_form_action);
480 </script>
481 <?php
482 }
483
484 public static function column_headers_labels() {
485 return array(
486 'wpda_table_name' => __( 'Table/View Name', 'wp-data-access' ),
487 'wpda_schema_name' => __( 'Database', 'wp-data-access' ),
488 'wpda_table_setname' => __( 'Template Set Name', 'wp-data-access' ),
489 'table_found' => __( 'Exists in DB?', 'wp-data-access' ),
490 'table_has_relations' => __( 'Has Relationships?', 'wp-data-access' ),
491 'table_rows' => __( '#Rows', 'wp-data-access' ),
492 );
493 }
494
495 public function get_bulk_actions() {
496 $actions = parent::get_bulk_actions();
497
498 unset(
499 $actions['bulk-export'],
500 $actions['bulk-export-xml'],
501 $actions['bulk-export-json'],
502 $actions['bulk-export-excel'],
503 $actions['bulk-export-csv']
504 );
505
506 return $actions;
507 }
508
509 }
510
511 }
512