Passed
Push — master ( bf29cf...6612ae )
by f
15:14
created

AlchemyZippy::canDeleteFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace wapmorgan\UnifiedArchive\Drivers;
3
4
use Alchemy\Zippy\Archive\Member;
0 ignored issues
show
Bug introduced by
The type Alchemy\Zippy\Archive\Member 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...
5
use Alchemy\Zippy\Exception\NoAdapterOnPlatformException;
0 ignored issues
show
Bug introduced by
The type Alchemy\Zippy\Exception\...pterOnPlatformException 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 Alchemy\Zippy\Zippy;
0 ignored issues
show
Bug introduced by
The type Alchemy\Zippy\Zippy 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...
7
use Exception;
8
use wapmorgan\UnifiedArchive\ArchiveEntry;
9
use wapmorgan\UnifiedArchive\ArchiveInformation;
10
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
11
use wapmorgan\UnifiedArchive\Exceptions\ArchiveExtractionException;
12
use wapmorgan\UnifiedArchive\Exceptions\ArchiveModificationException;
13
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
14
use wapmorgan\UnifiedArchive\Formats;
15
use wapmorgan\UnifiedArchive\Drivers\BasicDriver;
16
17
class AlchemyZippy extends BasicDriver
18
{
19
    /**
20
     * @var Zippy
21
     */
22
    protected static $zippy;
23
24
    /**
25
     * @var string
26
     */
27
    protected $fileName;
28
29
    /**
30
     * @var \Alchemy\Zippy\Archive\ArchiveInterface
0 ignored issues
show
Bug introduced by
The type Alchemy\Zippy\Archive\ArchiveInterface 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...
31
     */
32
    protected $archive;
33
34
    /**
35
     * @var array
36
     */
37
    protected $files;
38
39
    /**
40
     * @var string
41
     */
42
    protected $format;
43
44
    /**
45
     * @var Member[]
46
     */
47
    protected $members;
48
49
    /**
50
     * @return mixed|void
51
     */
52 1
    public static function getSupportedFormats()
53
    {
54
        return [
55 1
            Formats::ZIP,
56
            Formats::TAR,
57
            Formats::TAR_GZIP,
58
            Formats::TAR_BZIP,
59
        ];
60
    }
61
62 4
    protected static function init()
63
    {
64 4
        if (!class_exists('\Alchemy\Zippy\Zippy'))
65 4
            static::$zippy = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type Alchemy\Zippy\Zippy of property $zippy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
66
        else if (static::$zippy === null)
67
            static::$zippy = Zippy::load();
68 4
    }
69
70
    /**
71
     * @param $format
72
     * @return array
73
     */
74 4
    public static function checkFormatSupport($format)
75
    {
76 4
        static::init();
77
78 4
        if (static::$zippy === false)
0 ignored issues
show
introduced by
The condition static::zippy === false is always false.
Loading history...
79 4
            return [];
80
81
        switch ($format) {
82
            case Formats::TAR_BZIP:
83
            case Formats::TAR:
84
            case Formats::TAR_GZIP:
85
            case Formats::ZIP:
86
                if (static::checkAdapterFor($format) === false) {
87
                    return [];
88
                }
89
90
                return [
91
                    Formats::OPEN,
92
                    Formats::EXTRACT_CONTENT,
93
                    Formats::APPEND,
94
                    Formats::DELETE,
95
                    Formats::CREATE,
96
                ];
97
        }
98
    }
99
100
    /**
101
     * @inheritDoc
102
     */
103
    public static function getDescription()
104
    {
105
        return 'php-library and console programs';
106
    }
107
108
    /**
109
     * @inheritDoc
110
     */
111
    public static function getInstallationInstruction()
112
    {
113
        self::init();
114
        return static::$zippy === false
0 ignored issues
show
introduced by
The condition static::zippy === false is always false.
Loading history...
115
            ? 'install library [alchemy/zippy]: `composer require alchemy/zippy`' . "\n"  . ' and console programs (tar, zip): `apt install tar zip` - depends on OS'
116
            . "\n" . 'If you install SevenZip and AlchemyZippy:' . "\n" .
117
'1. You should specify symfony/console version before installation to any **3.x.x version**: `composer require symfony/process:~3.4`, because they require different `symfony/process` versions.' . "\n" .
118
'2. Install archive7z version 4.0.0: `composer require gemorroj/archive7z:~4.0`'
119
            : null;
120
    }
121
122
    /**
123
     * @param $format
124
     * @param $adapter
125
     * @return bool
126
     */
127
    protected static function checkAdapterFor($format, &$adapter = null)
128
    {
129
        try {
130
            $adapter = static::$zippy->getAdapterFor($format);
131
            return true;
132
        } catch (NoAdapterOnPlatformException $e) {
133
            return false;
134
        }
135
    }
136
137
    /**
138
     * @param $format
139
     * @return bool
140
     */
141
    public static function canCreateArchive($format)
142
    {
143
        return true;
144
    }
145
146
    /**
147
     * @param $format
148
     * @return bool
149
     */
150
    public static function canAddFiles($format)
151
    {
152
        return true;
153
    }
154
155
    /**
156
     * @param $format
157
     * @return bool
158
     */
159
    public static function canDeleteFiles($format)
160
    {
161
        return true;
162
    }
163
164
    /**
165
     * @param array $files
166
     * @param string $archiveFileName
167
     * @param int $archiveFormat
168
     * @param int $compressionLevel
169
     * @param null $password
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $password is correct as it would always require null to be passed?
Loading history...
170
     * @param $fileProgressCallable
171
     * @return int
172
     * @throws ArchiveCreationException
173
     * @throws UnsupportedOperationException
174
     */
175
    public static function createArchive(
176
        array $files,
177
        $archiveFileName,
178
        $archiveFormat,
179
        $compressionLevel = self::COMPRESSION_AVERAGE,
180
        $password = null,
181
        $fileProgressCallable = null
182
    )
183
    {
184
        if ($password !== null) {
0 ignored issues
show
introduced by
The condition $password !== null is always false.
Loading history...
185
            throw new UnsupportedOperationException('AlchemyZippy could not encrypt an archive');
186
        }
187
188
        try {
189
            $archive = static::$zippy->create($archiveFileName, $files);
0 ignored issues
show
Unused Code introduced by
The assignment to $archive is dead and can be removed.
Loading history...
190
        } catch (Exception $e) {
191
            throw new ArchiveCreationException('Could not create archive: '.$e->getMessage(), $e->getCode(), $e);
192
        }
193
        return count($files);
194
    }
195
196
    /**
197
     * @inheritDoc
198
     */
199
    public function __construct($archiveFileName, $format, $password = null)
200
    {
201
        $this->fileName = $archiveFileName;
202
        $this->format = $format;
203
        $this->archive = static::$zippy->open($archiveFileName);
204
    }
205
206
    /**
207
     * @inheritDoc
208
     */
209
    public function getArchiveInformation()
210
    {
211
        $this->files = [];
212
        $information = new ArchiveInformation();
213
214
        foreach ($this->archive->getMembers() as $member) {
215
            if ($member->isDir())
216
                continue;
217
218
            $this->files[] = $information->files[] = str_replace('\\', '/', $member->getLocation());
219
            $this->members[str_replace('\\', '/', $member->getLocation())] = $member;
220
            $information->compressedFilesSize += (int)$member->getSize();
221
            $information->uncompressedFilesSize += (int)$member->getSize();
222
        }
223
        return $information;
224
    }
225
226
    /**
227
     * @inheritDoc
228
     */
229
    public function getFileNames()
230
    {
231
        return $this->files;
232
    }
233
234
    /**
235
     * @inheritDoc
236
     */
237
    public function isFileExists($fileName)
238
    {
239
        return in_array($fileName, $this->files);
240
    }
241
242
    protected function getMember($fileName)
243
    {
244
        return $this->members[$fileName];
245
246
//        foreach ($this->archive->getMembers() as $member) {
247
//            if ($member->isDir())
248
//                continue;
249
//            if ($member->getLocation() === $fileName)
250
//                return $member;
251
//        }
252
//        return null;
253
    }
254
255
    /**
256
     * @inheritDoc
257
     */
258
    public function getFileData($fileName)
259
    {
260
        $member = $this->getMember($fileName);
261
        return new ArchiveEntry($member->getLocation(), $member->getSize(), $member->getSize(), strtotime($member->getLastModifiedDate()), true);
262
    }
263
264
    /**
265
     * @inheritDoc
266
     */
267
    public function getFileContent($fileName)
268
    {
269
        $member = $this->getMember($fileName);
270
        return (string)$member;
271
    }
272
273
    /**
274
     * @inheritDoc
275
     */
276
    public function getFileStream($fileName)
277
    {
278
        $member = $this->getMember($fileName);
279
        return self::wrapStringInStream((string)$member);
280
    }
281
282
    /**
283
     * @inheritDoc
284
     */
285
    public function extractFiles($outputFolder, array $files)
286
    {
287
        try {
288
            foreach ($files as $file) {
289
                $member = $this->getMember($file);
290
                $member->extract($outputFolder);
291
            }
292
        } catch (Exception $e) {
293
            throw new ArchiveExtractionException('Could not extract archive: '.$e->getMessage(), $e->getCode(), $e);
294
        }
295
        return count($files);
296
    }
297
298
    /**
299
     * @inheritDoc
300
     */
301
    public function extractArchive($outputFolder)
302
    {
303
        try {
304
            $this->archive->extract($outputFolder);
305
        } catch (Exception $e) {
306
            throw new ArchiveExtractionException('Could not extract archive: '.$e->getMessage(), $e->getCode(), $e);
307
        }
308
        return count($this->files);
309
    }
310
311
    /**
312
     * @inheritDoc
313
     */
314
    public function deleteFiles(array $files)
315
    {
316
        $members = [];
317
        try {
318
            foreach ($files as $file) {
319
                $members[] = $this->getMember($file);
320
            }
321
            $this->archive->removeMembers($members);
322
        } catch (Exception $e) {
323
            throw new ArchiveModificationException('Could not remove files from archive: '.$e->getMessage(), $e->getCode(), $e);
324
        }
325
        return count($files);
326
    }
327
328
    /**
329
     * @inheritDoc
330
     */
331
    public function addFiles(array $files)
332
    {
333
        $added = 0;
334
        try {
335
            foreach ($files as $localName => $filename) {
336
                if (is_null($filename)) {
337
//                    $this->archive->addEmptyDir($localName);
338
                } else {
339
                    $this->archive->addMembers([$filename => $localName]);
340
                    $added++;
341
                }
342
            }
343
        } catch (Exception $e) {
344
            throw new ArchiveModificationException('Could not add file "'.$filename.'": '.$e->getMessage(), $e->getCode());
345
        }
346
        $this->getArchiveInformation();
347
        return $added;
348
    }
349
350
    /**
351
     * @param string $inArchiveName
352
     * @param string $content
353
     * @return bool
354
     */
355
    public function addFileFromString($inArchiveName, $content)
356
    {
357
        $fp = fopen('php://memory', 'w');
358
        fwrite($fp, $content);
359
        rewind($fp);
360
        $this->archive->addMembers([$inArchiveName => $fp]);
361
        fclose($fp);
362
        return true;
363
    }
364
}