Passed
Push — master ( e9611b...a3681d )
by f
13:07
created

OneFileDriver   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 205
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 63
c 0
b 0
f 0
dl 0
loc 205
rs 10
ccs 0
cts 63
cp 0
wmc 26

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getInstallationInstruction() 0 3 1
A getFileNames() 0 3 1
A __construct() 0 9 3
A deleteFiles() 0 3 1
A checkFormatSupport() 0 8 3
A getSupportedFormats() 0 3 1
A isFileExists() 0 3 1
A addFileFromString() 0 3 1
A createArchive() 0 30 6
A extractArchive() 0 15 4
A getArchiveInformation() 0 7 1
A getFileData() 0 7 1
A extractFiles() 0 3 1
A isInstalled() 0 3 1
1
<?php
2
namespace wapmorgan\UnifiedArchive\Drivers\OneFile;
3
4
use wapmorgan\UnifiedArchive\ArchiveEntry;
5
use wapmorgan\UnifiedArchive\ArchiveInformation;
6
use wapmorgan\UnifiedArchive\Drivers\BasicDriver;
7
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
8
use wapmorgan\UnifiedArchive\Exceptions\ArchiveExtractionException;
9
use wapmorgan\UnifiedArchive\Exceptions\EmptyFileListException;
10
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
11
use wapmorgan\UnifiedArchive\Formats;
12
13
abstract class OneFileDriver extends BasicDriver
14
{
15
    /** @var null|string Should be filled for real format like 'gz' or other */
16
    const FORMAT_SUFFIX = null;
17
    const FORMAT = null;
18
    const PHP_EXTENSION = null;
19
20
    const TYPE = self::TYPE_EXTENSION;
21
22
    protected $fileName;
23
    protected $inArchiveFileName;
24
    protected $uncompressedSize;
25
    protected $modificationTime;
26
27
    public static function isInstalled()
28
    {
29
        return extension_loaded(static::PHP_EXTENSION);
0 ignored issues
show
Bug introduced by
static::PHP_EXTENSION of type null is incompatible with the type string expected by parameter $extension of extension_loaded(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

29
        return extension_loaded(/** @scrutinizer ignore-type */ static::PHP_EXTENSION);
Loading history...
30
    }
31
32
    public static function getInstallationInstruction()
33
    {
34
        return 'install `' . static::PHP_EXTENSION . '` extension';
35
    }
36
37
    public static function getSupportedFormats()
38
    {
39
        return [static::FORMAT];
40
    }
41
42
    /**
43
     * @param $format
44
     * @return array
45
     */
46
    public static function checkFormatSupport($format)
47
    {
48
        if (!static::isInstalled()) {
49
            return [];
50
        }
51
        switch ($format) {
52
            case static::FORMAT:
53
                return [BasicDriver::OPEN, BasicDriver::EXTRACT_CONTENT, BasicDriver::STREAM_CONTENT, BasicDriver::CREATE];
54
        }
55
    }
56
57
    /**
58
     * @inheritDoc
59
     */
60
    public function __construct($archiveFileName, $format, $password = null)
61
    {
62
        if (static::FORMAT_SUFFIX === null)
0 ignored issues
show
introduced by
The condition static::FORMAT_SUFFIX === null is always true.
Loading history...
63
            throw new \Exception('Format should be initialized');
64
        if ($password !== null)
65
            throw new UnsupportedOperationException(self::FORMAT_SUFFIX.' archive does not support password!');
66
67
        $this->fileName = $archiveFileName;
68
        $this->inArchiveFileName = basename($archiveFileName, '.'.static::FORMAT_SUFFIX);
69
    }
70
71
    /**
72
     * @return ArchiveInformation
73
     */
74
    public function getArchiveInformation()
75
    {
76
        $information = new ArchiveInformation();
77
        $information->compressedFilesSize = filesize($this->fileName);
78
        $information->uncompressedFilesSize = $this->uncompressedSize;
79
        $information->files[] = $this->inArchiveFileName;
80
        return $information;
81
    }
82
83
    /**
84
     * @return array
85
     */
86
    public function getFileNames()
87
    {
88
        return [$this->inArchiveFileName];
89
    }
90
91
    /**
92
     * @param string $fileName
93
     *
94
     * @return bool
95
     */
96
    public function isFileExists($fileName)
97
    {
98
        return $fileName === $this->inArchiveFileName;
99
    }
100
101
    /**
102
     * @param string $fileName
103
     * @return ArchiveEntry|false
104
     */
105
    public function getFileData($fileName)
106
    {
107
        return new ArchiveEntry(
108
            $this->inArchiveFileName,
109
            filesize($this->fileName),
110
            $this->uncompressedSize,
111
            $this->modificationTime);
112
    }
113
114
    /**
115
     * @param string $outputFolder
116
     * @param array $files
117
     * @return int
118
     * @throws ArchiveExtractionException
119
     */
120
    public function extractFiles($outputFolder, array $files = null)
121
    {
122
        return $this->extractArchive($outputFolder);
123
    }
124
125
    /**
126
     * @param string $outputFolder
127
     * @return int
128
     * @throws ArchiveExtractionException
129
     */
130
    public function extractArchive($outputFolder)
131
    {
132
        $data = $this->getFileContent($this->inArchiveFileName);
133
        if ($data === false)
134
            throw new ArchiveExtractionException('Could not extract archive');
135
136
        $size = strlen($data);
137
        $written = file_put_contents($outputFolder.$this->inArchiveFileName, $data);
138
139
        if ($written === true) {
140
            throw new ArchiveExtractionException('Could not extract file "'.$this->inArchiveFileName.'": could not write data');
141
        } else if ($written < $size) {
142
            throw new ArchiveExtractionException('Could not archive file "'.$this->inArchiveFileName.'": written '.$written.' of '.$size);
143
        }
144
        return 1;
145
    }
146
147
    /**
148
     * @param array $files
149
     * @return void
150
     * @throws UnsupportedOperationException
151
     */
152
    public function deleteFiles(array $files)
153
    {
154
        throw new UnsupportedOperationException();
155
    }
156
157
    /**
158
     * @param string $inArchiveName
159
     * @param string $content
160
     * @return bool|void
161
     * @throws UnsupportedOperationException@
162
     */
163
    public function addFileFromString($inArchiveName, $content)
164
    {
165
        throw new UnsupportedOperationException();
166
    }
167
168
    /**
169
     * @param array $files
170
     * @param string $archiveFileName
171
     * @param int $archiveFormat
172
     * @param int $compressionLevel
173
     * @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...
174
     * @param $fileProgressCallable
175
     * @return int
176
     * @throws ArchiveCreationException
177
     * @throws UnsupportedOperationException
178
     */
179
    public static function createArchive(
180
        array $files,
181
        $archiveFileName,
182
        $archiveFormat,
183
        $compressionLevel = self::COMPRESSION_AVERAGE,
184
        $password = null,
185
        $fileProgressCallable = null
186
    ) {
187
        if (count($files) > 1) {
188
            throw new UnsupportedOperationException('One-file format ('.__CLASS__.') could not archive few files');
189
        }
190
        if (empty($files)) {
191
            throw new EmptyFileListException();
192
        }
193
        if ($password !== null) {
0 ignored issues
show
introduced by
The condition $password !== null is always false.
Loading history...
194
            throw new UnsupportedOperationException('One-file format ('.__CLASS__.') could not encrypt an archive');
195
        }
196
197
        $filename = array_shift($files);
198
199
        $compressed_content = static::compressData(file_get_contents($filename), $compressionLevel);
200
        $size = strlen($compressed_content);
201
        $written = file_put_contents($archiveFileName, $compressed_content);
202
203
        if ($written === true) {
204
            throw new ArchiveCreationException('Could not archive file: could not write data');
205
        } else if ($written < $size) {
206
            throw new ArchiveCreationException('Could not archive file: written '.$written.' of '.$size);
207
        }
208
        return 1;
209
    }
210
211
    /**
212
     * @param string $data
213
     * @param int $compressionLevel
214
     * @return mixed
215
     * @throws UnsupportedOperationException
216
     */
217
    abstract protected static function compressData($data, $compressionLevel);
218
}
219