Browse Source

Added database backup manager feature

pull/4/head
Nafies Luthfi 9 years ago
parent
commit
c7e39f9c5b
  1. 30
      app/Helpers/helpers.php
  2. 84
      app/Http/Controllers/BackupsController.php
  3. 51
      app/Http/Requests/BackupUploadRequest.php
  4. 5
      composer.json
  5. 501
      composer.lock
  6. 3
      config/app.php
  7. 28
      resources/lang/id/backup.php
  8. 65
      resources/views/backups/forms.blade.php
  9. 54
      resources/views/backups/index.blade.php
  10. 8
      routes/web.php

30
app/Helpers/helpers.php

@ -30,3 +30,33 @@ function html_link_to_route($name, $title = null, $parameters = [], $attributes
return app('html')->decode(link_to_route($name, $title, $parameters, $attributes)); return app('html')->decode(link_to_route($name, $title, $parameters, $attributes));
} }
function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824)
{
$bytes = number_format($bytes / 1073741824, 2) . ' GB';
}
elseif ($bytes >= 1048576)
{
$bytes = number_format($bytes / 1048576, 2) . ' MB';
}
elseif ($bytes >= 1024)
{
$bytes = number_format($bytes / 1024, 2) . ' KB';
}
elseif ($bytes > 1)
{
$bytes = $bytes . ' bytes';
}
elseif ($bytes == 1)
{
$bytes = $bytes . ' byte';
}
else
{
$bytes = '0 bytes';
}
return $bytes;
}

84
app/Http/Controllers/BackupsController.php

@ -0,0 +1,84 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\BackupUploadRequest;
use BackupManager\Filesystems\Destination;
use BackupManager\Manager;
use Illuminate\Http\Request;
use League\Flysystem\FileExistsException;
use League\Flysystem\FileNotFoundException;
class BackupsController extends Controller
{
public function index(Request $request)
{
if (!file_exists(storage_path('app/backup/db'))) {
$backups = [];
} else {
$backups = \File::allFiles(storage_path('app/backup/db'));
// Sort files by modified time DESC
usort($backups, function($a, $b) {
return -1 * strcmp($a->getMTime(), $b->getMTime());
});
}
return view('backups.index',compact('backups'));
}
public function store(Request $request)
{
$this->validate($request, [
'file_name' => 'nullable|max:30|regex:/^[\w._-]+$/'
]);
try {
$manager = app()->make(Manager::class);
$fileName = $request->get('file_name') ?: date('Y-m-d_Hi');
$manager->makeBackup()->run('mysql', [
new Destination('local', 'backup/db/' . $fileName)
], 'gzip');
return redirect()->route('backups.index');
} catch (FileExistsException $e) {
return redirect()->route('backups.index');
}
}
public function destroy($fileName)
{
if (file_exists(storage_path('app/backup/db/') . $fileName)) {
unlink(storage_path('app/backup/db/') . $fileName);
}
return redirect()->route('backups.index');
}
public function download($fileName)
{
return response()->download(storage_path('app/backup/db/') . $fileName);
}
public function restore($fileName)
{
try {
$manager = app()->make(Manager::class);
$manager->makeRestore()->run('local', 'backup/db/' . $fileName, 'mysql', 'gzip');
} catch (FileNotFoundException $e) {}
return redirect()->route('backups.index');
}
public function upload(BackupUploadRequest $request)
{
$file = $request->file('backup_file');
if (file_exists(storage_path('app/backup/db/') . $file->getClientOriginalName()) == false) {
$file->storeAs('backup/db', $file->getClientOriginalName());
}
return redirect()->route('backups.index');
}
}

51
app/Http/Requests/BackupUploadRequest.php

@ -0,0 +1,51 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BackupUploadRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'backup_file' => 'required|sql_gz'
];
}
public function messages()
{
return [
'backup_file.sql_gz' => 'Invalid file type, must be <strong>.gz</strong> file',
];
}
protected function getValidatorInstance()
{
$validator = parent::getValidatorInstance();
$validator->addImplicitExtension('sql_gz', function($attribute, $value, $parameters) {
if ($value)
return $value->getClientOriginalExtension() == 'gz';
return false;
});
return $validator;
}
}

5
composer.json

@ -6,11 +6,14 @@
"type": "project", "type": "project",
"require": { "require": {
"php": ">=5.6.4", "php": ">=5.6.4",
"backup-manager/laravel": "^1.1",
"barryvdh/laravel-debugbar": "^2.0", "barryvdh/laravel-debugbar": "^2.0",
"barryvdh/laravel-dompdf": "^0.8.0",
"laracasts/flash": "~2", "laracasts/flash": "~2",
"laravel/browser-kit-testing": "^1.0", "laravel/browser-kit-testing": "^1.0",
"laravel/framework": "5.4.*", "laravel/framework": "5.4.*",
"luthfi/formfield": "0.1.5"
"league/flysystem": "^1.0",
"luthfi/formfield": "^0.1"
}, },
"require-dev": { "require-dev": {
"fzaninotto/faker": "~1.4", "fzaninotto/faker": "~1.4",

501
composer.lock

@ -4,9 +4,131 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "9f299db76f1c1ca4e041bd599519ac10",
"content-hash": "4e41f9e6740a63973ee0ead4612a612e",
"packages": [ "packages": [
{ {
"name": "backup-manager/backup-manager",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/backup-manager/backup-manager.git",
"reference": "9e53714a993135f57fe2bff001203b6f75c2387c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/backup-manager/backup-manager/zipball/9e53714a993135f57fe2bff001203b6f75c2387c",
"reference": "9e53714a993135f57fe2bff001203b6f75c2387c",
"shasum": ""
},
"require": {
"league/flysystem": "~1.0",
"php": ">=5.5.9",
"symfony/process": "~2.1|~3.0"
},
"require-dev": {
"aws/aws-sdk-php": "~3.0",
"dropbox/dropbox-sdk": "~1.1",
"league/flysystem-aws-s3-v3": "~1.0",
"league/flysystem-dropbox": "~1.0",
"league/flysystem-rackspace": "~1.0",
"league/flysystem-sftp": "~1.0",
"mockery/mockery": "~0.9",
"phpspec/phpspec": "~2.1",
"satooshi/php-coveralls": "~0.6"
},
"suggest": {
"league/flysystem-aws-s3-v3": "AwsS3 and GoogleCS adapter support.",
"league/flysystem-dropbox": "Dropbox adapter support.",
"league/flysystem-rackspace": "Rackspace adapter support.",
"league/flysystem-sftp": "Sftp adapter support."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"BackupManager\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Shawn McCool",
"email": "shawn@heybigname.com",
"homepage": "http://heybigname.com/"
},
{
"name": "Mitchell van Wijngaarden",
"email": "mitchell@kooding.nl",
"homepage": "http://heybigname.com/"
}
],
"description": "A framework agnostic database backup manager with user-definable procedures and support for S3, Dropbox, FTP, SFTP, and more with drivers for popular frameworks.",
"time": "2017-01-05T12:10:13+00:00"
},
{
"name": "backup-manager/laravel",
"version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/backup-manager/laravel.git",
"reference": "a94b98cd3033c8e5c5958dc3640bf05b0f2df636"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/backup-manager/laravel/zipball/a94b98cd3033c8e5c5958dc3640bf05b0f2df636",
"reference": "a94b98cd3033c8e5c5958dc3640bf05b0f2df636",
"shasum": ""
},
"require": {
"backup-manager/backup-manager": "^1.0",
"illuminate/console": "^4.0||^5.0",
"illuminate/container": "^4.0||^5.0",
"illuminate/support": "^4.0||^5.0",
"php": ">=5.5.0",
"symfony/process": "^2.0||^3.0"
},
"require-dev": {
"mockery/mockery": "dev-master",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"BackupManager\\Laravel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Shawn McCool",
"email": "shawn@heybigname.com",
"homepage": "http://heybigname.com/"
},
{
"name": "Mitchell van Wijngaarden",
"email": "mitchell@kooding.nl",
"homepage": "http://heybigname.com/"
}
],
"description": "Database backup manager seamlessly integrated with Laravel 4 or 5 with user-definable procedures and support for S3, Dropbox, FTP, SFTP, and more.",
"time": "2016-11-15T11:11:05+00:00"
},
{
"name": "barryvdh/laravel-debugbar", "name": "barryvdh/laravel-debugbar",
"version": "v2.3.2", "version": "v2.3.2",
"source": { "source": {
@ -61,6 +183,54 @@
"time": "2017-01-19T08:19:49+00:00" "time": "2017-01-19T08:19:49+00:00"
}, },
{ {
"name": "barryvdh/laravel-dompdf",
"version": "v0.8.0",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-dompdf.git",
"reference": "22ee9cb8e0ac0d5f11633d1194280ab40b2bba1f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/22ee9cb8e0ac0d5f11633d1194280ab40b2bba1f",
"reference": "22ee9cb8e0ac0d5f11633d1194280ab40b2bba1f",
"shasum": ""
},
"require": {
"dompdf/dompdf": "^0.8",
"illuminate/support": "5.1.x|5.2.x|5.3.x|5.4.x",
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.8-dev"
}
},
"autoload": {
"psr-4": {
"Barryvdh\\DomPDF\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "A DOMPDF Wrapper for Laravel",
"keywords": [
"dompdf",
"laravel",
"pdf"
],
"time": "2017-02-19T06:45:54+00:00"
},
{
"name": "doctrine/inflector", "name": "doctrine/inflector",
"version": "v1.1.0", "version": "v1.1.0",
"source": { "source": {
@ -128,6 +298,68 @@
"time": "2015-11-06T14:35:42+00:00" "time": "2015-11-06T14:35:42+00:00"
}, },
{ {
"name": "dompdf/dompdf",
"version": "v0.8.0",
"source": {
"type": "git",
"url": "https://github.com/dompdf/dompdf.git",
"reference": "0f418c6b58fdeafc2a0e80eb1fa5e644e185089c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/0f418c6b58fdeafc2a0e80eb1fa5e644e185089c",
"reference": "0f418c6b58fdeafc2a0e80eb1fa5e644e185089c",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-gd": "*",
"ext-mbstring": "*",
"phenx/php-font-lib": "0.5.*",
"phenx/php-svg-lib": "0.2.*",
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.8.*",
"squizlabs/php_codesniffer": "2.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-develop": "0.7-dev"
}
},
"autoload": {
"psr-4": {
"Dompdf\\": "src/"
},
"classmap": [
"lib/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Fabien Ménager",
"email": "fabien.menager@gmail.com"
},
{
"name": "Brian Sweeney",
"email": "eclecticgeek@gmail.com"
},
{
"name": "Gabriel Bull",
"email": "me@gabrielbull.com"
}
],
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
"homepage": "https://github.com/dompdf/dompdf",
"time": "2017-02-16T02:40:40+00:00"
},
{
"name": "erusev/parsedown", "name": "erusev/parsedown",
"version": "1.6.2", "version": "1.6.2",
"source": { "source": {
@ -261,16 +493,16 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v5.4.19",
"version": "v5.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "02444b7450350db17a7607c8a52f7268ebdb0dad"
"reference": "2ed668f96d1a6ca42f50d5c87ee9ceecfc0a6eee"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/02444b7450350db17a7607c8a52f7268ebdb0dad",
"reference": "02444b7450350db17a7607c8a52f7268ebdb0dad",
"url": "https://api.github.com/repos/laravel/framework/zipball/2ed668f96d1a6ca42f50d5c87ee9ceecfc0a6eee",
"reference": "2ed668f96d1a6ca42f50d5c87ee9ceecfc0a6eee",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -386,7 +618,7 @@
"framework", "framework",
"laravel" "laravel"
], ],
"time": "2017-04-16T13:33:34+00:00"
"time": "2017-04-28T15:40:01+00:00"
}, },
{ {
"name": "laravelcollective/html", "name": "laravelcollective/html",
@ -444,16 +676,16 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.0.39",
"version": "1.0.40",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "2474325ee924134bb05848663b12531f6f2e9fbe"
"reference": "3828f0b24e2c1918bb362d57a53205d6dc8fde61"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2474325ee924134bb05848663b12531f6f2e9fbe",
"reference": "2474325ee924134bb05848663b12531f6f2e9fbe",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3828f0b24e2c1918bb362d57a53205d6dc8fde61",
"reference": "3828f0b24e2c1918bb362d57a53205d6dc8fde61",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -523,7 +755,7 @@
"sftp", "sftp",
"storage" "storage"
], ],
"time": "2017-04-25T15:24:43+00:00"
"time": "2017-04-28T10:15:08+00:00"
}, },
{ {
"name": "luthfi/formfield", "name": "luthfi/formfield",
@ -850,6 +1082,80 @@
"time": "2017-03-13T16:27:32+00:00" "time": "2017-03-13T16:27:32+00:00"
}, },
{ {
"name": "phenx/php-font-lib",
"version": "0.5",
"source": {
"type": "git",
"url": "https://github.com/PhenX/php-font-lib.git",
"reference": "19ad2bebc35be028fcc0221025fcbf3d436a3962"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PhenX/php-font-lib/zipball/19ad2bebc35be028fcc0221025fcbf3d436a3962",
"reference": "19ad2bebc35be028fcc0221025fcbf3d436a3962",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "^4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"FontLib\\": "src/FontLib"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Fabien Ménager",
"email": "fabien.menager@gmail.com"
}
],
"description": "A library to read, parse, export and make subsets of different types of font files.",
"homepage": "https://github.com/PhenX/php-font-lib",
"time": "2017-02-11T10:58:43+00:00"
},
{
"name": "phenx/php-svg-lib",
"version": "v0.2",
"source": {
"type": "git",
"url": "https://github.com/PhenX/php-svg-lib.git",
"reference": "de291bec8449b89acfe85691b5c71434797959dc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PhenX/php-svg-lib/zipball/de291bec8449b89acfe85691b5c71434797959dc",
"reference": "de291bec8449b89acfe85691b5c71434797959dc",
"shasum": ""
},
"require": {
"sabberworm/php-css-parser": "6.0.*"
},
"type": "library",
"autoload": {
"psr-0": {
"Svg\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Fabien Ménager",
"email": "fabien.menager@gmail.com"
}
],
"description": "A library to read, parse and export to PDF SVG files.",
"homepage": "https://github.com/PhenX/php-svg-lib",
"time": "2016-12-13T20:25:45+00:00"
},
{
"name": "psr/log", "name": "psr/log",
"version": "1.0.2", "version": "1.0.2",
"source": { "source": {
@ -979,6 +1285,47 @@
"time": "2017-03-26T20:37:53+00:00" "time": "2017-03-26T20:37:53+00:00"
}, },
{ {
"name": "sabberworm/php-css-parser",
"version": "6.0.1",
"source": {
"type": "git",
"url": "https://github.com/sabberworm/PHP-CSS-Parser.git",
"reference": "9ea4b00c569b19f731d0c2e0e802055877ff40c2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/9ea4b00c569b19f731d0c2e0e802055877ff40c2",
"reference": "9ea4b00c569b19f731d0c2e0e802055877ff40c2",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"type": "library",
"autoload": {
"psr-0": {
"Sabberworm\\CSS": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Raphael Schweikert"
}
],
"description": "Parser for CSS Files written in PHP",
"homepage": "http://www.sabberworm.com/blog/2010/6/10/php-css-parser",
"keywords": [
"css",
"parser",
"stylesheet"
],
"time": "2015-08-24T08:48:52+00:00"
},
{
"name": "swiftmailer/swiftmailer", "name": "swiftmailer/swiftmailer",
"version": "v5.4.7", "version": "v5.4.7",
"source": { "source": {
@ -1034,16 +1381,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "c30243cc51f726812be3551316b109a2f5deaf8d"
"reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/c30243cc51f726812be3551316b109a2f5deaf8d",
"reference": "c30243cc51f726812be3551316b109a2f5deaf8d",
"url": "https://api.github.com/repos/symfony/console/zipball/a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38",
"reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1093,20 +1440,20 @@
], ],
"description": "Symfony Console Component", "description": "Symfony Console Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-04T14:33:42+00:00"
"time": "2017-04-26T01:39:17+00:00"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/css-selector.git", "url": "https://github.com/symfony/css-selector.git",
"reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c"
"reference": "02983c144038e697c959e6b06ef6666de759ccbc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/a48f13dc83c168f1253a5d2a5a4fb46c36244c4c",
"reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/02983c144038e697c959e6b06ef6666de759ccbc",
"reference": "02983c144038e697c959e6b06ef6666de759ccbc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1146,20 +1493,20 @@
], ],
"description": "Symfony CssSelector Component", "description": "Symfony CssSelector Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-02-21T09:12:04+00:00"
"time": "2017-05-01T14:55:58+00:00"
}, },
{ {
"name": "symfony/debug", "name": "symfony/debug",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/debug.git", "url": "https://github.com/symfony/debug.git",
"reference": "56f613406446a4a0a031475cfd0a01751de22659"
"reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/56f613406446a4a0a031475cfd0a01751de22659",
"reference": "56f613406446a4a0a031475cfd0a01751de22659",
"url": "https://api.github.com/repos/symfony/debug/zipball/fd6eeee656a5a7b384d56f1072243fe1c0e81686",
"reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1203,20 +1550,20 @@
], ],
"description": "Symfony Debug Component", "description": "Symfony Debug Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-03-28T21:38:24+00:00"
"time": "2017-04-19T20:17:50+00:00"
}, },
{ {
"name": "symfony/dom-crawler", "name": "symfony/dom-crawler",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dom-crawler.git", "url": "https://github.com/symfony/dom-crawler.git",
"reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee"
"reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/403944e294cf4ceb3b8447f54cbad88ea7b99cee",
"reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/f1ad34e8af09ed17570e027cf0c58a12eddec286",
"reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1259,20 +1606,20 @@
], ],
"description": "Symfony DomCrawler Component", "description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-02-21T09:12:04+00:00"
"time": "2017-04-12T14:13:17+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "154bb1ef7b0e42ccc792bd53edbce18ed73440ca"
"reference": "b8a401f733b43251e1d088c589368b2a94155e40"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/154bb1ef7b0e42ccc792bd53edbce18ed73440ca",
"reference": "154bb1ef7b0e42ccc792bd53edbce18ed73440ca",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b8a401f733b43251e1d088c589368b2a94155e40",
"reference": "b8a401f733b43251e1d088c589368b2a94155e40",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1319,20 +1666,20 @@
], ],
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-04T07:26:27+00:00"
"time": "2017-05-01T14:58:48+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "b20900ce5ea164cd9314af52725b0bb5a758217a"
"reference": "9cf076f8f492f4b1ffac40aae9c2d287b4ca6930"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/b20900ce5ea164cd9314af52725b0bb5a758217a",
"reference": "b20900ce5ea164cd9314af52725b0bb5a758217a",
"url": "https://api.github.com/repos/symfony/finder/zipball/9cf076f8f492f4b1ffac40aae9c2d287b4ca6930",
"reference": "9cf076f8f492f4b1ffac40aae9c2d287b4ca6930",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1368,20 +1715,20 @@
], ],
"description": "Symfony Finder Component", "description": "Symfony Finder Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-03-20T09:32:19+00:00"
"time": "2017-04-12T14:13:17+00:00"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "cb0b6418f588952c9290b3df4ca650f1b7ab570a"
"reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/cb0b6418f588952c9290b3df4ca650f1b7ab570a",
"reference": "cb0b6418f588952c9290b3df4ca650f1b7ab570a",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/9de6add7f731e5af7f5b2e9c0da365e43383ebef",
"reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1421,20 +1768,20 @@
], ],
"description": "Symfony HttpFoundation Component", "description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-04T15:30:56+00:00"
"time": "2017-05-01T14:55:58+00:00"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "8285ab5faf1306b1a5ebcf287fe91c231a6de88e"
"reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/8285ab5faf1306b1a5ebcf287fe91c231a6de88e",
"reference": "8285ab5faf1306b1a5ebcf287fe91c231a6de88e",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/46e8b209abab55c072c47d72d5cd1d62c0585e05",
"reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1503,7 +1850,7 @@
], ],
"description": "Symfony HttpKernel Component", "description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-05T12:52:03+00:00"
"time": "2017-05-01T17:46:48+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
@ -1566,16 +1913,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282"
"reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/57fdaa55827ae14d617550ebe71a820f0a5e2282",
"reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282",
"url": "https://api.github.com/repos/symfony/process/zipball/999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
"reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1611,20 +1958,20 @@
], ],
"description": "Symfony Process Component", "description": "Symfony Process Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-03-27T18:07:02+00:00"
"time": "2017-04-12T14:13:17+00:00"
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/routing.git", "url": "https://github.com/symfony/routing.git",
"reference": "d6605f9a5767bc5bc4895e1c762ba93964608aee"
"reference": "5029745d6d463585e8b487dbc83d6333f408853a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/d6605f9a5767bc5bc4895e1c762ba93964608aee",
"reference": "d6605f9a5767bc5bc4895e1c762ba93964608aee",
"url": "https://api.github.com/repos/symfony/routing/zipball/5029745d6d463585e8b487dbc83d6333f408853a",
"reference": "5029745d6d463585e8b487dbc83d6333f408853a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1686,20 +2033,20 @@
"uri", "uri",
"url" "url"
], ],
"time": "2017-03-02T15:58:09+00:00"
"time": "2017-04-12T14:13:17+00:00"
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "c740eee70783d2af4d3d6b70d5146f209e6b4d13"
"reference": "f4a04d2df710f81515df576b2de06bdeee518b83"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/c740eee70783d2af4d3d6b70d5146f209e6b4d13",
"reference": "c740eee70783d2af4d3d6b70d5146f209e6b4d13",
"url": "https://api.github.com/repos/symfony/translation/zipball/f4a04d2df710f81515df576b2de06bdeee518b83",
"reference": "f4a04d2df710f81515df576b2de06bdeee518b83",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1750,20 +2097,20 @@
], ],
"description": "Symfony Translation Component", "description": "Symfony Translation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-03-21T21:44:32+00:00"
"time": "2017-04-12T14:13:17+00:00"
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "81dce20f69a8b40427e1f4e6462178df87cafc03"
"reference": "fa47963ac7979ddbd42b2d646d1b056bddbf7bb8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/81dce20f69a8b40427e1f4e6462178df87cafc03",
"reference": "81dce20f69a8b40427e1f4e6462178df87cafc03",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/fa47963ac7979ddbd42b2d646d1b056bddbf7bb8",
"reference": "fa47963ac7979ddbd42b2d646d1b056bddbf7bb8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1774,9 +2121,11 @@
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
}, },
"require-dev": { "require-dev": {
"ext-iconv": "*",
"twig/twig": "~1.20|~2.0" "twig/twig": "~1.20|~2.0"
}, },
"suggest": { "suggest": {
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
"ext-symfony_debug": "" "ext-symfony_debug": ""
}, },
"type": "library", "type": "library",
@ -1816,7 +2165,7 @@
"debug", "debug",
"dump" "dump"
], ],
"time": "2017-03-12T16:07:05+00:00"
"time": "2017-05-01T14:55:58+00:00"
}, },
{ {
"name": "tijsverkoyen/css-to-inline-styles", "name": "tijsverkoyen/css-to-inline-styles",
@ -3285,16 +3634,16 @@
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v3.2.7",
"version": "v3.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/yaml.git", "url": "https://github.com/symfony/yaml.git",
"reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621"
"reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/62b4cdb99d52cb1ff253c465eb1532a80cebb621",
"reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621",
"url": "https://api.github.com/repos/symfony/yaml/zipball/acec26fcf7f3031e094e910b94b002fa53d4e4d6",
"reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3336,7 +3685,7 @@
], ],
"description": "Symfony Yaml Component", "description": "Symfony Yaml Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-03-20T09:45:15+00:00"
"time": "2017-05-01T14:55:58+00:00"
}, },
{ {
"name": "webmozart/assert", "name": "webmozart/assert",

3
config/app.php

@ -166,9 +166,10 @@ return [
/* /*
* Package Service Providers... * Package Service Providers...
*/ */
Luthfi\FormField\FormFieldServiceProvider::class,
BackupManager\Laravel\Laravel5ServiceProvider::class,
Barryvdh\Debugbar\ServiceProvider::class, Barryvdh\Debugbar\ServiceProvider::class,
Laracasts\Flash\FlashServiceProvider::class, Laracasts\Flash\FlashServiceProvider::class,
Luthfi\FormField\FormFieldServiceProvider::class,
/* /*
* Application Service Providers... * Application Service Providers...

28
resources/lang/id/backup.php

@ -0,0 +1,28 @@
<?php
return [
// Labels
'index_title' => 'Database Backup Manager',
'list' => 'Backup File List',
// Actions
'create' => 'Create Backup File',
'file_name' => 'File Name',
'file_size' => 'File Size',
'created_at' => 'Created at',
'actions' => 'Actions',
'delete' => 'Delete',
'delete_title' => 'Delete this backup file',
'sure_to_delete_file' => 'Are you sure to delete this file <strong>":filename"</strong>?',
'cancel_delete' => 'Cancel Delete',
'confirm_delete' => 'YES, please delete this file!',
'empty' => 'No backup file available.',
'download' => 'Download',
'download_title' => 'Download this file',
'restore' => 'Restore',
'restore_title' => 'Restore database from file',
'sure_to_restore' => 'Are you sure to restore database with this backup file "<strong>:filename</strong>"? <br><br>Please make sure your <strong>current database has been backed up</strong>.',
'cancel_restore' => 'Cancel Restore',
'confirm_restore' => 'YES, Restore Database!',
'upload' => 'Upload Backup File',
];

65
resources/views/backups/forms.blade.php

@ -0,0 +1,65 @@
@if (Request::get('action') == 'delete' && Request::has('file_name'))
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">{{ trans('backup.delete') }}</h3>
</div>
<div class="panel-body">
<p>{!! trans('backup.sure_to_delete_file', ['filename' => Request::get('file_name')]) !!}</p>
</div>
<div class="panel-footer">
<a href="{{ route('backups.index') }}" class="btn btn-default">{{ trans('backup.cancel_delete') }}</a>
<form action="{{ route('backups.destroy', Request::get('file_name')) }}" method="post" class="pull-right">
{{ method_field('delete') }}
{{ csrf_field() }}
<input type="hidden" name="file_name" value="{{ Request::get('file_name') }}">
<input type="submit" class="btn btn-danger" value="{{ trans('backup.confirm_delete') }}">
</form>
</div>
</div>
@endif
@if (Request::get('action') == 'restore' && Request::has('file_name'))
<div class="panel panel-warning">
<div class="panel-heading"><h3 class="panel-title">{{ trans('backup.restore') }}</h3></div>
<div class="panel-body">
<p>{!! trans('backup.sure_to_restore', ['filename' => Request::get('file_name')]) !!}</p>
</div>
<div class="panel-footer">
<a href="{{ route('backups.index') }}" class="btn btn-default">{{ trans('backup.cancel_restore') }}</a>
<form action="{{ route('backups.restore', Request::get('file_name')) }}"
method="post"
class="pull-right"
onsubmit="return confirm('Click OK to Restore.')">
{{ csrf_field() }}
<input type="hidden" name="file_name" value="{{ Request::get('file_name') }}">
<input type="submit" class="btn btn-warning" value="{{ trans('backup.confirm_restore') }}">
</form>
</div>
</div>
@endif
<div class="panel panel-default">
<div class="panel-body">
<form action="{{ route('backups.store') }}" method="post">
{{ csrf_field() }}
<div class="form-group">
<label for="file_name" class="control-label">{{ trans('backup.create') }}</label>
<input type="text" name="file_name" class="form-control" placeholder="{{ date('Y-m-d_Hi') }}">
{!! $errors->first('file_name', '<div class="text-danger text-right">:message</div>') !!}
</div>
<div class="form-group">
<input type="submit" value="{{ trans('backup.create') }}" class="btn btn-success">
</div>
</form>
<hr>
<form action="{{ route('backups.upload') }}" method="post" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<label for="backup_file" class="control-label">{{ trans('backup.upload') }}</label>
<input type="file" name="backup_file" class="form-control">
{!! $errors->first('backup_file', '<div class="text-danger text-right">:message</div>') !!}
</div>
<div class="form-group">
<input type="submit" value="{{ trans('backup.upload') }}" class="btn btn-primary">
</div>
</form>
</div>
</div>

54
resources/views/backups/index.blade.php

@ -0,0 +1,54 @@
@extends('layouts.app')
@section('title',trans('backup.index_title'))
@section('content')
<h3 class="page-header">{{ trans('backup.index_title') }}</h3>
<div class="row">
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('backup.list') }}</h3></div>
<table class="table table-condensed">
<thead>
<th>#</th>
<th>{{ trans('backup.file_name') }}</th>
<th>{{ trans('backup.file_size') }}</th>
<th>{{ trans('backup.created_at') }}</th>
<th class="text-center">{{ trans('backup.actions') }}</th>
</thead>
<tbody>
@forelse($backups as $key => $backup)
<tr>
<td>{{ $key + 1 }}</td>
<td>{{ $backup->getFilename() }}</td>
<td>{{ formatSizeUnits($backup->getSize()) }}</td>
<td>{{ date('Y-m-d H:i:s', $backup->getMTime()) }}</td>
<td class="text-center">
<a href="{{ route('backups.index', ['action' => 'restore', 'file_name' => $backup->getFilename()]) }}"
id="restore_{{ str_replace('.gz', '', $backup->getFilename()) }}"
class="btn btn-warning btn-xs"
title="{{ trans('backup.download') }}">{{ trans('backup.restore') }}</a>
<a href="{{ route('backups.download', [$backup->getFilename()]) }}"
id="download_{{ str_replace('.gz', '', $backup->getFilename()) }}"
class="btn btn-info btn-xs"
title="{{ trans('backup.download') }}">{{ trans('backup.download') }}</a>
<a href="{{ route('backups.index', ['action' => 'delete', 'file_name' => $backup->getFilename()]) }}"
id="del_{{ str_replace('.gz', '', $backup->getFilename()) }}"
class="btn btn-danger btn-xs"
title="{{ trans('backup.delete') }}">{{ trans('backup.delete') }}</a>
</td>
</tr>
@empty
<tr>
<td colspan="3">{{ trans('backup.empty') }}</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
<div class="col-md-4">
@include('backups.forms')
</div>
</div>
@endsection

8
routes/web.php

@ -47,4 +47,12 @@ Route::group(['middleware' => 'auth'], function () {
* Units Routes * Units Routes
*/ */
Route::resource('units', 'UnitsController', ['except' => ['create','show','edit']]); Route::resource('units', 'UnitsController', ['except' => ['create','show','edit']]);
/**
* Backup Restore Database Routes
*/
Route::post('backups/upload', ['as'=>'backups.upload', 'uses'=>'BackupsController@upload']);
Route::post('backups/{fileName}/restore', ['as'=>'backups.restore', 'uses'=>'BackupsController@restore']);
Route::get('backups/{fileName}/dl', ['as'=>'backups.download', 'uses'=>'BackupsController@download']);
Route::resource('backups','BackupsController', ['except' => ['create', 'show', 'edit']]);
}); });
Loading…
Cancel
Save