Completed
Pull Request — master (#901)
by
unknown
02:28
created

Zip::path()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Spatie\Backup\Tasks\Backup;
4
5
use ZipArchive;
6
use Illuminate\Support\Str;
7
use Spatie\Backup\Helpers\Format;
8
9
class Zip
10
{
11
    /** @var \ZipArchive */
12
    protected $zipFile;
13
14
    /** @var int */
15
    protected $fileCount = 0;
16
17
    /** @var string */
18
    protected $pathToZip;
19
20
    /** @var string */
21
    protected $password;
22
23
    public static function createForManifest(Manifest $manifest, string $pathToZip): self
24
    {
25
        $zip = new static($pathToZip);
26
27
        $zip->open();
28
29
        $zip->setPassword(config('backup.backup.password', null));
30
31
        foreach ($manifest->files() as $file) {
32
            $zip->add($file, self::determineNameOfFileInZip($file, $pathToZip));
33
        }
34
35
        $zip->close();
36
37
        return $zip;
38
    }
39
40
    protected static function determineNameOfFileInZip(string $pathToFile, string $pathToZip)
41
    {
42
        $zipDirectory = pathinfo($pathToZip, PATHINFO_DIRNAME);
43
44
        $fileDirectory = pathinfo($pathToFile, PATHINFO_DIRNAME);
45
46
        if (Str::startsWith($fileDirectory, $zipDirectory)) {
47
            return str_replace($zipDirectory, '', $pathToFile);
48
        }
49
50
        return $pathToFile;
51
    }
52
53
    public static function formatZipFilename(string $filename): string
54
    {
55
        return ltrim($filename, DIRECTORY_SEPARATOR);
56
    }
57
58
    public function __construct(string $pathToZip)
59
    {
60
        $this->zipFile = new ZipArchive();
61
62
        $this->pathToZip = $pathToZip;
63
64
        $this->open();
65
    }
66
67
    public function path(): string
68
    {
69
        return $this->pathToZip;
70
    }
71
72
    public function size(): int
73
    {
74
        if ($this->fileCount === 0) {
75
            return 0;
76
        }
77
78
        return filesize($this->pathToZip);
79
    }
80
81
    public function humanReadableSize(): string
82
    {
83
        return Format::humanReadableSize($this->size());
84
    }
85
86
    public function open()
87
    {
88
        $this->zipFile->open($this->pathToZip, ZipArchive::CREATE);
89
    }
90
91
    public function close()
92
    {
93
        $this->zipFile->close();
94
    }
95
96
    /**
97
     * @param string|null $password
98
     * @return Zip
99
     */
100
    public function setPassword(?string $password): self
101
    {
102
        $this->password = $password;
103
104
        return $this;
105
    }
106
107
    /**
108
     * @param string $nameInZip
109
     *
110
     * @return Zip
111
     */
112
    protected function passwordProtectFile(string $nameInZip): self
113
    {
114
        if (empty($this->password)) {
115
            return $this;
116
        }
117
118
        if (!$this->zipFile->setEncryptionName($nameInZip, ZipArchive::EM_AES_256, $this->password)) {
119
            consoleOutput()->warn('Cannot password protect ' . $nameInZip);
0 ignored issues
show
Documentation Bug introduced by
The method warn does not exist on object<Spatie\Backup\Helpers\ConsoleOutput>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
120
        }
121
122
        return $this;
123
    }
124
125
    /**
126
     * @param string|array $files
127
     * @param string $nameInZip
128
     *
129
     * @return \Spatie\Backup\Tasks\Backup\Zip
130
     */
131
    public function add($files, string $nameInZip = null): self
132
    {
133
        if (is_array($files)) {
134
            $nameInZip = null;
135
        }
136
137
        if (is_string($files)) {
138
            $files = [$files];
139
        }
140
141
        foreach ($files as $file) {
142
            if (file_exists($file)) {
143
                $localName = self::formatZipFilename($nameInZip ?? $file);
144
145
                if ($this->zipFile->addFile($file, $localName).PHP_EOL) {
146
                    $this->passwordProtectFile($localName);
147
                }
148
            }
149
            $this->fileCount++;
150
        }
151
152
        return $this;
153
    }
154
155
    public function count(): int
156
    {
157
        return $this->fileCount;
158
    }
159
}
160