OneFileDriver::getFormats()   A
last analyzed

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
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
ccs 0
cts 2
cp 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
namespace wapmorgan\UnifiedArchive\Drivers\OneFile;
3
4
use wapmorgan\UnifiedArchive\Abilities;
5
use wapmorgan\UnifiedArchive\ArchiveEntry;
6
use wapmorgan\UnifiedArchive\ArchiveInformation;
7
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicDriver;
8
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicExtensionDriver;
9
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
10
use wapmorgan\UnifiedArchive\Exceptions\ArchiveExtractionException;
11
use wapmorgan\UnifiedArchive\Exceptions\EmptyFileListException;
12
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
13
use wapmorgan\UnifiedArchive\Formats;
14
15
abstract class OneFileDriver extends BasicExtensionDriver
16
{
17
    /** @var null|string Should be filled for real format like 'gz' or other */
18
    const FORMAT = null;
19
20
    protected $fileName;
21
    protected $inArchiveFileName;
22
    protected $uncompressedSize;
23
    protected $modificationTime;
24
25
    public static function getFormats()
26
    {
27
        return [static::FORMAT];
28
    }
29
30
    /**
31
     * @param $format
32
     * @return array
33
     */
34
    public static function getFormatAbilities($format)
35
    {
36
        if (!static::isInstalled()) {
37
            return [];
38
        }
39
        switch ($format) {
40
            case static::FORMAT:
41
                return [Abilities::OPEN, Abilities::EXTRACT_CONTENT, Abilities::STREAM_CONTENT, Abilities::CREATE];
42
        }
43
    }
44
45
    /**
46
     * @inheritDoc
47
     * @throws UnsupportedOperationException
48
     * @throws \Exception
49
     */
50
    public function __construct($archiveFileName, $format, $password = null)
51
    {
52
        $suffix = Formats::getFormatExtension(static::FORMAT);
53
        if ($suffix === null) {
54
            throw new \Exception('Format suffix is empty for ' . static::FORMAT . ', it should be initialized!');
55
        }
56
        if ($password !== null) {
57
            throw new UnsupportedOperationException($suffix . ' archive does not support password!');
58
        }
59
60
        parent::__construct($archiveFileName, $format);
61
        $this->inArchiveFileName = basename($archiveFileName, '.' . $suffix);
62
    }
63
64
    /**
65
     * @return ArchiveInformation
66
     */
67
    public function getArchiveInformation()
68
    {
69
        $information = new ArchiveInformation();
70
        $information->compressedFilesSize = filesize($this->fileName);
71
        $information->uncompressedFilesSize = $this->uncompressedSize;
72
        $information->files[] = $this->inArchiveFileName;
73
        return $information;
74
    }
75
76
    /**
77
     * @return array
78
     */
79
    public function getFileNames()
80
    {
81
        return [$this->inArchiveFileName];
82
    }
83
84
    /**
85
     * @param string $fileName
86
     *
87
     * @return bool
88
     */
89
    public function isFileExists($fileName)
90
    {
91
        return $fileName === $this->inArchiveFileName;
92
    }
93
94
    /**
95
     * @param string $fileName
96
     * @return ArchiveEntry|false
97
     */
98
    public function getFileData($fileName)
99
    {
100
        return new ArchiveEntry(
101
            $this->inArchiveFileName,
102
            filesize($this->fileName),
103
            $this->uncompressedSize,
104
            $this->modificationTime);
105
    }
106
107
    /**
108
     * @param string $outputFolder
109
     * @param array $files
110
     * @return int
111
     * @throws ArchiveExtractionException
112
     */
113
    public function extractFiles($outputFolder, ?array $files = null)
114
    {
115
        return $this->extractArchive($outputFolder);
116
    }
117
118
    /**
119
     * @param string $outputFolder
120
     * @return int
121
     * @throws ArchiveExtractionException
122
     */
123
    public function extractArchive($outputFolder)
124
    {
125
        if(method_exists($this, 'streamToFile')){
126
            $this->streamToFile($outputFolder.$this->inArchiveFileName);
127
        }else{
128
            $data = $this->getFileContent($this->inArchiveFileName);
129
            if ($data === false)
130
                throw new ArchiveExtractionException('Could not extract archive');
131
132
            $size = strlen($data);
133
            $written = file_put_contents($outputFolder.$this->inArchiveFileName, $data);
134
135
            if ($written === true) {
136
                throw new ArchiveExtractionException('Could not extract file "'.$this->inArchiveFileName.'": could not write data');
137
            } else if ($written < $size) {
138
                throw new ArchiveExtractionException('Could not archive file "'.$this->inArchiveFileName.'": written '.$written.' of '.$size);
139
            }
140
        }
141
        return 1;
142
    }
143
144
    /**
145
     * @param array $files
146
     * @param string $archiveFileName
147
     * @param int $archiveFormat
148
     * @param int $compressionLevel
149
     * @param string|null $password
150
     * @param callable|null $fileProgressCallable
151
     * @return int Number of archived files
152
     * @throws ArchiveCreationException
153
     * @throws UnsupportedOperationException
154
     */
155
    public static function createArchive(
156
        array $files,
157
        $archiveFileName,
158
        $archiveFormat,
159
        $compressionLevel = self::COMPRESSION_AVERAGE,
160
        $password = null,
161
        $fileProgressCallable = null
162
    ) {
163
        if (count($files) > 1) {
164
            throw new UnsupportedOperationException('One-file format ('.__CLASS__.') could not archive few files');
165
        }
166
        if (empty($files)) {
167
            throw new EmptyFileListException();
168
        }
169
        if ($password !== null) {
170
            throw new UnsupportedOperationException('One-file format ('.__CLASS__.') could not encrypt an archive');
171
        }
172
173
        $filename = array_shift($files);
174
175
        $compressed_content = static::compressData(file_get_contents($filename), $compressionLevel);
176
        $size = strlen($compressed_content);
177
        $written = file_put_contents($archiveFileName, $compressed_content);
178
179
        if ($written === true) {
180
            throw new ArchiveCreationException('Could not archive file: could not write data');
181
        } else if ($written < $size) {
182
            throw new ArchiveCreationException('Could not archive file: written '.$written.' of '.$size);
183
        }
184
        return 1;
185
    }
186
187
    /**
188
     * @param string $data
189
     * @param int $compressionLevel
190
     * @return mixed
191
     * @throws UnsupportedOperationException
192
     */
193
    abstract protected static function compressData($data, $compressionLevel);
194
}
195