Passed
Push — master ( 087559...2f7326 )
by f
11:35
created

NelexaZip::createArchive()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
c 0
b 0
f 0
nc 4
nop 6
dl 0
loc 19
rs 10
1
<?php
2
3
namespace wapmorgan\UnifiedArchive\Drivers;
4
5
use PhpZip\ZipFile;
0 ignored issues
show
Bug introduced by
The type PhpZip\ZipFile was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use wapmorgan\UnifiedArchive\ArchiveEntry;
7
use wapmorgan\UnifiedArchive\ArchiveInformation;
8
use wapmorgan\UnifiedArchive\Commands\BaseArchiveCommand;
9
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicDriver;
10
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicPureDriver;
11
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
12
use wapmorgan\UnifiedArchive\Exceptions\NonExistentArchiveFileException;
13
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
14
use wapmorgan\UnifiedArchive\Formats;
15
16
class NelexaZip extends BasicPureDriver
17
{
18
    const PACKAGE_NAME = 'nelexa/zip';
19
    const MAIN_CLASS = '\\PhpZip\\ZipFile';
20
21
    /**
22
     * @var ZipFile
23
     */
24
    protected $zip;
25
26
    /**
27
     * @var array
28
     */
29
    protected $files;
30
31
    public static function getDescription()
32
    {
33
        return 'nelexa/zip driver';
34
    }
35
36
    public static function getSupportedFormats()
37
    {
38
        return [
39
            Formats::ZIP,
40
        ];
41
    }
42
43
    public static function checkFormatSupport($format)
44
    {
45
        if (!static::isInstalled()) {
46
            return [];
47
        }
48
        return [
49
            BasicDriver::OPEN,
50
            BasicDriver::OPEN_ENCRYPTED,
51
            BasicDriver::GET_COMMENT,
52
            BasicDriver::SET_COMMENT,
53
            BasicDriver::EXTRACT_CONTENT,
54
            BasicDriver::APPEND,
55
            BasicDriver::DELETE,
56
            BasicDriver::CREATE,
57
            BasicDriver::CREATE_ENCRYPTED,
58
            BasicDriver::CREATE_IN_STRING,
59
        ];
60
    }
61
62
    /**
63
     * @param array $files
64
     * @param $archiveFileName
65
     * @param $archiveFormat
66
     * @param $compressionLevel
67
     * @param $password
68
     * @param $fileProgressCallable
69
     * @return int
70
     * @throws ArchiveCreationException
71
     * @throws UnsupportedOperationException
72
     */
73
    public static function createArchive(
74
        array $files,
75
        $archiveFileName,
76
        $archiveFormat,
77
        $compressionLevel = self::COMPRESSION_AVERAGE,
78
        $password = null,
79
        $fileProgressCallable = null)
80
    {
81
        if ($fileProgressCallable !== null && !is_callable($fileProgressCallable)) {
82
            throw new ArchiveCreationException('File progress callable is not callable');
83
        }
84
85
        try {
86
            $zipFile = static::createArchiveInternal($files, $password, $fileProgressCallable);
87
            $zipFile->saveAsFile($archiveFileName)->close();
88
        } catch (\Exception $e) {
89
            throw new ArchiveCreationException('Could not create archive: '.$e->getMessage(), $e->getCode(), $e);
90
        }
91
        return count($files);
92
    }
93
94
    /**
95
     * @param array $files
96
     * @param string $archiveFormat
97
     * @param int $compressionLevel
98
     * @param string $password
99
     * @param callable|null $fileProgressCallable
100
     * @return string Content of archive
101
     * @throws ArchiveCreationException
102
     */
103
    public static function createArchiveInString(
104
        array $files,
105
        $archiveFormat,
106
        $compressionLevel = self::COMPRESSION_AVERAGE,
107
        $password = null,
108
        $fileProgressCallable = null
109
    ) {
110
        if ($fileProgressCallable !== null && !is_callable($fileProgressCallable)) {
111
            throw new ArchiveCreationException('File progress callable is not callable');
112
        }
113
114
        try {
115
            $zipFile = static::createArchiveInternal($files, $password, $fileProgressCallable);
116
            return $zipFile->outputAsString();
117
        } catch (\Exception $e) {
118
            throw new ArchiveCreationException('Could not create archive: '.$e->getMessage(), $e->getCode(), $e);
119
        }
120
    }
121
122
    protected static function createArchiveInternal(array $files, $password, $fileProgressCallable = null)
123
    {
124
        $current_file = 0;
125
        $total_files = count($files);
126
127
        $zipFile = new \PhpZip\ZipFile();
128
        foreach ($files as $localName => $archiveName) {
129
            $zipFile->addFile($localName, $archiveName);
130
            if ($fileProgressCallable !== null) {
131
                call_user_func_array(
132
                    $fileProgressCallable,
133
                    [$current_file++, $total_files, $localName, $archiveName]
134
                );
135
            }
136
        }
137
        if ($password !== null) {
138
            $zipFile->setPassword($password);
139
        }
140
        return $zipFile;
141
    }
142
143
    /**
144
     * @inheritDoc
145
     * @throws \PhpZip\Exception\ZipException
146
     */
147
    public function __construct($archiveFileName, $format, $password = null)
148
    {
149
        parent::__construct($archiveFileName, $format);
150
        $this->zip = new ZipFile();
151
        $this->zip->openFile($archiveFileName);
152
        if ($password !== null) {
153
            $this->zip->setReadPassword($password);
154
        }
155
    }
156
157
    /**
158
     * @inheritDoc
159
     */
160
    public function getArchiveInformation()
161
    {
162
        $this->files = [];
163
        $information = new ArchiveInformation();
164
165
        $files = method_exists($this->zip, 'getAllInfo')
166
            ? $this->zip->getAllInfo()
167
            : $this->zip->getEntries();
168
169
        foreach ($files as $info) {
170
            if (method_exists($info, 'isFolder') ? $info->isFolder() : $info->isDirectory())
171
                continue;
172
173
            $this->files[] = $information->files[] = str_replace('\\', '/', $info->getName());
174
            $information->compressedFilesSize += $info->getCompressedSize();
175
            $information->uncompressedFilesSize += method_exists($info, 'getSize') ? $info->getSize() : $info->getUncompressedSize();
176
        }
177
        return $information;
178
    }
179
180
    /**
181
     * @inheritDoc
182
     */
183
    public function getFileNames()
184
    {
185
        return $this->files;
186
    }
187
188
    /**
189
     * @inheritDoc
190
     */
191
    public function isFileExists($fileName)
192
    {
193
        return $this->zip->hasEntry($fileName);
194
    }
195
196
    /**
197
     * @inheritDoc
198
     */
199
    public function getFileData($fileName)
200
    {
201
        $info = method_exists($this->zip, 'getEntryInfo')
202
            ? $this->zip->getEntryInfo($fileName)
203
            : $this->zip->getEntry($fileName);
204
205
        return new ArchiveEntry(
206
            $fileName,
207
            $info->getCompressedSize(),
208
            method_exists($info, 'getSize') ? $info->getSize() : $info->getUncompressedSize(),
209
            $info->getMtime()->getTimestamp(),
210
            null,
211
            $info->getComment(),
212
            $info->getCrc()
213
        );
214
    }
215
216
    /**
217
     * @inheritDoc
218
     */
219
    public function getFileContent($fileName)
220
    {
221
        return $this->zip->getEntryContents($fileName);
222
    }
223
224
    /**
225
     * @inheritDoc
226
     * @throws NonExistentArchiveFileException
227
     */
228
    public function getFileStream($fileName)
229
    {
230
        return static::wrapStringInStream($this->getFileContent($fileName));
231
    }
232
233
    /**
234
     * @inheritDoc
235
     */
236
    public function extractFiles($outputFolder, array $files)
237
    {
238
        $this->zip->extractTo($outputFolder, $files);
239
        return count($files);
240
    }
241
242
    /**
243
     * @inheritDoc
244
     */
245
    public function extractArchive($outputFolder)
246
    {
247
        $this->zip->extractTo($outputFolder);
248
        return count($this->files);
249
    }
250
251
    /**
252
     * @inheritDoc
253
     * @throws \PhpZip\Exception\ZipException
254
     */
255
    public function addFileFromString($inArchiveName, $content)
256
    {
257
        return $this->zip->addFromString($inArchiveName, $content);
258
    }
259
260
    public function getComment()
261
    {
262
        return $this->zip->getArchiveComment();
263
    }
264
265
    public function setComment($comment)
266
    {
267
        return $this->zip->setArchiveComment($comment);
268
    }
269
270
    public function deleteFiles(array $files)
271
    {
272
        $deleted = 0;
273
        foreach ($files as $file) {
274
            $this->zip->deleteFromName($file);
275
            $deleted++;
276
        }
277
        return $deleted;
278
    }
279
280
    public function addFiles(array $files)
281
    {
282
        foreach ($files as $inArchiveName => $fsFileName)
283
        {
284
            $this->zip->addFile($fsFileName, $inArchiveName);
285
        }
286
    }
287
}
288