rudimentary backup [fixes #45]

This commit is contained in:
Gert
2015-04-27 13:37:22 +02:00
parent bfb0dc64dc
commit 1402e14272
7 changed files with 136 additions and 4 deletions

View File

@@ -200,7 +200,6 @@ class AdminPlugin extends Plugin
$format = $this->uri->extension();
$ext = '.' . ($format ? $format : 'html') . TWIG_EXT;
$twig->template = $this->template . $ext;
$twig->twig_vars['location'] = $this->template;
$twig->twig_vars['base_url_relative_frontend'] = $twig->twig_vars['base_url_relative'];
$twig->twig_vars['base_url_relative'] .=

View File

@@ -12,6 +12,7 @@ use Grav\Common\Page\Page;
use Grav\Common\Data;
use Grav\Common\GPM\GPM;
use RocketTheme\Toolbox\File\File;
use RocketTheme\Toolbox\File\JsonFile;
use RocketTheme\Toolbox\File\LogFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use RocketTheme\Toolbox\Session\Message;
@@ -415,6 +416,32 @@ class Admin
return $content;
}
public function lastBackup()
{
$file = JsonFile::instance($this->grav['locator']->findResource("log://backup.log"));
$content = $file->content();
if (empty($content)) {
return [
'days' => '∞',
'chart_fill' => 100,
'chart_empty' => 0
];
}
$backup = new \DateTime();
$backup->setTimestamp($content['time']);
$diff = $backup->diff(new \DateTime());
$days = $diff->days;
$chart_fill = $days > 30 ? 100 : round($days / 30 * 100);
return [
'days' => $days,
'chart_fill' => $chart_fill,
'chart_empty' => 100 - $chart_fill
];
}
/**
* Returns the page creating it if it does not exist.
*

View File

@@ -11,6 +11,9 @@ use Grav\Common\Data;
use Grav\Common\Page;
use Grav\Common\Page\Collection;
use Grav\Common\User\User;
use Grav\Common\Utils;
use Grav\Common\Backup\ZipBackup;
use RocketTheme\Toolbox\File\JsonFile;
class AdminController
{
@@ -266,6 +269,38 @@ class AdminController
return true;
}
protected function taskBackup()
{
$download = $this->grav['uri']->param('download');
if ($download) {
Utils::download(base64_decode(urldecode($download)), true);
}
$log = JsonFile::instance($this->grav['locator']->findResource("log://backup.log", true, true));
$backup = ZipBackup::backup();
$download = urlencode(base64_encode($backup));
$url = rtrim($this->grav['uri']->rootUrl(true), '/') . '/' . trim($this->admin->base, '/') . '/task:backup/download:' . $download;
$log->content([
'time' => time(),
'location' => $backup
]);
$log->save();
$this->admin->json_response = [
'status' => 'success',
'message' => 'Your backup is ready for download. <a href="'.$url.'" class="button">Download backup</a>',
'toastr' => [
'timeOut' => 0,
'closeButton' => true
]
];
return true;
}
protected function taskFilterPages()
{
$data = $this->post;

8
pages/admin/backup.md Normal file
View File

@@ -0,0 +1,8 @@
---
title: Backup
template: ajax
access:
admin.maintenance: true
admin.super: true
---

View File

@@ -92,6 +92,63 @@ $(function () {
});
});
// Update plugins/themes
$('[data-ajax]').on('click', function(e) {
var button = $(this),
icon = button.find('> .fa'),
url = button.data('ajax');
var iconClasses = [],
helperClasses = [ 'fa-lg', 'fa-2x', 'fa-3x', 'fa-4x', 'fa-5x',
'fa-fw', 'fa-ul', 'fa-li', 'fa-border',
'fa-rotate-90', 'fa-rotate-180', 'fa-rotate-270',
'fa-flip-horizontal', 'fa-flip-vertical' ];
// Disable button
button.attr('disabled','disabled');
// Swap fontawesome icon to loader
$.each(icon.attr('class').split(/\s+/), function (i, classname) {
if (classname.indexOf('fa-') === 0 && $.inArray(classname, helperClasses) === -1) {
iconClasses.push(classname);
icon.removeClass(classname);
}
});
icon.addClass('fa-refresh fa-spin');
GravAjax({
dataType: "json",
url: url,
success: function(result, status) {
var toastrBackup = {};
if (result.toastr) {
for (var setting in result.toastr) { if (result.toastr.hasOwnProperty(setting)) {
toastrBackup[setting] = toastr.options[setting];
toastr.options[setting] = result.toastr[setting];
}
}
}
if (result.status == 'success') {
toastr.success(result.message || 'Task completed.');
} else {
toastr.error(result.message || 'Something went terribly wrong.');
}
for (var setting in toastrBackup) { if (toastrBackup.hasOwnProperty(setting)) {
toastr.options[setting] = toastrBackup[setting];
}
}
}
}).complete(function() {
// Restore button
button.removeAttr('disabled');
icon.removeClass('fa-refresh fa-spin').addClass(iconClasses.join(' '));
});
});
var GPMRefresh = function () {
GravAjax({
dataType: "JSON",

View File

@@ -0,0 +1,5 @@
{% if admin.json_response %}
{{ admin.json_response|json_encode }}
{% else %}
{}
{% endif %}

View File

@@ -11,6 +11,7 @@
{% set gpm = admin.gpm() %}
{% set updatable = gpm.getUpdatablePlugins() %}
{% set backup = admin.lastBackup() %}
<div id="admin-dashboard">
<div id="updates" class="dashboard-item dashboard-left">
@@ -29,7 +30,7 @@
<div class="ct-chart"></div>
<script>
var data = {
series: [33,67]
series: [{{ backup.chart_fill }}, {{ backup.chart_empty }}]
};
var options = {
donut: true,
@@ -41,14 +42,14 @@
};
Chartist.Pie('.backups-chart .ct-chart', data, options);
</script>
<span class="numeric">13<em>days</em></span>
<span class="numeric">{{ backup.days }}<em>days</em></span>
</div>
<p>Last Backup</p>
</div>
</div>
<div class="flush-bottom button-bar">
<button data-maintenance-update="{{ base_url_relative }}/update.json/task:update" class="button"><i class="fa fa-cloud-download"></i> Update</button>
<button href="#" class="button"><i class="fa fa-database"></i> Backup</button>
<button data-ajax="{{ base_url_relative }}/backup.json/task:backup" class="button"><i class="fa fa-database"></i> Backup</button>
</div>
</div>
</div>