mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2025-11-04 20:36:03 +01:00
rudimentary backup [fixes #45]
This commit is contained in:
@@ -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'] .=
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
8
pages/admin/backup.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: Backup
|
||||
template: ajax
|
||||
|
||||
access:
|
||||
admin.maintenance: true
|
||||
admin.super: true
|
||||
---
|
||||
@@ -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",
|
||||
|
||||
5
themes/grav/templates/ajax.json.twig
Normal file
5
themes/grav/templates/ajax.json.twig
Normal file
@@ -0,0 +1,5 @@
|
||||
{% if admin.json_response %}
|
||||
{{ admin.json_response|json_encode }}
|
||||
{% else %}
|
||||
{}
|
||||
{% endif %}
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user