PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.77
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.77
5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 5.5.42 5.5.43 All 159 releases
wp-data-access / WPDataAccess / Utilities / WPDA_Remote_Database.php

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

1,284 lines 49.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- verified on page
4 namespace WPDataAccess\Utilities;
5
6 use WPDataAccess\API\WPDA_Tree;
7 use WPDataAccess\Connection\WPDADB;
8 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Access;
9 use WPDataAccess\WPDA;
10 class WPDA_Remote_Database {
11 private $page = null;
12
13 private $user_can_create_db = false;
14
15 private $rdb = array();
16
17 public function __construct() {
18 wp_enqueue_style( 'wp-jquery-ui-core' );
19 wp_enqueue_style( 'wp-jquery-ui-dialog' );
20 wp_enqueue_style( 'wp-jquery-ui-sortable' );
21 wp_enqueue_style( 'wp-jquery-ui-tabs' );
22 wp_enqueue_script( 'jquery-ui-core' );
23 wp_enqueue_script( 'jquery-ui-dialog' );
24 wp_enqueue_script( 'jquery-ui-tabs' );
25 wp_enqueue_script( 'jquery-ui-sortable' );
26 wp_enqueue_script( 'jquery-ui-tooltip' );
27 wp_enqueue_script( 'jquery-ui-autocomplete' );
28 if ( isset( $_REQUEST['page'] ) ) {
29 $this->page = sanitize_text_field( wp_unslash( $_REQUEST['page'] ) );
30 }
31 $this->user_can_create_db = WPDA_Dictionary_Access::can_create_db();
32 if ( WPDA::current_user_is_admin() ) {
33 if ( isset( $_REQUEST['action'] ) ) {
34 // Process create, drop and alter database actions.
35 if ( 'create_db' === $_REQUEST['action'] ) {
36 $this->create_db();
37 } elseif ( 'drop_db' === $_REQUEST['action'] ) {
38 $this->drop_db();
39 } elseif ( 'edit_db' === $_REQUEST['action'] ) {
40 $this->edit_db();
41 } elseif ( 'toggle_db' === $_REQUEST['action'] ) {
42 $this->toggle_db();
43 }
44 }
45 }
46 }
47
48 private function create_db() {
49 if ( !$this->check_wpnonce( 'wpda-create-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnoncecreatedb' ) ) {
50 return;
51 }
52 if ( isset( $_REQUEST['database_location'] ) && 'local' === $_REQUEST['database_location'] ) {
53 // Add local database
54 if ( !isset( $_REQUEST['local_database'] ) ) {
55 $msg = new WPDA_Message_Box(array(
56 'message_text' => __( 'Cannot create database [missing argument]', 'wp-data-access' ),
57 'message_type' => 'error',
58 'message_is_dismissible' => false,
59 ));
60 $msg->box();
61 return;
62 }
63 $database = str_replace( '`', '', sanitize_text_field( wp_unslash( $_REQUEST['local_database'] ) ) );
64 global $wpdb;
65 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders, WordPress.DB.DirectDatabaseQuery.SchemaChange
66 if ( false === $wpdb->query( $wpdb->prepare( 'create database `%1s`', array(WPDA::remove_backticks( $database )) ) ) ) {
67 // db call ok; no-cache ok.
68 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
69 $msg = new WPDA_Message_Box(array(
70 'message_text' => sprintf( __( 'Error creating database `%s`', 'wp-data-access' ), esc_attr( $database ) ),
71 'message_type' => 'error',
72 'message_is_dismissible' => false,
73 ));
74 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
75 $msg->box();
76 } else {
77 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
78 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
79 $msg = new WPDA_Message_Box(array(
80 'message_text' => sprintf( __( 'Database `%s` created', 'wp-data-access' ), esc_attr( $database ) ),
81 ));
82 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
83 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
84 $msg->box();
85 $this->switch_schema_name = $database;
86 }
87 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders, WordPress.DB.DirectDatabaseQuery.SchemaChange
88 } else {
89 // Add remote database
90 $database = ( isset( $_REQUEST['remote_database'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_database'] ) ) : '' );
91 if ( false !== WPDADB::get_remote_database( $database ) ) {
92 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
93 $msg = new WPDA_Message_Box(array(
94 'message_text' => __( 'Remote database connection already exists', 'wp-data-access' ),
95 'message_type' => 'error',
96 'message_is_dismissible' => false,
97 ));
98 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
99 $msg->box();
100 return;
101 }
102 $host = ( isset( $_REQUEST['remote_host'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_host'] ) ) : '' );
103 $user = ( isset( $_REQUEST['remote_user'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_user'] ) ) : '' );
104 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
105 $passwd = ( isset( $_REQUEST['remote_passwd'] ) ? wp_unslash( $_REQUEST['remote_passwd'] ) : '' );
106 // Cannot use sanitize_text_field on password field!
107 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
108 $port = ( isset( $_REQUEST['remote_port'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_port'] ) ) : '' );
109 $schema = ( isset( $_REQUEST['remote_schema'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_schema'] ) ) : '' );
110 $ssl = ( isset( $_REQUEST['remote_ssl'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_ssl'] ) ) : 'off' );
111 $ssl_key = ( isset( $_REQUEST['remote_client_key'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_client_key'] ) ) : '' );
112 $ssl_cert = ( isset( $_REQUEST['remote_client_certificate'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_client_certificate'] ) ) : '' );
113 $ssl_ca = ( isset( $_REQUEST['remote_ca_certificate'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_ca_certificate'] ) ) : '' );
114 $ssl_path = ( isset( $_REQUEST['remote_certificate_path'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_certificate_path'] ) ) : '' );
115 $ssl_cipher = ( isset( $_REQUEST['remote_specified_cipher'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['remote_specified_cipher'] ) ) : '' );
116 if ( '' === $database || '' === $host || '' === $user || '' === $schema ) {
117 $msg = new WPDA_Message_Box(array(
118 'message_text' => __( 'Cannot add remote database connection [missing argument]', 'wp-data-access' ),
119 'message_type' => 'error',
120 'message_is_dismissible' => false,
121 ));
122 $msg->box();
123 return;
124 }
125 if ( 'rdb:' === $database ) {
126 $msg = new WPDA_Message_Box(array(
127 'message_text' => __( 'Invalid database name [enter a valid database name, for example rdb:remotedb]', 'wp-data-access' ),
128 'message_type' => 'error',
129 'message_is_dismissible' => false,
130 ));
131 $msg->box();
132 return;
133 }
134 if ( !WPDADB::add_remote_database(
135 $database,
136 $host,
137 $user,
138 $passwd,
139 $port,
140 $schema,
141 $ssl,
142 $ssl_key,
143 $ssl_cert,
144 $ssl_ca,
145 $ssl_path,
146 $ssl_cipher
147 ) ) {
148 $msg = new WPDA_Message_Box(array(
149 'message_text' => __( 'Cannot add remote database connection', 'wp-data-access' ),
150 'message_type' => 'error',
151 'message_is_dismissible' => false,
152 ));
153 $msg->box();
154 } else {
155 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
156 $msg = new WPDA_Message_Box(array(
157 'message_text' => sprintf( __( 'Remote database connection `%s` added', 'wp-data-access' ), esc_attr( $database ) ),
158 ));
159 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
160 $msg->box();
161 $this->switch_schema_name = $database;
162 }
163 }
164 }
165
166 private function toggle_db() {
167 if ( !$this->check_wpnonce( 'wpda-toggle-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnoncetoggledb' ) ) {
168 return;
169 }
170 if ( !isset( $_REQUEST['database'], $_REQUEST['disabled'] ) ) {
171 $msg = new WPDA_Message_Box(array(
172 'message_text' => __( 'Cannot drop database [missing argument]', 'wp-data-access' ),
173 'message_type' => 'error',
174 'message_is_dismissible' => false,
175 ));
176 $msg->box();
177 return;
178 }
179 global $wpdb;
180 $database = str_replace( '`', '', sanitize_text_field( wp_unslash( $_REQUEST['database'] ) ) );
181 $disabled = $_REQUEST['disabled'] === 'true';
182 if ( 'rdb:' === substr( $database, 0, 4 ) ) {
183 // Toogle remote database
184 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
185 if ( false === WPDADB::get_remote_database( $database, true ) ) {
186 $msg = new WPDA_Message_Box(array(
187 'message_text' => sprintf( __( 'Cannot disable remote database connection `%s` [remote database connection not found]', 'wp-data-access' ), esc_attr( $database ) ),
188 'message_type' => 'error',
189 'message_is_dismissible' => false,
190 ));
191 $msg->box();
192 } else {
193 if ( false === WPDADB::dis_remote_database( $database, $disabled ) ) {
194 $msg = new WPDA_Message_Box(array(
195 'message_text' => sprintf( __( 'Cannot disable remote database connection `%s`', 'wp-data-access' ), esc_attr( $database ) ),
196 'message_type' => 'error',
197 'message_is_dismissible' => false,
198 ));
199 $msg->box();
200 } else {
201 $msg = new WPDA_Message_Box(array(
202 'message_text' => sprintf( __( 'Remote database connection `%s` disabled', 'wp-data-access' ), esc_attr( $database ) ),
203 ));
204 $msg->box();
205 $this->switch_schema_name = $wpdb->dbname;
206 }
207 }
208 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
209 }
210 }
211
212 private function drop_db() {
213 if ( !$this->check_wpnonce( 'wpda-drop-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnoncedropdb' ) ) {
214 return;
215 }
216 if ( !isset( $_REQUEST['database'] ) ) {
217 $msg = new WPDA_Message_Box(array(
218 'message_text' => __( 'Cannot drop database [missing argument]', 'wp-data-access' ),
219 'message_type' => 'error',
220 'message_is_dismissible' => false,
221 ));
222 $msg->box();
223 return;
224 }
225 global $wpdb;
226 $database = str_replace( '`', '', sanitize_text_field( wp_unslash( $_REQUEST['database'] ) ) );
227 if ( 'rdb:' === substr( $database, 0, 4 ) ) {
228 // Delete remote database
229 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
230 if ( false === WPDADB::get_remote_database( $database ) ) {
231 $msg = new WPDA_Message_Box(array(
232 'message_text' => sprintf( __( 'Cannot delete remote database connection `%s` [remote database connection not found]', 'wp-data-access' ), esc_attr( $database ) ),
233 'message_type' => 'error',
234 'message_is_dismissible' => false,
235 ));
236 $msg->box();
237 } else {
238 if ( false === WPDADB::del_remote_database( $database ) ) {
239 $msg = new WPDA_Message_Box(array(
240 'message_text' => sprintf( __( 'Cannot delete remote database connection `%s`', 'wp-data-access' ), esc_attr( $database ) ),
241 'message_type' => 'error',
242 'message_is_dismissible' => false,
243 ));
244 $msg->box();
245 } else {
246 $msg = new WPDA_Message_Box(array(
247 'message_text' => sprintf( __( 'Remote database connection `%s` deleted', 'wp-data-access' ), esc_attr( $database ) ),
248 ));
249 $msg->box();
250 $this->switch_schema_name = $wpdb->dbname;
251 }
252 }
253 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
254 } else {
255 // Drop local database
256 if ( $wpdb->dbname === $database ) {
257 $msg = new WPDA_Message_Box(array(
258 'message_text' => __( 'Cannot drop WordPress database', 'wp-data-access' ),
259 'message_type' => 'error',
260 'message_is_dismissible' => false,
261 ));
262 $msg->box();
263 return;
264 }
265 if ( 'sys' === $database || 'mysql' === $database || 'information_schema' === $database || 'performance_schema' === $database || '' === $database ) {
266 $msg = new WPDA_Message_Box(array(
267 'message_text' => __( 'Cannot drop MySQL database', 'wp-data-access' ),
268 'message_type' => 'error',
269 'message_is_dismissible' => false,
270 ));
271 $msg->box();
272 return;
273 }
274 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
275 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
276 if ( false === $wpdb->query( $wpdb->prepare( 'drop database `%1s`', array(WPDA::remove_backticks( $database )) ) ) ) {
277 // db call ok; no-cache ok.
278 $msg = new WPDA_Message_Box(array(
279 'message_text' => sprintf( __( 'Error dropping database `%s`', 'wp-data-access' ), esc_attr( $database ) ),
280 'message_type' => 'error',
281 'message_is_dismissible' => false,
282 ));
283 $msg->box();
284 } else {
285 $msg = new WPDA_Message_Box(array(
286 'message_text' => sprintf( __( 'Database `%s` dropped', 'wp-data-access' ), esc_attr( $database ) ),
287 ));
288 $msg->box();
289 $this->switch_schema_name = $wpdb->dbname;
290 }
291 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
292 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
293 }
294 }
295
296 private function edit_db() {
297 if ( !$this->check_wpnonce( 'wpda-edit-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnonceeditdb' ) ) {
298 return;
299 }
300 if ( !isset( $_REQUEST['edit_remote_database'] ) ) {
301 $msg = new WPDA_Message_Box(array(
302 'message_text' => __( 'Cannot update remote database connection [missing argument]', 'wp-data-access' ),
303 'message_type' => 'error',
304 'message_is_dismissible' => false,
305 ));
306 $msg->box();
307 return;
308 }
309 $database = sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_database'] ) );
310 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
311 $database_old = sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_database_old'] ) );
312 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
313 if ( $database !== $database_old ) {
314 // Update database connection name
315 if ( false === WPDADB::get_remote_database( $database_old ) ) {
316 $msg = new WPDA_Message_Box(array(
317 'message_text' => __( 'Cannot update remote database connection [remote database connection not found]', 'wp-data-access' ),
318 'message_type' => 'error',
319 'message_is_dismissible' => false,
320 ));
321 $msg->box();
322 return;
323 }
324 } else {
325 // Update database connection information
326 if ( false === WPDADB::get_remote_database( $database ) ) {
327 $msg = new WPDA_Message_Box(array(
328 'message_text' => __( 'Cannot update remote database connection [remote database connection not found]', 'wp-data-access' ),
329 'message_type' => 'error',
330 'message_is_dismissible' => false,
331 ));
332 $msg->box();
333 return;
334 }
335 }
336 $host = ( isset( $_REQUEST['edit_remote_host'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_host'] ) ) : '' );
337 $user = ( isset( $_REQUEST['edit_remote_user'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_user'] ) ) : '' );
338 // Cannot use sanitize_text_field on password field!
339 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
340 $passwd = ( isset( $_REQUEST['edit_remote_passwd'] ) ? wp_unslash( $_REQUEST['edit_remote_passwd'] ) : '' );
341 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
342 $port = ( isset( $_REQUEST['edit_remote_port'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_port'] ) ) : '' );
343 $schema = ( isset( $_REQUEST['edit_remote_schema'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_schema'] ) ) : '' );
344 $ssl = ( isset( $_REQUEST['edit_remote_ssl'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_ssl'] ) ) : 'off' );
345 $ssl_key = ( isset( $_REQUEST['edit_remote_client_key'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_client_key'] ) ) : '' );
346 $ssl_cert = ( isset( $_REQUEST['edit_remote_client_certificate'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_client_certificate'] ) ) : '' );
347 $ssl_ca = ( isset( $_REQUEST['edit_remote_ca_certificate'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_ca_certificate'] ) ) : '' );
348 $ssl_path = ( isset( $_REQUEST['edit_remote_certificate_path'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_certificate_path'] ) ) : '' );
349 $ssl_cipher = ( isset( $_REQUEST['edit_remote_specified_cipher'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['edit_remote_specified_cipher'] ) ) : '' );
350 if ( '' === $database || '' === $host || '' === $user || '' === $schema ) {
351 $msg = new WPDA_Message_Box(array(
352 'message_text' => __( 'Cannot edit remote database connection [missing arguments]', 'wp-data-access' ),
353 'message_type' => 'error',
354 'message_is_dismissible' => false,
355 ));
356 $msg->box();
357 return;
358 }
359 if ( !WPDADB::upd_remote_database(
360 $database,
361 $host,
362 $user,
363 $passwd,
364 $port,
365 $schema,
366 false,
367 $database_old,
368 $ssl,
369 $ssl_key,
370 $ssl_cert,
371 $ssl_ca,
372 $ssl_path,
373 $ssl_cipher
374 ) ) {
375 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
376 $msg = new WPDA_Message_Box(array(
377 'message_text' => sprintf( __( 'Cannot update remote database connection `%s`', 'wp-data-access' ), esc_attr( $database ) ),
378 'message_type' => 'error',
379 'message_is_dismissible' => false,
380 ));
381 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
382 $msg->box();
383 } else {
384 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
385 $msg = new WPDA_Message_Box(array(
386 'message_text' => sprintf( __( 'Remote database connection `%s` updated', 'wp-data-access' ), esc_attr( $database ) ),
387 ));
388 // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment
389 $msg->box();
390 if ( $database !== $database_old ) {
391 $this->switch_schema_name = $database;
392 }
393 }
394 }
395
396 private function check_wpnonce( $wp_nonce_action, $wp_nonce_arg ) {
397 $wp_nonce = ( isset( $_REQUEST[$wp_nonce_arg] ) ? sanitize_text_field( wp_unslash( $_REQUEST[$wp_nonce_arg] ) ) : '' );
398 // input var okay.
399 if ( !wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
400 $msg = new WPDA_Message_Box(array(
401 'message_text' => __( 'Not authorized', 'wp-data-access' ),
402 'message_type' => 'error',
403 'message_is_dismissible' => false,
404 ));
405 $msg->box();
406 return false;
407 }
408 return true;
409 }
410
411 public function show() {
412 if ( null !== $this->page ) {
413 $this->add_containers();
414 }
415 }
416
417 private function add_containers() {
418 ?>
419
420 <div id="wpda_manage_databases">
421 <div id="wpda_db_tabs">
422 <ul>
423 <li><a href="#wpda_tab-1">Manage Databases</a></li>
424 <li><a href="#wpda_tab-2">Create Remote Database Connection</a></li>
425 <li><a href="#wpda_tab-3">Create Local Database</a></li>
426 </ul>
427
428 <div class="container" id="wpda_tab-1">
429 <?php
430 $this->manage_databases();
431 ?>
432 </div>
433
434 <div class="container" id="wpda_tab-2">
435 <?php
436 $this->create_remote_database();
437 ?>
438 </div>
439
440 <div class="container" id="wpda_tab-3">
441 <?php
442 $this->create_local_database();
443 ?>
444 </div>
445 </div>
446
447 <div class="wpda_manage_databases_close">
448 <a href="javascript:void(0)"
449 onclick="jQuery('#wpda_manage_databases').hide()"><i
450 class="fas fa-xmark wpda_icon_on_button"></i>
451 </a>
452 </div>
453 </div>
454
455 <?php
456 $this->drop_database();
457 ?>
458 <?php
459 $this->toggle_database();
460 ?>
461
462 <?php
463 $this->js();
464 $this->css();
465 }
466
467 private function manage_databases() {
468 $tree = new WPDA_Tree();
469 $dbs = $tree->get_dbs( true );
470 $this->rdb = array();
471 $mdbs = array(
472 '' => '',
473 );
474 if ( isset( $dbs->data['data'] ) ) {
475 $dbs_list = $dbs->data['data'];
476 foreach ( $dbs_list as $db ) {
477 if ( 'local' === $db['dbs_type'] || 'remote' === $db['dbs_type'] ) {
478 // Admins can manage local and remote database only.
479 $mdbs[$db['dbs']] = $db['dbs_type'];
480 if ( 'remote' === $db['dbs_type'] ) {
481 // Store remote database info.
482 $this->rdb[$db['dbs']] = WPDADB::get_remote_database( $db['dbs'], true );
483 }
484 }
485 }
486 }
487 ?>
488
489 <h3 class="wpda_db_title">
490 <?php
491 esc_html_e( 'Manage Databases', 'wp-data-access' );
492 ?>
493 </h3>
494
495 <?php
496 if ( 1 === count( $mdbs ) ) {
497 $this->no_database();
498 } else {
499 $this->list_databases( $mdbs );
500 }
501 }
502
503 private function activate_pds() {
504 ?>
505 <div class="restyle_link">
506 <strong>NOTE</strong>
507 Please activate your Premium Data Services access <a href="options-general.php?page=wpdataaccess&tab=pds">here</a> to remotely connect to foreign DBMSs and remote files.
508 <a href="https://docs.remote.wpdataaccess.com/pds/remote-wizard.html" class="restyle_link" target="_blank">(read more...)</a>
509 </div>
510 <?php
511 }
512
513 private function no_database() {
514 esc_html_e( 'No manageable local databases or remote database connections found', 'wp-data-access' );
515 }
516
517 private function list_databases( $dbs ) {
518 ?>
519
520 <div class="wpda_manage_dbs">
521
522 <label for="edit_remote_database" class="database_item_label">Select database:</label>
523 <select id="manage_db_selection">
524 <?php
525 foreach ( $dbs as $db => $db_type ) {
526 echo '<option value="' . esc_attr( $db ) . '" data-type="' . esc_attr( $db_type ) . '">{$db}</option>';
527 }
528 ?>
529 </select>
530
531 <a id="manage_db_create_wp_user_access"
532 class="dashicons dashicons-admin-plugins wpda_tooltip"
533 style="display: none"
534 href="javascript:void(0)"
535 style="vertical-align:middle;"
536 title="<?php
537 esc_html_e( "Create function wpda_get_wp_user_id() to access the WordPress user ID from database views", 'wp-data-access' );
538 ?>"></a>
539
540 </div>
541
542 <?php
543 $this->edit_local_database();
544 $this->edit_remote_database();
545 }
546
547 private function edit_local_database() {
548 ?>
549
550 <div id="edit_local_database_form">
551 <label for="edit_local_database" class="database_item_label">Database name:</label>
552 <input type="text" name="edit_local_database" id="edit_local_database" readonly>
553 <a href="javascript:void(0)"
554 id="edit_local_database_action"
555 title="Drop Database"
556 class="button button-secondary wpda_tooltip"><i
557 class="fas fa-trash wpda_icon_on_button"></i></a>
558 </div>
559
560 <?php
561 }
562
563 private function edit_remote_database() {
564 ?>
565
566 <form method="post"
567 action="?page=<?php
568 echo esc_attr( $this->page );
569 ?>"
570 onsubmit="return editdb_validate_form();"
571 id="edit_remote_database_form"
572 >
573
574 <div>
575 <label for="edit_remote_database" class="database_item_label">Database name:</label>
576 <input type="text"
577 name="edit_remote_database"
578 id="edit_remote_database">
579 <input type="hidden"
580 name="edit_remote_database_old"
581 id="edit_remote_database_old">
582 <a href="javascript:void(0)"
583 id="disable_remote_database"
584 style="display: none"
585 title="Disable Remote Connection"
586 class="button button-secondary wpda_tooltip"><i
587 class="fas fa-ban wpda_icon_on_button"></i></a>
588 <a href="javascript:void(0)"
589 id="enable_remote_database"
590 style="display: none"
591 title="Enabled Remote Connection"
592 class="button button-secondary wpda_tooltip"><i
593 class="fas fa-check wpda_icon_on_button"></i></a>
594 <a href="javascript:void(0)"
595 id="remote_local_database_action"
596 title="Drop Database"
597 class="button button-secondary wpda_tooltip"><i
598 class="fas fa-trash wpda_icon_on_button"></i></a>
599 </div>
600
601 <div
602 id="remote_connection_is_disabled"
603 style="display: none"
604 >
605 <label class="database_item_label"></label>
606 <span style="color: red; line-height: 30px">
607 This remote database connection is currently disabled.
608 </span>
609 </div>
610
611 <div>
612 <label for="edit_remote_host" class="database_item_label">MySQL host:</label>
613 <input type="text"
614 name="edit_remote_host"
615 id="edit_remote_host">
616 </div>
617
618 <div>
619 <label for="edit_remote_user" class="database_item_label">MySQL username:</label>
620 <input type="text"
621 name="edit_remote_user"
622 id="edit_remote_user">
623 </div>
624
625 <div>
626 <label for="edit_remote_passwd" class="database_item_label">MySQL password:</label>
627 <input type="password"
628 name="edit_remote_passwd"
629 id="edit_remote_passwd"
630 autocomplete="new-password">
631 <i class="fas fa-eye"
632 onclick="wpda_toggle_password('edit_remote_passwd', event)"
633 style="cursor:pointer"></i>
634 </div>
635
636 <div>
637 <label for="edit_remote_port" class="database_item_label">MySQL port:</label>
638 <input type="text"
639 name="edit_remote_port"
640 id="edit_remote_port">
641 </div>
642
643 <div>
644 <label for="edit_remote_schema" class="database_item_label">MySQL schema:</label>
645 <input type="text"
646 name="edit_remote_schema"
647 id="edit_remote_schema">
648 </div>
649
650 <div class="wpda_db_ssl">
651 <label for="edit_remote_ssl" class="database_item_label">SSL:</label>
652 <input type="checkbox"
653 name="edit_remote_ssl"
654 id="edit_remote_ssl"
655 onclick="jQuery('#edit_remote_database_block_ssl').toggle()">
656 </div>
657
658 <div id="edit_remote_database_block_ssl">
659 <div>
660 <label for="edit_remote_client_key" class="database_item_label">Client key:</label>
661 <input type="text"
662 name="edit_remote_client_key"
663 id="edit_remote_client_key">
664 </div>
665
666 <div>
667 <label for="edit_remote_client_certificate" class="database_item_label">Client
668 certificate:</label>
669 <input type="text"
670 name="edit_remote_client_certificate"
671 id="edit_remote_client_certificate">
672 </div>
673
674 <div>
675 <label for="edit_remote_ca_certificate" class="database_item_label">CA certificate:</label>
676 <input type="text"
677 name="edit_remote_ca_certificate"
678 id="edit_remote_ca_certificate">
679 </div>
680
681 <div>
682 <label for="edit_remote_certificate_path" class="database_item_label">Certificate path:</label>
683 <input type="text"
684 name="edit_remote_certificate_path"
685 id="edit_remote_certificate_path">
686 </div>
687
688 <div>
689 <label for="edit_remote_specified_cipher" class="database_item_label">Specified Cipher:</label>
690 <input type="text"
691 name="edit_remote_specified_cipher"
692 id="edit_remote_specified_cipher">
693 </div>
694 </div>
695
696 <div>
697 <label class="database_item_label"></label>
698 <input type="button"
699 value="Test"
700 onclick="test_remote_connection('edit_'); return false;"
701 id="edit_remote_test_button"
702 class="button">
703 <input type="button"
704 value="Clear"
705 onclick="test_remote_clear('edit_'); return false;"
706 id="edit_remote_clear_button"
707 class="button">
708 </div>
709
710 <div id="edit_remote_database_block_test">
711 <div id="edit_remote_database_block_test_content"
712 class="remote_database_block_test_content"></div>
713 </div>
714
715 <input type="hidden" name="action" value="edit_db">
716 <?php
717 wp_nonce_field( 'wpda-edit-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnonceeditdb', false );
718 ?>
719
720 <?php
721 $this->buttons();
722 ?>
723
724 </form>
725
726 <?php
727 }
728
729 private function create_local_database() {
730 ?>
731
732 <h3 class="wpda_db_title">
733 <?php
734 esc_html_e( 'Create local database', 'wp-data-access' );
735 ?>
736 </h3>
737
738 <?php
739 if ( !$this->user_can_create_db ) {
740 esc_html_e( 'You are not authorized to create local databases', 'wp-data-access' );
741 } else {
742 ?>
743
744 <form method="post"
745 action="?page=<?php
746 echo esc_attr( $this->page );
747 ?>"
748 onsubmit="return createdb_validate_form_local();"
749 >
750
751 <div>
752 <label for="local_database" class="database_item_label">Database name:</label>
753 <input type="text" name="local_database" id="local_database">
754 </div>
755
756 <input type="hidden" name="action" value="create_db">
757 <input type="hidden" name="database_location" value="local">
758 <?php
759 wp_nonce_field( 'wpda-create-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnoncecreatedb', false );
760 ?>
761
762 <?php
763 $this->buttons();
764 ?>
765
766 </form>
767
768 <?php
769 }
770 }
771
772 private function create_remote_database() {
773 ?>
774
775 <form method="post" action="?page=<?php
776 echo esc_attr( $this->page );
777 ?>"
778 onsubmit="return createdb_validate_form_remote();">
779
780 <h3 class="wpda_db_title">
781 <?php
782 esc_html_e( 'Create remote database connection', 'wp-data-access' );
783 ?>
784 </h3>
785
786 <div>
787 <label for="remote_database"
788 class="database_item_label">Database name:</label>
789 <input type="text" name="remote_database" id="remote_database" value="rdb:">
790 </div>
791
792 <div>
793 <label for="remote_host" class="database_item_label">MySQL host:</label>
794 <input type="text" name="remote_host" id="remote_host">
795 </div>
796
797 <div>
798 <label for="remote_user" class="database_item_label">MySQL username:</label>
799 <input type="text" name="remote_user" id="remote_user">
800 </div>
801
802 <div>
803 <label for="remote_passwd" class="database_item_label">MySQL password:</label>
804 <input type="password" name="remote_passwd" id="remote_passwd" autocomplete="new-password">
805 <i class="fas fa-eye" onclick="wpda_toggle_password('remote_passwd', event)"
806 style="cursor:pointer"></i>
807 </div>
808
809 <div>
810 <label for="remote_port" class="database_item_label">MySQL port:</label>
811 <input type="text" name="remote_port" id="remote_port" value="3306">
812 </div>
813
814 <div>
815 <label for="remote_schema" class="database_item_label">MySQL schema:</label>
816 <input type="text" name="remote_schema" id="remote_schema">
817 </div>
818
819 <div class="wpda_db_ssl">
820 <label for="remote_ssl"
821 class="database_item_label">SSL:</label>
822 <input type="checkbox" name="remote_ssl" id="remote_ssl" unchecked
823 onclick="jQuery('#remote_database_block_ssl').toggle()">
824 </div>
825
826 <div id="remote_database_block_ssl">
827 <div>
828 <label for="remote_client_key" class="database_item_label">Client key:</label>
829 <input type="text" name="remote_client_key" id="remote_client_key">
830 </div>
831
832 <div>
833 <label for="remote_client_certificate" class="database_item_label">Client certificate:</label>
834 <input type="text" name="remote_client_certificate" id="remote_client_certificate">
835 </div>
836
837 <div>
838 <label for="remote_ca_certificate" class="database_item_label">CA certificate:</label>
839 <input type="text" name="remote_ca_certificate" id="remote_ca_certificate">
840 </div>
841
842 <div>
843 <label for="remote_certificate_path" class="database_item_label">Certificate path:</label>
844 <input type="text" name="remote_certificate_path" id="remote_certificate_path">
845 </div>
846
847 <div>
848 <label for="remote_specified_cipher" class="database_item_label">Specified Cipher:</label>
849 <input type="text" name="remote_specified_cipher" id="remote_specified_cipher">
850 </div>
851 </div>
852
853 <div>
854 <label class="database_item_label"></label>
855 <input type="button" value="Test" onclick="test_remote_connection(); return false;"
856 id="remote_test_button" class="button">
857 <input type="button" value="Clear" onclick="test_remote_clear(); return false;"
858 id="remote_clear_button" class="button" style="display:none;">
859 </div>
860
861 <div id="remote_database_block_test">
862 <div id="remote_database_block_test_content"
863 class="remote_database_block_test_content"></div>
864 </div>
865
866 <input type="hidden" name="action" value="create_db">
867 <input type="hidden" name="database_location" value="remote">
868 <?php
869 wp_nonce_field( 'wpda-create-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnoncecreatedb', false );
870 ?>
871
872 <?php
873 $this->buttons();
874 ?>
875
876 </form>
877
878 <?php
879 }
880
881 private function buttons() {
882 ?>
883
884 <div class="wpda_db_buttons">
885 <a href="javascript:void(0)"
886 onclick="jQuery(this).closest('form').submit()"
887 class="button button-primary"><i
888 class="fas fa-cloud-upload wpda_icon_on_button"></i> <?php
889 esc_html_e( 'Save', 'wp-data-access' );
890 ?>
891 </a>
892 <a href="javascript:void(0)"
893 onclick="jQuery('#wpda_manage_databases').hide()"
894 class="button button-secondary"><i
895 class="fas fa-times-circle wpda_icon_on_button"></i> <?php
896 esc_html_e( 'Cancel', 'wp-data-access' );
897 ?>
898 </a>
899 </div>
900
901 <?php
902 }
903
904 private function drop_database() {
905 ?>
906
907 <form id="wpda_form_drop_db"
908 method="post" action="?page=<?php
909 echo esc_attr( $this->page );
910 ?>"
911 >
912 <input type="hidden" name="database" id="drop_database">
913 <input type="hidden" name="action" value="drop_db">
914 <?php
915 wp_nonce_field( 'wpda-drop-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnoncedropdb', false );
916 ?>
917 </form>
918
919 <?php
920 }
921
922 private function toggle_database() {
923 ?>
924
925 <form id="wpda_form_toggle_db"
926 method="post" action="?page=<?php
927 echo esc_attr( $this->page );
928 ?>"
929 >
930 <input type="hidden" name="database" id="toggle_database">
931 <input type="hidden" name="action" value="toggle_db">
932 <input type="hidden" name="disabled" id="toggle_database_value">
933 <?php
934 wp_nonce_field( 'wpda-toggle-db-from-data-explorer-' . WPDA::get_current_user_login(), '_wpnoncetoggledb', false );
935 ?>
936 </form>
937
938 <?php
939 }
940
941 private function js() {
942 ?>
943
944 <script>
945 function editdb_validate_form() {
946 if (jQuery('#edit_remote_database').val() === '' || jQuery('#edit_remote_database').val() === 'rdb:') {
947 alert('Database name must be entered');
948 return false;
949 }
950
951 if (jQuery('#edit_remote_host').val() === '') {
952 alert('MySQL host must be entered');
953 return false;
954 }
955
956 if (jQuery('#edit_remote_user').val() === '') {
957 alert('MySQL username must be entered');
958 return false;
959 }
960
961 if (jQuery('#edit_remote_schema').val() === '') {
962 alert('MySQL schema must be entered');
963 return false;
964 }
965
966 return true;
967 }
968
969 function createdb_validate_form_remote() {
970 if (jQuery('#remote_database').val() === '' || jQuery('#remote_database').val() === 'rdb:') {
971 alert('Database name must be entered');
972 return false;
973 }
974
975 if (jQuery('#remote_host').val() === '') {
976 alert('MySQL host must be entered');
977 return false;
978 }
979
980 if (jQuery('#remote_user').val() === '') {
981 alert('MySQL username must be entered');
982 return false;
983 }
984
985 if (jQuery('#remote_schema').val() === '') {
986 alert('MySQL schema must be entered');
987 return false;
988 }
989
990 return true;
991 }
992
993 function createdb_validate_form_local() {
994 if (jQuery('#local_database').val() === '') {
995 alert('Database name must be entered');
996 return false;
997 }
998
999 return true;
1000 }
1001
1002 function test_remote_clear(mode = '') {
1003 jQuery('#' + mode + 'remote_database_block_test_content').html('');
1004 jQuery('#' + mode + 'remote_database_block_test').hide();
1005 jQuery('#' + mode + 'remote_clear_button').hide();
1006 }
1007
1008 function test_remote_connection(mode = '') {
1009 host = jQuery('#' + mode + 'remote_host').val();
1010 user = jQuery('#' + mode + 'remote_user').val();
1011 pass = jQuery('#' + mode + 'remote_passwd').val();
1012 port = jQuery('#' + mode + 'remote_port').val();
1013 dbs = jQuery('#' + mode + 'remote_schema').val();
1014 ssl = jQuery('#' + mode + 'remote_ssl').val();
1015 ssl_key = jQuery('#' + mode + 'remote_client_key').val();
1016 ssl_cert = jQuery('#' + mode + 'remote_client_certificate').val();
1017 ssl_ca = jQuery('#' + mode + 'remote_ca_certificate').val();
1018 ssl_path = jQuery('#' + mode + 'remote_certificate_path').val();
1019 ssl_cipher = jQuery('#' + mode + 'remote_specified_cipher').val();
1020
1021 url = '//' + window.location.host + window.location.pathname +
1022 '?action=wpda_check_remote_database_connection';
1023
1024 jQuery('#' + mode + 'remote_test_button').val('Testing...');
1025
1026 jQuery.ajax({
1027 method: 'POST',
1028 url: url,
1029 data: {
1030 host: host,
1031 user: user,
1032 passwd: pass,
1033 port: port,
1034 schema: dbs,
1035 ssl: ssl,
1036 ssl_key: ssl_key,
1037 ssl_cert: ssl_cert,
1038 ssl_ca: ssl_ca,
1039 ssl_path: ssl_path,
1040 ssl_cipher: ssl_cipher
1041 }
1042 }).done(
1043 function (msg) {
1044 jQuery('#' + mode + 'remote_database_block_test_content').html(msg);
1045 jQuery('#' + mode + 'remote_database_block_test').show();
1046 }
1047 ).fail(
1048 function () {
1049 jQuery('#' + mode + 'remote_database_block_test_content').html('Preparing connection...<br/>Establishing connection...<br/><br/><strong>Remote database connection invalid</strong>');
1050 jQuery('#' + mode + 'remote_database_block_test').show();
1051 }
1052 ).always(
1053 function () {
1054 jQuery('#' + mode + 'remote_test_button').val('Test');
1055 jQuery('#' + mode + 'remote_clear_button').show();
1056 }
1057 );
1058 }
1059
1060 jQuery(function () {
1061 jQuery('#database_location').on('change', function () {
1062 if (jQuery(this).val() === 'remote') {
1063 jQuery('#local_database_block').hide();
1064 jQuery('#remote_database_block').show();
1065 } else {
1066 jQuery('#remote_database_block').hide();
1067 jQuery('#local_database_block').show();
1068 }
1069 });
1070
1071 jQuery('#remote_database, #edit_remote_database').keydown(function () {
1072 var field = this;
1073 setTimeout(function () {
1074 if (field.value.indexOf('rdb:') !== 0) {
1075 jQuery(field).val('rdb:');
1076 }
1077 }, 1);
1078 });
1079
1080 jQuery('#wpda_db_tabs').tabs();
1081
1082 jQuery("#manage_db_selection").on('change', function () {
1083 const db_name = this.value;
1084 const db_type = jQuery("#manage_db_selection").find(':selected').data("type");
1085
1086 if (db_type === 'local') {
1087 jQuery("#edit_remote_database_form").hide();
1088 jQuery("#edit_local_database_form").show();
1089
1090 jQuery("#edit_local_database").val(db_name);
1091 } else {
1092 jQuery("#edit_local_database_form").hide();
1093 jQuery("#edit_remote_database_form").show();
1094
1095 if (wpda_rdb[db_name]) {
1096 // Load remote database info
1097 const rdb = wpda_rdb[db_name];
1098 jQuery("#edit_remote_database").val(db_name)
1099 jQuery("#edit_remote_database_old").val(db_name)
1100
1101 jQuery("#edit_remote_host").val(rdb.host)
1102 jQuery("#edit_remote_user").val(rdb.username)
1103 jQuery("#edit_remote_passwd").val(rdb.password)
1104 jQuery("#edit_remote_port").val(rdb.port)
1105 jQuery("#edit_remote_schema").val(rdb.database)
1106
1107 jQuery("#edit_remote_ssl").prop("checked", rdb.ssl === "on")
1108 jQuery("#edit_remote_client_key").val(rdb.ssl_key)
1109 jQuery("#edit_remote_client_certificate").val(rdb.ssl_cert)
1110 jQuery("#edit_remote_ca_certificate").val(rdb.ssl_ca)
1111 jQuery("#edit_remote_certificate_path").val(rdb.ssl_path)
1112 jQuery("#edit_remote_specified_cipher").val(rdb.ssl_cipher)
1113
1114 if (rdb.disabled === true) {
1115 jQuery("#enable_remote_database").show();
1116 jQuery("#disable_remote_database").hide();
1117 jQuery("#remote_connection_is_disabled").show();
1118 } else {
1119 jQuery("#disable_remote_database").show();
1120 jQuery("#enable_remote_database").hide();
1121 }
1122
1123 if (rdb.ssl === "on") {
1124 jQuery('#edit_remote_database_block_ssl').show();
1125 } else {
1126 jQuery('#edit_remote_database_block_ssl').hide();
1127 }
1128 } else {
1129 if (db_name !== "") {
1130 alert("Database not found");
1131 jQuery("#edit_remote_database_form").hide();
1132 } else {
1133 jQuery("#edit_remote_database_form").hide();
1134 jQuery("#edit_local_database_form").hide();
1135 }
1136 }
1137 }
1138
1139 if (db_name === '') {
1140 jQuery("#manage_db_create_wp_user_access").hide();
1141 } else {
1142 jQuery("#manage_db_create_wp_user_access").show();
1143 }
1144 })
1145
1146 jQuery("#manage_db_create_wp_user_access").on('click', function() {
1147 const selectedDatabase = jQuery("#manage_db_selection").val()
1148 wpda_dbinit_admin( selectedDatabase, '<?php
1149 echo esc_attr( wp_create_nonce( 'wpda_dbinit_admin_' . WPDA::get_current_user_login() ) );
1150 ?>' )
1151 })
1152
1153 jQuery("#edit_local_database_action").on('click', function () {
1154 if (confirm('Warning! All your tables and views will be deleted. This action cannot be undone! Are you sure you want to delete this database?')) {
1155 jQuery("#drop_database").val(jQuery("#edit_local_database").val())
1156 jQuery("#wpda_form_drop_db").submit();
1157 }
1158 })
1159
1160 jQuery("#remote_local_database_action").on('click', function () {
1161 if (confirm('Warning! All your tables and views will be deleted. This action cannot be undone! Are you sure you want to delete this database?')) {
1162 jQuery("#drop_database").val(jQuery("#edit_remote_database").val())
1163 jQuery("#wpda_form_drop_db").submit();
1164 }
1165 })
1166
1167 jQuery("#disable_remote_database").on('click', function() {
1168 if (confirm('Are you sure you want to disable this database?')) {
1169 jQuery("#toggle_database").val(jQuery("#edit_remote_database").val())
1170 jQuery("#toggle_database_value").val(true);
1171 jQuery("#wpda_form_toggle_db").submit();
1172 }
1173 })
1174
1175 jQuery("#enable_remote_database").on('click', function() {
1176 jQuery("#toggle_database").val(jQuery("#edit_remote_database").val())
1177 jQuery("#toggle_database_value").val(false);
1178 jQuery("#wpda_form_toggle_db").submit();
1179 })
1180 });
1181
1182 var wpda_rdb = <?php
1183 echo json_encode( $this->rdb );
1184 ?>;
1185 </script>
1186
1187 <?php
1188 }
1189
1190 private function css() {
1191 ?>
1192
1193 <style>
1194 #wpda_manage_databases {
1195 position: relative;
1196 display: none;
1197 padding: 24px;
1198 margin-bottom: 5px;
1199 border-radius: 4px;
1200 background-color: #fff;
1201 color: rgba(0, 0, 0, 0.87);
1202 -webkit-transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
1203 transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
1204 box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);
1205 }
1206
1207 #wpda_db_tabs {
1208 border: none;
1209 }
1210
1211 #wpda_db_tabs ul {
1212 background: none;
1213 border-top: none;
1214 border-right: none;
1215 border-left: none;
1216 border-radius: 0;
1217 }
1218
1219 #edit_remote_clear_button,
1220 #edit_remote_database_block_test,
1221 #wpda_form_drop_db,
1222 #remote_database_block_ssl,
1223 #remote_database_block_test,
1224 #edit_remote_database_form,
1225 #edit_local_database_form {
1226 display: none;
1227 }
1228
1229 #edit_remote_database_block_ssl,
1230 #remote_database_block_ssl {
1231 margin-bottom: 10px;
1232 }
1233
1234 #edit_remote_database_block_test,
1235 #remote_database_block_test {
1236 margin-top: 10px;
1237 }
1238
1239 .wpda_manage_dbs,
1240 .wpda_db_title {
1241 margin-bottom: 30px;
1242 }
1243
1244 .database_item_label {
1245 vertical-align: baseline;
1246 }
1247
1248 .wpda_db_ssl {
1249 margin-top: 10px;
1250 margin-bottom: 10px;
1251 }
1252
1253 .wpda_db_buttons {
1254 margin-top: 30px;
1255 }
1256 .wpda_manage_databases_close {
1257 position: absolute;
1258 top: 22px;
1259 right: 22px;
1260 z-index: 9999999;
1261 font-size: 1rem;
1262 }
1263
1264 .wpda_manage_databases_close .fas {
1265 color: rgb(60, 67, 74);
1266 }
1267
1268 .restyle_link a {
1269 color: #2271b1;
1270 text-decoration: none;
1271 font-weight: 700;
1272 }
1273
1274 #manage_db_create_wp_user_access:before {
1275 line-height: 28px;
1276 }
1277 </style>
1278
1279 <?php
1280 }
1281
1282 }
1283
1284 // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing