Primo Committ

This commit is contained in:
paoloar77
2024-05-07 12:17:25 +02:00
commit e73d0e5113
7204 changed files with 884387 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<?php
namespace Spatie\Backup\BackupDestination;
use Carbon\Carbon;
use Illuminate\Contracts\Filesystem\Filesystem;
use InvalidArgumentException;
use Spatie\Backup\Tasks\Backup\BackupJob;
class Backup
{
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
protected $disk;
/** @var string */
protected $path;
/** @var bool */
protected $exists;
/** @var Carbon */
protected $date;
/** @var int */
protected $size;
public function __construct(Filesystem $disk, string $path)
{
$this->disk = $disk;
$this->path = $path;
$this->exists = true;
}
public function disk(): Filesystem
{
return $this->disk;
}
public function path(): string
{
return $this->path;
}
public function exists(): bool
{
if ($this->exists === null) {
$this->exists = $this->disk->exists($this->path);
}
return $this->exists;
}
public function date(): Carbon
{
if ($this->date === null) {
try {
// try to parse the date from the filename
$basename = basename($this->path);
$this->date = Carbon::createFromFormat(BackupJob::FILENAME_FORMAT, $basename);
} catch (InvalidArgumentException $e) {
// if that fails, ask the (remote) filesystem
$this->date = Carbon::createFromTimestamp($this->disk->lastModified($this->path));
}
}
return $this->date;
}
/**
* Get the size in bytes.
*/
public function size(): float
{
if ($this->size === null) {
if (! $this->exists()) {
return 0;
}
$this->size = $this->disk->size($this->path);
}
return $this->size;
}
public function stream()
{
return $this->disk->readStream($this->path);
}
public function delete()
{
if (! $this->disk->delete($this->path)) {
consoleOutput()->error("Failed to delete backup `{$this->path}`.");
return;
}
$this->exists = false;
consoleOutput()->info("Deleted backup `{$this->path}`.");
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Spatie\Backup\BackupDestination;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Support\Collection;
use Spatie\Backup\Helpers\File;
class BackupCollection extends Collection
{
/** @var null|float */
protected $sizeCache = null;
public static function createFromFiles(?FileSystem $disk, array $files): self
{
return (new static($files))
->filter(function ($path) use ($disk) {
return (new File)->isZipFile($disk, $path);
})
->map(function ($path) use ($disk) {
return new Backup($disk, $path);
})
->sortByDesc(function (Backup $backup) {
return $backup->date()->timestamp;
})
->values();
}
public function newest(): ?Backup
{
return $this->first();
}
public function oldest(): ?Backup
{
return $this
->filter->exists()
->last();
}
public function size(): float
{
if ($this->sizeCache !== null) {
return $this->sizeCache;
}
return $this->sizeCache = $this->sum->size();
}
}

View File

@@ -0,0 +1,191 @@
<?php
namespace Spatie\Backup\BackupDestination;
use Carbon\Carbon;
use Exception;
use Illuminate\Contracts\Filesystem\Factory;
use Illuminate\Contracts\Filesystem\Filesystem;
use Spatie\Backup\Exceptions\InvalidBackupDestination;
class BackupDestination
{
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
protected $disk;
/** @var string */
protected $diskName;
/** @var string */
protected $backupName;
/** @var Exception */
public $connectionError;
/** @var null|\Spatie\Backup\BackupDestination\BackupCollection */
protected $backupCollectionCache = null;
public function __construct(Filesystem $disk = null, string $backupName, string $diskName)
{
$this->disk = $disk;
$this->diskName = $diskName;
$this->backupName = preg_replace('/[^a-zA-Z0-9.]/', '-', $backupName);
}
public function disk(): Filesystem
{
return $this->disk;
}
public function diskName(): string
{
return $this->diskName;
}
public function filesystemType(): string
{
if (is_null($this->disk)) {
return 'unknown';
}
$adapterClass = get_class($this->disk->getDriver()->getAdapter());
$filesystemType = last(explode('\\', $adapterClass));
return strtolower($filesystemType);
}
public static function create(string $diskName, string $backupName): self
{
try {
$disk = app(Factory::class)->disk($diskName);
return new static($disk, $backupName, $diskName);
} catch (Exception $exception) {
$backupDestination = new static(null, $backupName, $diskName);
$backupDestination->connectionError = $exception;
return $backupDestination;
}
}
public function write(string $file)
{
if (! is_null($this->connectionError)) {
throw InvalidBackupDestination::connectionError($this->diskName);
}
if (is_null($this->disk)) {
throw InvalidBackupDestination::diskNotSet($this->backupName);
}
$destination = $this->backupName.'/'.pathinfo($file, PATHINFO_BASENAME);
$handle = fopen($file, 'r+');
$result = $this->disk->getDriver()->writeStream(
$destination,
$handle,
$this->getDiskOptions()
);
if (is_resource($handle)) {
fclose($handle);
}
if ($result === false) {
throw InvalidBackupDestination::writeError($this->diskName);
}
}
public function backupName(): string
{
return $this->backupName;
}
public function backups(): BackupCollection
{
if ($this->backupCollectionCache) {
return $this->backupCollectionCache;
}
$files = [];
if (! is_null($this->disk)) {
// $this->disk->allFiles() may fail when $this->disk is not reachable
// in that case we still want to send the notification
try {
$files = $this->disk->allFiles($this->backupName);
} catch (Exception $ex) {
}
}
return $this->backupCollectionCache = BackupCollection::createFromFiles(
$this->disk,
$files
);
}
public function connectionError(): Exception
{
return $this->connectionError;
}
public function getDiskOptions(): array
{
return config("filesystems.disks.{$this->diskName()}.backup_options") ?? [];
}
public function isReachable(): bool
{
if (is_null($this->disk)) {
return false;
}
try {
$this->disk->allFiles($this->backupName);
return true;
} catch (Exception $exception) {
$this->connectionError = $exception;
return false;
}
}
public function usedStorage(): float
{
return $this->backups()->size();
}
public function newestBackup(): ?Backup
{
return $this->backups()->newest();
}
public function oldestBackup(): ?Backup
{
return $this->backups()->oldest();
}
public function newestBackupIsOlderThan(Carbon $date): bool
{
$newestBackup = $this->newestBackup();
if (is_null($newestBackup)) {
return true;
}
return $newestBackup->date()->gt($date);
}
public function fresh(): self
{
$this->backupCollectionCache = null;
return $this;
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Spatie\Backup\BackupDestination;
use Illuminate\Support\Collection;
class BackupDestinationFactory
{
public static function createFromArray(array $config): Collection
{
return collect($config['destination']['disks'])
->map(function ($filesystemName) use ($config) {
return BackupDestination::create($filesystemName, $config['name']);
});
}
}