Completed
Push — master ( 10fc3d...cbc6e7 )
by Michael
18s queued 10s
created

tar   C

Complexity

Total Complexity 68

Size/Duplication

Total Lines 566
Duplicated Lines 12.01 %

Coupling/Cohesion

Components 3
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 68
loc 566
rs 5.6756
c 0
b 0
f 0
ccs 0
cts 249
cp 0
wmc 68
lcom 3
cbo 1

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __computeUnsignedChecksum() 0 11 3
A getFile() 0 10 4
A getDirectory() 0 10 4
A removeDirectory() 0 12 4
A removeFile() 0 12 4
A openTAR() 0 19 2
A addDirectory() 0 18 3
B __parseTar() 0 84 5
A saveTar() 0 8 2
A __parseNullPaddedString() 0 4 1
B __readTar() 0 22 6
B toTar() 0 22 4
A containsDirectory() 0 10 4
A toTarOutput() 0 18 4
A appendTar() 0 8 2
C __generateTar() 0 78 7
B addFile() 0 34 5
A containsFile() 0 10 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like tar often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use tar, and based on these observations, apply Extract Interface, too.

1
<?php
2
// $Id$
3
4
/**
5
 * package::i.tools
6
 *
7
 * php-downloader    v1.0    -    www.ipunkt.biz
8
 *
9
 * (c)    2002 - www.ipunkt.biz (rok)
10
 */
11
/**
12
 * =======================================================================
13
 * Name:
14
 * tar Class
15
 *
16
 * Author:
17
 * Josh Barger <[email protected]>
18
 *
19
 * Description:
20
 * This class reads and writes Tape-Archive (TAR) Files and Gzip
21
 * compressed TAR files, which are mainly used on UNIX systems.
22
 * This class works on both windows AND unix systems, and does
23
 * NOT rely on external applications!! Woohoo!
24
 *
25
 * Usage:
26
 * Copyright (C) 2002  Josh Barger
27
 *
28
 * This library is free software; you can redistribute it and/or
29
 * modify it under the terms of the GNU Lesser General Public
30
 * License as published by the Free Software Foundation; either
31
 * version 2.1 of the License, or (at your option) any later version.
32
 *
33
 * This library is distributed in the hope that it will be useful,
34
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
36
 * Lesser General Public License for more details at:
37
 * http://www.gnu.org/copyleft/lesser.html
38
 *
39
 * If you use this script in your application/website, please
40
 * send me an e-mail letting me know about it :)
41
 *
42
 * Bugs:
43
 * Please report any bugs you might find to my e-mail address
44
 * at [email protected].  If you have already created a fix/patch
45
 * for the bug, please do send it to me so I can incorporate it into my release.
46
 *
47
 * Version History:
48
 * 1.0    04/10/2002    - InitialRelease
49
 *
50
 * 2.0    04/11/2002    - Merged both tarReader and tarWriter
51
 * classes into one
52
 * - Added support for gzipped tar files
53
 * Remember to name for .tar.gz or .tgz
54
 * if you use gzip compression!
55
 * :: THIS REQUIRES ZLIB EXTENSION ::
56
 * - Added additional comments to
57
 * functions to help users
58
 * - Added ability to remove files and
59
 * directories from archive
60
 * 2.1    04/12/2002    - Fixed serious bug in generating tar
61
 * - Created another example file
62
 * - Added check to make sure ZLIB is
63
 * installed before running GZIP
64
 * compression on TAR
65
 * 2.2    05/07/2002    - Added automatic detection of Gzipped
66
 * tar files (Thanks go to Jidgen Falch
67
 * for the idea)
68
 * - Changed "private" functions to have
69
 * special function names beginning with
70
 * two underscores
71
 * =======================================================================
72
 * XOOPS changes onokazu <[email protected]>
73
 *
74
 * 12/25/2002 - Added flag to addFile() function for binary files
75
 *
76
 * =======================================================================
77
 */
78
79
/**
80
 * tar Class
81
 *
82
 * This class reads and writes Tape-Archive (TAR) Files and Gzip
83
 * compressed TAR files, which are mainly used on UNIX systems.
84
 * This class works on both windows AND unix systems, and does
85
 * NOT rely on external applications!! Woohoo!
86
 *
87
 * @author Josh Barger <[email protected]>
88
 * @copyright Copyright (C) 2002  Josh Barger
89
 * @package class
90
 */
91
class tar
92
{
93
    /**
94
     * *#@+
95
     * Unprocessed Archive Information
96
     */
97
    public $filename;
98
    public $isGzipped;
99
    public $tar_file;
100
    /**
101
     * *#@-
102
     */
103
104
    /**
105
     * *#@+
106
     * Processed Archive Information
107
     */
108
    public $files;
109
    public $directories;
110
    public $numFiles;
111
    public $numDirectories;
112
113
    /**
114
     * *#@-
115
     */
116
117
    /**
118
     * Computes the unsigned Checksum of a file's header
119
     * to try to ensure valid file
120
     *
121
     * @param string $bytestring
122
     * @return int|string
123
     * @access private
124
     */
125
    private function __computeUnsignedChecksum($bytestring)
126
    {
127
        $unsigned_chksum = '';
128
        for ($i = 0; $i < 512; ++$i) {
129
            $unsigned_chksum += ord($bytestring[$i]);
130
        }
131
        for ($i = 0; $i < 8; ++$i) {
132
            $unsigned_chksum -= ord($bytestring[148 + $i]);
133
            $unsigned_chksum += ord(' ') * 8;
134
        }
135
        return $unsigned_chksum;
136
    }
137
138
    /**
139
     * Converts a NULL padded string to a non-NULL padded string
140
     *
141
     * @param string $string
142
     * @return string
143
     * @access private
144
     */
145
    private function __parseNullPaddedString($string)
146
    {
147
        $position = strpos($string, chr(0));
148
        return substr($string, 0, $position);
149
    }
150
151
    /**
152
     * This function parses the current TAR file
153
     *
154
     * @return bool always TRUE
155
     * @access private
156
     */
157
    private function __parseTar()
158
    {
159
        // Read Files from archive
160
        $tar_length = strlen($this->tar_file);
161
        $main_offset = 0;
162
        $this->numFiles = 0;
163
        while ($main_offset < $tar_length) {
164
            // If we read a block of 512 nulls, we are at the end of the archive
165
            if (substr($this->tar_file, $main_offset, 512) == str_repeat(chr(0), 512)) {
0 ignored issues
show
Bug introduced by
It seems like $main_offset can also be of type double; however, parameter $start of substr() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

165
            if (substr($this->tar_file, /** @scrutinizer ignore-type */ $main_offset, 512) == str_repeat(chr(0), 512)) {
Loading history...
166
                break;
167
            }
168
            // Parse file name
169
            $file_name = $this->__parseNullPaddedString(substr($this->tar_file, $main_offset, 100));
170
            // Parse the file mode
171
            $file_mode = substr($this->tar_file, $main_offset + 100, 8);
172
            // Parse the file user ID
173
            $file_uid = octdec(substr($this->tar_file, $main_offset + 108, 8));
174
            // Parse the file group ID
175
            $file_gid = octdec(substr($this->tar_file, $main_offset + 116, 8));
176
            // Parse the file size
177
            $file_size = octdec(substr($this->tar_file, $main_offset + 124, 12));
178
            // Parse the file update time - unix timestamp format
179
            $file_time = octdec(substr($this->tar_file, $main_offset + 136, 12));
180
            // Parse Checksum
181
            $file_chksum = octdec(substr($this->tar_file, $main_offset + 148, 6));
182
            // Parse user name
183
            $file_uname = $this->__parseNullPaddedString(substr($this->tar_file, $main_offset + 265, 32));
184
            // Parse Group name
185
            $file_gname = $this->__parseNullPaddedString(substr($this->tar_file, $main_offset + 297, 32));
186
            // Make sure our file is valid
187
            if ($this->__computeUnsignedChecksum(substr($this->tar_file, $main_offset, 512)) != $file_chksum) {
188
                return false;
189
            }
190
            // Parse File Contents
191
            $file_contents = substr($this->tar_file, $main_offset + 512, $file_size);
0 ignored issues
show
Bug introduced by
It seems like $file_size can also be of type double; however, parameter $length of substr() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

191
            $file_contents = substr($this->tar_file, $main_offset + 512, /** @scrutinizer ignore-type */ $file_size);
Loading history...
192
193
            /**
194
             * ### Unused Header Information ###
195
             * $activeFile["typeflag"]        = substr($this->tar_file,$main_offset + 156,1);
196
             * $activeFile["linkname"]        = substr($this->tar_file,$main_offset + 157,100);
197
             * $activeFile["magic"]        = substr($this->tar_file,$main_offset + 257,6);
198
             * $activeFile["version"]        = substr($this->tar_file,$main_offset + 263,2);
199
             * $activeFile["devmajor"]        = substr($this->tar_file,$main_offset + 329,8);
200
             * $activeFile["devminor"]        = substr($this->tar_file,$main_offset + 337,8);
201
             * $activeFile["prefix"]        = substr($this->tar_file,$main_offset + 345,155);
202
             * $activeFile["endheader"]    = substr($this->tar_file,$main_offset + 500,12);
203
             */
204
205
            if ($file_size > 0) {
206
                // Increment number of files
207
                $this->numFiles++;
208
                // Create us a new file in our array
209
                $activeFile =& $this->files[];
210
                // Asign Values
211
                $activeFile["name"] = $file_name;
212
                $activeFile["mode"] = $file_mode;
213
                $activeFile["size"] = $file_size;
214
                $activeFile["time"] = $file_time;
215
                $activeFile["user_id"] = $file_uid;
216
                $activeFile["group_id"] = $file_gid;
217
                $activeFile["user_name"] = $file_uname;
218
                $activeFile["group_name"] = $file_gname;
219
                $activeFile["checksum"] = $file_chksum;
220
                $activeFile["file"] = $file_contents;
221
            } else {
222
                // Increment number of directories
223
                $this->numDirectories++;
224
                // Create a new directory in our array
225
                $activeDir =& $this->directories[];
226
                // Assign values
227
                $activeDir["name"] = $file_name;
228
                $activeDir["mode"] = $file_mode;
229
                $activeDir["time"] = $file_time;
230
                $activeDir["user_id"] = $file_uid;
231
                $activeDir["group_id"] = $file_gid;
232
                $activeDir["user_name"] = $file_uname;
233
                $activeDir["group_name"] = $file_gname;
234
                $activeDir["checksum"] = $file_chksum;
235
            }
236
            // Move our offset the number of blocks we have processed
237
            $main_offset += 512 + (ceil($file_size / 512) * 512);
238
        }
239
240
        return true;
241
    }
242
243
    /**
244
     * Read a non gzipped tar file in for processing.
245
     *
246
     * @param string $filename full filename
247
     * @return bool always TRUE
248
     * @access private
249
     */
250
    private function __readTar($filename = '')
251
    {
252
        // Set the filename to load
253
        if (!$filename) {
254
            $filename = $this->filename;
255
        }
256
        // Read in the TAR file
257
        $fp = fopen($filename, 'rb');
258
        $this->tar_file = fread($fp, filesize($filename));
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

258
        $this->tar_file = fread(/** @scrutinizer ignore-type */ $fp, filesize($filename));
Loading history...
259
        fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

259
        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
260
261
        if ($this->tar_file[0] == chr(31) && $this->tar_file[1] == chr(139) && $this->tar_file[2] == chr(8)) {
262
            if (!function_exists('gzinflate')) {
263
                return false;
264
            }
265
            $this->isGzipped = true;
266
            $this->tar_file = gzinflate(substr($this->tar_file, 10, -4));
267
        }
268
        // Parse the TAR file
269
        $this->__parseTar();
270
271
        return true;
272
    }
273
274
    /**
275
     * Generates a TAR file from the processed data
276
     *
277
     * @return bool always TRUE
278
     * @access private
279
     */
280
    private function __generateTar()
281
    {
282
        // Clear any data currently in $this->tar_file
283
        unset($this->tar_file);
284
        // Generate Records for each directory, if we have directories
285
        if ($this->numDirectories > 0) {
286
            foreach ($this->directories as $key => $information) {
287
                $header = '';
288
                // Generate tar header for this directory
289
                // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
290
                $header .= str_pad($information["name"], 100, chr(0));
291
                $header .= str_pad(decoct($information["mode"]), 7, "0", STR_PAD_LEFT) . chr(0);
292
                $header .= str_pad(decoct($information["user_id"]), 7, "0", STR_PAD_LEFT) . chr(0);
293
                $header .= str_pad(decoct($information["group_id"]), 7, "0", STR_PAD_LEFT) . chr(0);
294
                $header .= str_pad(decoct(0), 11, "0", STR_PAD_LEFT) . chr(0);
295
                $header .= str_pad(decoct($information["time"]), 11, "0", STR_PAD_LEFT) . chr(0);
296
                $header .= str_repeat(" ", 8);
297
                $header .= "5";
298
                $header .= str_repeat(chr(0), 100);
299
                $header .= str_pad("ustar", 6, chr(32));
300
                $header .= chr(32) . chr(0);
301
                $header .= str_pad("", 32, chr(0));
302
                $header .= str_pad("", 32, chr(0));
303
                $header .= str_repeat(chr(0), 8);
304
                $header .= str_repeat(chr(0), 8);
305
                $header .= str_repeat(chr(0), 155);
306
                $header .= str_repeat(chr(0), 12);
307
                // Compute header checksum
308
                $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)), 6, "0", STR_PAD_LEFT);
0 ignored issues
show
Bug introduced by
It seems like $this->__computeUnsignedChecksum($header) can also be of type string; however, parameter $number of decoct() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

308
                $checksum = str_pad(decoct(/** @scrutinizer ignore-type */ $this->__computeUnsignedChecksum($header)), 6, "0", STR_PAD_LEFT);
Loading history...
309
                for ($i = 0; $i < 6; ++$i) {
310
                    $header[(148 + $i)] = substr($checksum, $i, 1);
311
                }
312
                $header[154] = chr(0);
313
                $header[155] = chr(32);
314
                // Add new tar formatted data to tar file contents
315
                $this->tar_file .= $header;
316
            }
317
        }
318
        // Generate Records for each file, if we have files (We should...)
319
        if ($this->numFiles > 0) {
320
            $this->tar_file = '';
321
            foreach ($this->files as $key => $information) {
322
                $header = '';
323
                // Generate the TAR header for this file
324
                // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
325
                $header .= str_pad($information["name"], 100, chr(0));
326
                $header .= str_pad(decoct($information["mode"]), 7, "0", STR_PAD_LEFT) . chr(0);
327
                $header .= str_pad(decoct($information["user_id"]), 7, "0", STR_PAD_LEFT) . chr(0);
328
                $header .= str_pad(decoct($information["group_id"]), 7, "0", STR_PAD_LEFT) . chr(0);
329
                $header .= str_pad(decoct($information["size"]), 11, "0", STR_PAD_LEFT) . chr(0);
330
                $header .= str_pad(decoct($information["time"]), 11, "0", STR_PAD_LEFT) . chr(0);
331
                $header .= str_repeat(" ", 8);
332
                $header .= "0";
333
                $header .= str_repeat(chr(0), 100);
334
                $header .= str_pad("ustar", 6, chr(32));
335
                $header .= chr(32) . chr(0);
336
                $header .= str_pad($information["user_name"], 32, chr(0)); // How do I get a file's user name from PHP?
337
                $header .= str_pad($information["group_name"], 32, chr(0)); // How do I get a file's group name from PHP?
338
                $header .= str_repeat(chr(0), 8);
339
                $header .= str_repeat(chr(0), 8);
340
                $header .= str_repeat(chr(0), 155);
341
                $header .= str_repeat(chr(0), 12);
342
                // Compute header checksum
343
                $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)), 6, "0", STR_PAD_LEFT);
344
                for ($i = 0; $i < 6; ++$i) {
345
                    $header[(148 + $i)] = substr($checksum, $i, 1);
346
                }
347
                $header[154] = chr(0);
348
                $header[155] = chr(32);
349
                // Pad file contents to byte count divisible by 512
350
                $file_contents = str_pad($information["file"], (ceil($information["size"] / 512) * 512), chr(0));
0 ignored issues
show
Bug introduced by
ceil($information['size'] / 512) * 512 of type double is incompatible with the type integer expected by parameter $pad_length of str_pad(). ( Ignorable by Annotation )

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

350
                $file_contents = str_pad($information["file"], /** @scrutinizer ignore-type */ (ceil($information["size"] / 512) * 512), chr(0));
Loading history...
351
                // Add new tar formatted data to tar file contents
352
                $this->tar_file .= $header . $file_contents;
353
            }
354
        }
355
        // Add 512 bytes of NULLs to designate EOF
356
        $this->tar_file .= str_repeat(chr(0), 512);
357
        return true;
358
    }
359
360
    /**
361
     * Open a TAR file
362
     *
363
     * @param string $filename
364
     * @return bool
365
     */
366
    public function openTAR($filename)
367
    {
368
        // Clear any values from previous tar archives
369
        unset($this->filename);
370
        unset($this->isGzipped);
371
        unset($this->tar_file);
372
        unset($this->files);
373
        unset($this->directories);
374
        unset($this->numFiles);
375
        unset($this->numDirectories);
376
        // If the tar file doesn't exist...
377
        if (!XoopsLoad::fileExists($filename)) {
378
            return false;
379
        }
380
381
        $this->filename = $filename;
382
        // Parse this file
383
        $this->__readTar();
384
        return true;
385
    }
386
387
    /**
388
     * Appends a tar file to the end of the currently opened tar file.
389
     *
390
     * @param string $filename
391
     * @return bool
392
     */
393
    public function appendTar($filename)
394
    {
395
        // If the tar file doesn't exist...
396
        if (!XoopsLoad::fileExists($filename)) {
397
            return false;
398
        }
399
        $this->__readTar($filename);
400
        return true;
401
    }
402
403
    /**
404
     * Retrieves information about a file in the current tar archive
405
     *
406
     * @param string $filename
407
     * @return string FALSE on fail
408
     */
409
    public function getFile($filename)
410
    {
411
        if ($this->numFiles > 0) {
412
            foreach ($this->files as $information) {
413
                if ($information['name'] == $filename) {
414
                    return $information;
415
                }
416
            }
417
        }
418
        return false;
419
    }
420
421
    /**
422
     * Retrieves information about a directory in the current tar archive
423
     *
424
     * @param string $dirname
425
     * @return string FALSE on fail
426
     */
427
    public function getDirectory($dirname)
428
    {
429
        if ($this->numDirectories > 0) {
430
            foreach ($this->directories as $information) {
431
                if ($information['name'] == $dirname) {
432
                    return $information;
433
                }
434
            }
435
        }
436
        return false;
437
    }
438
439
    /**
440
     * Check if this tar archive contains a specific file
441
     *
442
     * @param string $filename
443
     * @return bool
444
     */
445
    public function containsFile($filename)
446
    {
447
        if ($this->numFiles > 0) {
448
            foreach ($this->files as $information) {
449
                if ($information['name'] == $filename) {
450
                    return true;
451
                }
452
            }
453
        }
454
        return false;
455
    }
456
457
    /**
458
     * Check if this tar archive contains a specific directory
459
     *
460
     * @param string $dirname
461
     * @return bool
462
     */
463
    public function containsDirectory($dirname)
464
    {
465
        if ($this->numDirectories > 0) {
466
            foreach ($this->directories as $information) {
467
                if ($information['name'] == $dirname) {
468
                    return true;
469
                }
470
            }
471
        }
472
        return false;
473
    }
474
475
    /**
476
     * Add a directory to this tar archive
477
     *
478
     * @param string $dirname
479
     * @return bool
480
     */
481
    public function addDirectory($dirname)
482
    {
483
        if (!XoopsLoad::fileExists($dirname)) {
484
            return false;
485
        }
486
        // Get directory information
487
        $file_information = stat($dirname);
488
        // Add directory to processed data
489
        $this->numDirectories++;
490
        $activeDir =& $this->directories[];
491
        $activeDir['name'] = $dirname;
492
        $activeDir['mode'] = $file_information['mode'];
493
        $activeDir['time'] = $file_information['time'];
494
        $activeDir['user_id'] = $file_information['uid'];
495
        $activeDir['group_id'] = $file_information['gid'];
496
        $activeDir['checksum'] = isset($checksum) ? $checksum : '';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $checksum seems to never exist and therefore isset should always be false.
Loading history...
497
498
        return true;
499
    }
500
501
    /**
502
     * Add a file to the tar archive
503
     *
504
     * @param string $filename
505
     * @param boolean $binary Binary file?
506
     * @return bool
507
     */
508
    public function addFile($filename, $binary = false)
509
    {
510
        // Make sure the file we are adding exists!
511
        if (!XoopsLoad::fileExists($filename)) {
512
            return false;
513
        }
514
        // Make sure there are no other files in the archive that have this same filename
515
        if ($this->containsFile($filename)) {
516
            return false;
517
        }
518
        // Get file information
519
        $file_information = stat($filename);
520
        // Read in the file's contents
521
        if (!$binary) {
522
            $fp = fopen($filename, 'r');
523
        } else {
524
            $fp = fopen($filename, 'rb');
525
        }
526
        $file_contents = fread($fp, filesize($filename));
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

526
        $file_contents = fread(/** @scrutinizer ignore-type */ $fp, filesize($filename));
Loading history...
527
        fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

527
        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
528
        // Add file to processed data
529
        $this->numFiles++;
530
        $activeFile =& $this->files[];
531
        $activeFile['name'] = $filename;
532
        $activeFile['mode'] = $file_information['mode'];
533
        $activeFile['user_id'] = $file_information['uid'];
534
        $activeFile['group_id'] = $file_information['gid'];
535
        $activeFile['size'] = $file_information['size'];
536
        $activeFile['time'] = $file_information['mtime'];
537
        $activeFile['checksum'] = isset($checksum) ? $checksum : '';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $checksum seems to never exist and therefore isset should always be false.
Loading history...
538
        $activeFile['user_name'] = '';
539
        $activeFile['group_name'] = '';
540
        $activeFile['file'] = trim($file_contents);
541
        return true;
542
    }
543
544
    /**
545
     * Remove a file from the tar archive
546
     *
547
     * @param string $filename
548
     * @return bool
549
     */
550
    public function removeFile($filename)
551
    {
552
        if ($this->numFiles > 0) {
553
            foreach ($this->files as $key => $information) {
554
                if ($information['name'] == $filename) {
555
                    $this->numFiles--;
556
                    unset($this->files[$key]);
557
                    return true;
558
                }
559
            }
560
        }
561
        return false;
562
    }
563
564
    /**
565
     * Remove a directory from the tar archive
566
     *
567
     * @param string $dirname
568
     * @return bool
569
     */
570
    public function removeDirectory($dirname)
571
    {
572
        if ($this->numDirectories > 0) {
573
            foreach ($this->directories as $key => $information) {
574
                if ($information['name'] == $dirname) {
575
                    $this->numDirectories--;
576
                    unset($this->directories[$key]);
577
                    return true;
578
                }
579
            }
580
        }
581
        return false;
582
    }
583
584
    /**
585
     * Write the currently loaded tar archive to disk
586
     *
587
     * @return bool
588
     */
589
    public function saveTar()
590
    {
591
        if (!$this->filename) {
592
            return false;
593
        }
594
        // Write tar to current file using specified gzip compression
595
        $this->toTar($this->filename, $this->isGzipped);
596
        return true;
597
    }
598
599
    /**
600
     * Saves tar archive to a different file than the current file
601
     *
602
     * @param string $filename
603
     * @param bool $useGzip Use GZ compression?
604
     * @return bool
605
     */
606
    public function toTar($filename, $useGzip)
607
    {
608
        if (!$filename) {
609
            return false;
610
        }
611
        // Encode processed files into TAR file format
612
        $this->__generateTar();
613
        // GZ Compress the data if we need to
614
        if ($useGzip) {
615
            // Make sure we have gzip support
616
            if (!function_exists('gzencode')) {
617
                return false;
618
            }
619
            $file = gzencode($this->tar_file);
620
        } else {
621
            $file = $this->tar_file;
622
        }
623
        // Write the TAR file
624
        $fp = fopen($filename, 'wb');
625
        fwrite($fp, $file);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

625
        fwrite(/** @scrutinizer ignore-type */ $fp, $file);
Loading history...
626
        fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

626
        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
627
        return true;
628
    }
629
630
    /**
631
     * Sends tar archive to stdout
632
     *
633
     * @param string $filename
634
     * @param bool $useGzip Use GZ compression?
635
     * @return string
636
     */
637
    public function toTarOutput($filename, $useGzip)
638
    {
639
        if (!$filename) {
640
            return false;
641
        }
642
        // Encode processed files into TAR file format
643
        $this->__generateTar();
644
        // GZ Compress the data if we need to
645
        if ($useGzip) {
646
            // Make sure we have gzip support
647
            if (!function_exists('gzencode')) {
648
                return false;
649
            }
650
            $file = gzencode($this->tar_file);
651
        } else {
652
            $file = $this->tar_file;
653
        }
654
        return $file;
655
    }
656
}
657