Skip to content

Instantly share code, notes, and snippets.

@kbcarte
Last active March 16, 2022 16:59
Show Gist options
  • Save kbcarte/fdc9115df282d0b4dd5765c42b9b1d04 to your computer and use it in GitHub Desktop.
Save kbcarte/fdc9115df282d0b4dd5765c42b9b1d04 to your computer and use it in GitHub Desktop.
WordPress wp-admin download db backup
<?php
/**
* Checks that the filename has correct extensions
*/
function validate_export( $filename ){
$ext = explode(".", $filename);
if( $ext[1] && $ext[1] != "sql" ){
return false;
}
if( $ext[2] && $ext[2] != "gz" ){
return false;
}
return true;
}
/**
* Create a backup of the db using wp-cli
* then delete the backup whether the user aborts or not
* Requires wp-cli
*/
function wpcli_export() {
if( isset($_POST["filename"]) && validate_export($_POST["filename"]) ) {
$file = ABSPATH . $_POST["filename"];
$out = shell_exec("wp --quiet --allow-root db export - | gzip > ". $file);
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Length: ' . filesize($file));
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
readfile($file);
ignore_user_abort(true);
// explicitly delete the file for both conditions
if (connection_aborted()) {
unlink($file);
}else {
unlink($file);
}
}else{
echo "<script>alert('Wrong filetype chosen for database export.');history.back();</script>";
}
exit();
}
/**
* Register custom menu pages
*/
function exportdb_menu_page() {
add_menu_page(
__( 'Export DB', 'textdomain' ),
'Export DB',
'manage_options',
'export_db',
'exportdb_page',
'dashicons-database-export',
6
);
// set domain to null to hide from admin menu
add_submenu_page(
null,
'Export Now',
'Export Now',
'manage_options',
'export-now',
'wpcli_export'
);
// use the first example from here to get the string to put after "load-"
// https://developer.wordpress.org/reference/hooks/load-page-php/#user-contributed-notes
add_action("load-admin_page_export-now", 'wpcli_export', 10, 1);
}
add_action( 'admin_menu', 'exportdb_menu_page' );
/**
* Export DB menu render callback
*/
function exportdb_page() { ?>
<style>
.hide-me {
display: none;
}
p {
font-size: 16px;
line-height: 1em;
margin: .5em 0;
}
form {
margin-top: 2em;
}
input {
width: 130px;
}
.col {
padding: 10px 0;
display: flex;
flex-direction: column;
}
/* Yoink: https://codepen.io/avstorm/pen/gofFm */
.btn {
width: 130px;
position: relative;
background: #000;
border: 0;
padding: 14px 42px;
border-radius: 3px;
cursor: pointer;
overflow: hidden;
outline: none;
font-weight: 400;
color: #fff;
letter-spacing: 0.2em;
box-shadow: 0 8px 32px rgba(0,0,0,0.2);
transition: all 0.2s ease;
}
.btn:after {
content: '';
position: absolute;
top: 0;
left: -200%;
width: 200%;
height: 100%;
transform: skewX(-20deg);
background-image: linear-gradient(to right, transparent, rgba(255,255,255,0.3), transparent);
}
.btn:hover:after {
animation: shine 1.6s ease;
}
.btn:active {
transform: translateY(1px);
box-shadow: 0 4px 16px rgba(0,0,0,0.2);
}
@-moz-keyframes shine {
100% {
left: 200%;
}
}
@-webkit-keyframes shine {
100% {
left: 200%;
}
}
@-o-keyframes shine {
100% {
left: 200%;
}
}
@keyframes shine {
100% {
left: 200%;
}
}
</style>
<h1>Export DB</h1>
<p>This will export a backup of the database with wp-cli, then compresses it using gzip.</p>
<p>After clicking <em>Export Now</em>, you will be prompeted to dowload the newly created backup.</p>
<p>This does not save a copy of the backup on the server.</p>
<p><a href="https://wp-cli.org/" target="_blank">wp-cli</a> is required on the server hosting this website.</p>
<form id="export-form" action="/wp-admin/admin.php?page=export-now" method="post">
<div class="col">
<p><em>.sql.gz</em> file extension is <strong>required</strong>.</p>
<div class="col">
<label for="filename">Save file name:</label>
<input id="fname" type="text" name="filename" value="backup.sql.gz" />
</div>
</div>
<div class="col">
<button id="sbmt" class="btn">Export</button>
</div>
</form>
<p id="err" class="hide-me" style="color:red;">Must be .sql.gz file</p>
<script>
const err = document.getElementById("err");
const sbmit = document.getElementById("submit");
sbmit.addEventListener("click", function() {
err.classList.add("hide-me");
});
const export_form = document.getElementById("export-form");
const btn = document.getElementById("sbmt");
btn.addEventListener("click", function(){
export_form.submit();
});
function validation(event) {
const fname = document.getElementById("fname").value.split('.');
if(fname[1] != "sql") {
err.classList.remove("hide-me");
event.preventDefault();
}
if(fname[2] != "gz") {
err.classList.remove("hide-me");
event.preventDefault();
}
return true;
}
export_form.addEventListener("submit", validation);
</script>
<?php }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment