Passed
Push — master ( 16b802...f9c1a1 )
by Marco
28:43
created

ZipManager::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php namespace Comodojo\Zip;
2
3
use \Comodojo\Zip\Base\ManagerTools;
4
use \Comodojo\Foundation\Utils\UniqueId;
5
use \Comodojo\Exception\ZipException;
6
use \Countable;
7
use \Exception;
8
9
/**
10
 * Multiple Comodojo\Zip\Zip manager
11
 *
12
 * @package     Comodojo Spare Parts
13
 * @author      Marco Giovinazzi <[email protected]>
14
 * @license     MIT
15
 *
16
 * LICENSE:
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26
27
class ZipManager implements Countable {
28
29
    /**
30
     * Array of managed zip files
31
     *
32
     * @var array
33
     */
34
    private array $zip_archives = [];
35
36
    /**
37
     * Count the number of Zip objects registered to the manager
38
     *
39
     * @return int
40
     */
41 1
    public function count(): int {
42 1
        return count($this->zip_archives);
43
    }
44
45
    /**
46
     * Add a Zip object to manager and return its id
47
     *
48
     * @param Zip $zip
49
     *
50
     * @return string
51
     */
52 5
    public function addZip(Zip $zip): string {
53
54 5
        $id = UniqueId::generate(32);
55 5
        $this->zip_archives[$id] = $zip;
56 5
        return $id;
57
58
    }
59
60
    /**
61
     * Remove a Zip object from manager
62
     *
63
     * @param Zip $zip
64
     *
65
     * @return bool
66
     * @throws ZipException
67
     */
68 1
    public function removeZip(Zip $zip): bool {
69
70 1
        $archive_key = array_search($zip, $this->zip_archives, true);
71 1
        if ( $archive_key === false ) {
72
            throw new ZipException("Archive not found");
73
        }
74
75 1
        unset($this->zip_archives[$archive_key]);
76 1
        return true;
77
78
    }
79
80
    /**
81
     * Remove a Zip object from manager by Zip id
82
     *
83
     * @param string $id
84
     *
85
     * @return bool
86
     * @throws ZipException
87
     */
88 1
    public function removeZipById(string $id): bool {
89
90 1
        if ( isset($this->zip_archives[$id]) === false ) {
91
            throw new ZipException("Archive: $id not found");
92
        }
93 1
        unset($this->zip_archives[$id]);
94 1
        return true;
95
96
    }
97
98
    /**
99
     * Get a list of all registered Zips filenames as an array
100
     *
101
     * @return array
102
     */
103 1
    public function listZips(): array {
104
105 1
        return array_column(
106 1
            array_map(function($key, $archive) {
107 1
                return ["key" => $key, "file" => $archive->getZipFile()];
108 1
            }, array_keys($this->zip_archives), $this->zip_archives),
109 1
        "file", "key");
110
111
    }
112
113
    /**
114
     * Get a Zip object by Id
115
     *
116
     * @param string $id The zip id
117
     *
118
     * @return Zip
119
     * @throws ZipException
120
     */
121 2
    public function getZip(string $id): Zip {
122
123 2
        if ( array_key_exists($id, $this->zip_archives) === false ) {
124 1
            throw new ZipException("Archive id $id not found");
125
        }
126 1
        return $this->zip_archives[$id];
127
128
    }
129
130
    /**
131
     * Set current base path (to add relative files to zip archive)
132
     * for all Zips
133
     *
134
     * @param string $path
135
     *
136
     * @return ZipManager
137
     * @throws ZipException
138
     */
139
    public function setPath(string $path): ZipManager {
140
141
        try {
142
            foreach ( $this->zip_archives as $archive ) {
143
                $archive->setPath($path);
144
            }
145
            return $this;
146
        } catch (ZipException $ze) {
147
            throw $ze;
148
        }
149
150
    }
151
152
    /**
153
     * Get a list of paths used by Zips
154
     *
155
     * @return  array
156
     */
157
    public function getPath(): array {
158
159
        return array_column(
160
            array_map(function($key, $archive) {
161
                return ["key" => $key, "path" => $archive->getPath()];
162
            }, array_keys($this->zip_archives), $this->zip_archives),
163
        "path", "key");
164
165
    }
166
167
    /**
168
     * Set default file mask for all Zips
169
     *
170
     * @param int $mask
171
     *
172
     * @return ZipManager
173
     * @throws ZipException
174
     */
175
    public function setMask(int $mask): ZipManager {
176
177
        try {
178
            foreach ( $this->zip_archives as $archive ) {
179
                $archive->setMask($mask);
180
            }
181
            return $this;
182
        } catch (ZipException $ze) {
183
            throw $ze;
184
        }
185
186
    }
187
188
    /**
189
     * Get a list of masks from Zips
190
     *
191
     * @return array
192
     */
193
    public function getMask(): array {
194
195
        return array_column(
196
            array_map(function($key, $archive) {
197
                return ["key" => $key, "mask" => $archive->getMask()];
198
            }, array_keys($this->zip_archives), $this->zip_archives),
199
        "mask", "key");
200
201
    }
202
203
    /**
204
     * Get a list of files in Zips
205
     *
206
     * @return array
207
     * @throws ZipException
208
     */
209 1
    public function listFiles(): array {
210
211
        try {
212 1
            return array_column(
213 1
                array_map(function($key, $archive) {
214 1
                    return ["key" => $key, "files" => $archive->listFiles()];
215 1
                }, array_keys($this->zip_archives), $this->zip_archives),
216 1
            "files", "key");
217
        } catch (ZipException $ze) {
218
            throw $ze;
219
        }
220
221
    }
222
223
    /**
224
     * Extract Zips to common destination
225
     *
226
     * @param string $destination Destination path
227
     * @param bool $separate (optional) If true (default), files will be placed in different directories
228
     * @param mixed $files (optional) a filename or an array of filenames
229
     *
230
     * @return bool
231
     * @throws ZipException
232
     */
233 2
    public function extract(
234
        string $destination,
235
        bool $separate = true,
236
        $files = null
237
    ): bool {
238
239
        try {
240 2
            foreach ( $this->zip_archives as $archive ) {
241
242 2
                $local_path = substr($destination, -1) == '/' ? $destination : $destination.'/';
243 2
                $local_file = pathinfo($archive->getZipFile());
244 2
                $local_destination = $separate ? ($local_path.$local_file['filename']) : $destination;
245
246 2
                $archive->extract($local_destination, $files);
247
248
            }
249 2
            return true;
250
        } catch (ZipException $ze) {
251
            throw $ze;
252
        }
253
254
    }
255
256
    /**
257
     * Merge multiple Zips into one
258
     *
259
     * @param string $output_zip_file
260
     *  Destination zip
261
     * @param bool $separate (optional)
262
     *  If true (default), files will be placed in different directories
263
     *
264
     * @return bool
265
     * @throws ZipException
266
     */
267 1
    public function merge(string $output_zip_file, bool $separate = true): bool {
268
269 1
        $pathinfo = pathinfo($output_zip_file);
270 1
        $temporary_folder = $pathinfo['dirname']."/".ManagerTools::getTemporaryFolder();
271
272
        try {
273
274 1
            $this->extract($temporary_folder, $separate);
275 1
            $zip = Zip::create($output_zip_file);
276 1
            $zip->add($temporary_folder, true)->close();
277 1
            ManagerTools::recursiveUnlink($temporary_folder);
278 1
            return true;
279
280
        } catch (ZipException $ze) {
281
            throw $ze;
282
        } catch (Exception $e) {
283
            throw $e;
284
        }
285
286
    }
287
288
    /**
289
     * Add a file to all registered Zips
290
     *
291
     * @param mixed $file_name_or_array
292
     *  The filename to add or an array of filenames
293
     * @param bool $flatten_root_folder
294
     *  (optional) If true, the Zip root folder will be flattened (default: false)
295
     *
296
     * @return ZipManager
297
     * @throws ZipException
298
     */
299 1
    public function add($file_name_or_array, bool $flatten_root_folder = false): ZipManager {
300
301
        try {
302
303 1
            foreach ( $this->zip_archives as $archive ) {
304 1
                $archive->add($file_name_or_array, $flatten_root_folder);
305
            }
306 1
            return $this;
307
308
        } catch (ZipException $ze) {
309
            throw $ze;
310
        }
311
312
    }
313
314
    /**
315
     * Delete a file from any registered Zip
316
     *
317
     * @param mixed $file_name_or_array
318
     *  The filename to add or an array of filenames
319
     *
320
     * @return ZipManager
321
     * @throws ZipException
322
     */
323
    public function delete($file_name_or_array): ZipManager {
324
325
        try {
326
327
            foreach ( $this->zip_archives as $archive ) {
328
                $archive->delete($file_name_or_array);
329
            }
330
            return $this;
331
332
        } catch (ZipException $ze) {
333
            throw $ze;
334
        }
335
336
    }
337
338
    /**
339
     * Close all Zips
340
     *
341
     * @return bool
342
     * @throws ZipException
343
     */
344 4
    public function close(): bool {
345
346
        try {
347 4
            foreach ( $this->zip_archives as $archive ) {
348 3
                $archive->close();
349
            }
350 4
            return true;
351
        } catch (ZipException $ze) {
352
            throw $ze;
353
        }
354
355
    }
356
357
}
358