ZipFile::addFile()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 51
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 42
nc 2
nop 3
dl 0
loc 51
rs 9.248
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* vim: set expandtab sw=4 ts=4 sts=4: */
4
/**
5
 * Zip file creation
6
 *
7
 * @package PhpMyAdmin
8
 */
9
10
namespace F72X\Tools;
11
12
/**
13
 * Zip file creation class.
14
 * Makes zip files.
15
 *
16
 * @access  public
17
 * @package PhpMyAdmin
18
 * @see     Official ZIP file format: http://www.pkware.com/support/zip-app-note
19
 */
20
class ZipFile {
21
22
    /**
23
     * Whether to echo zip as it's built or return as string from -> file
24
     *
25
     * @var  boolean  $doWrite
26
     */
27
    var $doWrite = false;
28
29
    /**
30
     * Array to store compressed data
31
     *
32
     * @var  array    $datasec
33
     */
34
    var $datasec = array();
35
36
    /**
37
     * Central directory
38
     *
39
     * @var  array    $ctrl_dir
40
     */
41
    var $ctrl_dir = array();
42
43
    /**
44
     * End of central directory record
45
     *
46
     * @var  string   $eof_ctrl_dir
47
     */
48
    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
49
50
    /**
51
     * Last offset position
52
     *
53
     * @var  integer  $old_offset
54
     */
55
    var $old_offset = 0;
56
57
    /**
58
     * Sets member variable this -> doWrite to true
59
     * - Should be called immediately after class instantiation
60
     * - If set to true, then ZIP archive are echo'ed to STDOUT as each
61
     *   file is added via this -> addfile(), and central directories are
62
     *   echoed to STDOUT on final call to this -> file().  Also,
63
     *   this -> file() returns an empty string so it is safe to issue a
64
     *   "echo $zipfile;" command
65
     *
66
     * @access public
67
     *
68
     * @return void
69
     */
70
    function setDoWrite() {
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...
71
        $this->doWrite = true;
72
    }
73
74
// end of the 'setDoWrite()' method
75
    /**
76
     * Converts an Unix timestamp to a four byte DOS date and time format (date
77
     * in high two bytes, time in low two bytes allowing magnitude comparison).
78
     *
79
     * @param integer $unixtime the current Unix timestamp
80
     *
81
     * @return integer the current date in a four byte DOS format
82
     *
83
     * @access private
84
     */
85
    function unix2DosTime($unixtime = 0) {
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...
86
        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
87
        if ($timearray['year'] < 1980) {
88
            $timearray['year'] = 1980;
89
            $timearray['mon'] = 1;
90
            $timearray['mday'] = 1;
91
            $timearray['hours'] = 0;
92
            $timearray['minutes'] = 0;
93
            $timearray['seconds'] = 0;
94
        } // end if
95
        return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
96
    }
97
98
// end of the 'unix2DosTime()' method
99
    /**
100
     * Adds "file" to archive
101
     *
102
     * @param string  $data file contents
103
     * @param string  $name name of the file in the archive (may contains the path)
104
     * @param integer $time the current timestamp
105
     *
106
     * @access public
107
     *
108
     * @return void
109
     */
110
    function addFile($data, $name, $time = 0) {
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...
111
        $name = str_replace('\\', '/', $name);
112
        $hexdtime = pack('V', $this->unix2DosTime($time));
113
        $fr = "\x50\x4b\x03\x04";
114
        $fr .= "\x14\x00";            // ver needed to extract
115
        $fr .= "\x00\x00";            // gen purpose bit flag
116
        $fr .= "\x08\x00";            // compression method
117
        $fr .= $hexdtime;             // last mod time and date
118
        // "local file header" segment
119
        $unc_len = strlen($data);
120
        $crc = crc32($data);
121
        $zdata = gzcompress($data);
122
        $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
123
        $c_len = strlen($zdata);
124
        $fr .= pack('V', $crc);             // crc32
125
        $fr .= pack('V', $c_len);           // compressed filesize
126
        $fr .= pack('V', $unc_len);         // uncompressed filesize
127
        $fr .= pack('v', strlen($name));    // length of filename
128
        $fr .= pack('v', 0);                // extra field length
129
        $fr .= $name;
130
        // "file data" segment
131
        $fr .= $zdata;
132
        // echo this entry on the fly, ...
133
        if ($this->doWrite) {
134
            echo $fr;
135
        } else {                     // ... OR add this entry to array
136
            $this->datasec[] = $fr;
137
        }
138
        // now add to central directory record
139
        $cdrec = "\x50\x4b\x01\x02";
140
        $cdrec .= "\x00\x00";                // version made by
141
        $cdrec .= "\x14\x00";                // version needed to extract
142
        $cdrec .= "\x00\x00";                // gen purpose bit flag
143
        $cdrec .= "\x08\x00";                // compression method
144
        $cdrec .= $hexdtime;                 // last mod time & date
145
        $cdrec .= pack('V', $crc);           // crc32
146
        $cdrec .= pack('V', $c_len);         // compressed filesize
147
        $cdrec .= pack('V', $unc_len);       // uncompressed filesize
148
        $cdrec .= pack('v', strlen($name)); // length of filename
149
        $cdrec .= pack('v', 0);             // extra field length
150
        $cdrec .= pack('v', 0);             // file comment length
151
        $cdrec .= pack('v', 0);             // disk number start
152
        $cdrec .= pack('v', 0);             // internal file attributes
153
        $cdrec .= pack('V', 32);            // external file attributes
154
        // - 'archive' bit set
155
        $cdrec .= pack('V', $this->old_offset); // relative offset of local header
156
        $this->old_offset += strlen($fr);
157
        $cdrec .= $name;
158
        // optional extra field, file comment goes here
159
        // save to central directory
160
        $this->ctrl_dir[] = $cdrec;
161
    }
162
163
// end of the 'addFile()' method
164
    /**
165
     * Echo central dir if ->doWrite==true, else build string to return
166
     *
167
     * @return string  if ->doWrite {empty string} else the ZIP file contents
168
     *
169
     * @access public
170
     */
171
    function file() {
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...
172
        $ctrldir = implode('', $this->ctrl_dir);
173
        $header = $ctrldir .
174
                $this->eof_ctrl_dir .
175
                pack('v', sizeof($this->ctrl_dir)) . //total #of entries "on this disk"
176
                pack('v', sizeof($this->ctrl_dir)) . //total #of entries overall
177
                pack('V', strlen($ctrldir)) . //size of central dir
178
                pack('V', $this->old_offset) . //offset to start of central dir
179
                "\x00\x00";                            //.zip file comment length
180
        if ($this->doWrite) { // Send central directory & end ctrl dir to STDOUT
181
            echo $header;
182
            return "";            // Return empty string
183
        } else {                  // Return entire ZIP archive as string
184
            $data = implode('', $this->datasec);
185
            return $data . $header;
186
        }
187
    }
188
189
    /**
190
     * 
191
     * @param string $zipPath the zip file path
192
     * @param string $entryName the entry file name
193
     * @return string|int The entry content or:
194
     *  0 If the zip isn't found
195
     *  1 If the entry isn't found
196
     */
197
    public static function getEntry($zipPath, $entryName) {
198
        $zip = zip_open($zipPath);
199
        if (is_resource($zip)) {
200
            // find entry
201
            do {
202
                $entry = zip_read($zip);
203
            } while ($entry && zip_entry_name($entry) != $entryName);
204
            // Not found
205
            if (!$entry) {
0 ignored issues
show
introduced by
$entry is of type resource, thus it always evaluated to false.
Loading history...
206
                // close zip
207
                zip_close($zip);
208
                return -1;
209
            }
210
            // open entry
211
            zip_entry_open($zip, $entry, "r");
212
            // read entry
213
            $content = zip_entry_read($entry, zip_entry_filesize($entry));
214
            // close entry
215
            zip_entry_close($entry);
216
            // close zip
217
            zip_close($zip);
218
            return $content;
219
        } else {
220
            return 0;
221
        }
222
    }
223
224
// end of the 'file()' method
225
}
226
227
// end of the 'ZipFile' class