Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions database-admin-css.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.text-ok {
color: green;
}

/* -------------------------------------------------------------
DBManager Check Groups
------------------------------------------------------------- */
.dbmanager-check-group {
margin: 1em 0;
}

.dbmanager-check-group h3 {
margin: 0 0 .3em;
font-size: 1.2em;
}

/* Toggle button - Override WordPress defaults */
.dbmanager-check-group .dbmanager-toggle {
background: none;
border: none;
text-decoration: none;
outline: none;
padding: 0;
margin: 0;
cursor: pointer;
color: inherit;
font-size: inherit;
font-weight: normal;
line-height: 1.4;
width: auto;
display: inline;
}

/* Status colors */
.dbmanager-check-group .dbmanager-toggle.dbmanager-ok { color: green; }
.dbmanager-check-group .dbmanager-toggle.dbmanager-err { color: red; }

/* Content area */
.dbmanager-check-group .dbmanager-content {
margin-left: 0;
padding: 0;
display: none; /* Initially hidden */
}

.dbmanager-check-group .dbmanager-content p {
margin: .2em 0;
line-height: 1.4;
}

/* Details styling */
.dbmanager-details {
color: #666;
font-size: 0.9em;
margin-left: .4em;
}
150 changes: 131 additions & 19 deletions database-backup.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
### Variables Variables Variables
$base_name = plugin_basename('wp-dbmanager/database-manager.php');
$base_page = 'admin.php?page='.$base_name;
$return_page = 'admin.php?page=wp-dbmanager/database-manage.php';

$current_date = mysql2date(sprintf(__('%s @ %s', 'wp-dbmanager'), get_option('date_format'), get_option('time_format')), gmdate('Y-m-d H:i:s', current_time('timestamp')));
$backup = array();
$backup_options = get_option('dbmanager_options');
Expand Down Expand Up @@ -50,6 +52,7 @@
$backup['command'] = $brace . escapeshellcmd( $backup['mysqldumppath'] ) . $brace . ' --force --host=' . escapeshellarg( $backup['host'] ) . ' --user=' . escapeshellarg( DB_USER ) . ' --password=' . escapeshellarg( DB_PASSWORD ) . $backup['port'] . $backup['sock'] . $backup['charset'] . ' --add-drop-table --skip-lock-tables ' . DB_NAME . ' > ' . $brace . escapeshellcmd( $backup['filepath'] ) . $brace;
}
$error = execute_backup( $backup['command'] );

if ( ! is_writable( $backup['path'] ) ) {
$text = '<p style="color: red;">'.sprintf(__('Database Failed To Backup On \'%s\'. Backup Folder Not Writable.', 'wp-dbmanager'), $current_date).'</p>';
} elseif ( is_file( $backup['filepath'] ) && filesize( $backup['filepath'] ) === 0 ) {
Expand All @@ -59,9 +62,14 @@
} elseif ( $error ) {
$text = '<p style="color: red;">'.sprintf(__('Database Failed To Backup On \'%s\'.', 'wp-dbmanager'), $current_date).'</p>';
} else {
rename( $backup['filepath'], $backup['path'] . '/' . md5_file( $backup['filepath'] ) . '_-_' . $backup['filename'] );
$new_filepath = $backup['path'] . '/' . md5_file( $backup['filepath'] ) . '_-_' . $backup['filename'];
rename( $backup['filepath'], $new_filepath );
if (!empty($_POST['comment'])) {
file_put_contents("{$new_filepath}.txt",$_POST['comment']);
}
$text = '<p style="color: green;">'.sprintf(__('Database Backed Up Successfully On \'%s\'.', 'wp-dbmanager'), $current_date).'</p>';
}
header("Location: $return_page&info=" . base64_encode($text));
break;
}
}
Expand All @@ -73,65 +81,108 @@
### MYSQL Base Dir
$has_error = false;
$disabled_function = false;

### Detailed check status flags
$security_has_error = false;
$backup_has_error = false;
$phpfn_has_error = false;

/**
* Generate a collapsible check group header button
*
* @param string $title Group title (already translated)
* @param bool $hasError Whether group has errors
* @return string HTML for button
*
*/
function dbmanager_check_button($title, $hasError = false) {
$status = $hasError ? _e('Some tests failed', 'wp-dbmanager') : __('All OK', 'wp-dbmanager');
$class = $hasError ? 'dbmanager-err' : 'dbmanager-ok';
$expanded = $hasError ? 'true' : 'false';

// Exactly match your original inline structure
return '<button type="button"
class="dbmanager-toggle ' . $class . '"
role="button"
aria-expanded="' . $expanded . '">
' . $title . ' — ' . $status . '
<span class="dbmanager-details">(' . __('Click for details', 'wp-dbmanager') . ')</span>
</button>';
}
?>
<?php if( ! empty( $text ) ) { echo '<div id="message" class="updated">'.$text.'</div>'; } ?>
<!-- Checking Backup Status -->
<div class="wrap">
<h2><?php _e('Backup Database', 'wp-dbmanager'); ?></h2>
<h3><?php _e('Checking Security Status', 'wp-dbmanager'); ?></h3>
<p>
<div class="dbmanager-check-group" aria-expanded="false">
<h3>
<?php print dbmanager_check_button(__('Checking Security Status','wp-dbmanager'));?>
</h3>
<div class="dbmanager-content">
<!-- no changes in checking code -->
<?php
if( is_iis() ) {
if ( ! is_file( $backup_path . '/Web.config' ) ) {
echo '<p style="color: red;">' . sprintf( __( 'Web.config is missing from %s', 'wp-dbmanager' ), $backup_path ) . '</p>';
$has_error = true;
$security_has_error = true;
} else {
echo '<p style="color: green;">' . sprintf( __( 'Web.config is present in %s', 'wp-dbmanager' ), $backup_path ) . '</p>';
}
} else {
if( ! is_file( $backup_path . '/.htaccess' ) ) {
echo '<p style="color: red;">' . sprintf( __( '.htaccess is missing from %s', 'wp-dbmanager' ), $backup_path ) . '</p>';
$has_error = true;
$security_has_error = true;
} else {
echo '<p style="color: green;">' . sprintf( __( '.htaccess is present in %s', 'wp-dbmanager' ), $backup_path ) . '</p>';
}
}
if( ! is_file( $backup_path . '/index.php' ) ) {
echo '<p style="color: red;">' . sprintf( __( 'index.php is missing from %s', 'wp-dbmanager' ), $backup_path ) . '</p>';
$has_error = true;
$security_has_error = true;
} else {
echo '<p style="color: green;">' . sprintf( __( 'index.php is present in %s', 'wp-dbmanager' ), $backup_path ) . '</p>';
}
?>
</p>
<h3><?php _e('Checking Backup Status', 'wp-dbmanager'); ?></h3>
<p>
<!-- end of checking code -->
</div>
</div>

<div class="dbmanager-check-group" aria-expanded="false">
<h3>
<?php print dbmanager_check_button(__('Checking Backup Status','wp-dbmanager'));?>
</h3>
<div class="dbmanager-content">
<!-- no changes in checking code -->
<?php _e('Checking Backup Folder', 'wp-dbmanager'); ?> <span dir="ltr">(<strong><?php echo $backup_path; ?></strong>)</span> ...<br />
<?php
if( realpath( $backup_path ) === false ) {
echo '<p style="color: red;">' . sprintf( __( '%s is not a valid backup path', 'wp-dbmanager' ), $backup_path ) . '</p>';
$has_error = true;
$backup_has_error = true;
} else {
if ( @is_dir( $backup_path ) ) {
echo '<p style="color: green;">' . __('Backup folder exists', 'wp-dbmanager') . '</p>';
} else {
echo '<p style="color: red;">' . sprintf(__('Backup folder does NOT exist. Please create \'backup-db\' folder in \'%s\' folder and CHMOD it to \'777\' or change the location of the backup folder under DB Option.', 'wp-dbmanager'), WP_CONTENT_DIR) . '</p>';
$has_error = true;
$backup_has_error = true;
}
if ( @is_writable( $backup_path ) ) {
echo '<p style="color: green;">' . __('Backup folder is writable', 'wp-dbmanager') . '</p>';
} else {
echo '<p style="color: red;">' . __('Backup folder is NOT writable. Please CHMOD it to \'777\'.', 'wp-dbmanager') . '</p>';
$has_error = true;
$backup_has_error = true;
}
}
?>
</p>
<p>
<?php

if( dbmanager_is_valid_path( $backup['mysqldumppath'] ) === 0 ) {
echo '<p style="color: red;">' . sprintf( __( '%s is not a valid backup mysqldump path', 'wp-dbmanager' ), stripslashes( $backup['mysqldumppath'] ) ) . '</p>';
$has_error = true;
$backup_has_error = true;
} else {
if ( @file_exists( stripslashes( $backup['mysqldumppath'] ) ) ) {
echo __('Checking MYSQL Dump Path', 'wp-dbmanager') . ' <span dir="ltr">(<strong>' . stripslashes( $backup['mysqldumppath'] ) . '</strong>)</span> ...<br />';
Expand All @@ -140,15 +191,13 @@
echo __('Checking MYSQL Dump Path', 'wp-dbmanager') . ' ...<br />';
echo '<p style="color: red;">' . __('MYSQL dump path does NOT exist. Please check your mysqldump path under DB Options. If uncertain, contact your server administrator.', 'wp-dbmanager') . '</p>';
$has_error = true;
$backup_has_error = true;
}
}
?>
</p>
<p>
<?php
if( dbmanager_is_valid_path( $backup['mysqlpath'] ) === 0 ) {
echo '<p style="color: red;">' . sprintf( __( '%s is not a valid backup mysql path', 'wp-dbmanager' ), stripslashes( $backup['mysqlpath'] ) ) . '</p>';
$has_error = true;
$backup_has_error = true;
} else {
if ( @file_exists( stripslashes($backup['mysqlpath'] ) ) ) {
echo __('Checking MYSQL Path', 'wp-dbmanager') . ' <span dir="ltr">(<strong>' . stripslashes($backup['mysqlpath']) . '</strong>)</span> ...<br />';
Expand All @@ -157,42 +206,59 @@
echo __('Checking MYSQL Path', 'wp-dbmanager') . ' ...<br />';
echo '<p style="color: red;">' . __('MYSQL path does NOT exist. Please check your mysql path under DB Options. If uncertain, contact your server administrator.', 'wp-dbmanager') . '</p>';
$has_error = true;
$backup_has_error = true;
}
}
?>
</p>
<p>
<?php _e('Checking PHP Functions', 'wp-dbmanager'); ?> <span dir="ltr">(<strong>passthru()</strong>, <strong>system()</strong> <?php _e('and', 'wp-dbmanager'); ?> <strong>exec()</strong>)</span> ...<br />
<!-- end of checking code -->
</div>
</div>

<div class="dbmanager-check-group" aria-expanded="false">
<h3>
<?php print dbmanager_check_button(__('Checking PHP Functions','wp-dbmanager'));?>
</h3>
<div class="dbmanager-content">
<!-- no changes in checking code -->
<?php
if( dbmanager_is_function_disabled( 'passthru' ) ) {
echo '<p style="color: red;"><span dir="ltr">passthru()</span> '.__('disabled', 'wp-dbmanager').'.</p>';
$disabled_function = true;
$phpfn_has_error = true;
} else if( ! function_exists( 'passthru' ) ) {
echo '<p style="color: red;"><span dir="ltr">passthru()</span> '.__('missing', 'wp-dbmanager').'.</p>';
$disabled_function = true;
$phpfn_has_error = true;
} else {
echo '<p style="color: green;"><span dir="ltr">passthru()</span> '.__('enabled', 'wp-dbmanager').'.</p>';
}
if( dbmanager_is_function_disabled( 'system' ) ) {
echo '<p style="color: red;"><span dir="ltr">system()</span> '.__('disabled', 'wp-dbmanager').'.</p>';
$disabled_function = true;
$phpfn_has_error = true;
} else if( ! function_exists( 'system' ) ) {
echo '<p style="color: red;"><span dir="ltr">system()</span> '.__('missing', 'wp-dbmanager').'.</p>';
$disabled_function = true;
$phpfn_has_error = true;
} else {
echo '<p style="color: green;"><span dir="ltr">system()</span> '.__('enabled', 'wp-dbmanager').'.</p>';
}
if( dbmanager_is_function_disabled( 'exec' ) ) {
echo '<p style="color: red;"><span dir="ltr">exec()</span> '.__('disabled', 'wp-dbmanager').'.</p>';
$disabled_function = true;
$phpfn_has_error = true;
} else if( ! function_exists( 'exec' ) ) {
echo '<p style="color: red;"><span dir="ltr">exec()</span> '.__('missing', 'wp-dbmanager').'.</p>';
$disabled_function = true;
$phpfn_has_error = true;
} else {
echo '<p style="color: green;"><span dir="ltr">exec()</span> '.__('enabled', 'wp-dbmanager').'.</p>';
}
?>
</p>
<!-- end of checking code -->
</div>
</div>

<p>
<?php
if( $disabled_function ) {
Expand All @@ -206,6 +272,48 @@
</p>
<p><i><?php _e('Note: The checking of backup status is still undergoing testing, it may not be accurate.', 'wp-dbmanager'); ?></i></p>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Cache elements for better performance
const groups = document.querySelectorAll('.dbmanager-check-group');
const hasErrors = (content) => content.querySelectorAll('p[style*="color: red"]').length > 0;

// Update group status (reusable function)
const updateGroup = (group) => {
const content = group.querySelector('.dbmanager-content');
const toggle = group.querySelector('.dbmanager-toggle');
const hasErrorState = hasErrors(content);

// Update classes efficiently
toggle.className = `dbmanager-toggle ${hasErrorState ? 'dbmanager-err' : 'dbmanager-ok'}`;

// Update text content
const text = toggle.textContent;
toggle.textContent = text.replace('All OK', hasErrorState ? 'Some tests failed' : 'All OK');

// Set state and visibility
group.setAttribute('aria-expanded', hasErrorState ? 'true' : 'false');
content.style.display = hasErrorState ? 'block' : 'none';
};

// Initialize all groups
groups.forEach(updateGroup);

// Add click handlers efficiently using event delegation
document.addEventListener('click', (e) => {
const toggle = e.target.closest('.dbmanager-toggle');
if (!toggle) return;
e.preventDefault();
const group = toggle.closest('.dbmanager-check-group');
const content = group.querySelector('.dbmanager-content');
const isExpanded = group.getAttribute('aria-expanded') === 'true';

group.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
content.style.display = isExpanded ? 'none' : 'block';
});
});
</script>

<!-- Backup Database -->
<form method="post" action="<?php echo admin_url('admin.php?page='.plugin_basename(__FILE__)); ?>">
<?php wp_nonce_field('wp-dbmanager_backup'); ?>
Expand Down Expand Up @@ -245,7 +353,11 @@
</tr>
<tr>
<th><?php _e('GZIP Database Backup File?', 'wp-dbmanager'); ?></th>
<td><input type="radio" id="gzip-yes" name="gzip" value="1" />&nbsp;<label for="gzip-yes"><?php _e('Yes', 'wp-dbmanager'); ?></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio" id="gzip-no" name="gzip" value="0" checked="checked" />&nbsp;<label for="gzip-no"><?php _e('No', 'wp-dbmanager'); ?></label></td>
<td><input type="radio" id="gzip-yes" name="gzip" value="1" checked="checked" />&nbsp;<label for="gzip-yes"><?php _e('Yes', 'wp-dbmanager'); ?></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio" id="gzip-no" name="gzip" value="0" />&nbsp;<label for="gzip-no"><?php _e('No', 'wp-dbmanager'); ?></label></td>
</tr>
<tr>
<th><?php _e('Backup comment:', 'wp-dbmanager'); ?></th>
<td><input type="text" style="width: 100%" name="comment" value=""></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" name="do" value="<?php _e('Backup', 'wp-dbmanager'); ?>" class="button" />&nbsp;&nbsp;<input type="button" name="cancel" value="<?php _e('Cancel', 'wp-dbmanager'); ?>" class="button" onclick="javascript:history.go(-1)" /></td>
Expand Down
Loading