Completed
Branch master (1a8c72)
by Marco
11:05
created

ZipManager::removeZip()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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