NelexaZip::createArchiveInternal()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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