-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a4ad6ff
Showing
18 changed files
with
5,829 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?xml version="1.0"?> | ||
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer"> | ||
<config name="installed_paths" value="../../slevomat/coding-standard" /> | ||
<rule ref="Generic.Arrays.DisallowLongArraySyntax"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="PSR12"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="Generic.Files.LineLength"> | ||
<type>warning</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Arrays.SingleLineArrayWhitespace"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Arrays.MultiLineArrayEndBracketPlacement"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Arrays.TrailingArrayComma"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Classes.ClassStructure"> | ||
<type>warning</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.ControlStructures.LanguageConstructWithParentheses"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly"> | ||
<type>error</type> | ||
</rule> | ||
<rule ref="SlevomatCodingStandard.Whitespaces.DuplicateSpaces"> | ||
<type>error</type> | ||
<properties> | ||
<property name="ignoreSpacesInComment" value="true" /> | ||
</properties> | ||
</rule> | ||
<rule ref="Squiz.Strings.DoubleQuoteUsage"> | ||
<type>error</type> | ||
</rule> | ||
</ruleset> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 4 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: CI | ||
|
||
on: | ||
pull_request: | ||
|
||
jobs: | ||
commitlint: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: remindgmbh/[email protected] | ||
phpcs: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: shivammathur/setup-php@v2 | ||
with: | ||
php-version: 8.2 | ||
extensions: intl | ||
tools: composer:v2 | ||
- run: composer install | ||
- run: composer run-script phpcs |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
name: Release | ||
|
||
on: | ||
push: | ||
branches: | ||
- "main" | ||
|
||
jobs: | ||
release: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: remindgmbh/[email protected] | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
### IDE ### | ||
nbproject/ | ||
.idea/ | ||
|
||
### Composer ### | ||
composer.phar | ||
|
||
### Node ### | ||
node_modules/ | ||
|
||
### General ### | ||
*.log | ||
cache.properties | ||
|
||
### CI ### | ||
.build/bin/ | ||
.build/vendor/ | ||
.build/web/ | ||
.build/logs/ | ||
.build/coverage/ | ||
.build/pdepend/ |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"recommendations": [ | ||
"benjaminkott.typo3-typoscript", | ||
"devsense.phptools-vscode", | ||
"obliviousharmony.vscode-php-codesniffer" | ||
], | ||
"unwantedRecommendations": [] | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"phpCodeSniffer.exec.linux": "./.build/bin/phpcs", | ||
"phpCodeSniffer.standard": "Custom", | ||
"phpCodeSniffer.standardCustom": "./.build/phpcs.xml", | ||
"phpCodeSniffer.exclude": [ | ||
"**/vendor/{,!(remind)/**}" | ||
] | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Remind\Backup\Command; | ||
|
||
use Remind\Backup\Utility\FileNameUtility; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Input\InputOption; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; | ||
|
||
final class DeleteBackupCommand extends Command | ||
{ | ||
private const INPUT_DIR = 'dir'; | ||
private const INPUT_FILE = 'file'; | ||
private const INPUT_KEEP_COUNT = 'keep-count'; | ||
private array $extensionConfiguration; | ||
|
||
public function __construct( | ||
ExtensionConfiguration $extensionConfiguration | ||
) { | ||
$this->extensionConfiguration = $extensionConfiguration->get('rmnd_backup'); | ||
parent::__construct(); | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this | ||
->addOption( | ||
self::INPUT_DIR, | ||
'd', | ||
InputOption::VALUE_OPTIONAL, | ||
'', | ||
$this->extensionConfiguration['defaultDir'], | ||
) | ||
->addOption( | ||
self::INPUT_FILE, | ||
'f', | ||
InputOption::VALUE_OPTIONAL, | ||
'', | ||
$this->extensionConfiguration['defaultFile'], | ||
) | ||
->addOption( | ||
self::INPUT_KEEP_COUNT, | ||
null, | ||
InputOption::VALUE_OPTIONAL, | ||
'Number of database backups to keep', | ||
$this->extensionConfiguration['delete']['keepCount'] | ||
); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
if (!(bool) $this->extensionConfiguration['delete']['enable']) { | ||
$output->writeln( | ||
'Backup deletion has to be enabled with [\'EXTENSIONS\'][\'rmnd_backup\'][\'delete\'][\'enable\'] = 1' | ||
); | ||
return Command::SUCCESS; | ||
} | ||
|
||
$dir = $input->getOption(self::INPUT_DIR); | ||
$file = $input->getOption(self::INPUT_FILE); | ||
|
||
if (!is_dir($dir)) { | ||
$output->writeln(sprintf('Directory \'%s\' does not exist.', $dir)); | ||
return Command::FAILURE; | ||
} | ||
|
||
$files = array_values(array_diff(scandir($dir, SCANDIR_SORT_ASCENDING), ['.', '..'])); | ||
$matches = array_filter($files, function (string $fileToCheck) use ($file) { | ||
return preg_match(FileNameUtility::getRegexPattern($file), $fileToCheck); | ||
}); | ||
|
||
$filesToBeDeleted = array_slice($matches, 0, -$input->getOption(self::INPUT_KEEP_COUNT)); | ||
|
||
foreach ($filesToBeDeleted as $file) { | ||
unlink(FileNameUtility::buildPath($dir, $file)); | ||
} | ||
|
||
return Command::SUCCESS; | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Remind\Backup\Command; | ||
|
||
use Remind\Backup\Service\DatabaseService; | ||
use Remind\Backup\Utility\FileNameUtility; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Input\InputOption; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Process\Process; | ||
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; | ||
|
||
final class ExportCommand extends Command | ||
{ | ||
private const INPUT_DIR = 'dir'; | ||
private const INPUT_FILE = 'file'; | ||
private const INPUT_NO_DATA = 'no-data'; | ||
private const INPUT_INCLUDE_CACHE_DATA = 'include-cache-data'; | ||
private const INPUT_INCLUDE_DEFAULT_NO_DATA = 'include-default-no-data'; | ||
private const INPUT_OMIT_TIMESTAMP = 'omit-timestamp'; | ||
private const DEFAULT_NO_DATA = [ | ||
'be_sessions', | ||
'fe_sessions', | ||
'fe_users', | ||
'sys_history', | ||
'sys_http_report', | ||
'sys_lockedrecords', | ||
'sys_log', | ||
]; | ||
|
||
private array $extensionConfiguration; | ||
|
||
public function __construct( | ||
private readonly DatabaseService $databaseService, | ||
ExtensionConfiguration $extensionConfiguration, | ||
) { | ||
$this->extensionConfiguration = $extensionConfiguration->get('rmnd_backup'); | ||
parent::__construct(); | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this | ||
->addOption( | ||
self::INPUT_DIR, | ||
'd', | ||
InputOption::VALUE_OPTIONAL, | ||
'', | ||
$this->extensionConfiguration['defaultDir'], | ||
) | ||
->addOption( | ||
self::INPUT_FILE, | ||
'f', | ||
InputOption::VALUE_OPTIONAL, | ||
'', | ||
$this->extensionConfiguration['defaultFile'], | ||
) | ||
->addOption( | ||
self::INPUT_NO_DATA, | ||
null, | ||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, | ||
'Table with data excluded', | ||
[], | ||
) | ||
->addOption( | ||
self::INPUT_INCLUDE_CACHE_DATA, | ||
null, | ||
InputOption::VALUE_NONE, | ||
'Include cache tables data' | ||
) | ||
->addOption( | ||
self::INPUT_INCLUDE_DEFAULT_NO_DATA, | ||
null, | ||
InputOption::VALUE_NONE, | ||
sprintf('Include data for tables %s', implode(', ', self::DEFAULT_NO_DATA)), | ||
) | ||
->addOption( | ||
self::INPUT_OMIT_TIMESTAMP, | ||
null, | ||
InputOption::VALUE_NONE, | ||
'Omit timestamp in filename' | ||
); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
if (!(bool) $this->extensionConfiguration['export']['enable']) { | ||
$output->writeln( | ||
'Database export has to be enabled with [\'EXTENSIONS\'][\'rmnd_backup\'][\'export\'][\'enable\'] = 1' | ||
); | ||
return Command::SUCCESS; | ||
} | ||
|
||
$dir = $input->getOption(self::INPUT_DIR); | ||
|
||
$path = FileNameUtility::buildPath( | ||
$dir, | ||
$input->getOption(self::INPUT_FILE), | ||
!$input->getOption(self::INPUT_OMIT_TIMESTAMP), | ||
true, | ||
); | ||
|
||
if (file_exists($path)) { | ||
$output->writeln(sprintf('File \'%s\' already exists', $path)); | ||
return Command::FAILURE; | ||
} | ||
|
||
if (!file_exists($dir)) { | ||
mkdir($dir, 0755, true); | ||
} | ||
|
||
$tables = $this->databaseService->getTableNames(); | ||
|
||
$cacheTables = array_filter($tables, function (string $table) { | ||
return str_starts_with($table, 'cache_'); | ||
}); | ||
|
||
$ignoreTables = $input->getOption(self::INPUT_NO_DATA); | ||
|
||
if (!$input->getOption(self::INPUT_INCLUDE_CACHE_DATA)) { | ||
array_push($ignoreTables, ...$cacheTables); | ||
} | ||
|
||
if (!$input->getOption(self::INPUT_INCLUDE_DEFAULT_NO_DATA)) { | ||
array_push($ignoreTables, ...self::DEFAULT_NO_DATA); | ||
} | ||
|
||
$ignoreTableArgs = array_map(function (string $table) { | ||
return sprintf('--ignore-table=%s.%s', $this->databaseService->getDbName(), $table); | ||
}, $ignoreTables); | ||
|
||
$processes = [ | ||
$this->databaseService->mysqldump(['--single-transaction', '--no-data']), | ||
$this->databaseService->mysqldump(['--single-transaction', '--no-create-info', ...$ignoreTableArgs]), | ||
]; | ||
|
||
foreach ($processes as $process) { | ||
$exitCode = $process->run(function ($type, $buffer) use ($output, $path) { | ||
if ($type === Process::ERR) { | ||
$output->writeln($buffer); | ||
} else { | ||
file_put_contents($path, $buffer, FILE_APPEND | LOCK_EX); | ||
} | ||
}); | ||
|
||
if ($exitCode !== 0) { | ||
return Command::FAILURE; | ||
} | ||
} | ||
|
||
return Command::SUCCESS; | ||
} | ||
} |
Oops, something went wrong.