Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Laravel + Spatie Backup controller & views to see and manage DB backup files in the browser -- PLEASE DO NOT ASK FOR SUPPORT
<?php
namespace App\Http\Controllers;
use Alert;
use App\Http\Requests;
use Artisan;
use Log;
use Storage;
class BackupController extends Controller
{
public function index()
{
$disk = Storage::disk(config('laravel-backup.backup.destination.disks')[0]);
$files = $disk->files(config('laravel-backup.backup.name'));
$backups = [];
// make an array of backup files, with their filesize and creation date
foreach ($files as $k => $f) {
// only take the zip files into account
if (substr($f, -4) == '.zip' && $disk->exists($f)) {
$backups[] = [
'file_path' => $f,
'file_name' => str_replace(config('laravel-backup.backup.name') . '/', '', $f),
'file_size' => $disk->size($f),
'last_modified' => $disk->lastModified($f),
];
}
}
// reverse the backups, so the newest one would be on top
$backups = array_reverse($backups);
return view("backup.backups")->with(compact('backups'));
}
public function create()
{
try {
// start the backup process
Artisan::call('backup:run');
$output = Artisan::output();
// log the results
Log::info("Backpack\BackupManager -- new backup started from admin interface \r\n" . $output);
// return the results as a response to the ajax call
Alert::success('New backup created');
return redirect()->back();
} catch (Exception $e) {
Flash::error($e->getMessage());
return redirect()->back();
}
}
/**
* Downloads a backup zip file.
*
* TODO: make it work no matter the flysystem driver (S3 Bucket, etc).
*/
public function download($file_name)
{
$file = config('laravel-backup.backup.name') . '/' . $file_name;
$disk = Storage::disk(config('laravel-backup.backup.destination.disks')[0]);
if ($disk->exists($file)) {
$fs = Storage::disk(config('laravel-backup.backup.destination.disks')[0])->getDriver();
$stream = $fs->readStream($file);
return \Response::stream(function () use ($stream) {
fpassthru($stream);
}, 200, [
"Content-Type" => $fs->getMimetype($file),
"Content-Length" => $fs->getSize($file),
"Content-disposition" => "attachment; filename=\"" . basename($file) . "\"",
]);
} else {
abort(404, "The backup file doesn't exist.");
}
}
/**
* Deletes a backup file.
*/
public function delete($file_name)
{
$disk = Storage::disk(config('laravel-backup.backup.destination.disks')[0]);
if ($disk->exists(config('laravel-backup.backup.name') . '/' . $file_name)) {
$disk->delete(config('laravel-backup.backup.name') . '/' . $file_name);
return redirect()->back();
} else {
abort(404, "The backup file doesn't exist.");
}
}
}
@extends('layouts.default')
@section('content')
<h3>Administer Database Backups</h3>
<div class="row">
<div class="col-xs-12 clearfix">
<a id="create-new-backup-button" href="{{ url('backup/create') }}" class="btn btn-primary pull-right"
style="margin-bottom:2em;"><i
class="fa fa-plus"></i> Create New Backup
</a>
</div>
<div class="col-xs-12">
@if (count($backups))
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>File</th>
<th>Size</th>
<th>Date</th>
<th>Age</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach($backups as $backup)
<tr>
<td>{{ $backup['file_name'] }}</td>
<td>{{ humanFilesize($backup['file_size']) }}</td>
<td>
{{ formatTimeStamp($backup['last_modified'], 'F jS, Y, g:ia (T)') }}
</td>
<td>
{{ diffTimeStamp($backup['last_modified']) }}
</td>
<td class="text-right">
<a class="btn btn-xs btn-default"
href="{{ url('backup/download/'.$backup['file_name']) }}"><i
class="fa fa-cloud-download"></i> Download</a>
<a class="btn btn-xs btn-danger" data-button-type="delete"
href="{{ url('backup/delete/'.$backup['file_name']) }}"><i class="fa fa-trash-o"></i>
Delete</a>
</td>
</tr>
@endforeach
</tbody>
</table>
@else
<div class="well">
<h4>There are no backups</h4>
</div>
@endif
</div>
</div>
@endsection
// Backup routes
Route::get('backup', 'BackupController@index');
Route::get('backup/create', 'BackupController@create');
Route::get('backup/download/{file_name}', 'BackupController@download');
Route::get('backup/delete/{file_name}', 'BackupController@delete');
@willvincent

This comment has been minimized.

Copy link
Owner Author

commented Apr 12, 2017

A few notes

  • The controller assumes that Sweetalerts and the laracasts flash packages & facades are available for feedback on the manual creation of a backup.
  • view template assumes bootstrap is available
  • Routes should be placed in a group that applies adequate middleware protection so that only admin users can access the routes
@christiantigre

This comment has been minimized.

Copy link

commented Sep 2, 2017

error!!!!
php artisan backup:run --only-db
Starting backup...
Dumping database pcsolutions...
Backup failed because The dump process failed with exitcode 1 : General error :
"mysqldump" no se reconoce como un comando interno o externo,
programa o archivo por lotes ejecutable.
.
Backup completed!

@Midlord

This comment has been minimized.

Copy link

commented Nov 21, 2017

Hi sir. what is your code on laravel-backup.php?

@kikoseijo

This comment has been minimized.

Copy link

commented Feb 22, 2018

Excellent, saving others people times.
Thanks a lot"

@twf-nikhila

This comment has been minimized.

Copy link

commented Jun 5, 2018

Nice, Saved a lot of time with these codes. 👍

Thanks for sharing them

@elghomariayoub

This comment has been minimized.

Copy link

commented Jun 19, 2018

Call to undefined function humanFilesize() !!!
image

@banduongtincay

This comment has been minimized.

Copy link

commented Jul 23, 2018

in public function create(), commands Artisan::call('backup:run'); not end. help me!

@nasirkhan

This comment has been minimized.

Copy link

commented Jul 25, 2018

You need to add following helper function to show the human readable file size

function humanFilesize($size, $precision = 2) {
    $units = array('B','kB','MB','GB','TB','PB','EB','ZB','YB');
    $step = 1024;
    $i = 0;

    while (($size / $step) > 0.9) {
        $size = $size / $step;
        $i++;
    }
    
    return round($size, $precision).$units[$i];
}
@shahmir811

This comment has been minimized.

Copy link

commented Sep 23, 2018

backup is not working when call it from controller,
getting the following error:

Exception message: The dump process failed with exitcode 2 : Misuse of shell builtins : mysqldump: Got error: 2004: "Can't create TCP/IP socket (10106 "Unknown error")" when trying to connect

@kingfordCris

This comment has been minimized.

Copy link

commented Oct 13, 2018

There are no commands defined in the "backup" namespace.
how is this??

@faheemdad

This comment has been minimized.

Copy link

commented Feb 27, 2019

#[kingfordCris] how to solve There are no commands defined in the "backup" namespace. problem

@hideyatsu

This comment has been minimized.

Copy link

commented Jun 18, 2019

Call to undefined function humanFilesize() !!!
image

use Spatie\Backup\Helpers\Format;

Format::humanReadableSize($disk->size($f))

@denmaskevin

This comment has been minimized.

Copy link

commented Jul 22, 2019

Empty View

Screen Shot 2019-07-22 at 15 39 53
Screen Shot 2019-07-22 at 15 42 06

please help

@willvincent

This comment has been minimized.

Copy link
Owner Author

commented Jul 22, 2019

This is several years old. Likely much has changed with the spatie library, etc.. I'm not providing support on what amounts to an unmaintained hack that got this working for me several years ago.

I haven't used it since... Dig into the code and solve the problem, same as I had to do when I made this work initially. 🙂

@livevasiliy

This comment has been minimized.

Copy link

commented Jul 22, 2019

Hello @willvincent
Can you help me whats it's is function formatTimeStamp where from package.
I'm use spatie/laravel-backup v6

@willvincent

This comment has been minimized.

Copy link
Owner Author

commented Jul 22, 2019

Once again...

This is several years old. I'm not providing support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.