Last active
October 15, 2023 18:01
-
-
Save kikoseijo/d4ec87a121cba7bcb6231bfa046be291 to your computer and use it in GitHub Desktop.
Laravel Spatie backup with controller routes and views
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers; | |
use Alert; | |
use Artisan; | |
use Carbon\Carbon; | |
use Log; | |
use Spatie\Backup\Helpers\Format; | |
use Storage; | |
class BackupController extends Controller | |
{ | |
public function __construct() | |
{ | |
$this->middleware('auth'); | |
} | |
public function index() | |
{ | |
$disk = Storage::disk(config('backup.backup.destination.disks')[0]); | |
$files = $disk->files(config('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('backup.backup.name') . '/', '', $f), | |
'file_size' => Format::humanReadableSize($disk->size($f)), | |
'last_modified' => Carbon::createFromTimestamp($disk->lastModified($f)), | |
]; | |
} | |
} | |
// reverse the backups, so the newest one would be on top | |
$backups = array_reverse($backups); | |
return view("admin.backups")->with(compact('backups')); | |
} | |
public function create() | |
{ | |
try { | |
// start the backup process | |
Artisan::call('backup:run', ['--only-db' => 'true']); | |
$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('backup.backup.name') . '/' . $file_name; | |
$disk = Storage::disk(config('backup.backup.destination.disks')[0]); | |
if ($disk->exists($file)) { | |
$fs = Storage::disk(config('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('backup.backup.destination.disks')[0]); | |
if ($disk->exists(config('backup.backup.name') . '/' . $file_name)) { | |
$disk->delete(config('backup.backup.name') . '/' . $file_name); | |
return redirect()->back(); | |
} else { | |
abort(404, "The backup file doesn't exist."); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@if (count($backups)) | |
<table class="table table-striped table-bordered"> | |
<thead class="thead-dark"> | |
<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>{{ $backup['file_size'] }}</td> | |
<td> | |
{{ date('d/M/Y, g:ia', strtotime($backup['last_modified'])) }} | |
</td> | |
<td> | |
{{ diff_date_for_humans($backup['last_modified']) }} | |
</td> | |
<td class="text-right"> | |
<a class="btn btn-primary" href="{{ url('backup/download/'.$backup['file_name']) }}"> | |
<i class="fas 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="fal fa-trash"></i> | |
Delete | |
</a> | |
</td> | |
</tr> | |
@endforeach | |
</tbody> | |
</table> | |
@else | |
<div class="text-center py-5"> | |
<h1 class="text-muted">No existen backups</h1> | |
</div> | |
@endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@extends('layouts.crud') | |
@section('content') | |
<div class="container -body-block pb-5"> | |
@card(['title' => 'Backups de la base de datos']) | |
@component('ui.menu-nav') | |
<li class="nav-item active mr-3"> | |
<a href="{{ url('backup/create') }}" class="nav-link text-primary" title="Crear nuevo backup"> | |
<i class="far fa-plus" aria-hidden="true"></i> Crear nuevo backup | |
</a> | |
</li> | |
@endcomponent | |
<div class="py-4"></div> | |
@include('admin.backups-table') | |
<div class="py-3"></div> | |
@endcard | |
</div> | |
@endsection |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="row"> | |
<div class="col"> | |
<div class="card"> | |
@isset($title) | |
<div class="card-header">{{$title}}</div> | |
@endisset | |
<div class="card-body"> | |
{{ $slot }} | |
</div> | |
</div> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="{{ config('app.locale') }}"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<meta name="csrf-token" content="{{ csrf_token() }}"> | |
<title>{{ config('app.name', 'Sunnyface.com') }}</title> | |
<link href="{{ asset('css/app.css') }}" rel="stylesheet"> | |
<script> | |
window.AppRootData = {!! json_encode([ | |
'csrfToken' => csrf_token(), | |
'state' => ['user' => Auth::user()] | |
]) !!}; | |
</script> | |
</head> | |
<body> | |
<div id="app" class="boxx-wrapper"> | |
@include('parts.header.admin') | |
<div class="album py-5 bg-light"> | |
@include('ui.errors') | |
@yield('content') | |
</div> | |
@include('parts.footer') | |
@stack('modals') | |
</div> | |
<!-- Scripts --> | |
@if (app()->isLocal()) | |
<script src="{{ mix('js/app.js') }}"></script> | |
@else | |
<script src="{{ mix('js/manifest.js') }}"></script> | |
<script src="{{ mix('js/vendor.js') }}"></script> | |
<script src="{{ mix('js/app.js') }}"></script> | |
@endif | |
@stack('scripts') | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Carbon\Carbon; | |
function diff_date_for_humans(Carbon $date) : string | |
{ | |
return (new Jenssegers\Date\Date($date->timestamp))->ago(); | |
} | |
function diff_string_for_humans($stringDate) : string | |
{ | |
$date = Jenssegers\Date\Date::createFromFormat('Y-m-d H:i:s', $stringDate); | |
return (new Jenssegers\Date\Date($date))->ago(); | |
} | |
function scannerTableLabel($stringDate) : string | |
{ | |
$now = Jenssegers\Date\Date::now(); | |
$date = Jenssegers\Date\Date::createFromFormat('Y-m-d H:i:s', $stringDate); | |
$printDate = (new Jenssegers\Date\Date($date))->ago(); | |
$color = $now > $date ? 'info' : 'danger'; | |
$res = '<span class="badge badge-'.$color.'" style="color:white;">SCANNER: '; | |
$res .= $printDate ; | |
$res .= '</span>'; | |
return $res; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); |
Hello Sir,
Thanks for your instruction and efforts you solved big problem of me, but there is some error for me this code is working for in local server but in Cpanel it give the following error
Connection could not be established with host "mailhog:1025": stream_socket_client(): php_network_getaddresses: getaddrinfo for mailhog failed: Name or service not known
Hi, Because its based on a plugin for backups from spatie, its trying to send you an email and this is the error you are getting i suppose.
use Spatie\Backup\Helpers\Format;
Check spatie plugin for further customization.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No está al completo, pero le falta lo mínimo.
Credits
Special thanks to supporters and clients that provide me with enough time to work on contributing to develop this packages for the WWW.
DevOps Web development
AppDev Mobile aplications
SocialApp Residents mobile application
KikoSeijo.com Freelance senior programmer