Skip to content

Commit 4dc33b1

Browse files
author
Alex Schulte
committed
2 parents 9d3d5ed + 24b0ffd commit 4dc33b1

File tree

18 files changed

+402
-768
lines changed

18 files changed

+402
-768
lines changed

.github/FUNDING.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# These are supported funding model platforms
2+
3+
github: [breadlesscode]
4+
patreon: breadlesscode
5+
open_collective: # Replace with a single Open Collective username
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
otechie: # Replace with a single Otechie username
12+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

.github/workflows/documentation.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
name: 'Build & Deploy Documentation'
22

33
on:
4-
release:
5-
types:
6-
- created
7-
# push:
8-
# branches:
9-
# - master
4+
# release:
5+
# types:
6+
# - created
7+
push:
8+
branches:
9+
- master
1010

1111
jobs:
1212
build:

Classes/Command/BackupCommandController.php

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ public function createCommand(): void
3131

3232
/**
3333
* restores a single backup of a specific package
34+
*
35+
* @param string $name The name of the backup you want to restore
36+
* @param bool $noConfirm If true, you dant have to confirm the restore action
3437
*/
3538
public function restoreCommand(string $name, bool $noConfirm = false): void
3639
{
@@ -53,7 +56,7 @@ public function restoreCommand(string $name, bool $noConfirm = false): void
5356
}
5457

5558
if ($noConfirm === false) {
56-
$shouldRestore = $this->output->askConfirmation('Are you sure you want to restore this Backup?', false);
59+
$shouldRestore = $this->output->askConfirmation('Are you sure you want to restore this Backup? ', false);
5760
}
5861

5962
if(!$shouldRestore) {
@@ -73,6 +76,9 @@ public function restoreCommand(string $name, bool $noConfirm = false): void
7376

7477
/**
7578
* lists all backups
79+
*
80+
* @param int $offset Offset
81+
* @param int $limit Number of backups shown
7682
*/
7783
public function listCommand($offset = 0, $limit = 60): void
7884
{
@@ -89,13 +95,16 @@ public function listCommand($offset = 0, $limit = 60): void
8995

9096
/**
9197
* deletes backups
98+
*
99+
* @param string $name The name of the backup you want to delete
100+
* @param bool $noConfirm If true, you dant have to confirm the delete action
92101
*/
93102
public function deleteCommand(string $name, bool $noConfirm = false): void
94103
{
95104
$confirmed = true;
96105

97106
if (!$noConfirm) {
98-
$confirmed = $this->output->askConfirmation('Are you sure you want to delete this backup?');
107+
$confirmed = $this->output->askConfirmation('Are you sure you want to delete this backup? ');
99108
}
100109

101110
if (!$confirmed) {
@@ -114,6 +123,43 @@ public function deleteCommand(string $name, bool $noConfirm = false): void
114123
}
115124
}
116125

126+
/**
127+
* deletes all backups, but can keep X latest backups
128+
*
129+
* @param int $keep keep the latest X backups
130+
* @param bool $noConfirm If true, you dant have to confirm the delete action
131+
*/
132+
public function pruneCommand(int $keep = 0, bool $noConfirm = false): void
133+
{
134+
$confirmed = true;
135+
136+
if (!$noConfirm) {
137+
$question = ($keep > 0 ? ', except the latest '.$keep.' backups': '');
138+
$question = 'Are you sure you want to delete all backups'.$question.'? ';
139+
$confirmed = $this->output->askConfirmation($question);
140+
}
141+
142+
if (!$confirmed) {
143+
$this->outputLine();
144+
$this->outputLine('<error>Canceled by user</error>');
145+
$this->quit();
146+
}
147+
148+
$backupCount = $this->backupService->getCount();
149+
$backups = $this->backupService->getBackups($keep, $backupCount);
150+
151+
$this->output('Deleting '.($backupCount - $keep <= 0 ? '0': $backupCount - $keep).' backups...');
152+
153+
try {
154+
foreach ($backups as $backup) {
155+
$this->backupService->deleteBackup($backup['name']);
156+
}
157+
$this->outputLine('<success>success</success>');
158+
} catch (\Exception $e) {
159+
$this->outputError($e->getMessage());
160+
}
161+
}
162+
117163
protected function outputError(string $message): void
118164
{
119165
$this->outputLine('<error>failed</error>');

Classes/Service/BackupIndexService.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public function deleteBackup(string $name)
128128
return $success;
129129
}
130130

131+
public function getCount(): int
132+
{
133+
return $this->getReader()->count();
134+
}
135+
131136
public function getBackups(int $start = 0, int $limit = 25): array
132137
{
133138
$reader = $this->getReader();

Classes/Service/BackupService.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
use League\Flysystem\Filesystem;
1111
use Neos\Flow\Annotations as Flow;
1212
use Neos\Flow\Exception;
13+
use Neos\Flow\Log\PsrLoggerFactoryInterface;
1314
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
1415
use Neos\Flow\Persistence\Doctrine\PersistenceManager;
1516
use Neos\Utility\Files;
17+
use Psr\Log\LoggerInterface;
1618

1719
/**
1820
* @Flow\Scope(value="singleton")
@@ -45,6 +47,11 @@ class BackupService
4547
*/
4648
protected $persistenceManager;
4749

50+
/**
51+
* @var LoggerInterface#
52+
*/
53+
protected $logger;
54+
4855
public function __construct(ObjectManagerInterface $objectManager)
4956
{
5057
$this->objectManager = $objectManager;
@@ -54,8 +61,12 @@ public function initializeObject()
5461
{
5562
$this->indexService = $this->objectManager->get(BackupIndexService::class);
5663
$this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
64+
5765
$filesystemFactory = $this->objectManager->get(FilesystemFactory::class);
5866
$this->filesystem = $filesystemFactory->get($this->config['filesystem']['type']);
67+
68+
$loggerFactory = $this->objectManager->get(PsrLoggerFactoryInterface::class);
69+
$this->logger = $loggerFactory->get('backupLogger');
5970
}
6071

6172
public function getBackups(int $start = 0, int $limit = 0): array
@@ -71,11 +82,14 @@ public function getBackups(int $start = 0, int $limit = 0): array
7182
public function deleteBackup(string $name): bool
7283
{
7384
$this->indexService->deleteBackup($name);
85+
$backupFilename = $this->getCompressor()->generateFilename($name);
7486

75-
if ($this->filesystem->has($name)) {
76-
$this->filesystem->delete($name);
87+
if ($this->filesystem->has($backupFilename)) {
88+
$this->filesystem->delete($backupFilename);
7789
}
7890

91+
$this->logger->info('deleted backup '.$name);
92+
7993
return true;
8094
}
8195

@@ -102,6 +116,10 @@ public function restoreBackup(string $name)
102116
}
103117
// persist all changes from the steps
104118
$this->persistenceManager->persistAll();
119+
$this->logger->info('restored backup '.$name);
120+
// delete temp stuff
121+
Files::removeDirectoryRecursively($backupPath);
122+
Files::unlink($archivePath);
105123
}
106124

107125

@@ -136,6 +154,7 @@ public function createBackup()
136154
Files::removeDirectoryRecursively($backupPath);
137155
// update index
138156
$this->indexService->addBackup($backupName, new \DateTime(), $meta);
157+
$this->logger->info('added backup '.$backupName);
139158
}
140159

141160
/**
@@ -191,6 +210,10 @@ public function getStepsInstances(string $backupPath, array $whiteList = null):
191210
return $steps;
192211
}
193212

213+
public function getCount(): int
214+
{
215+
return $this->indexService->getCount();
216+
}
194217

195218
public function noStepsConfigured(): bool
196219
{

Classes/Step/FileExportStep.php

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ public function backup(): bool
1919
foreach ($copyPaths as $folderName => $path) {
2020
$tmpBackupPath = Files::concatenatePaths([$this->getBackupStepPath(), $folderName]);
2121

22-
if (is_dir($path)) {
23-
$this->copyDirectory($path, $tmpBackupPath);
24-
} else {
25-
copy($path, $tmpBackupPath);
26-
}
22+
Files::copyDirectoryRecursively($path, $tmpBackupPath);
2723
}
2824

2925
return true;
@@ -36,11 +32,9 @@ public function restore(): bool
3632
foreach ($copyPaths as $folderName => $path) {
3733
$tmpBackupPath = Files::concatenatePaths([$this->getBackupStepPath(), $folderName]);
3834

39-
if (is_dir($path)) {
40-
$this->copyDirectory($tmpBackupPath, $path);
41-
} else {
42-
copy($tmpBackupPath, $path);
43-
}
35+
Files::removeDirectoryRecursively($path);
36+
Files::createDirectoryRecursively($path);
37+
Files::copyDirectoryRecursively($tmpBackupPath, $path);
4438
}
4539

4640
return true;
@@ -60,27 +54,4 @@ public function getRestoreWarning(): ?string
6054

6155
return $restoreWarning;
6256
}
63-
64-
protected function copyDirectory(string $source, string $dest)
65-
{
66-
$dir = opendir($source);
67-
mkdir($dest);
68-
69-
while(false !== ($file = readdir($dir))) {
70-
if ($file === '.' || $file === '..') {
71-
continue;
72-
}
73-
74-
$srcFile = $source.'/'.$file;
75-
$destFile = $dest.'/'.$file;
76-
77-
if (is_dir($srcFile)) {
78-
$this->copyDirectory($srcFile, $destFile);
79-
} else {
80-
copy($srcFile, $destFile);
81-
}
82-
}
83-
84-
closedir($dir);
85-
}
8657
}

Configuration/Settings.Log.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Neos:
2+
Flow:
3+
log:
4+
psr3:
5+
'Neos\Flow\Log\PsrLoggerFactory':
6+
backupLogger:
7+
default:
8+
class: Neos\Flow\Log\Backend\FileBackend
9+
options:
10+
logFileURL: '%FLOW_PATH_DATA%Logs/Backup.log'
11+
createParentDirectories: true
12+
severityThreshold: '%LOG_INFO%'
13+
maximumLogFileSize: 10485760
14+
logFilesToKeep: 1

Documentation/.vuepress/config.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
1+
const socialMeta = {
2+
title: 'Neos Backups',
3+
description: 'Easy backup management plugin for Neos CMS',
4+
image: 'https://repository-images.githubusercontent.com/235191200/234dfe80-4129-11ea-9f1d-a938b96ec553',
5+
url: 'https://breadlesscode.github.io/neos-backups'
6+
};
7+
18
module.exports = {
29
title: 'Neos Backups',
310
base: process.env.NODE_ENV === 'production'? '/neos-backups/': '/',
11+
head: [
12+
['meta', {property: 'og:title', content: socialMeta.title}],
13+
['meta', {property: 'og:description', content: socialMeta.description}],
14+
['meta', {property: 'og:image', content: socialMeta.image}],
15+
['meta', {property: 'og:url', content: socialMeta.url}],
16+
['meta', {property: 'twitter:title', content: socialMeta.title}],
17+
['meta', {property: 'twitter:description', content: socialMeta.description}],
18+
['meta', {property: 'twitter:image', content: socialMeta.image}],
19+
['meta', {property: 'twitter:card', content: 'summary_large_image'}],
20+
],
421
themeConfig: {
522
nav: [
623
{text: 'Github', link: 'https://github.com/breadlesscode/neos-backups'}
@@ -9,6 +26,7 @@ module.exports = {
926
'/installation',
1027
'/filesystems',
1128
'/steps',
29+
'/commands',
1230
'/custom-behaviours'
1331
],
1432
theme: '@vuepress/theme-default',

Documentation/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ home: true
33
editLink: false
44
heroImage: /neos-backups.svg
55
heroText: Neos Backups
6-
tagline: Easy backup and restore your Neos CMS in different filesystems
6+
tagline: Easily backup and restore your Neos CMS in different file systems
77
actionText: Get Started →
88
actionLink: /installation
99
features:
10-
- title: Easy customizable
11-
details: You can easily add your own backup steps or add your own filesystem adapter.
12-
- title: Free
13-
details: Its free, why not use it? Its always better to have backups.
10+
- title: Easily customizable
11+
details: You can easily add your own backup steps or add your own file system adapter.
12+
- title: Easy to use
13+
details: Everything is ready to use. For a normal backup you don't have to write a single line of code.
1414
- title: Open Source
15-
details: You discovered a bug? No problem, go to the Github page and report it.
15+
details: It's free, why not use it? It's always better to have backups.
1616
footer: GPL-3.0 Licensed | Copyright © 2020 by Marvin Kuhn
1717
---

0 commit comments

Comments
 (0)