Passed
Branch master (f2d2e3)
by Michael
18:45
created

getid3_tar   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 199
rs 9.1199
wmc 41

3 Methods

Rating   Name   Duplication   Size   Complexity  
A get_flag_type() 0 21 1
F Analyze() 0 111 17
F display_perms() 0 56 23

How to fix   Complexity   

Complex Class

Complex classes like getid3_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.

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 getid3_tar, and based on these observations, apply Extract Interface, too.

1
<?php
2
// +----------------------------------------------------------------------+
3
// | PHP version 5                                                        |
4
// +----------------------------------------------------------------------+
5
// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 |
6
// +----------------------------------------------------------------------+
7
// | This source file is subject to version 2 of the GPL license,         |
8
// | that is bundled with this package in the file license.txt and is     |
9
// | available through the world-wide-web at the following url:           |
10
// | http://www.gnu.org/copyleft/gpl.html                                 |
11
// +----------------------------------------------------------------------+
12
// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    |
13
// +----------------------------------------------------------------------+
14
// | Authors: James Heinrich <info�getid3*org>                            |
15
// |          Allan Hansen <ah�artemis*dk>                                |
16
// +----------------------------------------------------------------------+
17
// | module.archive.tar.php                                               |
18
// | module for analyzing TAR files                                       |
19
// | dependencies: NONE                                                   |
20
// +----------------------------------------------------------------------+
21
// | Module originally written by Mike Mozolin <teddybear�mail*ru>        |
22
// +----------------------------------------------------------------------+
23
//
24
// $Id: module.archive.tar.php,v 1.2 2006/11/02 10:48:00 ah Exp $
25
26
        
27
        
28
class getid3_tar extends getid3_handler
29
{
30
31
    function Analyze() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
32
33
        $info = &$this->getid3->info;
34
35
        $info['fileformat'] = 'tar';
36
37
        $fp = $this->getid3->fp;
38
        
39
        fseek($fp, 0);
40
        
41
        $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155/prefix';
42
43
        $null_512k = str_repeat("\0", 512); // end-of-file marker
44
45
        $already_warned = false;
46
47
        while (!feof($fp)) {
48
            
49
            $buffer = fread($fp, 512);
50
            
51
            // check the block
52
            $checksum = 0;
53
            for ($i = 0; $i < 148; $i++) {
54
                $checksum += ord(substr($buffer, $i, 1));
55
            }
56
            for ($i = 148; $i < 156; $i++) {
57
                $checksum += ord(' ');
58
            }
59
            for ($i = 156; $i < 512; $i++) {
60
                $checksum += ord(substr($buffer, $i, 1));
61
            }
62
            $attr    = unpack($unpack_header, $buffer);
63
            $name    =        trim(@$attr['fname']);
64
            $mode    = octdec(trim(@$attr['mode']));
65
            $uid     = octdec(trim(@$attr['uid']));
66
            $gid     = octdec(trim(@$attr['gid']));
67
            $size    = octdec(trim(@$attr['size']));
68
            $mtime   = octdec(trim(@$attr['mtime']));
69
            $chksum  = octdec(trim(@$attr['chksum']));
70
            $typflag =        trim(@$attr['typflag']);
71
            $lnkname =        trim(@$attr['lnkname']);
72
            $magic   =        trim(@$attr['magic']);
73
            $ver     =        trim(@$attr['ver']);
74
            $uname   =        trim(@$attr['uname']);
75
            $gname   =        trim(@$attr['gname']);
76
            $devmaj  = octdec(trim(@$attr['devmaj']));
77
            $devmin  = octdec(trim(@$attr['devmin']));
78
            $prefix  =        trim(@$attr['prefix']);
79
80
            // EOF Found
81
            if (($checksum == 256) && ($chksum == 0)) {
82
                break;
83
            }
84
85
            // Check if filename if 7bit as spec requires
86
            if (!$already_warned) {
87
                for ($i = 0; $i < strlen($name); $i++) {
88
                    if ($name{$i} < chr(32) || $name{$i} > chr(127)) {
89
                        $this->getid3->warning('Some filenames contains extended characters, which breaks the tar specifation. This is not uncommon, but you will have to handle the character encoding for filenames yourself.');
90
                        $already_warned = true;
91
                        break;
92
                    }
93
                }
94
            }
95
            
96
            if ($prefix) {
97
                $name = $prefix.'/'.$name;
98
            }
99
            if ((preg_match('#/$#', $name)) && !$name) {
100
                $typeflag = 5;
0 ignored issues
show
Unused Code introduced by
The assignment to $typeflag is dead and can be removed.
Loading history...
101
            }
102
            
103
            // If it's the end of the tar-file...
104
            if ($buffer == $null_512k) {
105
                break;
106
            }
107
            
108
            // Protect against tar-files with garbage at the end
109
            if ($name == '') {
110
                break;
111
            }
112
            
113
            $info['tar']['file_details'][$name] = array (
114
                'name'     => $name,
115
                'mode_raw' => $mode,
116
                'mode'     => getid3_tar::display_perms($mode),
117
                'uid'      => $uid,
118
                'gid'      => $gid,
119
                'size'     => $size,
120
                'mtime'    => $mtime,
121
                'chksum'   => $chksum,
122
                'typeflag' => getid3_tar::get_flag_type($typflag),
123
                'linkname' => $lnkname,
124
                'magic'    => $magic,
125
                'version'  => $ver,
126
                'uname'    => $uname,
127
                'gname'    => $gname,
128
                'devmajor' => $devmaj,
129
                'devminor' => $devmin
130
            );
131
            
132
            // Skip the next chunk
133
            fseek($fp, $size, SEEK_CUR);
134
135
            // Throw away padding
136
            if ($size % 512) {
137
                fseek($fp, 512 - $diff, SEEK_CUR);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $diff seems to be never defined.
Loading history...
138
            }
139
            
140
        }
141
        return true;
142
    }
143
144
145
    // Parses the file mode to file permissions
146
    public static function display_perms($mode) {
147
148
        // Determine Type
149
        if ($mode & 0x1000) {
150
            $type='p'; // FIFO pipe
151
        }
152
        elseif ($mode & 0x2000) {
153
            $type='c'; // Character special
154
        }
155
        elseif ($mode & 0x4000) {
156
            $type='d'; // Directory
157
        }
158
        elseif ($mode & 0x6000) {
159
            $type='b'; // Block special
160
        }
161
        elseif ($mode & 0x8000) {
162
            $type='-'; // Regular
163
        }
164
        elseif ($mode & 0xA000) {
165
            $type='l'; // Symbolic Link
166
        }
167
        elseif ($mode & 0xC000) {
168
            $type='s'; // Socket
169
        }
170
        else {
171
            $type='u'; // UNKNOWN
172
        }
173
174
        // Determine permissions
175
        $owner['read']    = (($mode & 00400) ? 'r' : '-');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$owner was never initialized. Although not strictly required by PHP, it is generally a good practice to add $owner = array(); before regardless.
Loading history...
176
        $owner['write']   = (($mode & 00200) ? 'w' : '-');
177
        $owner['execute'] = (($mode & 00100) ? 'x' : '-');
178
        $group['read']    = (($mode & 00040) ? 'r' : '-');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$group was never initialized. Although not strictly required by PHP, it is generally a good practice to add $group = array(); before regardless.
Loading history...
179
        $group['write']   = (($mode & 00020) ? 'w' : '-');
180
        $group['execute'] = (($mode & 00010) ? 'x' : '-');
181
        $world['read']    = (($mode & 00004) ? 'r' : '-');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$world was never initialized. Although not strictly required by PHP, it is generally a good practice to add $world = array(); before regardless.
Loading history...
182
        $world['write']   = (($mode & 00002) ? 'w' : '-');
183
        $world['execute'] = (($mode & 00001) ? 'x' : '-');
184
185
        // Adjust for SUID, SGID and sticky bit
186
        if ($mode & 0x800) {
187
            $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S';
188
        }
189
        if ($mode & 0x400) {
190
            $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S';
191
        }
192
        if ($mode & 0x200) {
193
            $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T';
194
        }
195
196
        $s  = sprintf('%1s', $type);
197
        $s .= sprintf('%1s%1s%1s',      $owner['read'], $owner['write'], $owner['execute']);
198
        $s .= sprintf('%1s%1s%1s',      $group['read'], $group['write'], $group['execute']);
199
        $s .= sprintf('%1s%1s%1s'."\n", $world['read'], $world['write'], $world['execute']);
200
201
        return $s;
202
    }
203
204
205
    // Converts the file type
206
    public static function get_flag_type($typflag) {
207
208
        static $flag_types = array (
209
            '0' => 'LF_NORMAL',
210
            '1' => 'LF_LINK',
211
            '2' => 'LF_SYNLINK',
212
            '3' => 'LF_CHR',
213
            '4' => 'LF_BLK',
214
            '5' => 'LF_DIR',
215
            '6' => 'LF_FIFO',
216
            '7' => 'LF_CONFIG',
217
            'D' => 'LF_DUMPDIR',
218
            'K' => 'LF_LONGLINK',
219
            'L' => 'LF_LONGNAME',
220
            'M' => 'LF_MULTIVOL',
221
            'N' => 'LF_NAMES',
222
            'S' => 'LF_SPARSE',
223
            'V' => 'LF_VOLHDR'
224
        );
225
226
        return @$flag_types[$typflag];
227
    }
228
    
229
}
230
231
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...