Passed
Push — 0.1.x ( 81ff64...72f342 )
by f
01:32
created

Zip::createArchive()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 13
nc 6
nop 2
dl 0
loc 17
rs 9.2222
c 0
b 0
f 0
1
<?php
2
namespace wapmorgan\UnifiedArchive\Formats;
3
4
use Exception;
5
use wapmorgan\UnifiedArchive\ArchiveEntry;
6
use wapmorgan\UnifiedArchive\ArchiveInformation;
7
use ZipArchive;
8
9
/**
10
 * Class Zip
11
 *
12
 * @package wapmorgan\UnifiedArchive\Formats
13
 * @requires ext-zip
14
 */
15
class Zip extends BasicFormat
16
{
17
    /** @var ZipArchive */
18
    protected $zip;
19
20
    /**
21
     * BasicFormat constructor.
22
     *
23
     * @param string $archiveFileName
24
     * @throws \Exception
25
     */
26
    public function __construct($archiveFileName)
27
    {
28
        $this->open($archiveFileName);
29
    }
30
31
    /**
32
     * @param $archiveFileName
33
     *
34
     * @throws \Exception
35
     */
36
    protected function open($archiveFileName)
37
    {
38
        $this->zip = new ZipArchive();
39
        $open_result = $this->zip->open($archiveFileName);
40
        if ($open_result !== true) {
41
            throw new Exception('Could not open Zip archive: '.$open_result);
42
        }
43
    }
44
45
    /**
46
     * Zip format destructor
47
     */
48
    public function __destruct()
49
    {
50
        unset($this->zip);
51
    }
52
53
    /**
54
     * @return ArchiveInformation
55
     */
56
    public function getArchiveInformation()
57
    {
58
        $information = new ArchiveInformation();
59
        for ($i = 0; $i < $this->zip->numFiles; $i++) {
60
            $file = $this->zip->statIndex($i);
61
            $information->files[$i] = $file['name'];
62
            $information->compressedFilesSize += $file['comp_size'];
63
            $information->uncompressedFilesSize += $file['size'];
64
        }
65
        return $information;
66
    }
67
68
    /**
69
     * @return array
70
     */
71
    public function getFileNames()
72
    {
73
        $files = [];
74
        for ($i = 0; $i < $this->zip->numFiles; $i++)
75
            $files[] = $this->zip->getNameIndex($i);
76
        return $files;
77
    }
78
79
    /**
80
     * @param string $fileName
81
     *
82
     * @return bool
83
     */
84
    public function isFileExists($fileName)
85
    {
86
        return $this->zip->statName($fileName) !== false;
87
    }
88
89
    /**
90
     * @param string $fileName
91
     *
92
     * @return ArchiveEntry
93
     */
94
    public function getFileData($fileName)
95
    {
96
        $stat = $this->zip->statName($fileName);
97
        return new ArchiveEntry($fileName, $stat['comp_size'], $stat['size'], $stat['mtime'],
98
            $stat['comp_method'] != 0);
99
    }
100
101
    /**
102
     * @param string $fileName
103
     *
104
     * @return string|false
105
     * @throws \Exception
106
     */
107
    public function getFileContent($fileName)
108
    {
109
        $result = $this->zip->getFromName($fileName);
110
        if ($result === false)
111
            throw new Exception('Could not get file information: '.$result);
112
        return $result;
113
    }
114
115
    /**
116
     * @param string $fileName
117
     *
118
     * @return bool|resource|string
119
     */
120
    public function getFileResource($fileName)
121
    {
122
        return $this->zip->getStream($fileName);
123
    }
124
125
    /**
126
     * @param string $outputFolder
127
     * @param array $files
128
     * @return false|resource
129
     * @throws \Exception
130
     */
131
    public function extractFiles($outputFolder, array $files)
132
    {
133
        if ($this->zip->extractTo($outputFolder, $files) === false)
134
            throw new Exception($this->zip->getStatusString(), $this->zip->status);
135
136
        return count($files);
0 ignored issues
show
Bug Best Practice introduced by
The expression return count($files) returns the type integer which is incompatible with the documented return type false|resource.
Loading history...
137
    }
138
139
    /**
140
     * @param string $outputFolder
141
     * @throws \Exception
142
     */
143
    public function extractArchive($outputFolder)
144
    {
145
        if ($this->zip->extractTo($outputFolder) === false)
146
            throw new Exception($this->zip->getStatusString(), $this->zip->status);
147
        return $this->zip->numFiles;
148
    }
149
150
    /**
151
     * @param array $files
152
     *
153
     * @return int
154
     * @throws \Exception
155
     */
156
    public function deleteFiles(array $files)
157
    {
158
        $count = 0;
159
        foreach ($files as $file) {
160
            if ($this->zip->deleteName($file) === false)
161
                throw new Exception($this->zip->getStatusString(), $this->zip->status);
162
            $count++;
163
        }
164
165
        // reopen archive to save changes
166
        $archive_filename = $this->zip->filename;
167
        $this->zip->close();
168
        $this->open($archive_filename);
169
170
        return $count;
171
    }
172
173
    /**
174
     * @param array $files
175
     *
176
     * @return int
177
     * @throws \Exception
178
     */
179
    public function addFiles(array $files)
180
    {
181
        $added_files = 0;
182
        foreach ($files as $localName => $fileName) {
183
            if (is_null($fileName)) {
184
                if ($this->zip->addEmptyDir($localName) === false)
185
                    throw new Exception($this->zip->getStatusString(), $this->zip->status);
186
            } else {
187
                if ($this->zip->addFile($fileName, $localName) === false)
188
                    throw new Exception($this->zip->getStatusString(), $this->zip->status);
189
                $added_files++;
190
            }
191
        }
192
193
        // reopen archive to save changes
194
        $archive_filename = $this->zip->filename;
195
        $this->zip->close();
196
        $this->open($archive_filename);
197
198
        return $added_files;
199
    }
200
201
    /**
202
     * @param array  $files
203
     * @param string $archiveFileName
204
     *
205
     * @return false|int
206
     * @throws \Exception
207
     */
208
    public static function createArchive(array $files, $archiveFileName){
209
        $zip = new ZipArchive();
210
        $result = $zip->open($archiveFileName, ZipArchive::CREATE);
211
        if ($result !== true)
212
            throw new Exception('ZipArchive error: '.$result);
213
        foreach ($files as $localName => $fileName) {
214
            if ($fileName === null) {
215
                if ($zip->addEmptyDir($localName) === false)
216
                    return false;
217
            } else {
218
                if ($zip->addFile($fileName, $localName) === false)
219
                    return false;
220
            }
221
        }
222
        $zip->close();
223
224
        return count($files);
225
    }
226
}