PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.34
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.34
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 / Utilities / WPDA_Table_Actions.php

WPDA_Table_Actions.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.34, at WPDataAccess/Utilities/WPDA_Table_Actions.php

3,089 lines 104.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\Utilities
7 */
8 namespace WPDataAccess\Utilities;
9
10 use WPDataAccess\API\WPDA_API;
11 use WPDataAccess\Connection\WPDADB;
12 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Lists;
13 use WPDataAccess\Plugin_Table_Models\WPDA_Media_Model;
14 use WPDataAccess\Plugin_Table_Models\WPDA_Table_Settings_Model;
15 use WPDataAccess\Plugin_Table_Models\WPDA_User_Menus_Model;
16 use WPDataAccess\WPDA;
17 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Exist;
18 use WPDataAccess\Data_Dictionary\WPDA_List_Columns_Cache;
19 use WPDataAccess\Data_Dictionary\WPDA_List_Columns;
20 /**
21 * Class WPDA_Table_Actions
22 *
23 * @author Peter Schulz
24 * @since 2.0.13
25 */
26 class WPDA_Table_Actions {
27 /**
28 * Database schema name
29 *
30 * @var string
31 */
32 protected $schema_name;
33
34 /**
35 * Database table name
36 *
37 * @var string
38 */
39 protected $table_name;
40
41 /**
42 * Database table structure
43 *
44 * @var array
45 */
46 protected $table_structure;
47
48 /**
49 * Original create table statement
50 *
51 * @var string
52 */
53 protected $create_table_stmt_orig;
54
55 /**
56 * Reformatted create table statement
57 *
58 * @var string
59 */
60 protected $create_table_stmt;
61
62 /**
63 * Database indexes
64 *
65 * @var array
66 */
67 protected $indexes;
68
69 /**
70 * Database foreign key constraints
71 *
72 * @var array
73 */
74 protected $foreign_keys;
75
76 /**
77 * Indicates if table is a WordPress table
78 *
79 * @var boolean
80 */
81 protected $is_wp_table;
82
83 /**
84 * Possible values: Table and View
85 *
86 * @var string
87 */
88 protected $dbo_type;
89
90 /**
91 * Handle to instance of WPDA_List_Columns
92 *
93 * @var WPDA_List_Columns
94 */
95 protected $wpda_list_columns;
96
97 /**
98 * Engine
99 *
100 * @var string
101 */
102 protected $engine;
103
104 /**
105 * Row number in the list table
106 *
107 * @var int
108 */
109 protected $rownum;
110
111 /**
112 * Shows the specifications for the specified table or view
113 *
114 * There are four tabs provided:
115 *
116 * TAB Actions
117 * Provides actions for the given table or view, like export, rename, copy, drop, alter, and so on. A button
118 * is provided for every possible action. For some actions additional info can be provided through input fields
119 * like the type of download for an export. Not all buttons are available for all tables and views. WordPress
120 * tables for example cannot be dropped. Views for example can not be truncated. Which buttons are provided
121 * depends on the table or view.
122 *
123 * TAB Structure
124 * Shows the columns and their attributes.
125 *
126 * TAB Indexes
127 * Shows the indexes for the specified table. Not available for views.
128 *
129 * TAB SQL
130 * Shows the create table or views statement for the given table of view. A button is provided to copy
131 * this statement to the clipboard.
132 *
133 * @since 2.0.13
134 */
135 public function show() {
136 if ( !isset( $_REQUEST['table_name'] ) || !isset( $_REQUEST['wpdaschema_name'] ) || !isset( $_REQUEST['rownum'] ) ) {
137 wp_die( __( 'ERROR: Wrong arguments', 'wp-data-access' ) );
138 }
139 $this->schema_name = sanitize_text_field( wp_unslash( $_REQUEST['wpdaschema_name'] ) );
140 // input var okay.
141 $this->table_name = str_replace( '`', '', sanitize_text_field( wp_unslash( $_REQUEST['table_name'] ) ) );
142 // input var okay.
143 $this->rownum = sanitize_text_field( wp_unslash( $_REQUEST['rownum'] ) );
144 // input var okay.
145 $wpda_data_dictionary = new WPDA_Dictionary_Exist($this->schema_name, $this->table_name);
146 if ( !$wpda_data_dictionary->table_exists() ) {
147 echo '<div>' . __( 'ERROR: Invalid table name or not authorized', 'wp-data-access' ) . '</div>';
148 return;
149 }
150 $wp_nonce = ( isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : '?' );
151 // input var okay.
152 if ( !wp_verify_nonce( $wp_nonce, "wpda-actions-{$this->table_name}" ) ) {
153 echo '<div>' . __( 'ERROR: Not authorized', 'wp-data-access' ) . '</div>';
154 return;
155 }
156 $this->dbo_type = ( isset( $_REQUEST['dbo_type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['dbo_type'] ) ) : null );
157 // input var okay.
158 $this->is_wp_table = WPDA::is_wp_table( $this->table_name );
159 $this->engine = WPDA_Dictionary_Lists::get_engine( $this->schema_name, $this->table_name );
160 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
161 if ( null === $wpdadb ) {
162 wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
163 }
164 $query = "show full columns from `{$wpdadb->dbname}`.`{$this->table_name}`";
165 $this->table_structure = $wpdadb->get_results( $query, 'ARRAY_A' );
166 if ( stripos( $this->dbo_type, 'table' ) !== false ) {
167 $this->dbo_type = 'Table';
168 $query = "show create table `{$wpdadb->dbname}`.`{$this->table_name}`";
169 $create_table = $wpdadb->get_results( $query, 'ARRAY_A' );
170 if ( isset( $create_table[0]['Create Table'] ) ) {
171 $this->create_table_stmt_orig = $create_table[0]['Create Table'];
172 $this->create_table_stmt = preg_replace(
173 '/\\(/',
174 '<br/>(',
175 $this->create_table_stmt_orig,
176 1
177 );
178 $this->create_table_stmt = preg_replace( '/\\,\\s\\s\\s/', '<br/>, ', $this->create_table_stmt );
179 $pos = strrpos( $this->create_table_stmt, ')' );
180 if ( false !== $pos ) {
181 $this->create_table_stmt = substr( $this->create_table_stmt, 0, $pos - 1 ) . '<br/>)' . substr( $this->create_table_stmt, $pos + 1 );
182 }
183 $query = "show indexes from `{$wpdadb->dbname}`.`{$this->table_name}`";
184 $this->indexes = $wpdadb->get_results( $query, 'ARRAY_A' );
185 $query = $wpdadb->prepare( '
186 select constraint_name AS constraint_name,
187 column_name AS column_name,
188 referenced_table_name AS referenced_table_name,
189 referenced_column_name AS referenced_column_name
190 from information_schema.key_column_usage
191 where table_schema = %s
192 and table_name = %s
193 and referenced_table_name is not null
194 order by ordinal_position
195 ', array($wpdadb->dbname, $this->table_name) );
196 $this->foreign_keys = $wpdadb->get_results( $query, 'ARRAY_A' );
197 } else {
198 $this->create_table_stmt = __( 'Error reading create table statement', 'wp-data-access' );
199 }
200 } elseif ( strtoupper( $this->dbo_type ) === 'VIEW' ) {
201 $this->dbo_type = 'View';
202 $query = "show create view `{$wpdadb->dbname}`.`{$this->table_name}`";
203 $create_table = $wpdadb->get_results( $query, 'ARRAY_A' );
204 if ( isset( $create_table[0]['Create View'] ) ) {
205 $this->create_table_stmt_orig = $create_table[0]['Create View'];
206 $this->create_table_stmt = str_replace( 'AS select', 'AS<br/>select', $this->create_table_stmt_orig );
207 $this->create_table_stmt = str_replace( 'from', '<br/>from', $this->create_table_stmt );
208 }
209 }
210 $this->wpda_list_columns = WPDA_List_Columns_Cache::get_list_columns( $this->schema_name, $this->table_name );
211 ?>
212 <div id="<?php
213 echo esc_attr( $this->rownum );
214 ?>-tabs">
215 <div class="nav-tab-wrapper" style="padding-top: 0 !important;">
216 <?php
217 echo '<a id="' . esc_attr( $this->rownum ) . '-sel-1" class="nav-tab nav-tab-active wpda-manage-nav-tab' . '" href="javascript:void(0)" onclick="settab(\'' . esc_attr( $this->rownum ) . '\', \'1\');"
218 style="font-size:inherit;">' . '<span class="dashicons dashicons-admin-tools wpda_settings_icon"></span>' . '<span class="wpda_settings_label">' . __( 'Actions', 'wp-data-access' ) . '</span>' . '</a>';
219 if ( 'Table' === $this->dbo_type || 'View' === $this->dbo_type ) {
220 echo '<a id="' . esc_attr( $this->rownum ) . '-sel-6" class="nav-tab wpda-manage-nav-tab' . '" href="javascript:void(0)" onclick="settab(\'' . esc_attr( $this->rownum ) . '\', \'6\');"
221 style="font-size:inherit;">' . '<span class="dashicons dashicons-admin-generic wpda_settings_icon"></span> ' . '<span class="wpda_settings_label">' . __( 'Settings', 'wp-data-access' ) . '</span>' . '</a>';
222 }
223 if ( '' !== $this->dbo_type ) {
224 echo '<a id="' . esc_attr( $this->rownum ) . '-sel-2" class="nav-tab wpda-manage-nav-tab' . '" href="javascript:void(0)" onclick="settab(\'' . esc_attr( $this->rownum ) . '\', \'2\');"
225 style="font-size:inherit;">' . '<span class="dashicons dashicons-list-view wpda_settings_icon"></span> ' . '<span class="wpda_settings_label">' . __( 'Columns', 'wp-data-access' ) . '</span>' . '</a>';
226 }
227 if ( 'Table' === $this->dbo_type ) {
228 echo '<a id="' . esc_attr( $this->rownum ) . '-sel-3" class="nav-tab wpda-manage-nav-tab' . '" href="javascript:void(0)" onclick="settab(\'' . esc_attr( $this->rownum ) . '\', \'3\');"
229 style="font-size:inherit;">' . '<span class="dashicons dashicons-controls-forward wpda_settings_icon"></span> ' . '<span class="wpda_settings_label">' . __( 'Indexes', 'wp-data-access' ) . '</span>' . '</a>';
230 }
231 if ( 'Table' === $this->dbo_type ) {
232 echo '<a id="' . esc_attr( $this->rownum ) . '-sel-5" class="nav-tab wpda-manage-nav-tab' . '" href="javascript:void(0)" onclick="settab(\'' . esc_attr( $this->rownum ) . '\', \'5\');"
233 style="font-size:inherit;">' . '<span class="dashicons dashicons-networking wpda_settings_icon"></span> ' . '<span class="wpda_settings_label">' . __( 'Foreign Keys', 'wp-data-access' ) . '</span>' . '</a>';
234 }
235 if ( 'Table' === $this->dbo_type || 'View' === $this->dbo_type ) {
236 echo '<a id="' . esc_attr( $this->rownum ) . '-sel-4" class="nav-tab wpda-manage-nav-tab' . '" href="javascript:void(0)" onclick="settab(\'' . esc_attr( $this->rownum ) . '\', \'4\');"
237 style="font-size:inherit;">' . '<span class="dashicons dashicons-editor-code wpda_settings_icon"></span> ' . '<span class="wpda_settings_label">' . __( 'SQL', 'wp-data-access' ) . '</span>' . '</a>';
238 }
239 ?>
240 </div>
241 <div id="<?php
242 echo esc_attr( $this->rownum );
243 ?>-tab-1" style="padding:3px;">
244 <?php
245 $this->tab_actions();
246 ?>
247 </div>
248 <div id="<?php
249 echo esc_attr( $this->rownum );
250 ?>-tab-6" style="padding:3px;display:none;">
251 <?php
252 $this->tab_settings();
253 ?>
254 </div>
255 <?php
256 if ( '' !== $this->dbo_type ) {
257 ?>
258 <div id="<?php
259 echo esc_attr( $this->rownum );
260 ?>-tab-2" style="padding:3px;display:none;">
261 <?php
262 $this->tab_structure();
263 ?>
264 </div>
265 <?php
266 }
267 if ( 'Table' === $this->dbo_type ) {
268 ?>
269 <div id="<?php
270 echo esc_attr( $this->rownum );
271 ?>-tab-3" style="padding:3px;display:none;">
272 <?php
273 $this->tab_index();
274 ?>
275 </div>
276 <?php
277 }
278 if ( 'Table' === $this->dbo_type ) {
279 ?>
280 <div id="<?php
281 echo esc_attr( $this->rownum );
282 ?>-tab-5" style="padding:3px;display:none;">
283 <?php
284 $this->tab_foreign_keys();
285 ?>
286 </div>
287 <?php
288 }
289 if ( 'Table' === $this->dbo_type || 'View' === $this->dbo_type ) {
290 ?>
291 <div id="<?php
292 echo esc_attr( $this->rownum );
293 ?>-tab-4" style="padding:3px;display:none;">
294 <?php
295 $this->tab_sql();
296 ?>
297 </div>
298 <?php
299 }
300 ?>
301 </div>
302 <div style="height:0;padding:0;margin:0;"></div>
303 <script type='text/javascript'>
304 function copyTable(rowNum, dboType, tableName, formId) {
305 if (jQuery("#copy-table-from-" + rowNum).val()==="") {
306 alert('<?php
307 echo __( 'Please enter a valid table name', 'wp-data-access' );
308 ?>');
309 return false;
310 }
311
312 if (confirm('<?php
313 echo __( 'Copy', 'wp-data-access' );
314 ?> ' + dboType + '?')) {
315 jQuery("#copy_schema_name_" + tableName).val(
316 jQuery("#copy-schema-from-" + rowNum).val()
317 );
318 jQuery("#copy_table_name_" + tableName).val(
319 jQuery("#copy-table-from-" + rowNum).val()
320 );
321 jQuery("#" + formId).submit();
322 }
323 }
324 jQuery(function () {
325 var sql_to_clipboard = new ClipboardJS("#button-copy-clipboard-<?php
326 echo esc_attr( $this->rownum );
327 ?>");
328 sql_to_clipboard.on('success', function (e) {
329 jQuery.notify('<?php
330 echo __( 'SQL successfully copied to clipboard!', 'wp-data-access' );
331 ?>','info');
332 });
333 sql_to_clipboard.on('error', function (e) {
334 jQuery.notify('<?php
335 echo __( 'Could not copy SQL to clipboard!', 'wp-data-access' );
336 ?>','error');
337 });
338 jQuery("#rename-table-from-<?php
339 echo esc_attr( $this->rownum );
340 ?>").on('keyup paste', function () {
341 this.value = this.value.replace(/[^\w\$\_]/g, '');
342 });
343 jQuery("#copy-table-from-<?php
344 echo esc_attr( $this->rownum );
345 ?>").on('keyup paste', function () {
346 this.value = this.value.replace(/[^\w\$\_]/g, '');
347 });
348 });
349 </script>
350 <?php
351 }
352
353 /**
354 * Provides content for table settings
355 */
356 public function tab_settings() {
357 $settings_db = WPDA_Table_Settings_Model::query( $this->table_name, $this->schema_name );
358 if ( isset( $settings_db[0]['wpda_table_settings'] ) ) {
359 $settings_db_custom = json_decode( $settings_db[0]['wpda_table_settings'] );
360 $sql_dml = 'UPDATE';
361 } else {
362 $settings_db_custom = (object) null;
363 $sql_dml = 'INSERT';
364 }
365 if ( has_filter( 'wpda_add_column_settings' ) ) {
366 // Use filter
367 $column_settings_add_column = apply_filters( 'wpda_add_column_settings', null );
368 }
369 if ( isset( $column_settings_add_column ) && is_array( $column_settings_add_column ) ) {
370 $array_valid = true;
371 foreach ( $column_settings_add_column as $add_column ) {
372 if ( !isset( $add_column['label'] ) || !isset( $add_column['hint'] ) || !isset( $add_column['name_prefix'] ) || !isset( $add_column['type'] ) || !isset( $add_column['default'] ) || !isset( $add_column['disable'] ) ) {
373 $array_valid = false;
374 break;
375 }
376 }
377 if ( !$array_valid ) {
378 $column_settings_add_column = array();
379 }
380 } else {
381 $column_settings_add_column = array();
382 }
383 $row_count_is_configurable = 'innodb' === strtolower( $this->engine ) || 'federated' === strtolower( $this->engine ) || 'connect' === strtolower( $this->engine ) || $this->engine === null;
384 ?>
385 <style>
386 .wpda_table_settings_nested {
387 padding-top: 5px;
388 padding-left: 20px;
389 padding-bottom: 20px;
390 display: none;
391 margin-right: 20px;
392 }
393
394 .wpda_table_settings_nested table {
395 width: 100%;
396 }
397
398 .wpda_table_settings {
399 border-collapse: collapse;
400 }
401
402 .wpda_table_settings thead {
403 background-color: white;
404 border-bottom: 1px solid #c3c4c7;
405 }
406
407 .wpda_table_settings thead th {
408 text-align: left;
409 font-weight: bold;
410 padding: 16px 12px;
411 }
412
413 .wpda_table_settings thead th span {
414 vertical-align: middle;
415 }
416
417 .wpda_table_settings td {
418 vertical-align: top;
419 padding: 8px 12px;
420 margin: 0;
421 }
422
423 .wpda_table_settings tr:nth-child(even) {
424 background: #fff;
425 }
426
427 .wpda_table_settings_menu {
428 display: grid;
429 grid-template-columns: min(30%, 290px) auto;
430 padding: 10px;
431 }
432
433 .wpda_table_settings_panel {
434 border: 1px solid #c3c4c7;
435 margin: 9px 5px 10px 0;
436 padding: 10px;
437 }
438
439 .wpda_table_settings_nav_vertical {
440 display: grid;
441 grid-template-columns: auto;
442 margin-left: 5px;
443 margin-right: 3px;
444 padding-top: 0;
445 }
446
447 .wpda_table_settings_nav_vertical a {
448 margin: 0;
449 display: grid;
450 grid-template-columns: 24px auto;
451 align-items: center;
452 padding: 8px 12px;
453 }
454
455 .wpda_table_settings_nav_vertical a.nav-tab-active {
456 border-right: none;
457 background-color: transparent;
458 }
459
460 .wpda_table_settings_nav_vertical a.nav-tab:focus {
461 box-shadow: none;
462 }
463
464 ul.wpda_table_settings_panel h4 {
465 margin-top: 2em;
466 }
467
468 .wpda_table_settings_menu_content {
469 display: flex;
470 flex-direction: column;
471 align-items: stretch;
472 }
473
474 .wpda_table_settings_menu_content .wpda_table_settings_vertical_border {
475 height: 10px;
476 border-right: 1px solid #c3c4c7;
477 padding: 0;
478 margin: 9px 3px 0 0;
479 }
480
481 .wpda_table_settings_menu_content .wpda_table_settings_vertical_border.wpda_table_settings_vertical_border_end {
482 flex: 2;
483 margin-top: 0;
484 margin-bottom: 10px;
485 }
486
487 .nav-tab-active {
488 background-color: transparent;
489 }
490
491 .nav-tab-active:focus {
492 box-shadow: none;
493 background-color: transparent;
494 }
495
496 ul.wpda_geolocation_settings .wpda_fieldset {
497 background-color: #efefef;
498 }
499
500 .wpda_table_setting_item {
501 width: 100%;
502 }
503 </style>
504 <script>
505 function settingsNav(elem, className, setActive = true) {
506 if (setActive) {
507 jQuery(elem).closest(".wpda_table_settings_menu").find("a.nav-tab").removeClass("nav-tab-active");
508 jQuery(elem).addClass("nav-tab-active");
509 }
510
511 jQuery(elem).closest(".wpda_table_settings_menu").find("ul.wpda_table_settings_nested").hide();
512 jQuery(elem).closest(".wpda_table_settings_menu").find("ul.wpda_table_settings_nested." + className).show();
513 }
514 </script>
515 <table class="widefat striped rows wpda-structure-table">
516 <tr>
517 <td>
518 <div id="wpda_table_settings_<?php
519 echo esc_attr( $this->rownum );
520 ?>" class="wpda_table_settings_menu">
521 <div class="wpda_table_settings_menu_content">
522 <div class="wpda_table_settings_vertical_border"></div>
523 <nav class="nav-tab-wrapper wpda_table_settings_nav_vertical">
524 <a href="javascript:void(0)" onclick="settingsNav(this, 'wpda_table_table_settings')" class="nav-tab">
525 <i class="fa-solid fa-table wpda_settings_icon"></i>
526 <span>
527 Table Settings
528 </span>
529 </a>
530 <a href="javascript:void(0)" onclick="settingsNav(this, 'wpda_table_column_settings')" class="nav-tab">
531 <i class="fa-solid fa-table-columns wpda_settings_icon"></i>
532 <span>
533 Column Settings
534 </span>
535 </a>
536 <?php
537 ?>
538 <a href="javascript:void(0)" onclick="settingsNav(this, 'wpda_table_dynamic_hyperlinks_settings')" class="nav-tab">
539 <i class="fa-solid fa-link wpda_settings_icon"></i>
540 <span>
541 Dynamic Hyperlinks
542 </span>
543 </a>
544 <a href="javascript:void(0)" onclick="settingsNav(this, 'wpda_table_dashboard_menus_settings')" class="nav-tab">
545 <i class="fa-solid fa-bars wpda_settings_icon"></i>
546 <span>
547 Dashboard Menus
548 </span>
549 </a>
550 <a href="javascript:void(0)" onclick="settingsNav(this, 'wpda_table_rest_api_settings'); setRestApiDefaultTab();" class="nav-tab">
551 <i class="fa-solid fa-gears wpda_settings_icon"></i>
552 <span>
553 REST API
554 </span>
555 </a>
556 </nav>
557 <div class="wpda_table_settings_vertical_border wpda_table_settings_vertical_border_end"></div>
558 </div>
559 <ul class="wpda_table_settings_panel">
560 <?php
561 do_action(
562 'wpda_prepend_table_settings',
563 $this->schema_name,
564 $this->table_name,
565 $this->table_structure
566 );
567 ?>
568 <li>
569 <ul class="wpda_table_settings_nested wpda_table_table_settings">
570 <h2>
571 <?php
572 echo __( 'Table Settings', 'wp-data-access' );
573 ?>
574 <a href="https://wpdataaccess.com/docs/data-explorer-settings/manage-table-settings/" target="_blank">
575 <span class="dashicons dashicons-editor-help wpda_tooltip"
576 title="<?php
577 echo __( 'Help opens in a new tab or window', 'wp-data-access' );
578 ?>"
579 style="cursor:pointer"></span>
580 </a>
581 </h2>
582
583 <h4>
584 <?php
585 echo __( 'Row count (configurable for InnoDB tables, federated tables and views only)', 'wp-data-access' );
586 ?>
587 </h4>
588
589 <div style="font-size:90%;">
590 <label class="wpda_action_font">
591 <input type="radio"
592 name="<?php
593 echo esc_attr( $this->table_name );
594 ?>_row_count_estimate"
595 value="true"
596 <?php
597 echo ( !$row_count_is_configurable ? ' disabled ' : '' );
598 if ( isset( $settings_db_custom->table_settings->row_count_estimate ) && $settings_db_custom->table_settings->row_count_estimate ) {
599 echo ' checked ';
600 }
601 ?>
602 >
603 Show estimated row count (faster but less accurate)
604 </label>
605 <?php
606 $row_count_estimate_value = 'plugin';
607 if ( isset( $settings_db_custom->table_settings->row_count_estimate_value ) ) {
608 $row_count_estimate_value = $settings_db_custom->table_settings->row_count_estimate_value;
609 }
610 ?>
611 <div style="padding: 5px 0 5px 25px">
612 <label class="wpda_action_font">
613 <input type="radio"
614 name="<?php
615 echo esc_attr( $this->table_name );
616 ?>_row_count_estimated_value"
617 value="plugin"
618 <?php
619 echo ( 'plugin' === $row_count_estimate_value ? 'checked' : '' );
620 echo ( !$row_count_is_configurable ? ' disabled ' : '' );
621 ?>
622 />
623 Use plugin estimate calculation
624 </label>
625 <br/>
626 <label class="wpda_action_font">
627 <?php
628 $row_count = 0;
629 if ( isset( $settings_db_custom->table_settings->row_count_estimate_value_hard ) ) {
630 $row_count = $settings_db_custom->table_settings->row_count_estimate_value_hard;
631 } else {
632 if ( 'connect' === strtolower( $this->engine ) ) {
633 $row_count = '';
634 } else {
635 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
636 $explain = $wpdadb->get_results( 'explain select count(*) from `' . str_replace( '`', '', $this->table_name ) . '`', 'ARRAY_A' );
637 if ( isset( $explain[0]['rows'] ) ) {
638 $row_count = $explain[0]['rows'];
639 } elseif ( isset( $explain[0]['ROWS'] ) ) {
640 $row_count = $explain[0]['ROWS'];
641 }
642 }
643 }
644 ?>
645 <input type="radio"
646 name="<?php
647 echo esc_attr( $this->table_name );
648 ?>_row_count_estimated_value"
649 value="hard"
650 <?php
651 echo ( 'hard' === $row_count_estimate_value ? 'checked' : '' );
652 echo ( !$row_count_is_configurable ? ' disabled ' : '' );
653 ?>
654 />
655 Use hard estimate:
656 <input type="number"
657 id="<?php
658 echo esc_attr( $this->table_name );
659 ?>_row_count_estimated_value_hard"
660 value="<?php
661 echo esc_attr( $row_count );
662 ?>"
663 echo ! $row_count_is_configurable ? 'disabled ' : '';
664 />
665 <a href="javascript:void(0)"
666 onclick="get_table_row_count('<?php
667 echo esc_attr( wp_create_nonce( "wpda-get-row-count-{$this->table_name}" ) );
668 ?>', '<?php
669 echo esc_attr( $this->schema_name );
670 ?>', '<?php
671 echo esc_attr( $this->table_name );
672 ?>')"
673 title="Get real row count"
674 class="wpda_tooltip"
675 style="font-weight: bold; font-size: 140%;"
676 >Σ</a>
677 </label>
678 </div>
679 <label class="wpda_action_font">
680 <input type="radio"
681 name="<?php
682 echo esc_attr( $this->table_name );
683 ?>_row_count_estimate"
684 value="false"
685 <?php
686 echo ( !$row_count_is_configurable ? ' disabled ' : '' );
687 if ( isset( $settings_db_custom->table_settings->row_count_estimate ) && !$settings_db_custom->table_settings->row_count_estimate ) {
688 echo ' checked ';
689 } else {
690 if ( !$row_count_is_configurable ) {
691 echo ' checked ';
692 }
693 }
694 ?>
695 >
696 Show real row count
697 </label>
698 <br/>
699 <label class="wpda_action_font" style="display: inline-block; margin-top: 10px">
700 <input type="radio"
701 name="<?php
702 echo esc_attr( $this->table_name );
703 ?>_row_count_estimate"
704 value=""
705 <?php
706 echo ( !$row_count_is_configurable ? ' disabled ' : '' );
707 if ( isset( $settings_db_custom->table_settings->row_count_estimate ) ) {
708 if ( null === $settings_db_custom->table_settings->row_count_estimate ) {
709 echo ' checked ';
710 }
711 } else {
712 if ( $row_count_is_configurable ) {
713 echo ' checked ';
714 }
715 }
716 ?>
717 >
718 Use plugin default (current value=<?php
719 echo esc_attr( WPDA::get_option( WPDA::OPTION_BE_INNODB_COUNT ) );
720 ?>)
721 [<a href="<?php
722 echo admin_url( 'options-general.php' );
723 // phpcs:ignore WordPress.Security.EscapeOutput
724 ?>?page=wpdataaccess&tab=backend">change plugin default</a>]
725 </label>
726 <div style="margin-top: 5px; padding-left: 24px">
727 Performs real row count if estimate <= <?php
728 echo esc_attr( WPDA::get_option( WPDA::OPTION_BE_INNODB_COUNT ) );
729 ?>.
730 Uses estimated row count if estimate > <?php
731 echo esc_attr( WPDA::get_option( WPDA::OPTION_BE_INNODB_COUNT ) );
732 ?>.
733 </div>
734 </div>
735 <h4>
736 <?php
737 echo __( 'Query buffer size', 'wp-data-access' );
738 ?>
739 </h4>
740 <div style="font-size:90%;">
741 <label class="wpda_action_font">
742 <?php
743 echo __( 'Max rows per fetch', 'wp-data-access' );
744 ?>
745 </label>
746 <input type="text"
747 id="<?php
748 echo esc_attr( $this->table_name );
749 ?>_query_buffer_size"
750 <?php
751 if ( isset( $settings_db_custom->table_settings->query_buffer_size ) ) {
752 echo 'value="' . esc_attr( $settings_db_custom->table_settings->query_buffer_size ) . '"';
753 }
754 ?>
755 />
756 <span class="dashicons dashicons-editor-help wpda_tooltip" title="Large exports to other databases can result in an 'allowed memory size exhausted' error. Reduce the query buffer size to prevent this fatal error.
757
758 Start with high values and work down until the error disappears." style="cursor:pointer;vertical-align:middle"></span>
759 </div>
760 <h4>
761 <?php
762 echo __( 'Access control', 'wp-data-access' );
763 ?>
764 </h4>
765 <div style="font-size:90%;">
766 <label class="wpda_action_font">
767 <input type="checkbox"
768 id="<?php
769 echo esc_attr( $this->table_name );
770 ?>_row_level_security"
771 <?php
772 if ( isset( $settings_db_custom->table_settings->row_level_security ) ) {
773 echo ( 'true' === $settings_db_custom->table_settings->row_level_security ? 'checked' : '' );
774 }
775 ?>
776 />
777 <?php
778 echo __( 'Enable row level access control (adds token to row actions)', 'wp-data-access' );
779 ?>
780 </label>
781 </div>
782 <h4>
783 <?php
784 echo __( 'Process hyperlink columns as', 'wp-data-access' );
785 ?>
786 </h4>
787 <div style="font-size:90%;">
788 <label for="<?php
789 echo esc_attr( $this->table_name );
790 ?>table_top_setting_hyperlink_definition_json">
791 <input type="radio"
792 id="<?php
793 echo esc_attr( $this->table_name );
794 ?>table_top_setting_hyperlink_definition_json"
795 name="<?php
796 echo esc_attr( $this->table_name );
797 ?>table_top_setting_hyperlink_definition"
798 value="json"
799 class="wpda_table_top_setting_item wpda_action_font"
800 <?php
801 if ( isset( $settings_db_custom->table_settings->hyperlink_definition ) ) {
802 echo ( 'json' === $settings_db_custom->table_settings->hyperlink_definition ? 'checked' : '' );
803 } else {
804 echo 'checked';
805 }
806 ?>
807 />
808 <?php
809 echo __( 'Preformatted JSON (allows individual label and target setting)', 'wp-data-access' );
810 ?>
811 </label>
812 <br/>
813 <label for="<?php
814 echo esc_attr( $this->table_name );
815 ?>table_top_setting_hyperlink_definition_text" style="display: inline-block; margin-top: 10px">
816 <input type="radio"
817 id="<?php
818 echo esc_attr( $this->table_name );
819 ?>table_top_setting_hyperlink_definition_text"
820 name="<?php
821 echo esc_attr( $this->table_name );
822 ?>table_top_setting_hyperlink_definition"
823 value="text"
824 class="wpda_table_top_setting_item wpda_action_font"
825 <?php
826 if ( isset( $settings_db_custom->table_settings->hyperlink_definition ) ) {
827 echo ( 'text' === $settings_db_custom->table_settings->hyperlink_definition ? 'checked' : '' );
828 }
829 ?>
830 />
831 <?php
832 echo __( 'Plain text (column name used as link, opens a new tab or window)', 'wp-data-access' );
833 ?>
834 </label>
835 </div>
836 <br/>
837 <div>
838 <button type="button"
839 id="wpda_<?php
840 echo esc_attr( $this->rownum );
841 ?>_save_table_settings"
842 class="button button-primary"
843 >
844 <i class="fas fa-check wpda_icon_on_button"></i>
845 <?php
846 echo __( 'Save Table Settings', 'wp-data-access' );
847 ?>
848 </button>
849 </div>
850 </ul>
851 </li>
852 <li>
853 <ul class="wpda_table_settings_nested wpda_table_column_settings">
854 <h2>
855 <?php
856 echo __( 'Column Settings', 'wp-data-access' );
857 ?>
858 <a href="https://wpdataaccess.com/docs/data-explorer-settings/column-settings/" target="_blank">
859 <span class="dashicons dashicons-editor-help wpda_tooltip"
860 title="<?php
861 echo __( 'Help opens in a new tab or window', 'wp-data-access' );
862 ?>"
863 style="cursor:pointer"></span>
864 </a>
865 </h2>
866 <table class="wpda_table_settings">
867 <thead>
868 <tr>
869 <th>
870 <span>
871 <?php
872 echo __( 'Column', 'wp-data-access' );
873 ?>
874 </span>
875 </th>
876 <th>
877 <span>
878 <?php
879 echo __( 'Label on List Table', 'wp-data-access' );
880 ?>
881 </span>
882 <span
883 class="dashicons dashicons-editor-help wpda_tooltip"
884 title="<?php
885 echo __( 'Define column labels for list tables', 'wp-data-access' );
886 ?>"
887 ></span>
888 </th>
889 <th>
890 <span>
891 <?php
892 echo __( 'Label on Data Entry Form', 'wp-data-access' );
893 ?>
894 </span>
895 <span class="dashicons dashicons-editor-help wpda_tooltip"
896 title="<?php
897 echo __( 'Define column labels for data entry forms', 'wp-data-access' );
898 ?>"
899 ></span>
900 </th>
901 <th>
902 <span>
903 <?php
904 echo __( 'Column Type', 'wp-data-access' );
905 ?>
906 </span>
907 <span class="dashicons dashicons-editor-help wpda_tooltip"
908 title="<?php
909 echo __( 'Featured plugin column types', 'wp-data-access' );
910 ?>"
911 ></span>
912 </th>
913 <?php
914 foreach ( $column_settings_add_column as $add_column ) {
915 ?>
916 <th>
917 <span>
918 <?php
919 echo esc_attr( $add_column['label'] );
920 ?>
921 </span>
922 <span class="dashicons dashicons-editor-help wpda_tooltip"
923 title="<?php
924 echo esc_attr( $add_column['hint'] );
925 ?>"
926 ></span>
927 </th>
928 <?php
929 }
930 ?>
931 </tr>
932 </thead>
933 <tbody>
934 <?php
935 $columns = $this->wpda_list_columns->get_table_column_headers();
936 $media_pool = WPDA_Media_Model::get_pool();
937 $media_cols = array();
938 if ( isset( $media_pool[$this->schema_name][$this->table_name] ) ) {
939 $media_cols = $media_pool[$this->schema_name][$this->table_name];
940 }
941 foreach ( $this->table_structure as $column ) {
942 $label_list_table = $this->wpda_list_columns->get_column_label( $column['Field'] );
943 $label_data_entry = ( isset( $columns[$column['Field']] ) ? $columns[$column['Field']] : '' );
944 $option = ( isset( $media_cols[$column['Field']] ) ? $media_cols[$column['Field']] : '' );
945 ?>
946 <tr>
947 <td>
948 <?php
949 echo esc_attr( $column['Field'] );
950 ?>
951 </td>
952 <td>
953 <input
954 id="list_label_<?php
955 echo esc_attr( $column['Field'] );
956 ?>"
957 class="wpda_table_setting_item wpda_action_font"
958 type="text"
959 value="<?php
960 echo esc_attr( $label_list_table );
961 ?>"
962 style="font-size: 90%;"
963 >
964 </td>
965 <td>
966 <input
967 id="form_label_<?php
968 echo esc_attr( $column['Field'] );
969 ?>"
970 class="wpda_table_setting_item wpda_action_font"
971 type="text"
972 value="<?php
973 echo esc_attr( $label_data_entry );
974 ?>"
975 style="font-size: 90%;"
976 >
977 </td>
978 <td style="text-align:center;">
979 <select id="column_media_<?php
980 echo esc_attr( $column['Field'] );
981 ?>"
982 class="wpda_table_setting_item wpda_action_font"
983 style="font-size: 90%; height: 30px;"
984 >
985 <option value="" <?php
986 echo ( '' === $option ? 'selected' : '' );
987 ?>>
988 </option>
989 <option value="Attachment" <?php
990 echo ( 'Attachment' === $option ? 'selected' : '' );
991 ?>>
992 Attachment
993 </option>
994 <option value="Audio" <?php
995 echo ( 'Audio' === $option ? 'selected' : '' );
996 ?>>
997 Audio
998 </option>
999 <option value="Hyperlink" <?php
1000 echo ( 'Hyperlink' === $option ? 'selected' : '' );
1001 ?>>
1002 Hyperlink
1003 </option>
1004 <option value="Image" <?php
1005 echo ( 'Image' === $option ? 'selected' : '' );
1006 ?>>
1007 Image
1008 </option>
1009 <option value="ImageURL" <?php
1010 echo ( 'ImageURL' === $option ? 'selected' : '' );
1011 ?>>
1012 Image URL
1013 </option>
1014 <option value="Video" <?php
1015 echo ( 'Video' === $option ? 'selected' : '' );
1016 ?>>
1017 Video
1018 </option>
1019 </select>
1020 <input type="hidden"
1021 id="column_media_<?php
1022 echo esc_attr( $column['Field'] );
1023 ?>_dml"
1024 value="<?php
1025 echo ( isset( $media_cols[$column['Field']] ) ? 'UPDATE' : 'INSERT' );
1026 ?>"
1027 />
1028 <input type="hidden"
1029 id="column_media_<?php
1030 echo esc_attr( $column['Field'] );
1031 ?>_old"
1032 value="<?php
1033 echo esc_attr( $option );
1034 ?>"
1035 />
1036 </td>
1037 <?php
1038 foreach ( $column_settings_add_column as $add_column ) {
1039 ?>
1040 <td>
1041 <?php
1042 if ( 'Edit' === $add_column['label'] ) {
1043 echo '<label>';
1044 }
1045 ?>
1046 <input
1047 type="<?php
1048 echo esc_attr( $add_column['type'] );
1049 ?>"
1050 id="<?php
1051 echo esc_attr( $add_column['name_prefix'] ) . esc_attr( $column['Field'] );
1052 ?>"
1053 class="wpda_table_setting_item wpda_action_font wpda_tooltip"
1054 <?php
1055 if ( 'keys' === $add_column['disable'] ) {
1056 $primary_key = $this->wpda_list_columns->get_table_primary_key();
1057 if ( in_array( $column['Field'], $primary_key ) ) {
1058 //phpcs:ignore - 8.1 proof
1059 echo 'disabled="disabled" title="Not available for key columns"';
1060 }
1061 }
1062 if ( 'checkbox' === $add_column['type'] ) {
1063 $column_name = $add_column['name_prefix'] . esc_attr( $column['Field'] );
1064 if ( isset( $settings_db_custom->custom_settings->{$column_name} ) ) {
1065 echo ( $settings_db_custom->custom_settings->{$column_name} ? 'checked' : '' );
1066 } else {
1067 echo esc_attr( $add_column['default'] );
1068 }
1069 }
1070 ?>
1071 ><?php
1072 if ( 'Edit' === $add_column['label'] ) {
1073 echo '</label>';
1074 }
1075 ?>
1076 </td>
1077 <?php
1078 }
1079 ?>
1080 </tr>
1081 <?php
1082 }
1083 ?>
1084 </tbody></table>
1085 <br/>
1086 <div>
1087 <button type="button"
1088 id="wpda_<?php
1089 echo esc_attr( $this->rownum );
1090 ?>_save_column_settings"
1091 class="button button-primary"
1092 >
1093 <i class="fas fa-check wpda_icon_on_button"></i>
1094 <?php
1095 echo __( 'Save Column Settings', 'wp-data-access' );
1096 ?>
1097 </button>
1098 </div>
1099 </ul>
1100 </li>
1101 <?php
1102 $this->settings_tab_dynamic_hyperlinks( $settings_db_custom );
1103 $this->settings_tab_dashboard_menus();
1104 $this->settings_tab_rest_api();
1105 do_action( 'wpda_append_table_settings' );
1106 ?>
1107 </ul>
1108 <input class="wpda_table_setting_item" type="hidden" id="wpda_<?php
1109 echo esc_attr( $this->rownum );
1110 ?>_sql_dml"
1111 value="<?php
1112 echo esc_attr( $sql_dml );
1113 ?>"
1114 />
1115 </div>
1116 </td>
1117 </tr>
1118 </table>
1119 <script type='text/javascript'>
1120 jQuery(function () {
1121 // Show table settings menu on startup
1122 settingsNav("#wpda_table_settings_<?php
1123 echo esc_attr( $this->rownum );
1124 ?>", "wpda_table_table_settings", false);
1125 jQuery("#wpda_table_settings_<?php
1126 echo esc_attr( $this->rownum );
1127 ?>").find("a.nav-tab").removeClass("nav-tab-active");
1128 jQuery("#wpda_table_settings_<?php
1129 echo esc_attr( $this->rownum );
1130 ?>").find("a.nav-tab:first-child").addClass("nav-tab-active");
1131
1132 // Table settings
1133 jQuery('#wpda_<?php
1134 echo esc_attr( $this->rownum );
1135 ?>_save_table_settings').click( function() {
1136 return submit_table_settings(
1137 '<?php
1138 echo esc_attr( $this->rownum );
1139 ?>',
1140 '<?php
1141 echo esc_attr( $this->schema_name );
1142 ?>',
1143 '<?php
1144 echo esc_attr( $this->table_name );
1145 ?>'
1146 );
1147 });
1148 jQuery('#wpda_<?php
1149 echo esc_attr( $this->rownum );
1150 ?>_cancel_table_settings').click( function() {
1151 jQuery('#wpda_admin_menu_actions_<?php
1152 echo esc_attr( $this->rownum );
1153 ?>').toggle();
1154 wpda_toggle_row_actions('<?php
1155 echo esc_attr( $this->rownum );
1156 ?>');
1157 });
1158
1159 // Column settings
1160 jQuery('#wpda_<?php
1161 echo esc_attr( $this->rownum );
1162 ?>_save_column_settings').click( function() {
1163 return submit_column_settings(
1164 '<?php
1165 echo esc_attr( $this->rownum );
1166 ?>',
1167 '<?php
1168 echo esc_attr( $this->schema_name );
1169 ?>',
1170 '<?php
1171 echo esc_attr( $this->table_name );
1172 ?>'
1173 );
1174 });
1175 jQuery('#wpda_<?php
1176 echo esc_attr( $this->rownum );
1177 ?>_cancel_column_settings').click( function() {
1178 jQuery('#wpda_admin_menu_actions_<?php
1179 echo esc_attr( $this->rownum );
1180 ?>').toggle();
1181 wpda_toggle_row_actions('<?php
1182 echo esc_attr( $this->rownum );
1183 ?>');
1184 });
1185
1186 jQuery('.wpda_tooltip').tooltip();
1187 });
1188
1189 var custom_column_settings = [];
1190 <?php
1191 foreach ( $column_settings_add_column as $add_column ) {
1192 echo 'custom_column_settings.push("' . $add_column['name_prefix'] . '");';
1193 // phpcs:ignore WordPress.Security.EscapeOutput
1194 }
1195 ?>
1196 </script>
1197 <?php
1198 }
1199
1200 private function settings_tab_dashboard_menus() {
1201 ?>
1202 <li>
1203 <ul class="wpda_table_settings_nested wpda_table_dashboard_menus_settings">
1204 <h2>
1205 <?php
1206 echo __( 'Dashboard Menus', 'wp-data-access' );
1207 ?>
1208 <a href="https://wpdataaccess.com/docs/data-explorer-settings/dashboard-menus/" target="_blank">
1209 <span class="dashicons dashicons-editor-help wpda_tooltip"
1210 title="<?php
1211 echo sprintf( __( 'Help opens in a new tab or window', 'wp-data-access' ), esc_attr( $this->table_name ) );
1212 ?>"
1213 style="cursor:pointer;vertical-align:text-bottom;"></span>
1214 </a>
1215 </h2>
1216 <table class="wpda_table_settings">
1217 <thead>
1218 <tr>
1219 <th>
1220 <span>
1221 <?php
1222 echo __( 'Menu Name', 'wp-data-access' );
1223 ?>
1224 </span>
1225 <span class="dashicons dashicons-editor-help wpda_tooltip"
1226 title="<?php
1227 echo __( 'Name of your sub menu item', 'wp-data-access' );
1228 ?>"
1229 style="cursor:pointer;"></span>
1230 </th>
1231 <th>
1232 <span>
1233 <?php
1234 echo __( 'Menu Slug', 'wp-data-access' );
1235 ?>
1236 </span>
1237 <span class="dashicons dashicons-editor-help wpda_tooltip"
1238 title="<?php
1239 echo __( 'Menu slug of the main menu to which your sub menu should be added', 'wp-data-access' );
1240 ?>"
1241 style="cursor:pointer;"></span>
1242 </th>
1243 <th>
1244 <span>
1245 <?php
1246 echo __( 'Roles Authorized', 'wp-data-access' );
1247 ?>
1248 </span>
1249 <span class="dashicons dashicons-editor-help wpda_tooltip"
1250 title="<?php
1251 echo __( 'User roles authorized to see sub menu item', 'wp-data-access' );
1252 ?>"
1253 style="cursor:pointer;"></span>
1254 </th>
1255 <th style="width:20px"></th>
1256 </tr>
1257 </thead>
1258 <tbody id="wpda_<?php
1259 echo esc_attr( $this->rownum );
1260 ?>_add_dashboard_menu_body">
1261 <?php
1262 $table_menus = WPDA_User_Menus_Model::get_table_menus( $this->table_name, $this->schema_name );
1263 foreach ( $table_menus as $table_menu ) {
1264 ?>
1265 <tr>
1266 <td>
1267 <input data-id="menu_name"
1268 class="wpda_action_font" type="text"
1269 value="<?php
1270 echo esc_attr( $table_menu['menu_name'] );
1271 ?>"
1272 style="width:100%"
1273 >
1274 </td>
1275 <td>
1276 <input data-id="menu_slug"
1277 class="wpda_action_font" type="text"
1278 value="<?php
1279 echo esc_attr( $table_menu['menu_slug'] );
1280 ?>"
1281 style="width:100%"
1282 >
1283 </td>
1284 <td>
1285 <select data-id="menu_role"
1286 class="wpda_action_font" multiple size="5"
1287 style="width:100%"
1288 >
1289 <?php
1290 global $wp_roles;
1291 foreach ( $wp_roles->roles as $role => $val ) {
1292 $selected = ( false !== stripos( $table_menu['menu_role'], $role ) ? 'selected' : '' );
1293 $role_label = ( isset( $val['name'] ) ? $val['name'] : $role );
1294 echo "<option value='{$role}' {$selected}>{$role_label}</option>";
1295 // phpcs:ignore WordPress.Security.EscapeOutput
1296 }
1297 ?>
1298 </select>
1299 <input type="hidden" class="wpda_action_font wpda_dashboard_menu_id" data-id="menu_id" value="<?php
1300 echo esc_attr( $table_menu['menu_id'] );
1301 ?>"/>
1302 </td>
1303 <td style="width:20px">
1304 <a href="javascript:void(0)"
1305 class="dashicons dashicons-trash"
1306 onclick="if (confirm('<?php
1307 echo __( 'Delete menu?', 'wp-data-access' );
1308 ?>')) { deleteDashboardMenu(this, '<?php
1309 echo esc_attr( $this->rownum );
1310 ?>') }"
1311 ></a>
1312 </td>
1313 </tr>
1314 <?php
1315 }
1316 ?>
1317 </tbody>
1318 </table>
1319 <br/>
1320 <div>
1321 <button type="button"
1322 id="wpda_<?php
1323 echo esc_attr( $this->rownum );
1324 ?>_save_dashboard_menus"
1325 class="button button-primary"
1326 >
1327 <i class="fas fa-check wpda_icon_on_button"></i>
1328 <?php
1329 echo __( 'Save Dashboard Menus', 'wp-data-access' );
1330 ?>
1331 </button>
1332 <button type="button"
1333 id="wpda_<?php
1334 echo esc_attr( $this->rownum );
1335 ?>_add_dashboard_menus"
1336 class="button button-secondary"
1337 >
1338 <i class="fas fa-add wpda_icon_on_button"></i>
1339 Add Dashboard Menu
1340 </button>
1341 <script>
1342 jQuery('#wpda_<?php
1343 echo esc_attr( $this->rownum );
1344 ?>_save_dashboard_menus').click( function() {
1345 return submit_dashboard_menus(
1346 '<?php
1347 echo esc_attr( $this->rownum );
1348 ?>',
1349 '<?php
1350 echo esc_attr( $this->schema_name );
1351 ?>',
1352 '<?php
1353 echo esc_attr( $this->table_name );
1354 ?>'
1355 );
1356 });
1357
1358 jQuery('#wpda_<?php
1359 echo esc_attr( $this->rownum );
1360 ?>_add_dashboard_menus').click( function() {
1361 jQuery("#wpda_<?php
1362 echo esc_attr( $this->rownum );
1363 ?>_add_dashboard_menu_body").append(`
1364 <tr>
1365 <td>
1366 <input data-id="menu_name"
1367 class="wpda_action_font" type="text" value=""
1368 style="width:100%"
1369 >
1370 </td>
1371 <td>
1372 <input data-id="menu_slug"
1373 class="wpda_action_font" type="text" value=""
1374 style="width:100%"
1375 >
1376 </td>
1377 <td>
1378 <select data-id="menu_role"
1379 class="wpda_action_font" multiple size="5"
1380 style="width:100%"
1381 >
1382 <?php
1383 global $wp_roles;
1384 foreach ( $wp_roles->roles as $role => $val ) {
1385 $role_label = ( isset( $val['name'] ) ? $val['name'] : $role );
1386 echo "<option value='{$role}'>{$role_label}</option>";
1387 // phpcs:ignore WordPress.Security.EscapeOutput
1388 }
1389 ?>
1390 </select>
1391 <input type="hidden" class="wpda_action_font wpda_dashboard_menu_id" data-id="menu_id" value=""/>
1392 </td>
1393 <td style="width:20px">
1394 <a href="javascript:void(0)"
1395 class="dashicons dashicons-trash"
1396 onclick="if (confirm('<?php
1397 echo __( 'Delete menu?', 'wp-data-access' );
1398 ?>')) { deleteDashboardMenu(this, '<?php
1399 echo esc_attr( $this->rownum );
1400 ?>') }"
1401 ></a>
1402 </td>
1403 </tr>
1404 `);
1405 });
1406 </script>
1407 </div>
1408 </ul>
1409 </li>
1410 <?php
1411 }
1412
1413 private function settings_tab_dynamic_hyperlinks( $settings_db_custom ) {
1414 ?>
1415 <li>
1416 <ul class="wpda_table_settings_nested wpda_table_dynamic_hyperlinks_settings">
1417 <h2>
1418 <?php
1419 echo __( 'Dynamic Hyperlinks', 'wp-data-access' );
1420 ?>
1421 <a href="https://wpdataaccess.com/docs/data-explorer-settings/dynamic-hyperlinks/" target="_blank">
1422 <span class="dashicons dashicons-editor-help wpda_tooltip"
1423 title="<?php
1424 echo sprintf( __( 'Help opens in a new tab or window', 'wp-data-access' ), esc_attr( $this->table_name ) );
1425 ?>"
1426 style="cursor:pointer"></span>
1427 </a>
1428 </h2>
1429 <table class="wpda_table_settings">
1430 <thead>
1431 <tr>
1432 <th>
1433 <span>
1434 <?php
1435 echo __( 'Hyperlink Label', 'wp-data-access' );
1436 ?>
1437 </span>
1438 </th>
1439 <th style="text-align:center">
1440 <span>
1441 <?php
1442 echo __( '+List?', 'wp-data-access' );
1443 ?>
1444 </span>
1445 <span class="dashicons dashicons-editor-help wpda_tooltip"
1446 title="<?php
1447 echo __( 'Add hyperlink to list', 'wp-data-access' );
1448 ?>"
1449 style="cursor:pointer;"></span>
1450 </th>
1451 <th style="text-align:center">
1452 <span>
1453 <?php
1454 echo __( '+Form?', 'wp-data-access' );
1455 ?>
1456 </span>
1457 <span class="dashicons dashicons-editor-help wpda_tooltip"
1458 title="<?php
1459 echo __( 'Add hyperlink to form', 'wp-data-access' );
1460 ?>"
1461 style="cursor:pointer;"></span>
1462 </th>
1463 <th style="text-align:center">
1464 <span>
1465 <?php
1466 echo __( '+Window?', 'wp-data-access' );
1467 ?>
1468 </span>
1469 <span class="dashicons dashicons-editor-help wpda_tooltip"
1470 title="<?php
1471 echo __( 'Opens URL in a new tab or window', 'wp-data-access' );
1472 ?>"
1473 style="cursor:pointer;"></span>
1474 </th>
1475 <th>
1476 <span>
1477 <?php
1478 echo __( 'HTML', 'wp-data-access' );
1479 ?>
1480 </span>
1481 <span class="dashicons dashicons-editor-help wpda_tooltip"
1482 title="<?php
1483 echo __( 'Just the URL! For example:
1484
1485 https://yoursite.com/services.php?name=$$column_name$$
1486
1487 Variable $$column_name$$ will be replaced with the value of column $$column_name$$ in table `' . esc_attr( $this->table_name ) . '`.', 'wp-data-access' );
1488 ?>"
1489 style="cursor:pointer;"></span>
1490 </th>
1491 <th></th>
1492 </tr>
1493 <thead>
1494 <tbody id="wpda_<?php
1495 echo esc_attr( $this->rownum );
1496 ?>_add_hyperlink_body">
1497 <?php
1498 if ( isset( $settings_db_custom->hyperlinks ) && is_array( $settings_db_custom->hyperlinks ) ) {
1499 foreach ( $settings_db_custom->hyperlinks as $hyperlink ) {
1500 $hyperlink_label = ( isset( $hyperlink->hyperlink_label ) ? $hyperlink->hyperlink_label : '' );
1501 $hyperlink_list = ( isset( $hyperlink->hyperlink_list ) && true === $hyperlink->hyperlink_list ? 'checked' : '' );
1502 $hyperlink_form = ( isset( $hyperlink->hyperlink_form ) && true === $hyperlink->hyperlink_form ? 'checked' : '' );
1503 $hyperlink_target = ( isset( $hyperlink->hyperlink_target ) && true === $hyperlink->hyperlink_target ? 'checked' : '' );
1504 $hyperlink_html = ( isset( $hyperlink->hyperlink_html ) ? $hyperlink->hyperlink_html : '' );
1505 ?>
1506 <tr>
1507 <td>
1508 <input data-id="hyperlink_label"
1509 class="wpda_action_font"
1510 type="text"
1511 value="<?php
1512 echo esc_attr( $hyperlink_label );
1513 ?>"
1514 style="width:100%"
1515 />
1516 </td>
1517 <td style="text-align:center">
1518 <input data-id="hyperlink_list"
1519 class="wpda_action_font"
1520 type="checkbox"
1521 style="margin-top:7px;"
1522 <?php
1523 echo esc_attr( $hyperlink_list );
1524 ?>
1525 />
1526 </td>
1527 <td style="text-align:center">
1528 <input data-id="hyperlink_form"
1529 class="wpda_action_font"
1530 type="checkbox"
1531 style="margin-top:7px;"
1532 <?php
1533 echo esc_attr( $hyperlink_form );
1534 ?>
1535 />
1536 </td>
1537 <td style="text-align:center">
1538 <input data-id="hyperlink_target"
1539 class="wpda_action_font"
1540 type="checkbox"
1541 style="margin-top:7px;"
1542 <?php
1543 echo esc_attr( $hyperlink_target );
1544 ?>
1545 />
1546 </td>
1547 <td>
1548 <textarea data-id="hyperlink_html"
1549 rows="5"
1550 class="wpda_action_font"
1551 style="width:100%;resize:both;"
1552 ><?php
1553 echo urldecode( $hyperlink_html );
1554 // phpcs:ignore WordPress.Security.EscapeOutput
1555 ?></textarea>
1556 </td>
1557 <td>
1558 <a href="javascript:void(0)"
1559 class="dashicons dashicons-trash"
1560 style="margin-top:4px;"
1561 onclick="if (confirm('<?php
1562 echo __( 'Delete hyperlink?', 'wp-data-access' );
1563 ?>')) { jQuery(this).closest('tr').remove() }"
1564 ></a>
1565 </td>
1566 </tr>
1567 <?php
1568 }
1569 }
1570 ?>
1571 </tbody>
1572 </table>
1573 <br/>
1574 <div>
1575 <button type="button"
1576 id="wpda_<?php
1577 echo esc_attr( $this->rownum );
1578 ?>_save_hyperlinks"
1579 class="button button-primary"
1580 >
1581 <i class="fas fa-check wpda_icon_on_button"></i>
1582 <?php
1583 echo __( 'Save Dynamic Hyperlinks', 'wp-data-access' );
1584 ?>
1585 </button>
1586 <button type="button"
1587 id="wpda_<?php
1588 echo esc_attr( $this->rownum );
1589 ?>_add_hyperlink_link"
1590 class="button button-secondary"
1591 >
1592 <i class="fas fa-add wpda_icon_on_button"></i>
1593 Add Hyperlink
1594 </button>
1595 <script>
1596 jQuery(function() {
1597 jQuery('#wpda_<?php
1598 echo esc_attr( $this->rownum );
1599 ?>_save_hyperlinks').click( function() {
1600 return submit_hyperlinks(
1601 '<?php
1602 echo esc_attr( $this->rownum );
1603 ?>',
1604 '<?php
1605 echo esc_attr( $this->schema_name );
1606 ?>',
1607 '<?php
1608 echo esc_attr( $this->table_name );
1609 ?>'
1610 );
1611 });
1612
1613 jQuery('#wpda_<?php
1614 echo esc_attr( $this->rownum );
1615 ?>_add_hyperlink_link').click( function() {
1616 // Add new row to table
1617 jQuery("#wpda_<?php
1618 echo esc_attr( $this->rownum );
1619 ?>_add_hyperlink_body").append(`
1620 <tr>
1621 <td>
1622 <input data-id="hyperlink_label"
1623 class="wpda_action_font"
1624 type="text"
1625 value=""
1626 style="width:100%"
1627 />
1628 </td>
1629 <td style="text-align:center">
1630 <input data-id="hyperlink_link"
1631 class="wpda_action_font"
1632 type="checkbox"
1633 style="margin-top:7px;"
1634 />
1635 </td>
1636 <td style="text-align:center">
1637 <input data-id="hyperlink_form"
1638 class="wpda_action_font"
1639 type="checkbox"
1640 style="margin-top:7px;"
1641 />
1642 </td>
1643 <td style="text-align:center">
1644 <input data-id="hyperlink_target"
1645 class="wpda_action_font"
1646 type="checkbox"
1647 style="margin-top:7px;"
1648 />
1649 </td>
1650 <td>
1651 <textarea data-id="hyperlink_html"
1652 rows="5"
1653 class="wpda_action_font"
1654 style="width:100%;resize:both;"
1655 ></textarea>
1656 </td>
1657 <td>
1658 <a href="javascript:void(0)"
1659 class="dashicons dashicons-trash"
1660 style="margin-top:4px;"
1661 onclick="if (confirm('<?php
1662 echo __( 'Delete hyperlink %s?', 'wp-data-access' );
1663 ?>')) { jQuery(this).closest('tr').remove() }"
1664 ></a>
1665 </td>
1666 </tr>
1667 `);
1668 });
1669 });
1670 </script>
1671 </div>
1672 </ul>
1673 </li>
1674 <?php
1675 }
1676
1677 private function get_table_settings( $rest_api_settings, $rest_api_settings_saved, $action ) {
1678 if ( isset( $rest_api_settings_saved[$action] ) ) {
1679 $rest_api_settings['enabled'] = true;
1680 if ( isset( $rest_api_settings_saved[$action]['methods'] ) ) {
1681 $rest_api_settings[$action]['methods'] = $rest_api_settings_saved[$action]['methods'];
1682 }
1683 if ( isset( $rest_api_settings_saved[$action]['authorization'] ) ) {
1684 $rest_api_settings[$action]['authorization'] = $rest_api_settings_saved[$action]['authorization'];
1685 }
1686 if ( isset( $rest_api_settings_saved[$action]['authorized_roles'] ) ) {
1687 $rest_api_settings[$action]['authorized_roles'] = $rest_api_settings_saved[$action]['authorized_roles'];
1688 }
1689 if ( isset( $rest_api_settings_saved[$action]['authorized_users'] ) ) {
1690 $rest_api_settings[$action]['authorized_users'] = $rest_api_settings_saved[$action]['authorized_users'];
1691 }
1692 }
1693 return $rest_api_settings;
1694 }
1695
1696 private function settings_tab_rest_api() {
1697 $rest_api_settings = array(
1698 'enabled' => false,
1699 'select' => array(
1700 'methods' => [],
1701 'authorization' => 'authorized',
1702 'authorized_roles' => array(),
1703 'authorized_users' => array(),
1704 ),
1705 'insert' => array(
1706 'methods' => [],
1707 'authorization' => 'authorized',
1708 'authorized_roles' => array(),
1709 'authorized_users' => array(),
1710 ),
1711 'update' => array(
1712 'methods' => [],
1713 'authorization' => 'authorized',
1714 'authorized_roles' => array(),
1715 'authorized_users' => array(),
1716 ),
1717 'delete' => array(
1718 'methods' => [],
1719 'authorization' => 'authorized',
1720 'authorized_roles' => array(),
1721 'authorized_users' => array(),
1722 ),
1723 );
1724 $rest_api_settings_saved = get_option( WPDA_API::WPDA_REST_API_TABLE_ACCESS );
1725 if ( isset( $rest_api_settings_saved[$this->schema_name][$this->table_name] ) ) {
1726 $actions = array(
1727 'select',
1728 'insert',
1729 'update',
1730 'delete'
1731 );
1732 foreach ( $actions as $action ) {
1733 if ( isset( $rest_api_settings_saved[$this->schema_name][$this->table_name][$action] ) ) {
1734 $rest_api_settings = $this->get_table_settings( $rest_api_settings, $rest_api_settings_saved[$this->schema_name][$this->table_name], $action );
1735 }
1736 }
1737 }
1738 ?>
1739 <li>
1740 <ul class="wpda_table_settings_nested wpda_table_rest_api_settings" style="position: relative">
1741 <h2>
1742 <?php
1743 echo __( 'REST API', 'wp-data-access' );
1744 ?>
1745 </h2>
1746 <div style="position: absolute; top: 0; right: 0; font-weight: bold">
1747 <span class="dashicons dashicons-warning wpda_tooltip"></span>
1748 THIS FEATURE IS CURRENTLY IN BETA AND CAN BE SUBJECT TO CHANGE
1749 </div>
1750
1751 <?php
1752 if ( WPDA::is_wp_table( $this->table_name ) ) {
1753 ?>
1754 <h4 style="color: red">
1755 <span class="dashicons dashicons-flag"></span>
1756 We discourage enabling REST API services on <strong>WordPress</strong> tables!
1757 </h4>
1758 <?php
1759 }
1760 ?>
1761
1762 <p style="margin-top: 25px">
1763 <label>
1764 <input type="checkbox"
1765 id="wpda_<?php
1766 echo esc_attr( $this->rownum );
1767 ?>_rest_api"
1768 <?php
1769 if ( isset( $rest_api_settings['enabled'] ) && true === $rest_api_settings['enabled'] ) {
1770 echo 'checked';
1771 }
1772 ?>
1773 />
1774 Enable <strong>REST API</strong> for table <strong><?php
1775 echo esc_attr( $this->table_name );
1776 ?></strong>
1777 </label>
1778 </p>
1779
1780 <div id="wpda_<?php
1781 echo esc_attr( $this->rownum );
1782 ?>_rest_api_panel" style="display: none">
1783 <nav id="rest_api_tab_menu_<?php
1784 echo esc_attr( $this->rownum );
1785 ?>" class="nav-tab-wrapper">
1786 <a href="javascript:void(0)" class="nav-tab" data-id="select">
1787 <i class="fa-solid fa-magnifying-glass wpda_settings_icon"></i>
1788 <span>Select</span>
1789 </a>
1790 <a href="javascript:void(0)" class="nav-tab" data-id="insert">
1791 <i class="fa-solid fa-circle-plus wpda_settings_icon"></i>
1792 <span>Insert</span>
1793 </a>
1794 <a href="javascript:void(0)" class="nav-tab" data-id="update">
1795 <i class="fa-solid fa-check-circle wpda_settings_icon"></i>
1796 <span>Update</span>
1797 </a>
1798 <a href="javascript:void(0)" class="nav-tab" data-id="delete">
1799 <i class="fa-solid fa-circle-minus wpda_settings_icon"></i>
1800 <span>Delete</span>
1801 </a>
1802 </nav>
1803 <?php
1804 $this->settings_tab_rest_api_tab( 'select', $rest_api_settings );
1805 ?>
1806 <?php
1807 $this->settings_tab_rest_api_tab( 'insert', $rest_api_settings );
1808 ?>
1809 <?php
1810 $this->settings_tab_rest_api_tab( 'update', $rest_api_settings );
1811 ?>
1812 <?php
1813 $this->settings_tab_rest_api_tab( 'delete', $rest_api_settings );
1814 ?>
1815 </div>
1816 <br/>
1817 <div>
1818 <button type="button"
1819 id="wpda_<?php
1820 echo esc_attr( $this->rownum );
1821 ?>_save_rest_api"
1822 class="button button-primary"
1823 >
1824 <i class="fas fa-check wpda_icon_on_button"></i>
1825 <?php
1826 echo __( 'Save REST API Settings', 'wp-data-access' );
1827 ?>
1828 </button>
1829 </div>
1830 <style>
1831 .rest_api_tab {
1832 padding: 25px;
1833 border-left: 1px solid #ccd0d4;
1834 border-right: 1px solid #ccd0d4;
1835 border-bottom: 1px solid #ccd0d4;
1836 border-bottom-left-radius: 4px;
1837 border-bottom-right-radius: 4px;
1838 margin: 0;
1839 }
1840
1841 .wpda_rest_api_fieldset {
1842 margin: 30px 0 15px 0;
1843 padding: 30px !important;
1844 padding-bottom: 40px !important;
1845 }
1846
1847 .wpda_table_settings_rest_api_access {
1848 margin: 10px 20px 25px 24px;
1849 display: grid;
1850 grid-template-columns: repeat(auto-fill,minmax(250px, 1fr));
1851 gap: 20px;
1852 }
1853
1854 .wpda_table_settings_rest_api_access > div * {
1855 margin-top: 5px;
1856 }
1857
1858 .wpda_table_settings_rest_api_title {
1859 display: grid;
1860 grid-template-columns: auto 20px;
1861 justify-content: start;
1862 }
1863
1864 .wpda_table_settings_rest_api_select {
1865 font-size: 90% !important;
1866 width: 100%;
1867 }
1868 </style>
1869 <script>
1870 function setRestApiDefaultTab() {
1871 jQuery("#rest_api_tab_menu_<?php
1872 echo esc_attr( $this->rownum );
1873 ?> a:first-child").addClass("nav-tab-active");
1874 }
1875
1876 function saveAction(action) {
1877 let rest_api_methods = [];
1878 if (jQuery("#wpda_<?php
1879 echo esc_attr( $this->rownum );
1880 ?>_rest_api_" + action + "_http_get").is(":checked")) {
1881 rest_api_methods.push("GET");
1882 }
1883 if (jQuery("#wpda_<?php
1884 echo esc_attr( $this->rownum );
1885 ?>_rest_api_" + action + "_http_post").is(":checked")) {
1886 rest_api_methods.push("POST");
1887 }
1888
1889 let rest_api_settings = {};
1890 rest_api_settings = {};
1891 rest_api_settings.methods = rest_api_methods;
1892 rest_api_settings.authorization = jQuery("input[name=wpda_<?php
1893 echo esc_attr( $this->rownum );
1894 ?>_rest_api_" + action + "]:checked").val();
1895 rest_api_settings.authorized_roles = jQuery("#wpda_<?php
1896 echo esc_attr( $this->rownum );
1897 ?>_rest_api_roles_" + action + "").val();
1898 rest_api_settings.authorized_users = jQuery("#wpda_<?php
1899 echo esc_attr( $this->rownum );
1900 ?>_rest_api_users_" + action + "").val();
1901
1902 return rest_api_settings;
1903 }
1904
1905 function copyUrlToClipboard(action, extension = '') {
1906 let copy_url = new ClipboardJS("#wpda_<?php
1907 echo esc_attr( $this->rownum );
1908 ?>_rest_api_" + action + "_copy_url" + extension);
1909 copy_url.on('success', function (e) {
1910 jQuery.notify('<?php
1911 echo __( 'SQL successfully copied to clipboard!' );
1912 ?>', 'info');
1913 });
1914 copy_url.on('error', function (e) {
1915 jQuery.notify('<?php
1916 echo __( 'Could not copy SQL to clipboard!' );
1917 ?>', 'error');
1918 });
1919 }
1920
1921 jQuery(function() {
1922 // Navigation
1923 jQuery("#rest_api_tab_menu_<?php
1924 echo esc_attr( $this->rownum );
1925 ?> a").on("click", function() {
1926 jQuery(this).closest("div").find(".rest_api_tab").hide();
1927 jQuery(this).parent().find("a").removeClass("nav-tab-active");
1928
1929 jQuery("#rest_api_tab_" + jQuery(this).data("id") + "_<?php
1930 echo esc_attr( $this->rownum );
1931 ?>").show();
1932 jQuery(this).addClass("nav-tab-active");
1933 });
1934
1935 // Save settings
1936 jQuery("#wpda_<?php
1937 echo esc_attr( $this->rownum );
1938 ?>_save_rest_api").on("click", function() {
1939 let rest_api_settings = {};
1940
1941 if (!jQuery("#wpda_<?php
1942 echo esc_attr( $this->rownum );
1943 ?>_rest_api").is(":checked")) {
1944 rest_api_settings.enabled = false;
1945 rest_api_settings.select = {};
1946 rest_api_settings.insert = {};
1947 rest_api_settings.update = {};
1948 rest_api_settings.delete = {};
1949 } else {
1950 rest_api_settings.enabled = true;
1951 rest_api_settings.select = saveAction('select');
1952 rest_api_settings.insert = saveAction('insert');
1953 rest_api_settings.update = saveAction('update');
1954 rest_api_settings.delete = saveAction('delete');
1955 }
1956
1957 submit_rest_api(
1958 '<?php
1959 echo esc_attr( $this->schema_name );
1960 ?>',
1961 '<?php
1962 echo esc_attr( $this->table_name );
1963 ?>',
1964 rest_api_settings
1965 );
1966 });
1967
1968 // Panel interaction
1969 jQuery("#wpda_<?php
1970 echo esc_attr( $this->rownum );
1971 ?>_rest_api").on("change", function() {
1972 restApiPanelOnChange(
1973 jQuery("#wpda_<?php
1974 echo esc_attr( $this->rownum );
1975 ?>_rest_api"),
1976 jQuery("#wpda_<?php
1977 echo esc_attr( $this->rownum );
1978 ?>_rest_api_panel")
1979 );
1980 });
1981 restApiPanelOnChange(
1982 jQuery("#wpda_<?php
1983 echo esc_attr( $this->rownum );
1984 ?>_rest_api"),
1985 jQuery("#wpda_<?php
1986 echo esc_attr( $this->rownum );
1987 ?>_rest_api_panel")
1988 );
1989
1990 // Test select GET and POST endpoints
1991 jQuery("#wpda_<?php
1992 echo esc_attr( $this->rownum );
1993 ?>_rest_api_select_http_get_test").on("click", function() {
1994 let data = {
1995 dbs: "<?php
1996 echo esc_attr( $this->schema_name );
1997 ?>",
1998 tbl: "<?php
1999 echo esc_attr( $this->table_name );
2000 ?>"
2001 }
2002 wpda_rest_api("table/select", data, restApiTestCallbackOk, restApiTestCallbackError, "GET");
2003 });
2004 jQuery("#wpda_<?php
2005 echo esc_attr( $this->rownum );
2006 ?>_rest_api_select_http_post_test").on("click", function() {
2007 let data = {
2008 dbs: "<?php
2009 echo esc_attr( $this->schema_name );
2010 ?>",
2011 tbl: "<?php
2012 echo esc_attr( $this->table_name );
2013 ?>"
2014 }
2015 wpda_rest_api("table/select", data, restApiTestCallbackOk, restApiTestCallbackError);
2016 });
2017
2018 // Add copy to clipboard support
2019 let actions = ['select', 'insert', 'update', 'delete'];
2020 for (let i=0; i<actions.length; i++) {
2021 copyUrlToClipboard(actions[i]);
2022 if (actions[i]==='select') {
2023 copyUrlToClipboard(actions[i], '_get');
2024 copyUrlToClipboard(actions[i], '_datatable');
2025 }
2026 }
2027 });
2028 </script>
2029 </ul>
2030 </li>
2031 <?php
2032 }
2033
2034 private function settings_tab_rest_api_tab( $tab, $rest_api_settings ) {
2035 $authorized_roles = array();
2036 if ( isset( $rest_api_settings[$tab]['authorized_roles'] ) ) {
2037 $authorized_roles = $rest_api_settings[$tab]['authorized_roles'];
2038 }
2039 $authorized_users = array();
2040 if ( isset( $rest_api_settings[$tab]['authorized_users'] ) ) {
2041 $authorized_users = $rest_api_settings[$tab]['authorized_users'];
2042 }
2043 ?>
2044 <div id="rest_api_tab_<?php
2045 echo esc_attr( $tab );
2046 ?>_<?php
2047 echo esc_attr( $this->rownum );
2048 ?>"
2049 class="rest_api_tab"
2050 <?php
2051 echo ( 'select' === $tab ? '' : 'style="display: none"' );
2052 ?>
2053 >
2054 <div>
2055 <h4 style="margin-top: 0">
2056 Supported HTTP methods
2057 <span class="dashicons dashicons-editor-help wpda_tooltip" title="Leave unchecked to disable" style="cursor:pointer;vertical-align:bottom;"></span>
2058 </h4>
2059 <p>
2060 <label>
2061 <input type="checkbox"
2062 id="wpda_<?php
2063 echo esc_attr( $this->rownum );
2064 ?>_rest_api_<?php
2065 echo esc_attr( $tab );
2066 ?>_http_get"
2067 <?php
2068 //phpcs:ignore - 8.1 proof
2069 echo ( isset( $rest_api_settings[$tab]['methods'] ) && is_array( $rest_api_settings[$tab]['methods'] ) && in_array( 'GET', $rest_api_settings[$tab]['methods'] ) ? 'checked' : '' );
2070 ?>
2071 />
2072 <strong>GET</strong>
2073 </label>
2074 <label style="padding-left: 30px">
2075 <input type="checkbox"
2076 id="wpda_<?php
2077 echo esc_attr( $this->rownum );
2078 ?>_rest_api_<?php
2079 echo esc_attr( $tab );
2080 ?>_http_post"
2081 <?php
2082 //phpcs:ignore - 8.1 proof
2083 echo ( isset( $rest_api_settings[$tab]['methods'] ) && is_array( $rest_api_settings[$tab]['methods'] ) && in_array( 'POST', $rest_api_settings[$tab]['methods'] ) ? 'checked' : '' );
2084 ?>
2085 />
2086 <strong>POST</strong>
2087 </label>
2088 </p>
2089 <h4>
2090 URLs and parameters
2091 <a href="<?php
2092 echo site_url( '/wp-json/wpda' );
2093 // phpcs:ignore WordPress.Security.EscapeOutput
2094 ?>" target="_blank">
2095 <span class="dashicons dashicons-external wpda_tooltip"
2096 style="vertical-align: sub"
2097 title="Click to see WP Data Access endpoints and parameters"></span>
2098 </a>
2099 </h4>
2100 <p>
2101 <?php
2102 $select_url = esc_url( get_rest_url( null, "wpda/table/{$tab}" ) );
2103 echo $select_url;
2104 ?>
2105 <a href="javascript:void(0)"
2106 id="wpda_<?php
2107 echo esc_attr( $this->rownum );
2108 ?>_rest_api_<?php
2109 echo esc_attr( $tab );
2110 ?>_copy_url"
2111 title="Copy to clipboard"
2112 class="wpda_tooltip"
2113 style="padding-left: 5px"
2114 data-clipboard-text="<?php
2115 echo $select_url;
2116 ?>"
2117 >
2118 <i class="dashicons dashicons-clipboard wpda_tooltip"></i>
2119 <?php
2120 if ( 'select' === $tab ) {
2121 ?>
2122 (select multiple rows)
2123 <?php
2124 }
2125 ?>
2126 </a>
2127 <?php
2128 if ( 'select' === $tab ) {
2129 echo '<br/>';
2130 $select_url = esc_url( get_rest_url( null, "wpda/table/get" ) );
2131 echo $select_url;
2132 ?>
2133 <a href="javascript:void(0)"
2134 id="wpda_<?php
2135 echo esc_attr( $this->rownum );
2136 ?>_rest_api_<?php
2137 echo esc_attr( $tab );
2138 ?>_copy_url_get"
2139 title="Copy to clipboard"
2140 class="wpda_tooltip"
2141 style="padding-left: 5px"
2142 data-clipboard-text="<?php
2143 echo $select_url;
2144 ?>"
2145 >
2146 <i class="dashicons dashicons-clipboard wpda_tooltip"></i>
2147 (select single row)
2148 </a>
2149 <?php
2150 }
2151 ?>
2152 </p>
2153 </div>
2154 <div style="margin-top: 20px">
2155 <h4>
2156 Authorization
2157 </h4>
2158 <label>
2159 <input type="radio"
2160 name="wpda_<?php
2161 echo esc_attr( $this->rownum );
2162 ?>_rest_api_<?php
2163 echo esc_attr( $tab );
2164 ?>"
2165 value="authorized"
2166 <?php
2167 if ( isset( $rest_api_settings[$tab]['authorization'] ) && 'authorized' === $rest_api_settings[$tab]['authorization'] ) {
2168 echo 'checked';
2169 }
2170 ?>
2171 />
2172 Authorized access only
2173 </label>
2174 </div>
2175 <div class="wpda_table_settings_rest_api_access">
2176 <div>
2177 <div class="wpda_table_settings_rest_api_title">
2178 <span>
2179 <strong>
2180 Select roles to grant access
2181 </strong>
2182 </span>
2183 <span class="dashicons dashicons-editor-help wpda_tooltip" title="Hold down the control key to select multiple users" style="cursor:pointer"></span>
2184 </div>
2185 <select id="wpda_<?php
2186 echo esc_attr( $this->rownum );
2187 ?>_rest_api_roles_<?php
2188 echo esc_attr( $tab );
2189 ?>" multiple size="7" class="wpda_table_settings_rest_api_select">
2190 <?php
2191 global $wp_roles;
2192 $roles = $wp_roles->roles;
2193 foreach ( $roles as $key => $role ) {
2194 $selected = ( in_array( $key, $authorized_roles ) ? 'selected' : '' );
2195 //phpcs:ignore - 8.1 proof
2196 ?>
2197 <option value="<?php
2198 echo esc_attr( $key );
2199 ?>" <?php
2200 echo esc_attr( $selected );
2201 ?>>
2202 <?php
2203 echo esc_attr( $role['name'] );
2204 ?>
2205 </option>
2206 <?php
2207 }
2208 ?>
2209 </select>
2210 </div>
2211 <div>
2212 <div class="wpda_table_settings_rest_api_title">
2213 <span>
2214 <strong>
2215 Select users to grant access
2216 </strong>
2217 </span>
2218 <span class="dashicons dashicons-editor-help wpda_tooltip" title="Hold down the control key to select multiple users" style="cursor:pointer"></span>
2219 </div>
2220 <select id="wpda_<?php
2221 echo esc_attr( $this->rownum );
2222 ?>_rest_api_users_<?php
2223 echo esc_attr( $tab );
2224 ?>" multiple size="7" class="wpda_table_settings_rest_api_select">
2225 <?php
2226 $users = get_users();
2227 foreach ( $users as $user ) {
2228 $selected = ( in_array( $user->data->user_login, $authorized_users ) ? 'selected' : '' );
2229 //phpcs:ignore - 8.1 proof
2230 ?>
2231 <option value="<?php
2232 echo esc_attr( $user->data->user_login );
2233 ?>" <?php
2234 echo esc_attr( $selected );
2235 ?>>
2236 <?php
2237 echo esc_attr( $user->data->display_name );
2238 ?>
2239 </option>
2240 <?php
2241 }
2242 ?>
2243 </select>
2244 </div>
2245 </div>
2246 <div style="margin-top: 10px">
2247 <label>
2248 <input type="radio"
2249 name="wpda_<?php
2250 echo esc_attr( $this->rownum );
2251 ?>_rest_api_<?php
2252 echo esc_attr( $tab );
2253 ?>"
2254 value="anonymous"
2255 <?php
2256 if ( isset( $rest_api_settings[$tab]['authorization'] ) && 'anonymous' === $rest_api_settings[$tab]['authorization'] ) {
2257 echo 'checked';
2258 }
2259 ?>
2260 />
2261 Anonymous access
2262 </label>
2263 <span <?php
2264 if ( 'select' !== $tab ) {
2265 echo 'style="font-weight: bold;"';
2266 }
2267 ?>>
2268 <?php
2269 switch ( $tab ) {
2270 case 'select':
2271 echo ' - allows non-authorized users to query this table';
2272 break;
2273 default:
2274 echo ' - use this option only if you know what you are doing';
2275 }
2276 ?>
2277 </span>
2278 </div>
2279 </div>
2280 <?php
2281 }
2282
2283 /**
2284 * Provides content for tab Structure
2285 */
2286 protected function tab_structure() {
2287 ?>
2288 <table class="widefat striped rows wpda-structure-table">
2289 <tr>
2290 <th class="nobr"><strong><?php
2291 echo __( 'Column Name', 'wp-data-access' );
2292 ?></strong></th>
2293 <th class="nobr"><strong><?php
2294 echo __( 'Data Type', 'wp-data-access' );
2295 ?></strong></th>
2296 <th><strong><?php
2297 echo __( 'Collation', 'wp-data-access' );
2298 ?></strong></th>
2299 <th><strong><?php
2300 echo __( 'Null?', 'wp-data-access' );
2301 ?></strong></th>
2302 <th><strong><?php
2303 echo __( 'Key?', 'wp-data-access' );
2304 ?></strong></th>
2305 <th class="nobr"><strong><?php
2306 echo __( 'Default Value', 'wp-data-access' );
2307 ?></strong></th>
2308 <th style="width:80%;"><strong><?php
2309 echo __( 'Extra', 'wp-data-access' );
2310 ?></strong></th>
2311 </tr>
2312 <?php
2313 foreach ( $this->table_structure as $column ) {
2314 ?>
2315 <tr>
2316 <td class="nobr"><?php
2317 echo esc_attr( $column['Field'] );
2318 ?></td>
2319 <td class="nobr"><?php
2320 echo esc_attr( $column['Type'] );
2321 ?></td>
2322 <td class="nobr"><?php
2323 echo esc_attr( $column['Collation'] );
2324 ?></td>
2325 <td class="nobr"><?php
2326 echo esc_attr( $column['Null'] );
2327 ?></td>
2328 <td class="nobr"><?php
2329 echo esc_attr( $column['Key'] );
2330 ?></td>
2331 <td class="nobr"><?php
2332 echo esc_attr( $column['Default'] );
2333 ?></td>
2334 <td><?php
2335 echo esc_attr( $column['Extra'] );
2336 ?></td>
2337 </tr>
2338 <?php
2339 }
2340 ?>
2341 </table>
2342 <?php
2343 }
2344
2345 protected function tab_foreign_keys() {
2346 if ( false !== stripos( $this->create_table_stmt_orig, 'ENGINE=InnoDB' ) ) {
2347 ?>
2348 <table class="widefat striped rows wpda-structure-table">
2349 <tr>
2350 <th class="nobr">
2351 <strong><?php
2352 echo __( 'Constraint Name', 'wp-data-access' );
2353 ?></strong>
2354 </th>
2355 <th class="nobr">
2356 <strong><?php
2357 echo __( 'Column Name', 'wp-data-access' );
2358 ?></strong>
2359 </th>
2360 <th class="nobr">
2361 <strong><?php
2362 echo __( 'Referenced Table Name', 'wp-data-access' );
2363 ?></strong>
2364 </th>
2365 <th class="nobr" style="width:80%;">
2366 <strong><?php
2367 echo __( 'Referenced Column Name', 'wp-data-access' );
2368 ?></strong>
2369 </th>
2370 </tr>
2371 <?php
2372 if ( 0 === count( $this->foreign_keys ) ) {
2373 //phpcs:ignore - 8.1 proof
2374 echo '<tr><td colspan="4">' . __( 'No foreign keys defined for this table', 'wp-data-access' ) . '</td></tr>';
2375 }
2376 $constraint_name = '';
2377 foreach ( $this->foreign_keys as $foreign_key ) {
2378 $show_item = $constraint_name !== $foreign_key['constraint_name'];
2379 ?>
2380 <tr>
2381 <td class="nobr">
2382 <?php
2383 echo ( $show_item ? esc_attr( $foreign_key['constraint_name'] ) : '' );
2384 ?>
2385 </td>
2386 <td class="nobr">
2387 <?php
2388 echo esc_attr( $foreign_key['column_name'] );
2389 ?>
2390 </td>
2391 <td class="nobr">
2392 <?php
2393 echo ( $show_item ? esc_attr( $foreign_key['referenced_table_name'] ) : '' );
2394 ?>
2395 </td>
2396 <td class="nobr">
2397 <?php
2398 echo esc_attr( $foreign_key['referenced_column_name'] );
2399 ?>
2400 </td>
2401 </tr>
2402 <?php
2403 $constraint_name = $foreign_key['constraint_name'];
2404 }
2405 ?>
2406 </table>
2407 <?php
2408 }
2409 }
2410
2411 /**
2412 * Provides content for tab Indexes
2413 */
2414 protected function tab_index() {
2415 ?>
2416 <table class="widefat striped rows wpda-structure-table">
2417 <tr>
2418 <th class="nobr"><strong><?php
2419 echo __( 'Index Name', 'wp-data-access' );
2420 ?></strong></th>
2421 <th><strong><?php
2422 echo __( 'Unique?', 'wp-data-access' );
2423 ?></strong></th>
2424 <th><strong>#</strong></th>
2425 <th class="nobr"><strong><?php
2426 echo __( 'Column Name', 'wp-data-access' );
2427 ?></strong></th>
2428 <th><strong><?php
2429 echo __( 'Collation', 'wp-data-access' );
2430 ?></strong></th>
2431 <th class="nobr"><strong><?php
2432 echo __( 'Index Prefix?', 'wp-data-access' );
2433 ?></strong></th>
2434 <th><strong><?php
2435 echo __( 'Null?', 'wp-data-access' );
2436 ?></strong></th>
2437 <th class="nobr" style="width:80%;">
2438 <strong><?php
2439 echo __( 'Index Type', 'wp-data-access' );
2440 ?></strong></th>
2441 </tr>
2442 <?php
2443 if ( 0 === count( (array) $this->indexes ) ) {
2444 //phpcs:ignore - 8.1 proof
2445 echo '<tr><td colspan="8">' . __( 'No indexes defined for this table', 'wp-data-access' ) . '</td></tr>';
2446 }
2447 $current_index_name = '';
2448 foreach ( $this->indexes as $index ) {
2449 if ( $current_index_name !== $index['Key_name'] ) {
2450 $current_index_name = esc_attr( $index['Key_name'] );
2451 $new_index = true;
2452 } else {
2453 $new_index = false;
2454 }
2455 ?>
2456 <tr>
2457 <td class="nobr">
2458 <?php
2459 if ( $new_index ) {
2460 echo esc_attr( $index['Key_name'] );
2461 }
2462 ?>
2463 </td>
2464 <td class="nobr">
2465 <?php
2466 if ( $new_index ) {
2467 echo ( '0' === $index['Non_unique'] ? 'Yes' : 'No' );
2468 }
2469 ?>
2470 </td>
2471 <td class="nobr">
2472 <?php
2473 echo esc_attr( $index['Seq_in_index'] );
2474 ?>
2475 </td>
2476 <td class="nobr">
2477 <?php
2478 echo esc_attr( $index['Column_name'] );
2479 ?>
2480 </td>
2481 <td class="nobr">
2482 <?php
2483 echo ( 'A' === $index['Collation'] ? 'Ascending' : 'Not sorted' );
2484 ?>
2485 </td>
2486 <td class="nobr">
2487 <?php
2488 echo esc_attr( $index['Sub_part'] );
2489 ?>
2490 </td>
2491 <td class="nobr">
2492 <?php
2493 echo ( '' === $index['Null'] ? 'NO' : esc_attr( $index['Null'] ) );
2494 ?>
2495 </td>
2496 <td><?php
2497 echo esc_attr( $index['Index_type'] );
2498 ?></td>
2499 </tr>
2500 <?php
2501 }
2502 ?>
2503 </table>
2504 <?php
2505 }
2506
2507 /**
2508 * Provides content for tab SQL
2509 */
2510 protected function tab_sql() {
2511 ?>
2512 <table class="widefat striped rows wpda-structure-table">
2513 <tr>
2514 <td>
2515 <?php
2516 echo wp_kses( $this->create_table_stmt, array(
2517 'br' => array(),
2518 ) );
2519 ?>
2520 </td>
2521 <td style="text-align: right;">
2522 <a id="button-copy-clipboard-<?php
2523 echo esc_attr( $this->rownum );
2524 ?>"
2525 href="javascript:void(0)"
2526 class="button button-primary"
2527 data-clipboard-text="<?php
2528 echo $this->create_table_stmt_orig;
2529 // phpcs:ignore WordPress.Security.EscapeOutput
2530 ?>"
2531 >
2532 <i class="fas fa-clipboard wpda_icon_on_button"></i>
2533 <?php
2534 echo __( 'Copy to clipboard', 'wp-data-access' );
2535 ?>
2536 </a>
2537 </td>
2538 </tr>
2539 </table>
2540 <?php
2541 }
2542
2543 /**
2544 * Provides content for tab Actions
2545 */
2546 protected function tab_actions() {
2547 $is_pds = false;
2548 ?>
2549 <table class="widefat striped rows wpda-structure-table">
2550 <?php
2551 $this->tab_export();
2552 if ( $this->is_wp_table === false && ('Table' === $this->dbo_type || 'View' === $this->dbo_type) && !$is_pds ) {
2553 $this->tab_rename();
2554 }
2555 if ( 'Table' === $this->dbo_type ) {
2556 $this->tab_copy();
2557 }
2558 if ( 'Table' === $this->dbo_type && $this->is_wp_table === false && !$is_pds ) {
2559 $this->tab_truncate();
2560 }
2561 if ( $this->is_wp_table === false && ('Table' === $this->dbo_type || 'View' === $this->dbo_type) ) {
2562 $this->tab_drop();
2563 }
2564 if ( 'Table' === $this->dbo_type && !$is_pds ) {
2565 $this->tab_optimize();
2566 }
2567 if ( 'Table' === $this->dbo_type ) {
2568 $this->tab_alter();
2569 }
2570 if ( $is_pds ) {
2571 // Premium data service connection
2572 $this->pds();
2573 }
2574 ?>
2575 </table>
2576 <?php
2577 }
2578
2579 protected function pds() {
2580 }
2581
2582 /**
2583 * Provides content for Export action
2584 */
2585 protected function tab_export() {
2586 $wp_nonce_action = 'wpda-export-' . json_encode( $this->table_name );
2587 $wp_nonce = wp_create_nonce( $wp_nonce_action );
2588 $sql_option_prefix = '';
2589 $export_variable_prefix_option = false;
2590 if ( 'Table' === $this->dbo_type ) {
2591 $export_variable_prefix_option = 'on' === WPDA::get_option( WPDA::OPTION_BE_EXPORT_VARIABLE_PREFIX );
2592 }
2593 ?>
2594 <tr>
2595 <td style="box-sizing:border-box;text-align:center;white-space:nowrap;width:150px;vertical-align:middle;">
2596 <a href="javascript:void(0)"
2597 target="_blank"
2598 class="button button-primary"
2599 onclick="return wpda_export_button_<?php
2600 echo esc_attr( $this->rownum );
2601 ?>()"
2602 style="display:block;"
2603 >
2604 <?php
2605 echo __( 'EXPORT', 'wp-data-access' );
2606 ?>
2607 </a>
2608 </td>
2609 <td style="vertical-align:middle;">
2610 <span><?php
2611 echo __( 'Export', 'wp-data-access' );
2612 ?> <strong><?php
2613 echo __( 'table', 'wp-data-access' );
2614 ?> `<?php
2615 echo esc_attr( $this->table_name );
2616 ?>`</strong> <?php
2617 echo __( 'to', 'wp-data-access' );
2618 ?>: </span>
2619 <select id="format_type_<?php
2620 echo esc_attr( $this->rownum );
2621 ?>"
2622 name="format_type"
2623 class="wpda_action_font"
2624 style="height:inherit;padding-top:3px;">
2625 <option value="sql" <?php
2626 echo ( $export_variable_prefix_option ? '' : 'selected' );
2627 ?>>SQL</option>
2628 <?php
2629 global $wpdb;
2630 if ( stripos( $this->table_name, $wpdb->prefix ) === 0 ) {
2631 // Add SQL + prefix export
2632 ?>
2633 <option value="sqlpre" <?php
2634 echo ( $export_variable_prefix_option ? 'selected' : '' );
2635 ?>>SQL (add WP prefix)</option>
2636 <?php
2637 }
2638 ?>
2639 <option value="xml">XML</option>
2640 <option value="json">JSON</option>
2641 <option value="excel">Excel</option>
2642 <option value="csv">CSV</option>
2643 </select>
2644 <label style="vertical-align:text-top;">
2645 <input id="include_table_settings_<?php
2646 echo esc_attr( $this->rownum );
2647 ?>"
2648 type="checkbox"
2649 class="wpda_action_font"
2650 >
2651 <?php
2652 echo __( 'Include table settings (SQL only)', 'wp-data-access' );
2653 ?>&nbsp;
2654 </label>
2655 <script type="text/javascript">
2656 function wpda_export_button_<?php
2657 echo esc_attr( $this->rownum );
2658 ?>() {
2659 <?php
2660 $check_export_access = 'true';
2661 if ( 'on' === WPDA::get_option( WPDA::OPTION_BE_CONFIRM_EXPORT ) ) {
2662 $check_export_access = "confirm('Export table {$this->table_name}?')";
2663 }
2664 ?>
2665 if (<?php
2666 echo $check_export_access;
2667 // phpcs:ignore WordPress.Security.EscapeOutput
2668 ?>) {
2669 wpda_table_export(
2670 '<?php
2671 echo esc_attr( $this->schema_name );
2672 ?>',
2673 '<?php
2674 echo esc_attr( $this->table_name );
2675 ?>',
2676 '<?php
2677 echo esc_attr( $wp_nonce );
2678 ?>',
2679 jQuery('#format_type_<?php
2680 echo esc_attr( $this->rownum );
2681 ?>').val(),
2682 jQuery('#include_table_settings_<?php
2683 echo esc_attr( $this->rownum );
2684 ?>').prop('checked') ? 'on' : 'off'
2685 );
2686 }
2687 return false;
2688 }
2689 </script>
2690 </td>
2691 </tr>
2692 <?php
2693 }
2694
2695 /**
2696 * Provides content for Rename action
2697 */
2698 protected function tab_rename() {
2699 $wp_nonce_action_rename = "wpda-rename-{$this->table_name}";
2700 $wp_nonce_rename = wp_create_nonce( $wp_nonce_action_rename );
2701 $rename_table_form_id = 'rename_table_form_' . esc_attr( $this->table_name );
2702 $rename_table_form = '<form' . " id='" . $rename_table_form_id . "'" . " action='?page=" . esc_attr( \WP_Data_Access_Admin::PAGE_MAIN ) . "'" . " method='post'>" . "<input type='hidden' name='action' value='rename-table' />" . "<input type='hidden' name='rename_table_name_old' value='" . esc_attr( $this->table_name ) . "' />" . "<input type='hidden' name='rename_table_name_new' id='rename_table_name_" . esc_attr( $this->rownum ) . "' value='' />" . "<input type='hidden' name='_wpnonce' value='" . esc_attr( $wp_nonce_rename ) . "' />" . '</form>';
2703 ?>
2704 <tr>
2705 <td style="box-sizing:border-box;text-align:center;white-space:nowrap;width:150px;vertical-align:middle;">
2706 <script type='text/javascript'>
2707 jQuery("#wpda_invisible_container").append("<?php
2708 echo $rename_table_form;
2709 // phpcs:ignore WordPress.Security.EscapeOutput
2710 ?>");
2711 </script>
2712 <a href="javascript:void(0)"
2713 class="button button-primary"
2714 onclick="if (jQuery('#rename-table-from-<?php
2715 echo esc_attr( $this->rownum );
2716 ?>').val()==='') { alert('<?php
2717 echo __( 'Please enter a valid table name', 'wp-data-access' );
2718 ?>'); return false; } if (confirm('<?php
2719 echo __( 'Rename', 'wp-data-access' ) . ' ' . esc_attr( strtolower( $this->dbo_type ) ) . '?';
2720 ?>')) { jQuery('#rename_table_name_<?php
2721 echo esc_attr( $this->rownum );
2722 ?>').val(jQuery('#rename-table-from-<?php
2723 echo esc_attr( $this->rownum );
2724 ?>').val()); jQuery('#<?php
2725 echo esc_attr( $rename_table_form_id );
2726 ?>').submit(); }"
2727 style="display:block;"
2728 >
2729 <?php
2730 echo __( 'RENAME', 'wp-data-access' );
2731 ?>
2732 </a>
2733 </td>
2734 <td style="vertical-align:middle;">
2735 <?php
2736 echo __( 'Rename', 'wp-data-access' );
2737 ?>
2738 <strong><?php
2739 echo esc_attr( strtolower( $this->dbo_type ) );
2740 ?>
2741 `<?php
2742 echo esc_attr( $this->table_name );
2743 ?>`</strong> to:
2744 <input type="text" id="rename-table-from-<?php
2745 echo esc_attr( $this->rownum );
2746 ?>" value=""
2747 class="wpda_action_font">
2748 </td>
2749 </tr>
2750 <?php
2751 }
2752
2753 /**
2754 * Provides content for Copy action
2755 */
2756 protected function tab_copy() {
2757 // Add copy form.
2758 $wp_nonce_action_copy = "wpda-copy-{$this->table_name}";
2759 $wp_nonce_copy = wp_create_nonce( $wp_nonce_action_copy );
2760 $copy_table_form_id = 'copy_table_form_' . esc_attr( $this->table_name );
2761 $copy_table_form = '<form' . " id='{$copy_table_form_id}'" . " action='?page=" . esc_attr( \WP_Data_Access_Admin::PAGE_MAIN ) . "'" . " method='post'>" . "<input type='hidden' name='action' value='copy-table' />" . "<input type='hidden' name='copy_schema_name_src' value='" . esc_attr( $this->schema_name ) . "' />" . "<input type='hidden' name='copy_table_name_src' value='" . esc_attr( $this->table_name ) . "' />" . "<input type='hidden' name='copy_schema_name_dst' id='copy_schema_name_" . esc_attr( $this->table_name ) . "' value='' />" . "<input type='hidden' name='copy_table_name_dst' id='copy_table_name_" . esc_attr( $this->table_name ) . "' value='' />" . "<input type='checkbox' name='copy-table-data' id='copy_table_data_" . esc_attr( $this->rownum ) . "' checked />" . "<input type='hidden' name='_wpnonce' value='" . esc_attr( $wp_nonce_copy ) . "' />" . '</form>';
2762 ?>
2763 <tr>
2764 <td style="box-sizing:border-box;text-align:center;white-space:nowrap;width:150px;vertical-align:middle;">
2765 <script type='text/javascript'>
2766 jQuery("#wpda_invisible_container").append("<?php
2767 echo $copy_table_form;
2768 // phpcs:ignore WordPress.Security.EscapeOutput
2769 ?>");
2770 </script>
2771 <a href="javascript:void(0)"
2772 class="button button-primary"
2773 onclick="copyTable('<?php
2774 echo esc_attr( $this->rownum );
2775 ?>', '<?php
2776 echo esc_attr( $this->dbo_type );
2777 ?>', '<?php
2778 echo esc_attr( $this->table_name );
2779 ?>', '<?php
2780 echo esc_attr( $copy_table_form_id );
2781 ?>')"
2782 style="display:block;"
2783 >
2784 <?php
2785 echo __( 'COPY', 'wp-data-access' );
2786 ?>
2787 </a>
2788 </td>
2789 <td style="vertical-align:middle;">
2790 <?php
2791 echo __( 'Copy', 'wp-data-access' );
2792 ?>
2793 <strong><?php
2794 echo esc_attr( strtolower( $this->dbo_type ) );
2795 ?>
2796 `<?php
2797 echo esc_attr( $this->table_name );
2798 ?>
2799 `</strong> <?php
2800 echo __( 'to', 'wp-data-access' );
2801 ?>:
2802 <select id="copy-schema-from-<?php
2803 echo esc_attr( $this->rownum );
2804 ?>">
2805 <?php
2806 // Get available databases.
2807 $schema_names = WPDA_Dictionary_Lists::get_db_schemas();
2808 global $wpdb;
2809 foreach ( $schema_names as $schema_name ) {
2810 $selected = ( $schema_name['schema_name'] === $this->schema_name ? 'selected' : '' );
2811 $database = ( $schema_name['schema_name'] === $wpdb->dbname ? "WordPress database ({$schema_name['schema_name']})" : $schema_name['schema_name'] );
2812 echo '<option value="' . esc_attr( $schema_name['schema_name'] ) . '" ' . $selected . '>' . esc_attr( $database ) . '</option>';
2813 }
2814 ?>
2815 </select>
2816 <input type="text" id="copy-table-from-<?php
2817 echo esc_attr( $this->rownum );
2818 ?>" value=""
2819 class="wpda_action_font">
2820 <label style="vertical-align:baseline">
2821 <input type="checkbox"
2822 checked
2823 onclick="jQuery('#copy_table_data_<?php
2824 echo esc_attr( $this->rownum );
2825 ?>').prop('checked', jQuery(this).is(':checked'));"
2826 class="wpda_action_font"
2827 >
2828 <?php
2829 echo __( 'Copy data', 'wp-data-access' );
2830 ?>
2831 </label>
2832 </td>
2833 </tr>
2834 <?php
2835 }
2836
2837 /**
2838 * Provides content for Truncate action
2839 */
2840 protected function tab_truncate() {
2841 $wp_nonce_action_truncate = "wpda-truncate-{$this->table_name}";
2842 $wp_nonce_truncate = wp_create_nonce( $wp_nonce_action_truncate );
2843 $truncate_table_form_id = 'truncate_table_form_' . esc_attr( $this->table_name );
2844 $truncate_table_form = '<form' . " id='{$truncate_table_form_id}'" . " action='?page=" . esc_attr( \WP_Data_Access_Admin::PAGE_MAIN ) . "'" . " method='post'>" . "<input type='hidden' name='action' value='truncate' />" . "<input type='hidden' name='truncate_table_name' value='" . esc_attr( $this->table_name ) . "' />" . "<input type='hidden' name='_wpnonce' value='" . esc_attr( $wp_nonce_truncate ) . "' />" . '</form>';
2845 ?>
2846 <tr>
2847 <td style="box-sizing:border-box;text-align:center;white-space:nowrap;width:150px;vertical-align:middle;">
2848 <script type='text/javascript'>
2849 jQuery("#wpda_invisible_container").append("<?php
2850 echo $truncate_table_form;
2851 // phpcs:ignore WordPress.Security.EscapeOutput
2852 ?>");
2853 </script>
2854 <a href="javascript:void(0)"
2855 class="button button-primary"
2856 onclick="if (confirm('<?php
2857 echo __( 'Truncate table?', 'wp-data-access' );
2858 ?>')) { jQuery('#<?php
2859 echo esc_attr( $truncate_table_form_id );
2860 ?>').submit(); }"
2861 style="display:block;"
2862 >
2863 <?php
2864 echo __( 'TRUNCATE', 'wp-data-access' );
2865 ?>
2866 </a>
2867 </td>
2868 <td style="vertical-align:middle;">
2869 <?php
2870 echo __( 'Permanently delete all data from', 'wp-data-access' );
2871 ?>
2872 <strong><?php
2873 echo esc_attr( strtolower( $this->dbo_type ) );
2874 ?>
2875 `<?php
2876 echo esc_attr( $this->table_name );
2877 ?>`</strong>
2878 .<br/>
2879 <strong><?php
2880 echo __( 'This action cannot be undone!', 'wp-data-access' );
2881 ?></strong>
2882 </td>
2883 </tr>
2884 <?php
2885 }
2886
2887 /**
2888 * Provides content for Drop action
2889 */
2890 protected function tab_drop() {
2891 $wp_nonce_action_drop = "wpda-drop-{$this->table_name}";
2892 $wp_nonce_drop = wp_create_nonce( $wp_nonce_action_drop );
2893 if ( 'View' === $this->dbo_type ) {
2894 $msg_drop = __( 'Drop view?', 'wp-data-access' );
2895 } else {
2896 $msg_drop = __( 'Drop table?', 'wp-data-access' );
2897 }
2898 $drop_table_form_id = 'drop_table_form_' . esc_attr( $this->table_name );
2899 $drop_table_form = '<form' . " id='{$drop_table_form_id}'" . " action='?page=" . esc_attr( \WP_Data_Access_Admin::PAGE_MAIN ) . "'" . " method='post'>" . "<input type='hidden' name='action' value='drop' />" . "<input type='hidden' name='drop_table_name' value='" . esc_attr( $this->table_name ) . "' />" . "<input type='hidden' name='_wpnonce' value='" . esc_attr( $wp_nonce_drop ) . "' />" . '</form>';
2900 ?>
2901 <tr>
2902 <td style="box-sizing:border-box;text-align:center;white-space:nowrap;width:150px;vertical-align:middle;">
2903 <script type='text/javascript'>
2904 jQuery("#wpda_invisible_container").append("<?php
2905 echo $drop_table_form;
2906 // phpcs:ignore WordPress.Security.EscapeOutput
2907 ?>");
2908 </script>
2909 <a href="javascript:void(0)"
2910 class="button button-primary"
2911 onclick="if (confirm('<?php
2912 echo $msg_drop;
2913 // phpcs:ignore WordPress.Security.EscapeOutput
2914 ?>')) { jQuery('#<?php
2915 echo esc_attr( $drop_table_form_id );
2916 ?>').submit(); }"
2917 style="display:block;"
2918 >
2919 <?php
2920 echo __( 'DROP', 'wp-data-access' );
2921 ?>
2922 </a>
2923 </td>
2924 <td style="vertical-align:middle;">
2925 <?php
2926 echo __( 'Permanently delete', 'wp-data-access' );
2927 ?>
2928 <strong><?php
2929 echo esc_attr( strtolower( $this->dbo_type ) );
2930 ?>
2931 `<?php
2932 echo esc_attr( $this->table_name );
2933 ?>`</strong>
2934 <?php
2935 echo __( 'and all table data from the database.', 'wp-data-access' );
2936 ?><br/>
2937 <strong><?php
2938 echo __( 'This action cannot be undone!', 'wp-data-access' );
2939 ?></strong>
2940 </td>
2941 </tr>
2942 <?php
2943 }
2944
2945 /**
2946 * Provides content for Optimize action
2947 *
2948 * Data_length
2949 * Index_length
2950 * Data_free
2951 */
2952 protected function tab_optimize() {
2953 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
2954 if ( null === $wpdadb ) {
2955 wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
2956 }
2957 $table_structure = $wpdadb->get_row( $wpdadb->prepare( 'show table status like %s', $this->table_name ) );
2958 $query_innodb_file_per_table = $wpdadb->get_row( "show session variables like 'innodb_file_per_table'" );
2959 if ( !empty( $query_innodb_file_per_table ) ) {
2960 $innodb_file_per_table = 'ON' === $query_innodb_file_per_table->Value;
2961 } else {
2962 $innodb_file_per_table = true;
2963 }
2964 if ( 'InnoDB' === $table_structure->Engine && !$innodb_file_per_table ) {
2965 return;
2966 }
2967 $consider_optimize = $table_structure->Data_free > 0 && $table_structure->Data_length > 0 && $table_structure->Data_free / $table_structure->Data_length > 0.2;
2968 $wp_nonce_action_optimize = "wpda-optimize-{$this->table_name}";
2969 $wp_nonce_optimize = wp_create_nonce( $wp_nonce_action_optimize );
2970 $optimize_table_form_id = 'optimize_table_form_' . esc_attr( $this->table_name );
2971 $optimize_table_form = '<form' . " id='{$optimize_table_form_id}'" . " action='?page=" . esc_attr( \WP_Data_Access_Admin::PAGE_MAIN ) . "'" . " method='post'>" . "<input type='hidden' name='action' value='optimize-table' />" . "<input type='hidden' name='optimize_table_name' value='" . esc_attr( $this->table_name ) . "' />" . "<input type='hidden' name='_wpnonce' value='" . esc_attr( $wp_nonce_optimize ) . "' />" . '</form>';
2972 $msg_optimize = __( 'Optimize table?', 'wp-data-access' );
2973 ?>
2974 <tr>
2975 <td style="box-sizing:border-box;text-align:center;white-space:nowrap;width:150px;vertical-align:middle;">
2976 <script type='text/javascript'>
2977 jQuery("#wpda_invisible_container").append("<?php
2978 echo $optimize_table_form;
2979 // phpcs:ignore WordPress.Security.EscapeOutput
2980 ?>");
2981 </script>
2982 <a href="javascript:void(0)"
2983 class="button button-primary"
2984 onclick="if (confirm('<?php
2985 echo $msg_optimize;
2986 // phpcs:ignore WordPress.Security.EscapeOutput
2987 ?>')) { jQuery('#<?php
2988 echo esc_attr( $optimize_table_form_id );
2989 ?>').submit(); }"
2990 style="display:block;
2991 <?php
2992 if ( !$consider_optimize ) {
2993 echo 'opacity:0.5;';
2994 }
2995 ?>
2996 "
2997 >
2998 <?php
2999 echo __( 'OPTIMIZE', 'wp-data-access' );
3000 ?>
3001 </a>
3002 </td>
3003 <td style="vertical-align:middle;
3004 <?php
3005 if ( !$consider_optimize ) {
3006 echo 'opacity:0.5;';
3007 }
3008 ?>
3009 ">
3010 <?php
3011 echo __( 'Optimize', 'wp-data-access' );
3012 ?>
3013 <strong><?php
3014 echo esc_attr( strtolower( $this->dbo_type ) );
3015 ?>
3016 `<?php
3017 echo esc_attr( $this->table_name );
3018 ?>`</strong>.<br/>
3019 <?php
3020 if ( $consider_optimize ) {
3021 ?>
3022 <strong><?php
3023 echo __( 'MySQL locks the table during the time OPTIMIZE TABLE is running!', 'wp-data-access' );
3024 ?></strong>
3025 <?php
3026 } else {
3027 ?>
3028 <strong><?php
3029 echo __( 'Table optimization not considered useful! But you can...', 'wp-data-access' );
3030 ?></strong>
3031 <?php
3032 }
3033 ?>
3034 </td>
3035 </tr>
3036 <?php
3037 }
3038
3039 /**
3040 * Provides content for Alter action
3041 */
3042 protected function tab_alter() {
3043 $wp_nonce_action_alter = "wpda-alter-{$this->table_name}";
3044 $wp_nonce_alter = wp_create_nonce( $wp_nonce_action_alter );
3045 $alter_table_form_id = 'alter_table_form_' . esc_attr( $this->table_name );
3046 $alter_table_form = '<form' . " id='{$alter_table_form_id}'" . " action='?page=" . esc_attr( \WP_Data_Access_Admin::PAGE_DESIGNER ) . "'" . " method='post'>" . "<input type='hidden' name='action' value='edit' />" . "<input type='hidden' name='action2' value='init' />" . "<input type='hidden' name='wpda_schema_name' value='" . esc_attr( $this->schema_name ) . "' />" . "<input type='hidden' name='wpda_schema_name_re' value='" . esc_attr( $this->schema_name ) . "' />" . "<input type='hidden' name='wpda_table_name' value='" . esc_attr( $this->table_name ) . "' />" . "<input type='hidden' name='wpda_table_name_re' value='" . esc_attr( $this->table_name ) . "' />" . "<input type='hidden' name='_wpnonce' value='" . esc_attr( $wp_nonce_alter ) . "' />" . "<input type='hidden' name='page_number' value='1' />" . "<input type='hidden' name='caller' value='dataexplorer' />" . '</form>';
3047 ?>
3048 <tr>
3049 <td style="box-sizing:border-box;text-align:center;white-space:nowrap;width:150px;vertical-align:middle;">
3050 <script type='text/javascript'>
3051 jQuery("#wpda_invisible_container").append("<?php
3052 echo $alter_table_form;
3053 // phpcs:ignore WordPress.Security.EscapeOutput
3054 ?>");
3055 </script>
3056 <a href="javascript:void(0)"
3057 class="button button-primary"
3058 onclick="if (confirm('<?php
3059 echo __( 'Alter table?', 'wp-data-access' );
3060 ?>')) { jQuery('#<?php
3061 echo esc_attr( $alter_table_form_id );
3062 ?>').submit(); }"
3063 style="display:block;"
3064 >
3065 <?php
3066 echo __( 'ALTER', 'wp-data-access' );
3067 ?>
3068 </a>
3069 </td>
3070 <td style="vertical-align:middle;">
3071 <?php
3072 echo __( 'Loads', 'wp-data-access' );
3073 ?>
3074 <strong><?php
3075 echo esc_attr( strtolower( $this->dbo_type ) );
3076 ?>
3077 `<?php
3078 echo esc_attr( $this->table_name );
3079 ?>`</strong>
3080 <?php
3081 echo __( 'into the Data Designer.', 'wp-data-access' );
3082 ?>
3083 </td>
3084 </tr>
3085 <?php
3086 }
3087
3088 }
3089