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

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