ZipArchiver   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 41
dl 0
loc 87
ccs 44
cts 44
cp 1
rs 10
c 2
b 0
f 0
wmc 18

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A ensureDirectoryExists() 0 5 3
A setArchiveCreationCallback() 0 5 1
A findArchiveFileName() 0 16 3
A setExtension() 0 5 1
A addFilesToArchive() 0 15 4
A create() 0 18 5
1
<?php
2
3
namespace LaravelDownloadUtil\Archivers;
4
5
use Carbon\Carbon;
6
use Closure;
7
use Illuminate\Filesystem\FilesystemAdapter;
8
use Illuminate\Support\Facades\Storage;
9
use Illuminate\Support\Str;
10
use ZipArchive;
11
12
class ZipArchiver
13
{
14
    protected string $ext = 'zip';
15
16
    protected FilesystemAdapter $storage;
17
18
    protected ?Closure $archiveCreationCallback = null;
19
20 5
    public function __construct(?FilesystemAdapter $storage = null)
21
    {
22 5
        $this->storage = $storage ?? Storage::disk(config('download-util.storage.default'));
23
    }
24
25 1
    public function setExtension(string $ext): static
26
    {
27 1
        $this->ext = ltrim($ext, '.');
28
29 1
        return $this;
30
    }
31
32 1
    public function setArchiveCreationCallback(?Closure $callback): static
33
    {
34 1
        $this->archiveCreationCallback = $callback;
35
36 1
        return $this;
37
    }
38
39 5
    public function create(array $files, ?string $filePrefix = null): ?string
40
    {
41 5
        $filePrefix = $filePrefix ?: Carbon::now()->format('Y-m-d-his');
42
43 5
        $archive         = new ZipArchive;
44 5
        $archiveFileName = $this->findArchiveFileName($filePrefix);
45 5
        $this->ensureDirectoryExists($archiveFileName);
46
47 5
        if (!empty($files)
48 5
            && $archive->open($this->storage->path($archiveFileName), ZipArchive::CREATE) === true
49
        ) {
50 4
            $this->addFilesToArchive($archive, $files);
51 4
            if ($archive->close()) {
52 4
                return $archiveFileName;
53
            }
54
        }
55
56 1
        return null;
57
    }
58
59 4
    protected function addFilesToArchive(ZipArchive $archive, array $files): ZipArchive
60
    {
61 4
        if ($this->archiveCreationCallback && is_callable($this->archiveCreationCallback)) {
62 1
            call_user_func_array($this->archiveCreationCallback, [
63 1
                $archive,
64 1
                $files,
65 1
                $this->storage,
66 1
            ]);
67
        } else {
68 3
            foreach ($files as $file) {
69 3
                $archive->addFile($file);
70
            }
71
        }
72
73 4
        return $archive;
74
    }
75
76 5
    protected function findArchiveFileName(string $filePrefix): string
77
    {
78 5
        $archiveFileName = "{$filePrefix}.{$this->ext}";
79 5
        $counter         = 1;
80 5
        while ($this->storage->exists($archiveFileName)) {
81 2
            if ($counter > config('download-util.archiver.name_duplication_limiter', 1000)) {
82 1
                $uuid            = Str::uuid();
83 1
                $archiveFileName = "{$filePrefix}__{$uuid}.{$this->ext}";
84
85 1
                break;
86
            }
87 2
            $archiveFileName = "{$filePrefix}__{$counter}.{$this->ext}";
88 2
            $counter++;
89
        }
90
91 5
        return $archiveFileName;
92
    }
93
94 5
    protected function ensureDirectoryExists(string $archiveFileName): void
95
    {
96 5
        $folderPath      = Str::beforeLast($archiveFileName, '/');
97 5
        if ($folderPath != $archiveFileName && !$this->storage->directoryExists($folderPath)) {
98 1
            $this->storage->createDirectory($folderPath);
99
        }
100
    }
101
}
102