From c88103ca13f850214f3be0ae22e7a6a3361802ca Mon Sep 17 00:00:00 2001
From: Niels Vanpachtenbeke <10651054+Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 09:46:14 +0200
Subject: [PATCH 1/9] init Rector

---
 composer.json     |  8 +++++---
 phpstan.neon.dist |  3 +--
 rector.php        | 26 ++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 5 deletions(-)
 create mode 100644 rector.php

diff --git a/composer.json b/composer.json
index 173939cf..9094525a 100644
--- a/composer.json
+++ b/composer.json
@@ -45,7 +45,8 @@
         "pestphp/pest": "^1.20|^2.0",
         "phpstan/extension-installer": "^1.1",
         "phpstan/phpstan-deprecation-rules": "^1.0",
-        "phpstan/phpstan-phpunit": "^1.1"
+        "phpstan/phpstan-phpunit": "^1.1",
+        "rector/rector": "^1.1"
     },
     "autoload": {
         "psr-4": {
@@ -61,9 +62,10 @@
         }
     },
     "scripts": {
-        "test": "vendor/bin/pest",
+        "test": "vendor/bin/pest --compact",
         "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes",
-        "analyse": "vendor/bin/phpstan analyse"
+        "analyse": "vendor/bin/phpstan analyse",
+        "rector": "./vendor/bin/rector --dry-run"
     },
     "suggest": {
         "laravel/slack-notification-channel": "Required for sending notifications via Slack"
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 2670010c..9bfe1ece 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -2,14 +2,13 @@ includes:
     - phpstan-baseline.neon
 
 parameters:
-    level: 5
+    level: max
     paths:
         - src
         - config
     tmpDir: build/phpstan
     checkOctaneCompatibility: true
     checkModelProperties: true
-    checkMissingIterableValueType: false
 
     ignoreErrors:
         - '#Unsafe usage of new static#'
diff --git a/rector.php b/rector.php
new file mode 100644
index 00000000..eb66deb4
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+use Rector\CodeQuality\Rector\ClassMethod\OptionalParametersAfterRequiredRector;
+use Rector\Config\RectorConfig;
+use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
+use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector;
+use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector;
+
+return RectorConfig::configure()
+    ->withPaths([
+        __DIR__ . '/config',
+        __DIR__ . '/resources',
+        __DIR__ . '/src',
+        __DIR__ . '/tests',
+    ])
+    ->withPhpSets(php81: true)
+    ->withRules([
+        AddVoidReturnTypeWhereNoReturnRector::class,
+    ])
+    ->withSkip([
+        ReturnNeverTypeRector::class,
+        OptionalParametersAfterRequiredRector::class,
+        ClosureToArrowFunctionRector::class,
+    ]);

From 25e2e3ba7daf3b8cfddf4267e6e7445b03207d62 Mon Sep 17 00:00:00 2001
From: Niels Vanpachtenbeke <10651054+Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 09:48:09 +0200
Subject: [PATCH 2/9] apply rector for 8.1

---
 composer.json                                     |  3 ++-
 phpstan-baseline.neon                             |  9 +++++++++
 phpstan.neon.dist                                 |  2 +-
 src/BackupDestination/BackupDestination.php       | 15 ++-------------
 src/BackupServiceProvider.php                     |  4 ++--
 src/Commands/CleanupCommand.php                   |  6 +-----
 .../Channels/Discord/DiscordMessage.php           |  2 +-
 src/Tasks/Backup/BackupJob.php                    |  2 +-
 src/Tasks/Backup/DbDumperFactory.php              |  4 ++--
 src/Tasks/Backup/FileSelection.php                |  2 +-
 src/Tasks/Backup/Manifest.php                     |  8 ++------
 src/Tasks/Backup/Zip.php                          | 10 +++-------
 src/Tasks/Cleanup/CleanupJob.php                  | 12 ++----------
 src/Tasks/Cleanup/Strategies/DefaultStrategy.php  |  2 +-
 tests/BackupDestination/BackupTest.php            |  6 +++---
 tests/Commands/BackupCommandTest.php              |  2 +-
 tests/Commands/CleanupCommandTest.php             |  2 +-
 tests/Commands/MonitorCommandTest.php             |  2 +-
 tests/FormatTest.php                              |  6 +++---
 tests/TestCase.php                                |  2 +-
 20 files changed, 40 insertions(+), 61 deletions(-)

diff --git a/composer.json b/composer.json
index 9094525a..ffaea00b 100644
--- a/composer.json
+++ b/composer.json
@@ -65,7 +65,8 @@
         "test": "vendor/bin/pest --compact",
         "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes",
         "analyse": "vendor/bin/phpstan analyse",
-        "rector": "./vendor/bin/rector --dry-run"
+        "rector": "./vendor/bin/rector --dry-run",
+        "baseline": "./vendor/bin/phpstan analyse --generate-baseline --memory-limit=2G"
     },
     "suggest": {
         "laravel/slack-notification-channel": "Required for sending notifications via Slack"
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 364905f7..41478adf 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -1,2 +1,11 @@
 parameters:
 	ignoreErrors:
+		-
+			message: "#^Deprecated in PHP 8\\.0\\: Required parameter \\$diskName follows optional parameter \\$disk\\.$#"
+			count: 1
+			path: src/BackupDestination/BackupDestination.php
+
+		-
+			message: "#^Deprecated in PHP 8\\.1\\: Required parameter \\$backupName follows optional parameter \\$disk\\.$#"
+			count: 1
+			path: src/BackupDestination/BackupDestination.php
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 9bfe1ece..81a4e5b0 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -2,7 +2,7 @@ includes:
     - phpstan-baseline.neon
 
 parameters:
-    level: max
+    level: 5
     paths:
         - src
         - config
diff --git a/src/BackupDestination/BackupDestination.php b/src/BackupDestination/BackupDestination.php
index 9c689f6a..ea271602 100644
--- a/src/BackupDestination/BackupDestination.php
+++ b/src/BackupDestination/BackupDestination.php
@@ -10,23 +10,12 @@
 
 class BackupDestination
 {
-    protected ?Filesystem $disk;
-
-    protected string $diskName;
-
-    protected string $backupName;
-
     public ?Exception $connectionError = null;
 
     protected ?BackupCollection $backupCollectionCache = null;
 
-    public function __construct(Filesystem $disk = null, string $backupName, string $diskName)
+    public function __construct(protected ?Filesystem $disk = null, protected string $backupName, protected string $diskName)
     {
-        $this->disk = $disk;
-
-        $this->diskName = $diskName;
-
-        $this->backupName = $backupName;
     }
 
     public function disk(): Filesystem
@@ -49,7 +38,7 @@ public function filesystemType(): string
 
         $filesystemType = last(explode('\\', $adapterClass));
 
-        return strtolower($filesystemType);
+        return strtolower((string) $filesystemType);
     }
 
     public static function create(string $diskName, string $backupName): self
diff --git a/src/BackupServiceProvider.php b/src/BackupServiceProvider.php
index 64e4c663..8e460d53 100644
--- a/src/BackupServiceProvider.php
+++ b/src/BackupServiceProvider.php
@@ -34,7 +34,7 @@ public function configurePackage(Package $package): void
             ]);
     }
 
-    public function packageBooted()
+    public function packageBooted(): void
     {
         $this->app['events']->subscribe(EventHandler::class);
 
@@ -43,7 +43,7 @@ public function packageBooted()
         }
     }
 
-    public function packageRegistered()
+    public function packageRegistered(): void
     {
         $this->app->singleton(ConsoleOutput::class);
 
diff --git a/src/Commands/CleanupCommand.php b/src/Commands/CleanupCommand.php
index d770f07e..28551e3f 100644
--- a/src/Commands/CleanupCommand.php
+++ b/src/Commands/CleanupCommand.php
@@ -20,13 +20,9 @@ class CleanupCommand extends BaseCommand implements Isolatable
     /** @var string */
     protected $description = 'Remove all backups older than specified number of days in config.';
 
-    protected CleanupStrategy $strategy;
-
-    public function __construct(CleanupStrategy $strategy)
+    public function __construct(protected CleanupStrategy $strategy)
     {
         parent::__construct();
-
-        $this->strategy = $strategy;
     }
 
     public function handle(): int
diff --git a/src/Notifications/Channels/Discord/DiscordMessage.php b/src/Notifications/Channels/Discord/DiscordMessage.php
index 8854aef2..b6bb5341 100644
--- a/src/Notifications/Channels/Discord/DiscordMessage.php
+++ b/src/Notifications/Channels/Discord/DiscordMessage.php
@@ -120,7 +120,7 @@ public function toArray(): array
                     'type' => 'rich',
                     'description' => $this->description,
                     'fields' => $this->fields,
-                    'color' => hexdec($this->color),
+                    'color' => hexdec((string) $this->color),
                     'footer' => [
                         'text' => $this->footer ?? '',
                     ],
diff --git a/src/Tasks/Backup/BackupJob.php b/src/Tasks/Backup/BackupJob.php
index 952cb57e..c425cac5 100644
--- a/src/Tasks/Backup/BackupJob.php
+++ b/src/Tasks/Backup/BackupJob.php
@@ -249,7 +249,7 @@ protected function dumpDatabases(): array
             ->map(function (DbDumper $dbDumper, $key) {
                 consoleOutput()->info("Dumping database {$dbDumper->getDbName()}...");
 
-                $dbType = mb_strtolower(basename(str_replace('\\', '/', get_class($dbDumper))));
+                $dbType = mb_strtolower(basename(str_replace('\\', '/', $dbDumper::class)));
 
 
                 if (config('backup.backup.database_dump_filename_base') === 'connection') {
diff --git a/src/Tasks/Backup/DbDumperFactory.php b/src/Tasks/Backup/DbDumperFactory.php
index d62ff378..c416abd1 100644
--- a/src/Tasks/Backup/DbDumperFactory.php
+++ b/src/Tasks/Backup/DbDumperFactory.php
@@ -69,14 +69,14 @@ public static function createFromConnection(string $dbConnectionName): DbDumper
         return $dbDumper;
     }
 
-    public static function extend(string $driver, callable $callback)
+    public static function extend(string $driver, callable $callback): void
     {
         static::$custom[$driver] = $callback;
     }
 
     protected static function forDriver($dbDriver): DbDumper
     {
-        $driver = strtolower($dbDriver);
+        $driver = strtolower((string) $dbDriver);
 
         if (isset(static::$custom[$driver])) {
             return (static::$custom[$driver])();
diff --git a/src/Tasks/Backup/FileSelection.php b/src/Tasks/Backup/FileSelection.php
index 93a03958..84071495 100644
--- a/src/Tasks/Backup/FileSelection.php
+++ b/src/Tasks/Backup/FileSelection.php
@@ -140,6 +140,6 @@ protected function getMatchingPaths(string $path): array
 
     protected function canUseGlobBrace(string $path): bool
     {
-        return strpos($path, '*') !== false && defined('GLOB_BRACE');
+        return str_contains($path, '*') && defined('GLOB_BRACE');
     }
 }
diff --git a/src/Tasks/Backup/Manifest.php b/src/Tasks/Backup/Manifest.php
index 69894cfe..fe6c233b 100644
--- a/src/Tasks/Backup/Manifest.php
+++ b/src/Tasks/Backup/Manifest.php
@@ -8,18 +8,14 @@
 
 class Manifest implements Countable
 {
-    protected string $manifestPath;
-
     public static function create(string $manifestPath): self
     {
         return new static($manifestPath);
     }
 
-    public function __construct(string $manifestPath)
+    public function __construct(protected string $manifestPath)
     {
-        $this->manifestPath = $manifestPath;
-
-        touch($manifestPath);
+        touch($this->manifestPath);
     }
 
     public function path(): string
diff --git a/src/Tasks/Backup/Zip.php b/src/Tasks/Backup/Zip.php
index 3dbcbf1f..bf5c1a48 100644
--- a/src/Tasks/Backup/Zip.php
+++ b/src/Tasks/Backup/Zip.php
@@ -12,12 +12,10 @@ class Zip
 
     protected int $fileCount = 0;
 
-    protected string $pathToZip;
-
     public static function createForManifest(Manifest $manifest, string $pathToZip): self
     {
         $relativePath = config('backup.backup.source.files.relative_path') ?
-            rtrim(config('backup.backup.source.files.relative_path'), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : false;
+            rtrim((string) config('backup.backup.source.files.relative_path'), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : false;
 
         $zip = new static($pathToZip);
 
@@ -49,12 +47,10 @@ protected static function determineNameOfFileInZip(string $pathToFile, string $p
         return $pathToFile;
     }
 
-    public function __construct(string $pathToZip)
+    public function __construct(protected string $pathToZip)
     {
         $this->zipFile = new ZipArchive();
 
-        $this->pathToZip = $pathToZip;
-
         $this->open();
     }
 
@@ -106,7 +102,7 @@ public function add(string | iterable $files, string $nameInZip = null): self
             }
 
             if (is_file($file)) {
-                $this->zipFile->addFile($file, ltrim($nameInZip, DIRECTORY_SEPARATOR));
+                $this->zipFile->addFile($file, ltrim((string) $nameInZip, DIRECTORY_SEPARATOR));
 
                 if (is_int($compressionMethod)) {
                     $this->zipFile->setCompressionName(
diff --git a/src/Tasks/Cleanup/CleanupJob.php b/src/Tasks/Cleanup/CleanupJob.php
index d327cda5..c782e426 100644
--- a/src/Tasks/Cleanup/CleanupJob.php
+++ b/src/Tasks/Cleanup/CleanupJob.php
@@ -11,21 +11,13 @@
 
 class CleanupJob
 {
-    protected Collection $backupDestinations;
-
-    protected CleanupStrategy $strategy;
-
     protected bool $sendNotifications = true;
 
     public function __construct(
-        Collection $backupDestinations,
-        CleanupStrategy $strategy,
+        protected Collection $backupDestinations,
+        protected CleanupStrategy $strategy,
         bool $disableNotifications = false,
     ) {
-        $this->backupDestinations = $backupDestinations;
-
-        $this->strategy = $strategy;
-
         $this->sendNotifications = ! $disableNotifications;
     }
 
diff --git a/src/Tasks/Cleanup/Strategies/DefaultStrategy.php b/src/Tasks/Cleanup/Strategies/DefaultStrategy.php
index 81152de4..f73dca91 100644
--- a/src/Tasks/Cleanup/Strategies/DefaultStrategy.php
+++ b/src/Tasks/Cleanup/Strategies/DefaultStrategy.php
@@ -13,7 +13,7 @@ class DefaultStrategy extends CleanupStrategy
 {
     protected ?Backup $newestBackup = null;
 
-    public function deleteOldBackups(BackupCollection $backups)
+    public function deleteOldBackups(BackupCollection $backups): void
     {
         // Don't ever delete the newest backup.
         $this->newestBackup = $backups->shift();
diff --git a/tests/BackupDestination/BackupTest.php b/tests/BackupDestination/BackupTest.php
index 4dd6bf4d..9767eabd 100644
--- a/tests/BackupDestination/BackupTest.php
+++ b/tests/BackupDestination/BackupTest.php
@@ -62,7 +62,7 @@
 });
 
 it('can determine its size', function () {
-    $backup = getBackupForFile('test.zip', 0, 'this backup has content');
+    $backup = getBackupForFile('test.zip', 0);
 
     $fileSize = floatval(Storage::disk('local')->size('mysite.com/test.zip'));
 
@@ -72,7 +72,7 @@
 });
 
 it('can determine its size even after it has been deleted', function () {
-    $backup = getBackupForFile('test.zip', 0, 'this backup has content');
+    $backup = getBackupForFile('test.zip', 0);
 
     $backup->delete();
 
@@ -113,7 +113,7 @@
 });
 
 it('need a float type size', function () {
-    $backup = getBackupForFile('test.zip', 0, 'this backup has content');
+    $backup = getBackupForFile('test.zip', 0);
 
     expect($backup->sizeInBytes())->toBeFloat();
 });
diff --git a/tests/Commands/BackupCommandTest.php b/tests/Commands/BackupCommandTest.php
index 446af30b..aa157cd1 100644
--- a/tests/Commands/BackupCommandTest.php
+++ b/tests/Commands/BackupCommandTest.php
@@ -123,7 +123,7 @@
     }
     $zip->close();
 
-    expect($zipFile)->toStartWith(ltrim($this->getStubDirectory(), DIRECTORY_SEPARATOR));
+    expect($zipFile)->toStartWith(ltrim((string) $this->getStubDirectory(), DIRECTORY_SEPARATOR));
 });
 
 it('excludes the temporary directory from the backup', function () {
diff --git a/tests/Commands/CleanupCommandTest.php b/tests/Commands/CleanupCommandTest.php
index 1e717e4c..4ff893e1 100644
--- a/tests/Commands/CleanupCommandTest.php
+++ b/tests/Commands/CleanupCommandTest.php
@@ -35,7 +35,7 @@
 
             return [
                 $this->createFileOnDisk('local', "mysite/test_{$date->format('Ymd')}_first.zip", $date),
-                $this->createFileOnDisk('local', "mysite/test_{$date->format('Ymd')}_second.zip", $date->addHour(2)),
+                $this->createFileOnDisk('local', "mysite/test_{$date->format('Ymd')}_second.zip", $date->addHours(2)),
             ];
         })->partition(function (string $backupPath) {
             return in_array($backupPath, [
diff --git a/tests/Commands/MonitorCommandTest.php b/tests/Commands/MonitorCommandTest.php
index a43b7c32..ccc28270 100644
--- a/tests/Commands/MonitorCommandTest.php
+++ b/tests/Commands/MonitorCommandTest.php
@@ -7,7 +7,7 @@
 class MonitorCommandTest extends TestCase
 {
     /** @test */
-    public function it_warns_the_user_about_the_old_style_config_keys()
+    public function it_warns_the_user_about_the_old_style_config_keys(): void
     {
         $this->artisan('backup:monitor')
             ->assertSuccessful();
diff --git a/tests/FormatTest.php b/tests/FormatTest.php
index dd4bb4e0..a61d0eea 100644
--- a/tests/FormatTest.php
+++ b/tests/FormatTest.php
@@ -18,7 +18,7 @@
     Carbon::setTestNow(Carbon::create(2016, 1, 1)->startOfDay());
 
     expect(Format::ageInDays(Carbon::now()->subSeconds(5)))->toEqual('0.00 (5 seconds ago)');
-    expect(Format::ageInDays(Carbon::now()->subHour(1)))->toEqual('0.04 (1 hour ago)');
-    expect(Format::ageInDays(Carbon::now()->subHour(1)->subDay(1)))->toEqual('1.04 (1 day ago)');
-    expect(Format::ageInDays(Carbon::now()->subHour(1)->subMonths(1)))->toEqual('30.04 (4 weeks ago)');
+    expect(Format::ageInDays(Carbon::now()->subHour()))->toEqual('0.04 (1 hour ago)');
+    expect(Format::ageInDays(Carbon::now()->subHour()->subDay()))->toEqual('1.04 (1 day ago)');
+    expect(Format::ageInDays(Carbon::now()->subHour()->subMonths(1)))->toEqual('30.04 (4 weeks ago)');
 });
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 27f4ce42..67ba0c7f 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -206,7 +206,7 @@ public function getTempDirectory(?string $file = null): string
         return __DIR__.'/temp'.($file ? '/'.$file : '');
     }
 
-    public function initializeTempDirectory()
+    public function initializeTempDirectory(): void
     {
         $this->initializeDirectory($this->getTempDirectory());
     }

From 46b98e38cb175f5258bb008bccb4331f99c6d5cb Mon Sep 17 00:00:00 2001
From: Nielsvanpach <Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 07:53:49 +0000
Subject: [PATCH 3/9] Fix styling

---
 rector.php                                    |  8 ++++----
 src/BackupDestination/BackupDestination.php   |  2 +-
 src/Commands/ListCommand.php                  |  4 ++--
 src/Commands/MonitorCommand.php               |  2 +-
 src/Exceptions/CannotCreateDbDumper.php       |  2 +-
 src/Helpers/ConsoleOutput.php                 |  1 +
 src/Helpers/File.php                          |  2 +-
 .../Channels/Discord/DiscordMessage.php       |  4 +++-
 src/Notifications/EventHandler.php            |  2 +-
 src/Notifications/Notifiable.php              |  2 +-
 .../HealthyBackupWasFoundNotification.php     |  2 +-
 src/Tasks/Backup/BackupJob.php                | 19 ++++++++-----------
 src/Tasks/Backup/FileSelection.php            | 12 ++++++------
 src/Tasks/Backup/Manifest.php                 |  4 ++--
 src/Tasks/Backup/Zip.php                      |  8 ++++----
 src/Tasks/Monitor/BackupDestinationStatus.php |  2 +-
 .../BackupDestinationStatusFactory.php        |  4 ++--
 src/Traits/Retryable.php                      |  6 +++---
 tests/Commands/BackupCommandTest.php          |  2 --
 tests/Commands/ListCommandTest.php            |  2 +-
 tests/Commands/MonitorCommandTest.php         |  2 +-
 tests/DbDumperFactoryTest.php                 |  1 -
 tests/FileSelectionTest.php                   |  7 +++----
 tests/FormatTest.php                          |  1 -
 tests/Listeners/EncryptBackupArchiveTest.php  |  2 +-
 tests/ManifestTest.php                        |  1 -
 tests/Pest.php                                |  4 ++--
 tests/TestCase.php                            |  8 +++-----
 28 files changed, 54 insertions(+), 62 deletions(-)

diff --git a/rector.php b/rector.php
index eb66deb4..378933ec 100644
--- a/rector.php
+++ b/rector.php
@@ -10,10 +10,10 @@
 
 return RectorConfig::configure()
     ->withPaths([
-        __DIR__ . '/config',
-        __DIR__ . '/resources',
-        __DIR__ . '/src',
-        __DIR__ . '/tests',
+        __DIR__.'/config',
+        __DIR__.'/resources',
+        __DIR__.'/src',
+        __DIR__.'/tests',
     ])
     ->withPhpSets(php81: true)
     ->withRules([
diff --git a/src/BackupDestination/BackupDestination.php b/src/BackupDestination/BackupDestination.php
index ea271602..73d6f684 100644
--- a/src/BackupDestination/BackupDestination.php
+++ b/src/BackupDestination/BackupDestination.php
@@ -14,7 +14,7 @@ class BackupDestination
 
     protected ?BackupCollection $backupCollectionCache = null;
 
-    public function __construct(protected ?Filesystem $disk = null, protected string $backupName, protected string $diskName)
+    public function __construct(protected ?Filesystem $disk, protected string $backupName, protected string $diskName)
     {
     }
 
diff --git a/src/Commands/ListCommand.php b/src/Commands/ListCommand.php
index ac9cada7..cf63ca23 100644
--- a/src/Commands/ListCommand.php
+++ b/src/Commands/ListCommand.php
@@ -20,7 +20,7 @@ class ListCommand extends BaseCommand
     public function handle(): int
     {
         if (config()->has('backup.monitorBackups')) {
-            $this->warn("Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.");
+            $this->warn('Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.');
         }
 
         $statuses = BackupDestinationStatusFactory::createForMonitorConfig(config('backup.monitor_backups'));
@@ -98,7 +98,7 @@ protected function displayFailures(Collection $backupDestinationStatuses)
         return $this;
     }
 
-    protected function getFormattedBackupDate(Backup $backup = null)
+    protected function getFormattedBackupDate(?Backup $backup = null)
     {
         return is_null($backup)
             ? 'No backups present'
diff --git a/src/Commands/MonitorCommand.php b/src/Commands/MonitorCommand.php
index f68040bf..652cda42 100644
--- a/src/Commands/MonitorCommand.php
+++ b/src/Commands/MonitorCommand.php
@@ -18,7 +18,7 @@ class MonitorCommand extends BaseCommand implements Isolatable
     public function handle(): int
     {
         if (config()->has('backup.monitorBackups')) {
-            $this->warn("Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.");
+            $this->warn('Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.');
         }
 
         $hasError = false;
diff --git a/src/Exceptions/CannotCreateDbDumper.php b/src/Exceptions/CannotCreateDbDumper.php
index dca0e6bf..9680b20b 100644
--- a/src/Exceptions/CannotCreateDbDumper.php
+++ b/src/Exceptions/CannotCreateDbDumper.php
@@ -8,7 +8,7 @@ class CannotCreateDbDumper extends Exception
 {
     public static function unsupportedDriver(string $driver): self
     {
-        $supportedDrivers = collect(config("database.connections"))->keys();
+        $supportedDrivers = collect(config('database.connections'))->keys();
 
         $formattedSupportedDrivers = $supportedDrivers
             ->map(fn (string $supportedDriver) => "`$supportedDriver`")
diff --git a/src/Helpers/ConsoleOutput.php b/src/Helpers/ConsoleOutput.php
index dbe2728f..72107288 100644
--- a/src/Helpers/ConsoleOutput.php
+++ b/src/Helpers/ConsoleOutput.php
@@ -6,6 +6,7 @@
 
 /**
  * @phpstan-ignore-next-line
+ *
  * @mixin \Illuminate\Console\Concerns\InteractsWithIO
  */
 class ConsoleOutput
diff --git a/src/Helpers/File.php b/src/Helpers/File.php
index c1f6b2d8..bcf7a2fe 100644
--- a/src/Helpers/File.php
+++ b/src/Helpers/File.php
@@ -32,7 +32,7 @@ protected function hasAllowedMimeType(?Filesystem $disk, string $path): bool
         return in_array($this->mimeType($disk, $path), self::$allowedMimeTypes);
     }
 
-    protected function mimeType(?Filesystem $disk, string $path): bool | string
+    protected function mimeType(?Filesystem $disk, string $path): bool|string
     {
         try {
             if ($disk && method_exists($disk, 'mimeType')) {
diff --git a/src/Notifications/Channels/Discord/DiscordMessage.php b/src/Notifications/Channels/Discord/DiscordMessage.php
index b6bb5341..b7bf6555 100644
--- a/src/Notifications/Channels/Discord/DiscordMessage.php
+++ b/src/Notifications/Channels/Discord/DiscordMessage.php
@@ -7,7 +7,9 @@
 class DiscordMessage
 {
     public const COLOR_SUCCESS = '0b6623';
+
     public const COLOR_WARNING = 'fD6a02';
+
     public const COLOR_ERROR = 'e32929';
 
     protected string $username = 'Laravel Backup';
@@ -28,7 +30,7 @@ class DiscordMessage
 
     protected string $url = '';
 
-    public function from(string $username, string $avatarUrl = null): self
+    public function from(string $username, ?string $avatarUrl = null): self
     {
         $this->username = $username;
 
diff --git a/src/Notifications/EventHandler.php b/src/Notifications/EventHandler.php
index 5feb46e0..25c20f3a 100644
--- a/src/Notifications/EventHandler.php
+++ b/src/Notifications/EventHandler.php
@@ -40,7 +40,7 @@ protected function determineNotifiable()
 
     protected function determineNotification($event): Notification
     {
-        $lookingForNotificationClass = class_basename($event) . "Notification";
+        $lookingForNotificationClass = class_basename($event).'Notification';
 
         $notificationClass = collect($this->config->get('backup.notifications.notifications'))
             ->keys()
diff --git a/src/Notifications/Notifiable.php b/src/Notifications/Notifiable.php
index f20549a2..13e30475 100644
--- a/src/Notifications/Notifiable.php
+++ b/src/Notifications/Notifiable.php
@@ -8,7 +8,7 @@ class Notifiable
 {
     use NotifiableTrait;
 
-    public function routeNotificationForMail(): string | array
+    public function routeNotificationForMail(): string|array
     {
         return config('backup.notifications.mail.to');
     }
diff --git a/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php b/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php
index 6ed4a9e8..eb10b85f 100644
--- a/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php
+++ b/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php
@@ -49,7 +49,7 @@ public function toDiscord(): DiscordMessage
             ->from(config('backup.notifications.discord.username'), config('backup.notifications.discord.avatar_url'))
             ->title(
                 trans('backup::notifications.healthy_backup_found_subject_title', [
-                'application_name' => $this->applicationName(),
+                    'application_name' => $this->applicationName(),
                 ])
             )->fields($this->backupDestinationProperties()->toArray());
     }
diff --git a/src/Tasks/Backup/BackupJob.php b/src/Tasks/Backup/BackupJob.php
index c425cac5..662acfda 100644
--- a/src/Tasks/Backup/BackupJob.php
+++ b/src/Tasks/Backup/BackupJob.php
@@ -170,7 +170,7 @@ public function run(): void
 
             $this->copyToBackupDestinations($zipFile);
         } catch (Exception $exception) {
-            consoleOutput()->error("Backup failed because: {$exception->getMessage()}." . PHP_EOL . $exception->getTraceAsString());
+            consoleOutput()->error("Backup failed because: {$exception->getMessage()}.".PHP_EOL.$exception->getTraceAsString());
 
             $this->temporaryDirectory->delete();
 
@@ -211,7 +211,7 @@ protected function directoriesUsedByBackupJob(): array
         return $this->backupDestinations
             ->filter(fn (BackupDestination $backupDestination) => $backupDestination->filesystemType() === 'localfilesystemadapter')
             ->map(
-                fn (BackupDestination $backupDestination) => $backupDestination->disk()->path('') . $backupDestination->backupName()
+                fn (BackupDestination $backupDestination) => $backupDestination->disk()->path('').$backupDestination->backupName()
             )
             ->each(fn (string $backupDestinationDirectory) => $this->fileSelection->excludeFilesFrom($backupDestinationDirectory))
             ->push($this->temporaryDirectory->path())
@@ -222,7 +222,7 @@ protected function createZipContainingEveryFileInManifest(Manifest $manifest): s
     {
         consoleOutput()->info("Zipping {$manifest->count()} files and directories...");
 
-        $pathToZip = $this->temporaryDirectory->path(config('backup.backup.destination.filename_prefix') . $this->filename);
+        $pathToZip = $this->temporaryDirectory->path(config('backup.backup.destination.filename_prefix').$this->filename);
 
         $zip = Zip::createForManifest($manifest, $pathToZip);
 
@@ -240,8 +240,6 @@ protected function createZipContainingEveryFileInManifest(Manifest $manifest): s
     /**
      * Dumps the databases to the given directory.
      * Returns an array with paths to the dump files.
-     *
-     * @return array
      */
     protected function dumpDatabases(): array
     {
@@ -251,33 +249,32 @@ protected function dumpDatabases(): array
 
                 $dbType = mb_strtolower(basename(str_replace('\\', '/', $dbDumper::class)));
 
-
                 if (config('backup.backup.database_dump_filename_base') === 'connection') {
                     $dbName = $key;
                 } elseif ($dbDumper instanceof Sqlite) {
-                    $dbName = $key . '-database';
+                    $dbName = $key.'-database';
                 } else {
                     $dbName = $dbDumper->getDbName();
                 }
 
                 $timeStamp = '';
                 if ($timeStampFormat = config('backup.backup.database_dump_file_timestamp_format')) {
-                    $timeStamp = '-' . Carbon::now()->format($timeStampFormat);
+                    $timeStamp = '-'.Carbon::now()->format($timeStampFormat);
                 }
 
                 $fileName = "{$dbType}-{$dbName}{$timeStamp}.{$this->getExtension($dbDumper)}";
 
                 if (config('backup.backup.gzip_database_dump')) {
                     $dbDumper->useCompressor(new GzipCompressor());
-                    $fileName .= '.' . $dbDumper->getCompressorExtension();
+                    $fileName .= '.'.$dbDumper->getCompressorExtension();
                 }
 
                 if ($compressor = config('backup.backup.database_dump_compressor')) {
                     $dbDumper->useCompressor(new $compressor());
-                    $fileName .= '.' . $dbDumper->getCompressorExtension();
+                    $fileName .= '.'.$dbDumper->getCompressorExtension();
                 }
 
-                $temporaryFilePath = $this->temporaryDirectory->path('db-dumps' . DIRECTORY_SEPARATOR . $fileName);
+                $temporaryFilePath = $this->temporaryDirectory->path('db-dumps'.DIRECTORY_SEPARATOR.$fileName);
 
                 event(new DumpingDatabase($dbDumper));
 
diff --git a/src/Tasks/Backup/FileSelection.php b/src/Tasks/Backup/FileSelection.php
index 84071495..ff51274e 100644
--- a/src/Tasks/Backup/FileSelection.php
+++ b/src/Tasks/Backup/FileSelection.php
@@ -17,19 +17,19 @@ class FileSelection
 
     protected bool $shouldIgnoreUnreadableDirs = false;
 
-    public static function create(array | string $includeFilesAndDirectories = []): self
+    public static function create(array|string $includeFilesAndDirectories = []): self
     {
         return new static($includeFilesAndDirectories);
     }
 
-    public function __construct(array | string $includeFilesAndDirectories = [])
+    public function __construct(array|string $includeFilesAndDirectories = [])
     {
         $this->includeFilesAndDirectories = collect($includeFilesAndDirectories);
 
         $this->excludeFilesAndDirectories = collect();
     }
 
-    public function excludeFilesFrom(array | string $excludeFilesAndDirectories): self
+    public function excludeFilesFrom(array|string $excludeFilesAndDirectories): self
     {
         $this->excludeFilesAndDirectories = $this->excludeFilesAndDirectories->merge($this->sanitize($excludeFilesAndDirectories));
 
@@ -50,7 +50,7 @@ public function shouldIgnoreUnreadableDirs(bool $ignoreUnreadableDirs): self
         return $this;
     }
 
-    public function selectedFiles(): Generator | array
+    public function selectedFiles(): Generator|array
     {
         if ($this->includeFilesAndDirectories->isEmpty()) {
             return [];
@@ -105,7 +105,7 @@ protected function shouldExclude(string $path): bool
     {
         $path = realpath($path);
         if (is_dir($path)) {
-            $path .= DIRECTORY_SEPARATOR ;
+            $path .= DIRECTORY_SEPARATOR;
         }
         foreach ($this->excludeFilesAndDirectories as $excludedPath) {
             if (Str::startsWith($path, $excludedPath.(is_dir($excludedPath) ? DIRECTORY_SEPARATOR : ''))) {
@@ -120,7 +120,7 @@ protected function shouldExclude(string $path): bool
         return false;
     }
 
-    protected function sanitize(string | array $paths): Collection
+    protected function sanitize(string|array $paths): Collection
     {
         return collect($paths)
             ->reject(fn ($path) => $path === '')
diff --git a/src/Tasks/Backup/Manifest.php b/src/Tasks/Backup/Manifest.php
index fe6c233b..330b23b9 100644
--- a/src/Tasks/Backup/Manifest.php
+++ b/src/Tasks/Backup/Manifest.php
@@ -23,7 +23,7 @@ public function path(): string
         return $this->manifestPath;
     }
 
-    public function addFiles(array | string | Generator $filePaths): self
+    public function addFiles(array|string|Generator $filePaths): self
     {
         if (is_string($filePaths)) {
             $filePaths = [$filePaths];
@@ -38,7 +38,7 @@ public function addFiles(array | string | Generator $filePaths): self
         return $this;
     }
 
-    public function files(): Generator | array
+    public function files(): Generator|array
     {
         $file = new SplFileObject($this->path());
 
diff --git a/src/Tasks/Backup/Zip.php b/src/Tasks/Backup/Zip.php
index bf5c1a48..d6d664a0 100644
--- a/src/Tasks/Backup/Zip.php
+++ b/src/Tasks/Backup/Zip.php
@@ -15,7 +15,7 @@ class Zip
     public static function createForManifest(Manifest $manifest, string $pathToZip): self
     {
         $relativePath = config('backup.backup.source.files.relative_path') ?
-            rtrim((string) config('backup.backup.source.files.relative_path'), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : false;
+            rtrim((string) config('backup.backup.source.files.relative_path'), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR : false;
 
         $zip = new static($pathToZip);
 
@@ -32,9 +32,9 @@ public static function createForManifest(Manifest $manifest, string $pathToZip):
 
     protected static function determineNameOfFileInZip(string $pathToFile, string $pathToZip, string $relativePath)
     {
-        $fileDirectory = pathinfo($pathToFile, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR;
+        $fileDirectory = pathinfo($pathToFile, PATHINFO_DIRNAME).DIRECTORY_SEPARATOR;
 
-        $zipDirectory = pathinfo($pathToZip, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR;
+        $zipDirectory = pathinfo($pathToZip, PATHINFO_DIRNAME).DIRECTORY_SEPARATOR;
 
         if (Str::startsWith($fileDirectory, $zipDirectory)) {
             return substr($pathToFile, strlen($zipDirectory));
@@ -83,7 +83,7 @@ public function close(): void
         $this->zipFile->close();
     }
 
-    public function add(string | iterable $files, string $nameInZip = null): self
+    public function add(string|iterable $files, ?string $nameInZip = null): self
     {
         if (is_array($files)) {
             $nameInZip = null;
diff --git a/src/Tasks/Monitor/BackupDestinationStatus.php b/src/Tasks/Monitor/BackupDestinationStatus.php
index e63e8900..5908ef7d 100644
--- a/src/Tasks/Monitor/BackupDestinationStatus.php
+++ b/src/Tasks/Monitor/BackupDestinationStatus.php
@@ -22,7 +22,7 @@ public function backupDestination(): BackupDestination
         return $this->backupDestination;
     }
 
-    public function check(HealthCheck $check): bool | HealthCheckFailure
+    public function check(HealthCheck $check): bool|HealthCheckFailure
     {
         try {
             $check->checkHealth($this->backupDestination());
diff --git a/src/Tasks/Monitor/BackupDestinationStatusFactory.php b/src/Tasks/Monitor/BackupDestinationStatusFactory.php
index 061b3132..81036302 100644
--- a/src/Tasks/Monitor/BackupDestinationStatusFactory.php
+++ b/src/Tasks/Monitor/BackupDestinationStatusFactory.php
@@ -12,7 +12,7 @@ public static function createForMonitorConfig(array $monitorConfiguration): Coll
     {
         return collect($monitorConfiguration)
             ->flatMap(fn (array $monitorProperties) => self::createForSingleMonitor($monitorProperties))
-            ->sortBy(fn (BackupDestinationStatus $backupDestinationStatus) => $backupDestinationStatus->backupDestination()->backupName() . '-' .
+            ->sortBy(fn (BackupDestinationStatus $backupDestinationStatus) => $backupDestinationStatus->backupDestination()->backupName().'-'.
                 $backupDestinationStatus->backupDestination()->diskName());
     }
 
@@ -39,7 +39,7 @@ protected static function buildHealthChecks($monitorConfig): array
             })->toArray();
     }
 
-    protected static function buildHealthCheck(string $class, string | array $options): HealthCheck
+    protected static function buildHealthCheck(string $class, string|array $options): HealthCheck
     {
         if (! is_array($options)) {
             return new $class($options);
diff --git a/src/Traits/Retryable.php b/src/Traits/Retryable.php
index b0ef0fb6..69a973c2 100644
--- a/src/Traits/Retryable.php
+++ b/src/Traits/Retryable.php
@@ -32,16 +32,16 @@ protected function sleepFor(int $seconds = 0)
     protected function setTries(string $type)
     {
         if ($this->option('tries')) {
-            $this->tries = (int)$this->option('tries');
+            $this->tries = (int) $this->option('tries');
 
             return;
         }
 
-        $this->tries = (int)config('backup.' . $type . '.tries', 1);
+        $this->tries = (int) config('backup.'.$type.'.tries', 1);
     }
 
     protected function getRetryDelay(string $type)
     {
-        return (int)config('backup.' . $type . '.retry_delay', 0);
+        return (int) config('backup.'.$type.'.retry_delay', 0);
     }
 }
diff --git a/tests/Commands/BackupCommandTest.php b/tests/Commands/BackupCommandTest.php
index aa157cd1..c35e1498 100644
--- a/tests/Commands/BackupCommandTest.php
+++ b/tests/Commands/BackupCommandTest.php
@@ -386,7 +386,6 @@
     expect($zip->statIndex(0)['comp_method'])->toBe(ZipArchive::CM_DEFLATE);
     $zip->close();
 
-
     // check no compression with ZipArchive::CM_STORE method
     config()->set('backup.backup.destination.compression_method', ZipArchive::CM_STORE);
     config()->set('backup.backup.destination.compression_level', 0);
@@ -399,7 +398,6 @@
     expect($zip->statIndex(0)['comp_method'])->toBe(ZipArchive::CM_STORE);
     $zip->close();
 
-
     // check ZipArchive::CM_DEFLATE method with custom compression level
     config()->set('backup.backup.destination.compression_method', ZipArchive::CM_DEFLATE);
     config()->set('backup.backup.destination.compression_level', 2);
diff --git a/tests/Commands/ListCommandTest.php b/tests/Commands/ListCommandTest.php
index 35657b57..e3c12903 100644
--- a/tests/Commands/ListCommandTest.php
+++ b/tests/Commands/ListCommandTest.php
@@ -15,5 +15,5 @@
     config(['backup.monitorBackups' => config('backup.monitor_backups')]);
 
     $this->artisan('backup:list')
-        ->expectsOutput("Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.");
+        ->expectsOutput('Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.');
 });
diff --git a/tests/Commands/MonitorCommandTest.php b/tests/Commands/MonitorCommandTest.php
index ccc28270..79277a05 100644
--- a/tests/Commands/MonitorCommandTest.php
+++ b/tests/Commands/MonitorCommandTest.php
@@ -15,6 +15,6 @@ public function it_warns_the_user_about_the_old_style_config_keys(): void
         config(['backup.monitorBackups' => config('backup.monitor_backups')]);
 
         $this->artisan('backup:monitor')
-            ->expectsOutput("Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.");
+            ->expectsOutput('Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.');
     }
 }
diff --git a/tests/DbDumperFactoryTest.php b/tests/DbDumperFactoryTest.php
index d93c82ee..d45c4158 100644
--- a/tests/DbDumperFactoryTest.php
+++ b/tests/DbDumperFactoryTest.php
@@ -174,7 +174,6 @@
     expect(DbDumperFactory::createFromConnection('mysql'))->toBeInstanceOf(MongoDb::class);
 });
 
-
 function getDumpCommand(): string
 {
     $dumpFile = '';
diff --git a/tests/FileSelectionTest.php b/tests/FileSelectionTest.php
index 4c5b9eeb..db75ff40 100644
--- a/tests/FileSelectionTest.php
+++ b/tests/FileSelectionTest.php
@@ -37,7 +37,7 @@
 
 it('can exclude files from a given subdirectory', function () {
     $fileSelection = (new FileSelection($this->sourceDirectory))
-                    ->excludeFilesFrom("{$this->sourceDirectory}/directory1");
+        ->excludeFilesFrom("{$this->sourceDirectory}/directory1");
 
     $testFiles = getTestFiles([
         '.dot',
@@ -62,8 +62,8 @@
 it('can exclude files with wildcards from a given subdirectory', function () {
     $fileSelection = (new FileSelection($this->sourceDirectory))
         ->excludeFilesFrom(getTestFiles([
-            "*/file1.txt",
-            "*/directory1",
+            '*/file1.txt',
+            '*/directory1',
         ]));
 
     $testFiles = getTestFiles([
@@ -160,7 +160,6 @@
     expect($fileSelection)->toBeInstanceOf(FileSelection::class);
 });
 
-
 function assertSameArrayContent($expected, $actual, $message = '')
 {
     test()->assertCount(count($expected), array_intersect($expected, $actual), $message);
diff --git a/tests/FormatTest.php b/tests/FormatTest.php
index a61d0eea..0f61ed97 100644
--- a/tests/FormatTest.php
+++ b/tests/FormatTest.php
@@ -1,7 +1,6 @@
 <?php
 
 use Carbon\Carbon;
-
 use Spatie\Backup\Helpers\Format;
 
 it('can determine a human readable filesize', function () {
diff --git a/tests/Listeners/EncryptBackupArchiveTest.php b/tests/Listeners/EncryptBackupArchiveTest.php
index 9ea73acc..756c22d4 100644
--- a/tests/Listeners/EncryptBackupArchiveTest.php
+++ b/tests/Listeners/EncryptBackupArchiveTest.php
@@ -23,7 +23,7 @@
 });
 
 /**
- * @param int $algorithm
+ * @param  int  $algorithm
  */
 it('encrypts archive with password', function (int $algorithm) {
     config()->set('backup.backup.encryption', $algorithm);
diff --git a/tests/ManifestTest.php b/tests/ManifestTest.php
index 52f372b7..85ab2f86 100644
--- a/tests/ManifestTest.php
+++ b/tests/ManifestTest.php
@@ -67,7 +67,6 @@
     }
 });
 
-
 function getManifestTestFiles(): array
 {
     return collect(range(1, 3))
diff --git a/tests/Pest.php b/tests/Pest.php
index 0819fb64..43d20332 100644
--- a/tests/Pest.php
+++ b/tests/Pest.php
@@ -1,9 +1,9 @@
 <?php
 
-use function PHPUnit\Framework\assertTrue;
-
 use Spatie\Backup\Tests\TestCase;
 
+use function PHPUnit\Framework\assertTrue;
+
 uses(TestCase::class)->in(__DIR__);
 
 expect()->extend('hasItemContaining', function (string $searchString) {
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 67ba0c7f..dca6ea6b 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -19,9 +19,7 @@
 abstract class TestCase extends Orchestra
 {
     /**
-     * @param \Illuminate\Foundation\Application $app
-     *
-     * @return array
+     * @param  \Illuminate\Foundation\Application  $app
      */
     protected function getPackageProviders($app): array
     {
@@ -31,7 +29,7 @@ protected function getPackageProviders($app): array
     }
 
     /**
-     * @param \Illuminate\Foundation\Application $app
+     * @param  \Illuminate\Foundation\Application  $app
      */
     protected function getEnvironmentSetUp($app)
     {
@@ -236,7 +234,7 @@ public function fakeBackup(): self
         return $this;
     }
 
-    public function makeHealthCheckFail(Exception $customException = null): self
+    public function makeHealthCheckFail(?Exception $customException = null): self
     {
         FakeFailingHealthCheck::$reason = $customException;
 

From 0c66d929fc9cda8c5edbce9367a17fd33e92d863 Mon Sep 17 00:00:00 2001
From: Niels Vanpachtenbeke <10651054+Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 10:13:18 +0200
Subject: [PATCH 4/9] add code styling config

---
 rector.php | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/rector.php b/rector.php
index 378933ec..eff24e15 100644
--- a/rector.php
+++ b/rector.php
@@ -3,24 +3,32 @@
 declare(strict_types=1);
 
 use Rector\CodeQuality\Rector\ClassMethod\OptionalParametersAfterRequiredRector;
+use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
+use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
+use Rector\CodingStyle\Rector\ArrowFunction\StaticArrowFunctionRector;
+use Rector\CodingStyle\Rector\Closure\StaticClosureRector;
+use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
+use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector;
+use Rector\CodingStyle\Rector\Plus\UseIncrementAssignRector;
+use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
 use Rector\Config\RectorConfig;
 use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
-use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector;
 use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector;
 
 return RectorConfig::configure()
-    ->withPaths([
-        __DIR__.'/config',
-        __DIR__.'/resources',
-        __DIR__.'/src',
-        __DIR__.'/tests',
-    ])
+    ->withPaths(['config', 'resources', 'src', 'tests'])
     ->withPhpSets(php81: true)
-    ->withRules([
-        AddVoidReturnTypeWhereNoReturnRector::class,
-    ])
+    ->withPreparedSets(deadCode: true,codingStyle: true)
     ->withSkip([
         ReturnNeverTypeRector::class,
         OptionalParametersAfterRequiredRector::class,
         ClosureToArrowFunctionRector::class,
+        FlipTypeControlToUseExclusiveTypeRector::class,
+        ExplicitBoolCompareRector::class,
+        EncapsedStringsToSprintfRector::class,
+        StaticClosureRector::class,
+        StaticArrowFunctionRector::class,
+        UseIncrementAssignRector::class,
+        PostIncDecToPreIncDecRector::class,
+        NullableCompareToNullRector::class,
     ]);

From 225f4dff81e4faecbf6ce96a92d6615d3d99292c Mon Sep 17 00:00:00 2001
From: Niels Vanpachtenbeke <10651054+Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 10:13:41 +0200
Subject: [PATCH 5/9] apply code styling from rector

---
 phpstan-baseline.neon                              | 11 -----------
 rector.php                                         |  4 ++--
 resources/lang/fr/notifications.php                | 14 +++++++-------
 resources/lang/it/notifications.php                | 10 +++++-----
 src/Commands/BackupCommand.php                     |  1 +
 src/Commands/BaseCommand.php                       |  2 +-
 src/Exceptions/CannotCreateDbDumper.php            |  2 +-
 src/Helpers/Format.php                             |  1 +
 src/Listeners/EncryptBackupArchive.php             |  2 +-
 .../Notifications/BackupHasFailedNotification.php  |  2 +-
 .../BackupWasSuccessfulNotification.php            |  2 +-
 .../Notifications/CleanupHasFailedNotification.php |  2 +-
 .../CleanupWasSuccessfulNotification.php           |  2 +-
 .../HealthyBackupWasFoundNotification.php          |  2 +-
 .../UnhealthyBackupWasFoundNotification.php        |  2 +-
 src/Tasks/Backup/FileSelection.php                 |  3 ++-
 src/Tasks/Backup/Zip.php                           |  1 +
 tests/Commands/BackupCommandTest.php               | 11 +++++++++++
 tests/Notifications/EventHandlerTest.php           |  2 +-
 tests/TestCase.php                                 |  4 ++--
 20 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 41478adf..e69de29b 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -1,11 +0,0 @@
-parameters:
-	ignoreErrors:
-		-
-			message: "#^Deprecated in PHP 8\\.0\\: Required parameter \\$diskName follows optional parameter \\$disk\\.$#"
-			count: 1
-			path: src/BackupDestination/BackupDestination.php
-
-		-
-			message: "#^Deprecated in PHP 8\\.1\\: Required parameter \\$backupName follows optional parameter \\$disk\\.$#"
-			count: 1
-			path: src/BackupDestination/BackupDestination.php
diff --git a/rector.php b/rector.php
index eff24e15..0e029b14 100644
--- a/rector.php
+++ b/rector.php
@@ -16,9 +16,9 @@
 use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector;
 
 return RectorConfig::configure()
-    ->withPaths(['config', 'resources', 'src', 'tests'])
+    ->withPaths(['config', 'resources', 'src'])
     ->withPhpSets(php81: true)
-    ->withPreparedSets(deadCode: true,codingStyle: true)
+    ->withPreparedSets(deadCode: true, codingStyle: true, typeDeclarations: true)
     ->withSkip([
         ReturnNeverTypeRector::class,
         OptionalParametersAfterRequiredRector::class,
diff --git a/resources/lang/fr/notifications.php b/resources/lang/fr/notifications.php
index 2ae49765..ad60a5c9 100644
--- a/resources/lang/fr/notifications.php
+++ b/resources/lang/fr/notifications.php
@@ -1,10 +1,10 @@
 <?php
 
 return [
-    'exception_message' => 'Message de l\'exception : :message',
-    'exception_trace' => 'Trace de l\'exception : :trace',
-    'exception_message_title' => 'Message de l\'exception',
-    'exception_trace_title' => 'Trace de l\'exception',
+    'exception_message' => "Message de l'exception : :message",
+    'exception_trace' => "Trace de l'exception : :trace",
+    'exception_message_title' => "Message de l'exception",
+    'exception_trace_title' => "Trace de l'exception",
 
     'backup_failed_subject' => 'Échec de la sauvegarde de :application_name',
     'backup_failed_body' => 'Important : Une erreur est survenue lors de la sauvegarde de :application_name',
@@ -27,14 +27,14 @@
     'unhealthy_backup_found_subject' => 'Important : Les sauvegardes pour :application_name sont corrompues',
     'unhealthy_backup_found_subject_title' => 'Important : Les sauvegardes pour :application_name sont corrompues. :problem',
     'unhealthy_backup_found_body' => 'Les sauvegardes pour :application_name sur le disque :disk_name sont corrompues.',
-    'unhealthy_backup_found_not_reachable' => 'La destination de la sauvegarde n\'est pas accessible. :error',
-    'unhealthy_backup_found_empty' => 'Il n\'y a aucune sauvegarde pour cette application.',
+    'unhealthy_backup_found_not_reachable' => "La destination de la sauvegarde n'est pas accessible. :error",
+    'unhealthy_backup_found_empty' => "Il n'y a aucune sauvegarde pour cette application.",
     'unhealthy_backup_found_old' => 'La dernière sauvegarde du :date est considérée trop vieille.',
     'unhealthy_backup_found_unknown' => 'Désolé, une raison exacte ne peut être déterminée.',
     'unhealthy_backup_found_full' => 'Les sauvegardes utilisent trop d\'espace disque. L\'utilisation actuelle est de :disk_usage alors que la limite autorisée est de :disk_limit.',
 
     'no_backups_info' => 'Aucune sauvegarde n\'a encore été effectuée',
-    'application_name' => 'Nom de l\'application',
+    'application_name' => "Nom de l'application",
     'backup_name' => 'Nom de la sauvegarde',
     'disk' => 'Disque',
     'newest_backup_size' => 'Taille de la sauvegarde la plus récente',
diff --git a/resources/lang/it/notifications.php b/resources/lang/it/notifications.php
index 94fe1415..e96618d0 100644
--- a/resources/lang/it/notifications.php
+++ b/resources/lang/it/notifications.php
@@ -1,10 +1,10 @@
 <?php
 
 return [
-    'exception_message' => 'Messaggio dell\'eccezione: :message',
-    'exception_trace' => 'Traccia dell\'eccezione: :trace',
-    'exception_message_title' => 'Messaggio dell\'eccezione',
-    'exception_trace_title' => 'Traccia dell\'eccezione',
+    'exception_message' => "Messaggio dell'eccezione: :message",
+    'exception_trace' => "Traccia dell'eccezione: :trace",
+    'exception_message_title' => "Messaggio dell'eccezione",
+    'exception_trace_title' => "Traccia dell'eccezione",
 
     'backup_failed_subject' => 'Fallito il backup di :application_name',
     'backup_failed_body' => 'Importante: Si è verificato un errore durante il backup di :application_name',
@@ -34,7 +34,7 @@
     'unhealthy_backup_found_full' => 'I backup utilizzano troppa memoria. L\'utilizzo corrente è :disk_usage che è superiore al limite consentito di :disk_limit.',
 
     'no_backups_info' => 'Non sono stati ancora effettuati backup',
-    'application_name' => 'Nome dell\'applicazione',
+    'application_name' => "Nome dell'applicazione",
     'backup_name' => 'Nome di backup',
     'disk' => 'Disco',
     'newest_backup_size' => 'Dimensione backup più recente',
diff --git a/src/Commands/BackupCommand.php b/src/Commands/BackupCommand.php
index 6dba3b7c..b69d5cfd 100644
--- a/src/Commands/BackupCommand.php
+++ b/src/Commands/BackupCommand.php
@@ -36,6 +36,7 @@ public function handle(): int
             if ($this->option('only-db')) {
                 $backupJob->dontBackupFilesystem();
             }
+
             if ($this->option('db-name')) {
                 $backupJob->onlyDbName($this->option('db-name'));
             }
diff --git a/src/Commands/BaseCommand.php b/src/Commands/BaseCommand.php
index c12ad4f5..0762f723 100644
--- a/src/Commands/BaseCommand.php
+++ b/src/Commands/BaseCommand.php
@@ -30,7 +30,7 @@ public function run(InputInterface $input, OutputInterface $output): int
 
     protected function runningInConsole(): bool
     {
-        return in_array(php_sapi_name(), ['cli', 'phpdbg']);
+        return in_array(PHP_SAPI, ['cli', 'phpdbg']);
     }
 
     public function getSubscribedSignals(): array
diff --git a/src/Exceptions/CannotCreateDbDumper.php b/src/Exceptions/CannotCreateDbDumper.php
index 9680b20b..3c756a23 100644
--- a/src/Exceptions/CannotCreateDbDumper.php
+++ b/src/Exceptions/CannotCreateDbDumper.php
@@ -11,7 +11,7 @@ public static function unsupportedDriver(string $driver): self
         $supportedDrivers = collect(config('database.connections'))->keys();
 
         $formattedSupportedDrivers = $supportedDrivers
-            ->map(fn (string $supportedDriver) => "`$supportedDriver`")
+            ->map(fn (string $supportedDriver) => "`{$supportedDriver}`")
             ->join(glue: ', ', finalGlue: ' or ');
 
         return new static("Cannot create a dumper for db driver `{$driver}`. Use {$formattedSupportedDrivers}.");
diff --git a/src/Helpers/Format.php b/src/Helpers/Format.php
index 07903a95..49a6ed19 100644
--- a/src/Helpers/Format.php
+++ b/src/Helpers/Format.php
@@ -13,6 +13,7 @@ public static function humanReadableSize(float $sizeInBytes): string
         if ($sizeInBytes === 0.0) {
             return '0 '.$units[1];
         }
+
         for ($i = 0; $sizeInBytes > 1024; $i++) {
             $sizeInBytes /= 1024;
         }
diff --git a/src/Listeners/EncryptBackupArchive.php b/src/Listeners/EncryptBackupArchive.php
index 35d62b1d..ceca313b 100644
--- a/src/Listeners/EncryptBackupArchive.php
+++ b/src/Listeners/EncryptBackupArchive.php
@@ -57,7 +57,7 @@ protected static function getAlgorithm(): ?int
         $encryption = config('backup.backup.encryption');
 
         if ($encryption === 'default') {
-            $encryption = defined("\ZipArchive::EM_AES_256")
+            $encryption = defined(\ZipArchive::class . '::EM_AES_256')
                 ? ZipArchive::EM_AES_256
                 : null;
         }
diff --git a/src/Notifications/Notifications/BackupHasFailedNotification.php b/src/Notifications/Notifications/BackupHasFailedNotification.php
index 64d99bd8..bf4cea52 100644
--- a/src/Notifications/Notifications/BackupHasFailedNotification.php
+++ b/src/Notifications/Notifications/BackupHasFailedNotification.php
@@ -26,7 +26,7 @@ public function toMail(): MailMessage
             ->line(trans('backup::notifications.exception_message', ['message' => $this->event->exception->getMessage()]))
             ->line(trans('backup::notifications.exception_trace', ['trace' => $this->event->exception->getTraceAsString()]));
 
-        $this->backupDestinationProperties()->each(fn ($value, $name) => $mailMessage->line("{$name}: $value"));
+        $this->backupDestinationProperties()->each(fn ($value, $name) => $mailMessage->line("{$name}: {$value}"));
 
         return $mailMessage;
     }
diff --git a/src/Notifications/Notifications/BackupWasSuccessfulNotification.php b/src/Notifications/Notifications/BackupWasSuccessfulNotification.php
index 013bafc9..2b21b335 100644
--- a/src/Notifications/Notifications/BackupWasSuccessfulNotification.php
+++ b/src/Notifications/Notifications/BackupWasSuccessfulNotification.php
@@ -24,7 +24,7 @@ public function toMail(): MailMessage
             ->line(trans('backup::notifications.backup_successful_body', ['application_name' => $this->applicationName(), 'disk_name' => $this->diskName()]));
 
         $this->backupDestinationProperties()->each(function ($value, $name) use ($mailMessage) {
-            $mailMessage->line("{$name}: $value");
+            $mailMessage->line("{$name}: {$value}");
         });
 
         return $mailMessage;
diff --git a/src/Notifications/Notifications/CleanupHasFailedNotification.php b/src/Notifications/Notifications/CleanupHasFailedNotification.php
index 42cf2383..0a76876b 100644
--- a/src/Notifications/Notifications/CleanupHasFailedNotification.php
+++ b/src/Notifications/Notifications/CleanupHasFailedNotification.php
@@ -27,7 +27,7 @@ public function toMail(): MailMessage
             ->line(trans('backup::notifications.exception_trace', ['trace' => $this->event->exception->getTraceAsString()]));
 
         $this->backupDestinationProperties()->each(function ($value, $name) use ($mailMessage) {
-            $mailMessage->line("{$name}: $value");
+            $mailMessage->line("{$name}: {$value}");
         });
 
         return $mailMessage;
diff --git a/src/Notifications/Notifications/CleanupWasSuccessfulNotification.php b/src/Notifications/Notifications/CleanupWasSuccessfulNotification.php
index b554be0d..8ab7da53 100644
--- a/src/Notifications/Notifications/CleanupWasSuccessfulNotification.php
+++ b/src/Notifications/Notifications/CleanupWasSuccessfulNotification.php
@@ -24,7 +24,7 @@ public function toMail(): MailMessage
             ->line(trans('backup::notifications.cleanup_successful_body', ['application_name' => $this->applicationName(), 'disk_name' => $this->diskName()]));
 
         $this->backupDestinationProperties()->each(function ($value, $name) use ($mailMessage) {
-            $mailMessage->line("{$name}: $value");
+            $mailMessage->line("{$name}: {$value}");
         });
 
         return $mailMessage;
diff --git a/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php b/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php
index eb10b85f..44ed0d1b 100644
--- a/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php
+++ b/src/Notifications/Notifications/HealthyBackupWasFoundNotification.php
@@ -24,7 +24,7 @@ public function toMail(): MailMessage
             ->line(trans('backup::notifications.healthy_backup_found_body', ['application_name' => $this->applicationName()]));
 
         $this->backupDestinationProperties()->each(function ($value, $name) use ($mailMessage) {
-            $mailMessage->line("{$name}: $value");
+            $mailMessage->line("{$name}: {$value}");
         });
 
         return $mailMessage;
diff --git a/src/Notifications/Notifications/UnhealthyBackupWasFoundNotification.php b/src/Notifications/Notifications/UnhealthyBackupWasFoundNotification.php
index 4e7570f8..8c7fab75 100644
--- a/src/Notifications/Notifications/UnhealthyBackupWasFoundNotification.php
+++ b/src/Notifications/Notifications/UnhealthyBackupWasFoundNotification.php
@@ -27,7 +27,7 @@ public function toMail(): MailMessage
             ->line($this->problemDescription());
 
         $this->backupDestinationProperties()->each(function ($value, $name) use ($mailMessage) {
-            $mailMessage->line("{$name}: $value");
+            $mailMessage->line("{$name}: {$value}");
         });
 
         if ($this->failure()->wasUnexpected()) {
diff --git a/src/Tasks/Backup/FileSelection.php b/src/Tasks/Backup/FileSelection.php
index ff51274e..a11f6b08 100644
--- a/src/Tasks/Backup/FileSelection.php
+++ b/src/Tasks/Backup/FileSelection.php
@@ -72,7 +72,7 @@ public function selectedFiles(): Generator|array
             yield $includedFile;
         }
 
-        if (! count($this->includedDirectories())) {
+        if ($this->includedDirectories() === []) {
             return [];
         }
 
@@ -107,6 +107,7 @@ protected function shouldExclude(string $path): bool
         if (is_dir($path)) {
             $path .= DIRECTORY_SEPARATOR;
         }
+
         foreach ($this->excludeFilesAndDirectories as $excludedPath) {
             if (Str::startsWith($path, $excludedPath.(is_dir($excludedPath) ? DIRECTORY_SEPARATOR : ''))) {
                 if ($path != $excludedPath && is_file($excludedPath)) {
diff --git a/src/Tasks/Backup/Zip.php b/src/Tasks/Backup/Zip.php
index d6d664a0..1234649a 100644
--- a/src/Tasks/Backup/Zip.php
+++ b/src/Tasks/Backup/Zip.php
@@ -112,6 +112,7 @@ public function add(string|iterable $files, ?string $nameInZip = null): self
                     );
                 }
             }
+
             $this->fileCount++;
         }
 
diff --git a/tests/Commands/BackupCommandTest.php b/tests/Commands/BackupCommandTest.php
index c35e1498..3b883325 100644
--- a/tests/Commands/BackupCommandTest.php
+++ b/tests/Commands/BackupCommandTest.php
@@ -102,6 +102,7 @@
     foreach (range(0, $zip->numFiles - 1) as $i) {
         $zipFiles[] = $zip->statIndex($i)['name'];
     }
+
     $zip->close();
     sort($testFiles);
     sort($zipFiles);
@@ -121,6 +122,7 @@
     if ($zip->numFiles) {
         $zipFile = $zip->statIndex(0)['name'];
     }
+
     $zip->close();
 
     expect($zipFile)->toStartWith(ltrim((string) $this->getStubDirectory(), DIRECTORY_SEPARATOR));
@@ -132,6 +134,7 @@
     if (! file_exists($tempDirectoryPath)) {
         mkdir($tempDirectoryPath, 0777, true);
     }
+
     touch($tempDirectoryPath.DIRECTORY_SEPARATOR.'testing-file-temp.txt');
 
     $this->artisan('backup:run --only-files')->assertExitCode(0);
@@ -367,8 +370,10 @@
 
     $zip = new ZipArchive();
     $zip->open(Storage::disk('local')->path($this->expectedZipPath));
+
     expect($zip->numFiles)->toBe(1);
     expect($zip->statIndex(0)['encryption_method'])->toBe(ZipArchive::EM_AES_256);
+
     $zip->close();
 
     Event::assertNotDispatched(BackupZipWasCreated::class);
@@ -382,8 +387,10 @@
 
     $zip = new ZipArchive();
     $zip->open(Storage::disk('local')->path($this->expectedZipPath));
+
     expect($zip->numFiles)->toBe(1);
     expect($zip->statIndex(0)['comp_method'])->toBe(ZipArchive::CM_DEFLATE);
+
     $zip->close();
 
     // check no compression with ZipArchive::CM_STORE method
@@ -394,8 +401,10 @@
 
     $zip = new ZipArchive();
     $zip->open(Storage::disk('local')->path($this->expectedZipPath));
+
     expect($zip->numFiles)->toBe(1);
     expect($zip->statIndex(0)['comp_method'])->toBe(ZipArchive::CM_STORE);
+
     $zip->close();
 
     // check ZipArchive::CM_DEFLATE method with custom compression level
@@ -406,8 +415,10 @@
 
     $zip = new ZipArchive();
     $zip->open(Storage::disk('local')->path($this->expectedZipPath));
+
     expect($zip->numFiles)->toBe(1);
     expect($zip->statIndex(0)['comp_method'])->toBe(ZipArchive::CM_DEFLATE);
+
     $zip->close();
 });
 
diff --git a/tests/Notifications/EventHandlerTest.php b/tests/Notifications/EventHandlerTest.php
index b001bc39..5da94435 100644
--- a/tests/Notifications/EventHandlerTest.php
+++ b/tests/Notifications/EventHandlerTest.php
@@ -4,7 +4,7 @@
 use Spatie\Backup\BackupDestination\BackupDestinationFactory;
 use Spatie\Backup\Events\BackupHasFailed;
 use Spatie\Backup\Notifications\Notifiable;
-use Spatie\Backup\Notifications\Notifications\BackupHasFailedNotification as BackupHasFailedNotification;
+use Spatie\Backup\Notifications\Notifications\BackupHasFailedNotification;
 
 beforeEach(function () {
     Notification::fake();
diff --git a/tests/TestCase.php b/tests/TestCase.php
index dca6ea6b..28b699ef 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -72,7 +72,7 @@ protected function seeInConsoleOutput(string $expectedText): void
         $this->assertStringContainsString(
             $expectedText,
             $consoleOutput,
-            "Did not see `{$expectedText}` in console output: `$consoleOutput`"
+            "Did not see `{$expectedText}` in console output: `{$consoleOutput}`"
         );
     }
 
@@ -83,7 +83,7 @@ protected function doNotSeeInConsoleOutput(string $unexpectedText): void
         $this->assertNotContains(
             $unexpectedText,
             $consoleOutput,
-            "Did not expect to see `{$unexpectedText}` in console output: `$consoleOutput`"
+            "Did not expect to see `{$unexpectedText}` in console output: `{$consoleOutput}`"
         );
     }
 

From e835ce842a7a8003296af9f14d7191cd7396ce1a Mon Sep 17 00:00:00 2001
From: Nielsvanpach <Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 08:17:10 +0000
Subject: [PATCH 6/9] Fix styling

---
 src/Listeners/EncryptBackupArchive.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Listeners/EncryptBackupArchive.php b/src/Listeners/EncryptBackupArchive.php
index ceca313b..230aa700 100644
--- a/src/Listeners/EncryptBackupArchive.php
+++ b/src/Listeners/EncryptBackupArchive.php
@@ -57,7 +57,7 @@ protected static function getAlgorithm(): ?int
         $encryption = config('backup.backup.encryption');
 
         if ($encryption === 'default') {
-            $encryption = defined(\ZipArchive::class . '::EM_AES_256')
+            $encryption = defined(\ZipArchive::class.'::EM_AES_256')
                 ? ZipArchive::EM_AES_256
                 : null;
         }

From 1b1fa88c43f539344afbf938e4938027a9918679 Mon Sep 17 00:00:00 2001
From: Niels Vanpachtenbeke <10651054+Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 10:20:55 +0200
Subject: [PATCH 7/9] add return types

---
 rector.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/rector.php b/rector.php
index 0e029b14..a81f8384 100644
--- a/rector.php
+++ b/rector.php
@@ -13,6 +13,7 @@
 use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
 use Rector\Config\RectorConfig;
 use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
+use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;
 use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector;
 
 return RectorConfig::configure()
@@ -31,4 +32,5 @@
         UseIncrementAssignRector::class,
         PostIncDecToPreIncDecRector::class,
         NullableCompareToNullRector::class,
+        AddArrowFunctionReturnTypeRector::class,
     ]);

From a93a5b8d4fcfd65d961600faf3e67dca93851f5b Mon Sep 17 00:00:00 2001
From: Niels Vanpachtenbeke <10651054+Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 10:59:48 +0200
Subject: [PATCH 8/9] add more types

---
 composer.json                                 |  4 +-
 phpstan-baseline.neon                         | 56 +++++++++++++++++++
 phpstan.neon.dist                             |  2 +-
 src/BackupDestination/Backup.php              |  1 +
 src/BackupDestination/BackupCollection.php    |  2 +
 src/BackupDestination/BackupDestination.php   |  1 +
 .../BackupDestinationFactory.php              |  4 ++
 src/BackupServiceProvider.php                 |  2 +-
 src/Commands/BackupCommand.php                |  2 +-
 src/Commands/BaseCommand.php                  |  2 +
 src/Commands/ListCommand.php                  | 11 +++-
 src/Exceptions/CannotCreateDbDumper.php       |  8 ++-
 src/Exceptions/NotificationCouldNotBeSent.php |  2 +-
 src/Helpers/ConsoleOutput.php                 |  3 +-
 src/Helpers/File.php                          |  1 +
 src/Notifications/BaseNotification.php        |  2 +
 .../Channels/Discord/DiscordChannel.php       |  3 +-
 .../Channels/Discord/DiscordMessage.php       |  4 +-
 src/Notifications/EventHandler.php            | 10 +++-
 src/Notifications/Notifiable.php              |  1 +
 src/Tasks/Backup/BackupJob.php                | 17 ++++--
 src/Tasks/Backup/BackupJobFactory.php         |  7 +++
 src/Tasks/Backup/DbDumperFactory.php          |  8 ++-
 src/Tasks/Backup/FileSelection.php            | 24 ++++++--
 src/Tasks/Backup/Manifest.php                 |  3 +
 src/Tasks/Backup/Zip.php                      |  2 +-
 src/Tasks/Cleanup/CleanupJob.php              |  3 +-
 src/Tasks/Cleanup/CleanupStrategy.php         |  2 +-
 .../Cleanup/Strategies/DefaultStrategy.php    | 14 +++--
 src/Tasks/Monitor/BackupDestinationStatus.php |  2 +
 .../BackupDestinationStatusFactory.php        | 27 ++++++++-
 src/Tasks/Monitor/HealthCheck.php             |  2 +-
 src/Traits/Retryable.php                      | 10 ++--
 tests/TestSupport/FakeFailingHealthCheck.php  |  2 +-
 34 files changed, 195 insertions(+), 49 deletions(-)

diff --git a/composer.json b/composer.json
index ffaea00b..d41ff2e0 100644
--- a/composer.json
+++ b/composer.json
@@ -32,10 +32,10 @@
         "spatie/laravel-signal-aware-command": "^1.2|^2.0",
         "spatie/temporary-directory": "^2.0",
         "symfony/console": "^6.0|^7.0",
-        "symfony/finder": "^6.0|^7.0"
+        "symfony/finder": "^6.0|^7.0",
+        "ext-pcntl": "*"
     },
     "require-dev": {
-        "ext-pcntl": "*",
         "composer-runtime-api": "^2.0",
         "larastan/larastan": "^2.7.0",
         "laravel/slack-notification-channel": "^2.5|^3.0",
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index e69de29b..c56c638a 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -0,0 +1,56 @@
+parameters:
+	ignoreErrors:
+		-
+			message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<int,Spatie\\\\Backup\\\\BackupDestination\\\\Backup\\>\\:\\:filter\\(\\) expects \\(callable\\(Spatie\\\\Backup\\\\BackupDestination\\\\Backup, int\\)\\: bool\\)\\|null, Closure\\(string\\)\\: bool given\\.$#"
+			count: 1
+			path: src/BackupDestination/BackupCollection.php
+
+		-
+			message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<int,Spatie\\\\Backup\\\\BackupDestination\\\\Backup\\>\\:\\:map\\(\\) expects callable\\(Spatie\\\\Backup\\\\BackupDestination\\\\Backup, int\\)\\: Spatie\\\\Backup\\\\BackupDestination\\\\Backup, Closure\\(string\\)\\: Spatie\\\\Backup\\\\BackupDestination\\\\Backup given\\.$#"
+			count: 1
+			path: src/BackupDestination/BackupCollection.php
+
+		-
+			message: "#^Unable to resolve the template type TKey in call to function collect$#"
+			count: 1
+			path: src/BackupDestination/BackupDestinationFactory.php
+
+		-
+			message: "#^Unable to resolve the template type TValue in call to function collect$#"
+			count: 1
+			path: src/BackupDestination/BackupDestinationFactory.php
+
+		-
+			message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<int,int\\>\\:\\:map\\(\\) expects callable\\(int, int\\)\\: string, Closure\\(string\\)\\: non\\-falsy\\-string given\\.$#"
+			count: 1
+			path: src/Exceptions/CannotCreateDbDumper.php
+
+		-
+			message: "#^Method Spatie\\\\Backup\\\\Notifications\\\\Channels\\\\Discord\\\\DiscordMessage\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
+			count: 1
+			path: src/Notifications/Channels/Discord/DiscordMessage.php
+
+		-
+			message: "#^Method Spatie\\\\Backup\\\\Tasks\\\\Backup\\\\FileSelection\\:\\:sanitize\\(\\) return type with generic class Illuminate\\\\Support\\\\Collection does not specify its types\\: TKey, TValue$#"
+			count: 1
+			path: src/Tasks/Backup/FileSelection.php
+
+		-
+			message: "#^Method Spatie\\\\Backup\\\\Tasks\\\\Backup\\\\Manifest\\:\\:files\\(\\) return type has no value type specified in iterable type array\\.$#"
+			count: 1
+			path: src/Tasks/Backup/Manifest.php
+
+		-
+			message: "#^Method Spatie\\\\Backup\\\\Tasks\\\\Backup\\\\Manifest\\:\\:files\\(\\) return type has no value type specified in iterable type array\\|Generator\\.$#"
+			count: 1
+			path: src/Tasks/Backup/Manifest.php
+
+		-
+			message: "#^Method Spatie\\\\Backup\\\\Tasks\\\\Backup\\\\Zip\\:\\:add\\(\\) has parameter \\$files with no value type specified in iterable type iterable\\.$#"
+			count: 1
+			path: src/Tasks/Backup/Zip.php
+
+		-
+			message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<int,Spatie\\\\Backup\\\\BackupDestination\\\\Backup\\>\\:\\:each\\(\\) expects callable\\(Spatie\\\\Backup\\\\BackupDestination\\\\Backup, int\\)\\: mixed, Closure\\(Spatie\\\\Backup\\\\BackupDestination\\\\BackupCollection\\)\\: void given\\.$#"
+			count: 1
+			path: src/Tasks/Cleanup/Strategies/DefaultStrategy.php
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 81a4e5b0..685a823f 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -2,7 +2,7 @@ includes:
     - phpstan-baseline.neon
 
 parameters:
-    level: 5
+    level: 6
     paths:
         - src
         - config
diff --git a/src/BackupDestination/Backup.php b/src/BackupDestination/Backup.php
index b4b4c0f7..6a0d6d31 100644
--- a/src/BackupDestination/Backup.php
+++ b/src/BackupDestination/Backup.php
@@ -66,6 +66,7 @@ public function sizeInBytes(): float
         return $this->size;
     }
 
+    /** @return resource */
     public function stream()
     {
         return throw_unless(
diff --git a/src/BackupDestination/BackupCollection.php b/src/BackupDestination/BackupCollection.php
index 514c1bfa..dc998fdf 100644
--- a/src/BackupDestination/BackupCollection.php
+++ b/src/BackupDestination/BackupCollection.php
@@ -6,10 +6,12 @@
 use Illuminate\Support\Collection;
 use Spatie\Backup\Helpers\File;
 
+/** @extends Collection<int,Backup> */
 class BackupCollection extends Collection
 {
     protected ?float $sizeCache = null;
 
+    /** @param array<string> $files */
     public static function createFromFiles(?FileSystem $disk, array $files): self
     {
         return (new static($files))
diff --git a/src/BackupDestination/BackupDestination.php b/src/BackupDestination/BackupDestination.php
index 73d6f684..3ef69882 100644
--- a/src/BackupDestination/BackupDestination.php
+++ b/src/BackupDestination/BackupDestination.php
@@ -114,6 +114,7 @@ public function connectionError(): Exception
         return $this->connectionError;
     }
 
+    /** @return array<string, string> */
     public function getDiskOptions(): array
     {
         return config("filesystems.disks.{$this->diskName()}.backup_options") ?? [];
diff --git a/src/BackupDestination/BackupDestinationFactory.php b/src/BackupDestination/BackupDestinationFactory.php
index 3212470a..99c085b4 100644
--- a/src/BackupDestination/BackupDestinationFactory.php
+++ b/src/BackupDestination/BackupDestinationFactory.php
@@ -6,6 +6,10 @@
 
 class BackupDestinationFactory
 {
+    /**
+     * @param array<string, mixed> $config
+     * @return Collection<int, BackupDestination>
+     */
     public static function createFromArray(array $config): Collection
     {
         return collect($config['destination']['disks'])
diff --git a/src/BackupServiceProvider.php b/src/BackupServiceProvider.php
index 8e460d53..ecd087bb 100644
--- a/src/BackupServiceProvider.php
+++ b/src/BackupServiceProvider.php
@@ -52,7 +52,7 @@ public function packageRegistered(): void
         $this->registerDiscordChannel();
     }
 
-    protected function registerDiscordChannel()
+    protected function registerDiscordChannel(): void
     {
         Notification::resolved(function (ChannelManager $service) {
             $service->extend('discord', function ($app) {
diff --git a/src/Commands/BackupCommand.php b/src/Commands/BackupCommand.php
index b69d5cfd..07dfdaa7 100644
--- a/src/Commands/BackupCommand.php
+++ b/src/Commands/BackupCommand.php
@@ -95,7 +95,7 @@ public function handle(): int
         }
     }
 
-    protected function guardAgainstInvalidOptions()
+    protected function guardAgainstInvalidOptions(): void
     {
         if (! $this->option('only-db')) {
             return;
diff --git a/src/Commands/BaseCommand.php b/src/Commands/BaseCommand.php
index 0762f723..b05aaf56 100644
--- a/src/Commands/BaseCommand.php
+++ b/src/Commands/BaseCommand.php
@@ -10,6 +10,7 @@
 
 abstract class BaseCommand extends SignalAwareCommand
 {
+    /** @var array<int> */
     protected array $handlesSignals = [];
 
     public function __construct()
@@ -33,6 +34,7 @@ protected function runningInConsole(): bool
         return in_array(PHP_SAPI, ['cli', 'phpdbg']);
     }
 
+    /** @return array<int> */
     public function getSubscribedSignals(): array
     {
         return $this->handlesSignals;
diff --git a/src/Commands/ListCommand.php b/src/Commands/ListCommand.php
index cf63ca23..94d961e3 100644
--- a/src/Commands/ListCommand.php
+++ b/src/Commands/ListCommand.php
@@ -30,7 +30,10 @@ public function handle(): int
         return static::SUCCESS;
     }
 
-    protected function displayOverview(Collection $backupDestinationStatuses)
+    /**
+     * @param Collection<int, BackupDestinationStatus> $backupDestinationStatuses
+     */
+    protected function displayOverview(Collection $backupDestinationStatuses): static
     {
         $headers = ['Name', 'Disk', 'Reachable', 'Healthy', '# of backups', 'Newest backup', 'Used storage'];
 
@@ -46,6 +49,7 @@ protected function displayOverview(Collection $backupDestinationStatuses)
         return $this;
     }
 
+    /** @return array{0: string, 1: string, 2: string, disk: string, amount: integer, newest: string, usedStorage: string} */
     public function convertToRow(BackupDestinationStatus $backupDestinationStatus): array
     {
         $destination = $backupDestinationStatus->backupDestination();
@@ -73,7 +77,8 @@ public function convertToRow(BackupDestinationStatus $backupDestinationStatus):
         return $row;
     }
 
-    protected function displayFailures(Collection $backupDestinationStatuses)
+    /** @param Collection<int, BackupDestinationStatus> $backupDestinationStatuses */
+    protected function displayFailures(Collection $backupDestinationStatuses): static
     {
         $failed = $backupDestinationStatuses
             ->filter(function (BackupDestinationStatus $backupDestinationStatus) {
@@ -98,7 +103,7 @@ protected function displayFailures(Collection $backupDestinationStatuses)
         return $this;
     }
 
-    protected function getFormattedBackupDate(?Backup $backup = null)
+    protected function getFormattedBackupDate(?Backup $backup = null): string
     {
         return is_null($backup)
             ? 'No backups present'
diff --git a/src/Exceptions/CannotCreateDbDumper.php b/src/Exceptions/CannotCreateDbDumper.php
index 3c756a23..5fabe436 100644
--- a/src/Exceptions/CannotCreateDbDumper.php
+++ b/src/Exceptions/CannotCreateDbDumper.php
@@ -6,11 +6,13 @@
 
 class CannotCreateDbDumper extends Exception
 {
-    public static function unsupportedDriver(string $driver): self
+    public static function unsupportedDriver(string $driver): static
     {
-        $supportedDrivers = collect(config('database.connections'))->keys();
+        /** @var array<int, string> $supportedDrivers */
+        $supportedDrivers = config('database.connections');
 
-        $formattedSupportedDrivers = $supportedDrivers
+        $formattedSupportedDrivers = collect($supportedDrivers)
+            ->keys()
             ->map(fn (string $supportedDriver) => "`{$supportedDriver}`")
             ->join(glue: ', ', finalGlue: ' or ');
 
diff --git a/src/Exceptions/NotificationCouldNotBeSent.php b/src/Exceptions/NotificationCouldNotBeSent.php
index b01d0c17..c09dfad1 100644
--- a/src/Exceptions/NotificationCouldNotBeSent.php
+++ b/src/Exceptions/NotificationCouldNotBeSent.php
@@ -6,7 +6,7 @@
 
 class NotificationCouldNotBeSent extends Exception
 {
-    public static function noNotificationClassForEvent($event): self
+    public static function noNotificationClassForEvent(object $event): static
     {
         $eventClass = $event::class;
 
diff --git a/src/Helpers/ConsoleOutput.php b/src/Helpers/ConsoleOutput.php
index 72107288..8294d3ab 100644
--- a/src/Helpers/ConsoleOutput.php
+++ b/src/Helpers/ConsoleOutput.php
@@ -18,7 +18,8 @@ public function setCommand(Command $command): void
         $this->command = $command;
     }
 
-    public function __call(string $method, array $arguments)
+    /** @param array<int, mixed> $arguments */
+    public function __call(string $method, array $arguments): void
     {
         $consoleOutput = app(static::class);
 
diff --git a/src/Helpers/File.php b/src/Helpers/File.php
index bcf7a2fe..0c33b3d1 100644
--- a/src/Helpers/File.php
+++ b/src/Helpers/File.php
@@ -7,6 +7,7 @@
 
 class File
 {
+    /** @var array<string> */
     protected static array $allowedMimeTypes = [
         'application/zip',
         'application/x-zip',
diff --git a/src/Notifications/BaseNotification.php b/src/Notifications/BaseNotification.php
index 9a509e9f..d91d75e4 100644
--- a/src/Notifications/BaseNotification.php
+++ b/src/Notifications/BaseNotification.php
@@ -9,6 +9,7 @@
 
 abstract class BaseNotification extends Notification
 {
+    /** @return array<string, string> */
     public function via(): array
     {
         $notificationChannels = config('backup.notifications.notifications.'.static::class);
@@ -34,6 +35,7 @@ public function diskName(): string
         return $this->backupDestination()->diskName();
     }
 
+    /** @return Collection<string, string>  */
     protected function backupDestinationProperties(): Collection
     {
         $backupDestination = $this->backupDestination();
diff --git a/src/Notifications/Channels/Discord/DiscordChannel.php b/src/Notifications/Channels/Discord/DiscordChannel.php
index 6571e12d..93c32230 100644
--- a/src/Notifications/Channels/Discord/DiscordChannel.php
+++ b/src/Notifications/Channels/Discord/DiscordChannel.php
@@ -4,10 +4,11 @@
 
 use Illuminate\Notifications\Notification;
 use Illuminate\Support\Facades\Http;
+use Spatie\Backup\Notifications\Notifiable;
 
 class DiscordChannel
 {
-    public function send($notifiable, Notification $notification): void
+    public function send(Notifiable $notifiable, Notification $notification): void
     {
         $discordMessage = $notification->toDiscord(); // @phpstan-ignore-line
 
diff --git a/src/Notifications/Channels/Discord/DiscordMessage.php b/src/Notifications/Channels/Discord/DiscordMessage.php
index b7bf6555..1d865eeb 100644
--- a/src/Notifications/Channels/Discord/DiscordMessage.php
+++ b/src/Notifications/Channels/Discord/DiscordMessage.php
@@ -20,6 +20,7 @@ class DiscordMessage
 
     protected string $description = '';
 
+    /** @var array<string> */
     protected array $fields = [];
 
     protected ?string $timestamp = null;
@@ -48,7 +49,7 @@ public function url(string $url): self
         return $this;
     }
 
-    public function title($title): self
+    public function title(string $title): self
     {
         $this->title = $title;
 
@@ -97,6 +98,7 @@ public function error(): self
         return $this;
     }
 
+    /** @param array<string, string> $fields */
     public function fields(array $fields, bool $inline = true): self
     {
         foreach ($fields as $label => $value) {
diff --git a/src/Notifications/EventHandler.php b/src/Notifications/EventHandler.php
index 25c20f3a..6f1fdeec 100644
--- a/src/Notifications/EventHandler.php
+++ b/src/Notifications/EventHandler.php
@@ -31,18 +31,21 @@ public function subscribe(Dispatcher $events): void
         });
     }
 
-    protected function determineNotifiable()
+    protected function determineNotifiable(): Notifiable
     {
         $notifiableClass = $this->config->get('backup.notifications.notifiable');
 
         return app($notifiableClass);
     }
 
-    protected function determineNotification($event): Notification
+    protected function determineNotification(object $event): Notification
     {
         $lookingForNotificationClass = class_basename($event).'Notification';
 
-        $notificationClass = collect($this->config->get('backup.notifications.notifications'))
+        /** @var array<class-string, array<int, string>> $notificationClasses */
+        $notificationClasses = $this->config->get('backup.notifications.notifications');
+
+        $notificationClass = collect($notificationClasses)
             ->keys()
             ->first(fn (string $notificationClass) => class_basename($notificationClass) === $lookingForNotificationClass);
 
@@ -53,6 +56,7 @@ protected function determineNotification($event): Notification
         return new $notificationClass($event);
     }
 
+    /** @return array<int, class-string> */
     protected function allBackupEventClasses(): array
     {
         return [
diff --git a/src/Notifications/Notifiable.php b/src/Notifications/Notifiable.php
index 13e30475..419ce283 100644
--- a/src/Notifications/Notifiable.php
+++ b/src/Notifications/Notifiable.php
@@ -8,6 +8,7 @@ class Notifiable
 {
     use NotifiableTrait;
 
+    /** @return string|array{int, string} */
     public function routeNotificationForMail(): string|array
     {
         return config('backup.notifications.mail.to');
diff --git a/src/Tasks/Backup/BackupJob.php b/src/Tasks/Backup/BackupJob.php
index 662acfda..16bf96d2 100644
--- a/src/Tasks/Backup/BackupJob.php
+++ b/src/Tasks/Backup/BackupJob.php
@@ -27,8 +27,10 @@ class BackupJob
 
     protected FileSelection $fileSelection;
 
+    /** @var Collection<string, DbDumper> */
     protected Collection $dbDumpers;
 
+    /** @var Collection<int, BackupDestination> */
     protected Collection $backupDestinations;
 
     protected string $filename;
@@ -56,6 +58,7 @@ public function dontBackupFilesystem(): self
         return $this;
     }
 
+    /** @param array<string> $allowedDbNames */
     public function onlyDbName(array $allowedDbNames): self
     {
         $this->dbDumpers = $this->dbDumpers->filter(
@@ -100,6 +103,10 @@ public function setFileSelection(FileSelection $fileSelection): self
         return $this;
     }
 
+    /**
+     * @param Collection<string, DbDumper> $dbDumpers
+     * @return $this
+     */
     public function setDbDumpers(Collection $dbDumpers): self
     {
         $this->dbDumpers = $dbDumpers;
@@ -127,6 +134,7 @@ public function onlyBackupTo(string $diskName): self
         return $this;
     }
 
+    /** @param Collection<int, BackupDestination> $backupDestinations */
     public function setBackupDestinations(Collection $backupDestinations): self
     {
         $this->backupDestinations = $backupDestinations;
@@ -134,9 +142,7 @@ public function setBackupDestinations(Collection $backupDestinations): self
         return $this;
     }
 
-    /**
-     * @throws Exception
-     */
+    /** @throws Exception */
     public function run(): void
     {
         $temporaryDirectoryPath = config('backup.backup.temporary_directory') ?? storage_path('app/backup-temp');
@@ -206,6 +212,7 @@ public function filesToBeBackedUp(): Generator
         return $this->fileSelection->selectedFiles();
     }
 
+    /** @return array<string> */
     protected function directoriesUsedByBackupJob(): array
     {
         return $this->backupDestinations
@@ -240,6 +247,8 @@ protected function createZipContainingEveryFileInManifest(Manifest $manifest): s
     /**
      * Dumps the databases to the given directory.
      * Returns an array with paths to the dump files.
+     *
+     * @return array<string, string>
      */
     protected function dumpDatabases(): array
     {
@@ -312,7 +321,7 @@ protected function copyToBackupDestinations(string $path): void
             });
     }
 
-    protected function sendNotification($notification): void
+    protected function sendNotification(object|string $notification): void
     {
         if ($this->sendNotifications) {
             rescue(
diff --git a/src/Tasks/Backup/BackupJobFactory.php b/src/Tasks/Backup/BackupJobFactory.php
index f9cfddfe..3ce874a8 100644
--- a/src/Tasks/Backup/BackupJobFactory.php
+++ b/src/Tasks/Backup/BackupJobFactory.php
@@ -5,9 +5,11 @@
 use Illuminate\Support\Arr;
 use Illuminate\Support\Collection;
 use Spatie\Backup\BackupDestination\BackupDestinationFactory;
+use Spatie\DbDumper\DbDumper;
 
 class BackupJobFactory
 {
+    /** @param array<string, array<string, mixed>> $config */
     public static function createFromArray(array $config): BackupJob
     {
         return (new BackupJob())
@@ -16,6 +18,7 @@ public static function createFromArray(array $config): BackupJob
             ->setBackupDestinations(BackupDestinationFactory::createFromArray($config['backup']));
     }
 
+    /** @param array<string, mixed> $sourceFiles */
     protected static function createFileSelection(array $sourceFiles): FileSelection
     {
         return FileSelection::create($sourceFiles['include'])
@@ -24,6 +27,10 @@ protected static function createFileSelection(array $sourceFiles): FileSelection
             ->shouldIgnoreUnreadableDirs(Arr::get($sourceFiles, 'ignore_unreadable_directories', false));
     }
 
+    /**
+     * @param array<int, string> $dbConnectionNames
+     * @return Collection<string, DbDumper>
+     */
     protected static function createDbDumpers(array $dbConnectionNames): Collection
     {
         return collect($dbConnectionNames)->mapWithKeys(
diff --git a/src/Tasks/Backup/DbDumperFactory.php b/src/Tasks/Backup/DbDumperFactory.php
index c416abd1..f879a790 100644
--- a/src/Tasks/Backup/DbDumperFactory.php
+++ b/src/Tasks/Backup/DbDumperFactory.php
@@ -15,6 +15,7 @@
 
 class DbDumperFactory
 {
+    /** @var array<DbDumper> */
     protected static array $custom = [];
 
     public static function createFromConnection(string $dbConnectionName): DbDumper
@@ -74,9 +75,9 @@ public static function extend(string $driver, callable $callback): void
         static::$custom[$driver] = $callback;
     }
 
-    protected static function forDriver($dbDriver): DbDumper
+    protected static function forDriver(string $dbDriver): DbDumper
     {
-        $driver = strtolower((string) $dbDriver);
+        $driver = strtolower($dbDriver);
 
         if (isset(static::$custom[$driver])) {
             return (static::$custom[$driver])();
@@ -91,6 +92,7 @@ protected static function forDriver($dbDriver): DbDumper
         };
     }
 
+    /** @param array<string, string|array<string>> $dumpConfiguration */
     protected static function processExtraDumpParameters(array $dumpConfiguration, DbDumper $dbDumper): DbDumper
     {
         collect($dumpConfiguration)->each(function ($configValue, $configName) use ($dbDumper) {
@@ -107,7 +109,7 @@ protected static function processExtraDumpParameters(array $dumpConfiguration, D
         return $dbDumper;
     }
 
-    protected static function callMethodOnDumper(DbDumper $dbDumper, string $methodName, $methodValue): DbDumper
+    protected static function callMethodOnDumper(DbDumper $dbDumper, string $methodName, mixed $methodValue): DbDumper
     {
         if (! $methodValue) {
             $dbDumper->$methodName();
diff --git a/src/Tasks/Backup/FileSelection.php b/src/Tasks/Backup/FileSelection.php
index a11f6b08..45364662 100644
--- a/src/Tasks/Backup/FileSelection.php
+++ b/src/Tasks/Backup/FileSelection.php
@@ -9,19 +9,23 @@
 
 class FileSelection
 {
+    /** @var Collection<int, string> */
     protected Collection $includeFilesAndDirectories;
 
+    /** @var Collection<int, string> */
     protected Collection $excludeFilesAndDirectories;
 
     protected bool $shouldFollowLinks = false;
 
     protected bool $shouldIgnoreUnreadableDirs = false;
 
-    public static function create(array|string $includeFilesAndDirectories = []): self
+    /** @param array<string>|string $includeFilesAndDirectories */
+    public static function create(array|string $includeFilesAndDirectories = []): static
     {
         return new static($includeFilesAndDirectories);
     }
 
+    /** @param array<string>|string $includeFilesAndDirectories */
     public function __construct(array|string $includeFilesAndDirectories = [])
     {
         $this->includeFilesAndDirectories = collect($includeFilesAndDirectories);
@@ -29,6 +33,7 @@ public function __construct(array|string $includeFilesAndDirectories = [])
         $this->excludeFilesAndDirectories = collect();
     }
 
+    /** @param array<string>|string $excludeFilesAndDirectories */
     public function excludeFilesFrom(array|string $excludeFilesAndDirectories): self
     {
         $this->excludeFilesAndDirectories = $this->excludeFilesAndDirectories->merge($this->sanitize($excludeFilesAndDirectories));
@@ -50,6 +55,7 @@ public function shouldIgnoreUnreadableDirs(bool $ignoreUnreadableDirs): self
         return $this;
     }
 
+    /** @return Generator|array<empty> */
     public function selectedFiles(): Generator|array
     {
         if ($this->includeFilesAndDirectories->isEmpty()) {
@@ -87,18 +93,20 @@ public function selectedFiles(): Generator|array
         }
     }
 
+    /** @return array<string> */
     protected function includedFiles(): array
     {
         return $this
             ->includeFilesAndDirectories
-            ->filter(fn ($path) => is_file($path))->toArray();
+            ->filter(fn (string $path) => is_file($path))->toArray();
     }
 
+    /** @return array<string> */
     protected function includedDirectories(): array
     {
         return $this
             ->includeFilesAndDirectories
-            ->reject(fn ($path) => is_file($path))->toArray();
+            ->reject(fn (string $path) => is_file($path))->toArray();
     }
 
     protected function shouldExclude(string $path): bool
@@ -121,15 +129,19 @@ protected function shouldExclude(string $path): bool
         return false;
     }
 
+    /**
+     * @param string|array<string> $paths
+     */
     protected function sanitize(string|array $paths): Collection
     {
         return collect($paths)
-            ->reject(fn ($path) => $path === '')
-            ->flatMap(fn ($path) => $this->getMatchingPaths($path))
-            ->map(fn ($path) => realpath($path))
+            ->reject(fn (string $path) => $path === '')
+            ->flatMap(fn (string $path) => $this->getMatchingPaths($path))
+            ->map(fn (string $path) => realpath($path))
             ->reject(fn ($path) => $path === false);
     }
 
+    /** @return array<string> */
     protected function getMatchingPaths(string $path): array
     {
         if ($this->canUseGlobBrace($path)) {
diff --git a/src/Tasks/Backup/Manifest.php b/src/Tasks/Backup/Manifest.php
index 330b23b9..ab0efa2d 100644
--- a/src/Tasks/Backup/Manifest.php
+++ b/src/Tasks/Backup/Manifest.php
@@ -23,6 +23,9 @@ public function path(): string
         return $this->manifestPath;
     }
 
+    /**
+     * @param Generator|string|array<string> $filePaths
+     */
     public function addFiles(array|string|Generator $filePaths): self
     {
         if (is_string($filePaths)) {
diff --git a/src/Tasks/Backup/Zip.php b/src/Tasks/Backup/Zip.php
index 1234649a..83b0010f 100644
--- a/src/Tasks/Backup/Zip.php
+++ b/src/Tasks/Backup/Zip.php
@@ -30,7 +30,7 @@ public static function createForManifest(Manifest $manifest, string $pathToZip):
         return $zip;
     }
 
-    protected static function determineNameOfFileInZip(string $pathToFile, string $pathToZip, string $relativePath)
+    protected static function determineNameOfFileInZip(string $pathToFile, string $pathToZip, string $relativePath): string
     {
         $fileDirectory = pathinfo($pathToFile, PATHINFO_DIRNAME).DIRECTORY_SEPARATOR;
 
diff --git a/src/Tasks/Cleanup/CleanupJob.php b/src/Tasks/Cleanup/CleanupJob.php
index c782e426..a8734eda 100644
--- a/src/Tasks/Cleanup/CleanupJob.php
+++ b/src/Tasks/Cleanup/CleanupJob.php
@@ -13,6 +13,7 @@ class CleanupJob
 {
     protected bool $sendNotifications = true;
 
+    /** @param Collection<int, BackupDestination> $backupDestinations */
     public function __construct(
         protected Collection $backupDestinations,
         protected CleanupStrategy $strategy,
@@ -49,7 +50,7 @@ public function run(): void
         });
     }
 
-    protected function sendNotification($notification): void
+    protected function sendNotification(string|object $notification): void
     {
         if ($this->sendNotifications) {
             rescue(
diff --git a/src/Tasks/Cleanup/CleanupStrategy.php b/src/Tasks/Cleanup/CleanupStrategy.php
index 49bf3438..59d698f9 100644
--- a/src/Tasks/Cleanup/CleanupStrategy.php
+++ b/src/Tasks/Cleanup/CleanupStrategy.php
@@ -15,7 +15,7 @@ public function __construct(
     ) {
     }
 
-    abstract public function deleteOldBackups(BackupCollection $backups);
+    abstract public function deleteOldBackups(BackupCollection $backups): void;
 
     public function setBackupDestination(BackupDestination $backupDestination): self
     {
diff --git a/src/Tasks/Cleanup/Strategies/DefaultStrategy.php b/src/Tasks/Cleanup/Strategies/DefaultStrategy.php
index f73dca91..d4ba5c17 100644
--- a/src/Tasks/Cleanup/Strategies/DefaultStrategy.php
+++ b/src/Tasks/Cleanup/Strategies/DefaultStrategy.php
@@ -20,7 +20,7 @@ public function deleteOldBackups(BackupCollection $backups): void
 
         $dateRanges = $this->calculateDateRanges();
 
-        /** @var Collection<(string|BackupCollection)> */
+        /** @var Collection<string, BackupCollection> $backupsPerPeriod */
         $backupsPerPeriod = $dateRanges->map(function (Period $period) use ($backups) {
             return $backups
                 ->filter(fn (Backup $backup) => $backup->date()->between($period->startDate(), $period->endDate()));
@@ -38,6 +38,7 @@ public function deleteOldBackups(BackupCollection $backups): void
         $this->removeOldBackupsUntilUsingLessThanMaximumStorage($backups);
     }
 
+    /** @return Collection<string, Period> */
     protected function calculateDateRanges(): Collection
     {
         $config = $this->config->get('backup.cleanup.default_strategy');
@@ -70,15 +71,16 @@ protected function calculateDateRanges(): Collection
         return collect(compact('daily', 'weekly', 'monthly', 'yearly'));
     }
 
-    protected function groupByDateFormat(Collection $backups, string $dateFormat): Collection
+    protected function groupByDateFormat(BackupCollection $backups, string $dateFormat): BackupCollection
     {
         return $backups->groupBy(fn (Backup $backup) => $backup->date()->format($dateFormat));
     }
 
-    protected function removeBackupsForAllPeriodsExceptOne(Collection $backupsPerPeriod)
+    /** @param Collection<string, BackupCollection> $backupsPerPeriod */
+    protected function removeBackupsForAllPeriodsExceptOne(Collection $backupsPerPeriod): void
     {
         $backupsPerPeriod->each(function (Collection $groupedBackupsByDateProperty, string $periodName) {
-            $groupedBackupsByDateProperty->each(function (Collection $group) {
+            $groupedBackupsByDateProperty->each(function (BackupCollection $group) {
                 $group->shift();
 
                 $group->each(fn (Backup $backup) => $backup->delete());
@@ -86,14 +88,14 @@ protected function removeBackupsForAllPeriodsExceptOne(Collection $backupsPerPer
         });
     }
 
-    protected function removeBackupsOlderThan(Carbon $endDate, BackupCollection $backups)
+    protected function removeBackupsOlderThan(Carbon $endDate, BackupCollection $backups): void
     {
         $backups
             ->filter(fn (Backup $backup) => $backup->exists() && $backup->date()->lt($endDate))
             ->each(fn (Backup $backup) => $backup->delete());
     }
 
-    protected function removeOldBackupsUntilUsingLessThanMaximumStorage(BackupCollection $backups)
+    protected function removeOldBackupsUntilUsingLessThanMaximumStorage(BackupCollection $backups): void
     {
         if (! $this->shouldRemoveOldestBackup($backups)) {
             return;
diff --git a/src/Tasks/Monitor/BackupDestinationStatus.php b/src/Tasks/Monitor/BackupDestinationStatus.php
index 5908ef7d..35387e6f 100644
--- a/src/Tasks/Monitor/BackupDestinationStatus.php
+++ b/src/Tasks/Monitor/BackupDestinationStatus.php
@@ -11,6 +11,7 @@ class BackupDestinationStatus
 {
     protected ?HealthCheckFailure $healthCheckFailure = null;
 
+    /** @param array<int, HealthCheck> $healthChecks */
     public function __construct(
         protected BackupDestination $backupDestination,
         protected array $healthChecks = []
@@ -33,6 +34,7 @@ public function check(HealthCheck $check): bool|HealthCheckFailure
         return true;
     }
 
+    /** @return Collection<int, HealthCheck> */
     public function getHealthChecks(): Collection
     {
         return collect($this->healthChecks)->prepend(new IsReachable());
diff --git a/src/Tasks/Monitor/BackupDestinationStatusFactory.php b/src/Tasks/Monitor/BackupDestinationStatusFactory.php
index 81036302..eb2ad233 100644
--- a/src/Tasks/Monitor/BackupDestinationStatusFactory.php
+++ b/src/Tasks/Monitor/BackupDestinationStatusFactory.php
@@ -8,6 +8,11 @@
 
 class BackupDestinationStatusFactory
 {
+
+    /**
+     * @param array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>} $monitorConfiguration
+     * @return Collection<int, BackupDestinationStatus>
+     */
     public static function createForMonitorConfig(array $monitorConfiguration): Collection
     {
         return collect($monitorConfiguration)
@@ -16,6 +21,10 @@ public static function createForMonitorConfig(array $monitorConfiguration): Coll
                 $backupDestinationStatus->backupDestination()->diskName());
     }
 
+    /**
+     * @param array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>} $monitorConfig
+     * @return Collection<int, BackupDestinationStatus>
+     */
     public static function createForSingleMonitor(array $monitorConfig): Collection
     {
         return collect($monitorConfig['disks'])
@@ -26,9 +35,22 @@ public static function createForSingleMonitor(array $monitorConfig): Collection
             });
     }
 
-    protected static function buildHealthChecks($monitorConfig): array
+    /**
+     * @param array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>} $monitorConfig
+     * @return array<HealthCheck>
+     */
+    protected static function buildHealthChecks(array $monitorConfig): array
     {
-        return collect(Arr::get($monitorConfig, 'health_checks'))
+        ray(collect($monitorConfig['health_checks'])
+            ->map(function ($options, $class) {
+                if (is_int($class)) {
+                    $class = $options;
+                    $options = [];
+                }
+
+                return static::buildHealthCheck($class, $options);
+            })->toArray());
+        return collect($monitorConfig['health_checks'])
             ->map(function ($options, $class) {
                 if (is_int($class)) {
                     $class = $options;
@@ -39,6 +61,7 @@ protected static function buildHealthChecks($monitorConfig): array
             })->toArray();
     }
 
+    /** @param string|array<string, mixed> $options */
     protected static function buildHealthCheck(string $class, string|array $options): HealthCheck
     {
         if (! is_array($options)) {
diff --git a/src/Tasks/Monitor/HealthCheck.php b/src/Tasks/Monitor/HealthCheck.php
index 6d04f141..499c12e5 100644
--- a/src/Tasks/Monitor/HealthCheck.php
+++ b/src/Tasks/Monitor/HealthCheck.php
@@ -8,7 +8,7 @@
 
 abstract class HealthCheck
 {
-    abstract public function checkHealth(BackupDestination $backupDestination);
+    abstract public function checkHealth(BackupDestination $backupDestination): void;
 
     public function name(): string
     {
diff --git a/src/Traits/Retryable.php b/src/Traits/Retryable.php
index 69a973c2..bae1cf1a 100644
--- a/src/Traits/Retryable.php
+++ b/src/Traits/Retryable.php
@@ -10,7 +10,7 @@ trait Retryable
 
     protected int $currentTry = 1;
 
-    protected function shouldRetry()
+    protected function shouldRetry(): bool
     {
         if ($this->tries <= 1) {
             return false;
@@ -19,17 +19,17 @@ protected function shouldRetry()
         return $this->currentTry < $this->tries;
     }
 
-    protected function hasRetryDelay(string $type)
+    protected function hasRetryDelay(string $type): bool
     {
         return ! empty($this->getRetryDelay($type));
     }
 
-    protected function sleepFor(int $seconds = 0)
+    protected function sleepFor(int $seconds = 0): void
     {
         Sleep::for($seconds)->seconds();
     }
 
-    protected function setTries(string $type)
+    protected function setTries(string $type): void
     {
         if ($this->option('tries')) {
             $this->tries = (int) $this->option('tries');
@@ -40,7 +40,7 @@ protected function setTries(string $type)
         $this->tries = (int) config('backup.'.$type.'.tries', 1);
     }
 
-    protected function getRetryDelay(string $type)
+    protected function getRetryDelay(string $type): int
     {
         return (int) config('backup.'.$type.'.retry_delay', 0);
     }
diff --git a/tests/TestSupport/FakeFailingHealthCheck.php b/tests/TestSupport/FakeFailingHealthCheck.php
index 7f96a5f6..d0be35a4 100644
--- a/tests/TestSupport/FakeFailingHealthCheck.php
+++ b/tests/TestSupport/FakeFailingHealthCheck.php
@@ -10,7 +10,7 @@ class FakeFailingHealthCheck extends HealthCheck
 {
     public static $reason;
 
-    public function checkHealth(BackupDestination $backupDestination)
+    public function checkHealth(BackupDestination $backupDestination): void
     {
         throw (static::$reason ?: new Exception('dummy exception message'));
     }

From 3016d9987825763c96cc1af7602253e7d2dba83f Mon Sep 17 00:00:00 2001
From: Nielsvanpach <Nielsvanpach@users.noreply.github.com>
Date: Fri, 7 Jun 2024 11:43:33 +0000
Subject: [PATCH 9/9] Fix styling

---
 src/BackupDestination/BackupDestinationFactory.php   | 2 +-
 src/Commands/ListCommand.php                         | 4 ++--
 src/Tasks/Backup/BackupJob.php                       | 2 +-
 src/Tasks/Backup/BackupJobFactory.php                | 2 +-
 src/Tasks/Backup/FileSelection.php                   | 2 +-
 src/Tasks/Backup/Manifest.php                        | 2 +-
 src/Tasks/Monitor/BackupDestinationStatusFactory.php | 9 ++++-----
 7 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/src/BackupDestination/BackupDestinationFactory.php b/src/BackupDestination/BackupDestinationFactory.php
index 99c085b4..8ba0e95b 100644
--- a/src/BackupDestination/BackupDestinationFactory.php
+++ b/src/BackupDestination/BackupDestinationFactory.php
@@ -7,7 +7,7 @@
 class BackupDestinationFactory
 {
     /**
-     * @param array<string, mixed> $config
+     * @param  array<string, mixed>  $config
      * @return Collection<int, BackupDestination>
      */
     public static function createFromArray(array $config): Collection
diff --git a/src/Commands/ListCommand.php b/src/Commands/ListCommand.php
index 94d961e3..2c76faa1 100644
--- a/src/Commands/ListCommand.php
+++ b/src/Commands/ListCommand.php
@@ -31,7 +31,7 @@ public function handle(): int
     }
 
     /**
-     * @param Collection<int, BackupDestinationStatus> $backupDestinationStatuses
+     * @param  Collection<int, BackupDestinationStatus>  $backupDestinationStatuses
      */
     protected function displayOverview(Collection $backupDestinationStatuses): static
     {
@@ -49,7 +49,7 @@ protected function displayOverview(Collection $backupDestinationStatuses): stati
         return $this;
     }
 
-    /** @return array{0: string, 1: string, 2: string, disk: string, amount: integer, newest: string, usedStorage: string} */
+    /** @return array{0: string, 1: string, 2: string, disk: string, amount: int, newest: string, usedStorage: string} */
     public function convertToRow(BackupDestinationStatus $backupDestinationStatus): array
     {
         $destination = $backupDestinationStatus->backupDestination();
diff --git a/src/Tasks/Backup/BackupJob.php b/src/Tasks/Backup/BackupJob.php
index 16bf96d2..5453426c 100644
--- a/src/Tasks/Backup/BackupJob.php
+++ b/src/Tasks/Backup/BackupJob.php
@@ -104,7 +104,7 @@ public function setFileSelection(FileSelection $fileSelection): self
     }
 
     /**
-     * @param Collection<string, DbDumper> $dbDumpers
+     * @param  Collection<string, DbDumper>  $dbDumpers
      * @return $this
      */
     public function setDbDumpers(Collection $dbDumpers): self
diff --git a/src/Tasks/Backup/BackupJobFactory.php b/src/Tasks/Backup/BackupJobFactory.php
index 3ce874a8..64bfb7fc 100644
--- a/src/Tasks/Backup/BackupJobFactory.php
+++ b/src/Tasks/Backup/BackupJobFactory.php
@@ -28,7 +28,7 @@ protected static function createFileSelection(array $sourceFiles): FileSelection
     }
 
     /**
-     * @param array<int, string> $dbConnectionNames
+     * @param  array<int, string>  $dbConnectionNames
      * @return Collection<string, DbDumper>
      */
     protected static function createDbDumpers(array $dbConnectionNames): Collection
diff --git a/src/Tasks/Backup/FileSelection.php b/src/Tasks/Backup/FileSelection.php
index 45364662..9daae78b 100644
--- a/src/Tasks/Backup/FileSelection.php
+++ b/src/Tasks/Backup/FileSelection.php
@@ -130,7 +130,7 @@ protected function shouldExclude(string $path): bool
     }
 
     /**
-     * @param string|array<string> $paths
+     * @param  string|array<string>  $paths
      */
     protected function sanitize(string|array $paths): Collection
     {
diff --git a/src/Tasks/Backup/Manifest.php b/src/Tasks/Backup/Manifest.php
index ab0efa2d..538dc4a8 100644
--- a/src/Tasks/Backup/Manifest.php
+++ b/src/Tasks/Backup/Manifest.php
@@ -24,7 +24,7 @@ public function path(): string
     }
 
     /**
-     * @param Generator|string|array<string> $filePaths
+     * @param  Generator|string|array<string>  $filePaths
      */
     public function addFiles(array|string|Generator $filePaths): self
     {
diff --git a/src/Tasks/Monitor/BackupDestinationStatusFactory.php b/src/Tasks/Monitor/BackupDestinationStatusFactory.php
index eb2ad233..233fdec8 100644
--- a/src/Tasks/Monitor/BackupDestinationStatusFactory.php
+++ b/src/Tasks/Monitor/BackupDestinationStatusFactory.php
@@ -2,15 +2,13 @@
 
 namespace Spatie\Backup\Tasks\Monitor;
 
-use Illuminate\Support\Arr;
 use Illuminate\Support\Collection;
 use Spatie\Backup\BackupDestination\BackupDestination;
 
 class BackupDestinationStatusFactory
 {
-
     /**
-     * @param array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>} $monitorConfiguration
+     * @param  array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>}  $monitorConfiguration
      * @return Collection<int, BackupDestinationStatus>
      */
     public static function createForMonitorConfig(array $monitorConfiguration): Collection
@@ -22,7 +20,7 @@ public static function createForMonitorConfig(array $monitorConfiguration): Coll
     }
 
     /**
-     * @param array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>} $monitorConfig
+     * @param  array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>}  $monitorConfig
      * @return Collection<int, BackupDestinationStatus>
      */
     public static function createForSingleMonitor(array $monitorConfig): Collection
@@ -36,7 +34,7 @@ public static function createForSingleMonitor(array $monitorConfig): Collection
     }
 
     /**
-     * @param array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>} $monitorConfig
+     * @param  array{name: string, disks: array<string>, health_checks: array<class-string|int, array<string, mixed>>}  $monitorConfig
      * @return array<HealthCheck>
      */
     protected static function buildHealthChecks(array $monitorConfig): array
@@ -50,6 +48,7 @@ protected static function buildHealthChecks(array $monitorConfig): array
 
                 return static::buildHealthCheck($class, $options);
             })->toArray());
+
         return collect($monitorConfig['health_checks'])
             ->map(function ($options, $class) {
                 if (is_int($class)) {