Skip to content

Commit bda2fc3

Browse files
committed
Adding zipping functionality + refactor status messages.
1 parent b9e5bf5 commit bda2fc3

File tree

1 file changed

+156
-49
lines changed

1 file changed

+156
-49
lines changed

unzipper.php

Lines changed: 156 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,34 @@
11
<?php
22
/**
3-
* The Unzipper extracts .zip or .rar archives and .gz files on webservers. It's handy if you
4-
* do not have shell access. E.g. if you want to upload a lot of files
5-
* (php framework or image collection) as archive to save time.
6-
*
3+
* The Unzipper extracts .zip or .rar archives and .gz files on webservers.
4+
* It's handy if you do not have shell access. E.g. if you want to upload a lot
5+
* of files (php framework or image collection) as an archive to save time.
6+
* As of version 0.1.0 it also supports creating archives.
77
*
88
* @author Andreas Tasch, at[tec], attec.at
99
* @license GNU GPL v3
1010
* @package attec.toolbox
11-
* @version 0.0.4 Beta
11+
* @version 0.1.0
1212
*/
13+
define('VERSION', '0.1.0');
1314

1415
$timestart = microtime(TRUE);
16+
$GLOBALS['status'] = array();
1517

1618
$arc = new Unzipper;
19+
if (isset($_POST['dounzip'])) {
20+
//check if an archive was selected for unzipping
21+
$archive = isset($_POST['zipfile']) ? strip_tags($_POST['zipfile']) : '';
22+
$destination = isset($_POST['extpath']) ? strip_tags($_POST['extpath']) : '';
23+
$arc->prepareExtraction($archive, $destination);
24+
}
25+
26+
if(isset($_POST['dozip'])) {
27+
$zippath = !empty($_POST['zippath']) ? strip_tags($_POST['zippath']) : '.';
28+
// Resulting zipfile e.g. zipper--2016-07-23--11-55.zip
29+
$zipfile = 'zipper-' . date("Y-m-d--H-i") . '.zip';
30+
Zipper::zipDir($zippath, $zipfile);
31+
}
1732

1833
$timeend = microtime(TRUE);
1934
$time = $timeend - $timestart;
@@ -41,32 +56,30 @@ public function __construct() {
4156
closedir($dh);
4257

4358
if (!empty($this->zipfiles)) {
44-
self::$status = '.zip or .gz or .rar files found, ready for extraction';
59+
$GLOBALS['status'] = array('info' => '.zip or .gz or .rar files found, ready for extraction');
4560
}
4661
else {
47-
self::$status = '<span class="status--ERROR">Error: No .zip or .gz or rar files found.</span>';
62+
$GLOBALS['status'] = array('info' => 'No .zip or .gz or rar files found. So only zipping functionality available.');
4863
}
4964
}
65+
}
5066

51-
//check if an archive was selected for unzipping
52-
//check if archive has been selected
53-
$input = isset($_POST['zipfile']) ? strip_tags($_POST['zipfile']) : '';
54-
$destination = isset($_POST['extpath']) ? strip_tags($_POST['extpath']) : '';
55-
//allow only local existing archives to extract
56-
if ($input !== '') {
57-
if (empty($destination)) {
58-
$extpath = $this->localdir;
59-
}
60-
else {
61-
$extpath = $this->localdir . '/' . $destination;
62-
if (!is_dir($extpath)) {
63-
mkdir($extpath);
64-
}
65-
}
66-
if (in_array($input, $this->zipfiles)) {
67-
self::extract($input, $extpath);
67+
public function prepareExtraction($archive, $destination) {
68+
// Determine paths.
69+
if (empty($destination)) {
70+
$extpath = $this->localdir;
71+
}
72+
else {
73+
$extpath = $this->localdir . '/' . $destination;
74+
// todo move this to extraction function
75+
if (!is_dir($extpath)) {
76+
mkdir($extpath);
6877
}
6978
}
79+
//allow only local existing archives to extract
80+
if (in_array($archive, $this->zipfiles)) {
81+
self::extract($archive, $extpath);
82+
}
7083
}
7184

7285
/**
@@ -100,7 +113,7 @@ public static function extract($archive, $destination) {
100113
public static function extractZipArchive($archive, $destination) {
101114
// Check if webserver supports unzipping.
102115
if (!class_exists('ZipArchive')) {
103-
self::$status = '<span class="status--ERROR">Error: Your PHP version does not support unzip functionality.</span>';
116+
$GLOBALS['status'] = array('error' => 'Error: Your PHP version does not support unzip functionality.');
104117
return;
105118
}
106119

@@ -112,14 +125,14 @@ public static function extractZipArchive($archive, $destination) {
112125
if (is_writeable($destination . '/')) {
113126
$zip->extractTo($destination);
114127
$zip->close();
115-
self::$status = '<span class="status--OK">Files unzipped successfully</span>';
128+
$GLOBALS['status'] = array('success' => 'Files unzipped successfully');
116129
}
117130
else {
118-
self::$status = '<span class="status--ERROR">Error: Directory not writeable by webserver.</span>';
131+
$GLOBALS['status'] = array('error' => 'Error: Directory not writeable by webserver.');
119132
}
120133
}
121134
else {
122-
self::$status = '<span class="status--ERROR">Error: Cannot read .zip archive.</span>';
135+
$GLOBALS['status'] = array('error' => 'Error: Cannot read .zip archive.');
123136
}
124137
}
125138

@@ -132,7 +145,7 @@ public static function extractZipArchive($archive, $destination) {
132145
public static function extractGzipFile($archive, $destination) {
133146
// Check if zlib is enabled
134147
if (!function_exists('gzopen')) {
135-
self::$status = '<span class="status--ERROR">Error: Your PHP has no zlib support enabled.</span>';
148+
$GLOBALS['status'] = array('error' => 'Error: Your PHP has no zlib support enabled.');
136149
return;
137150
}
138151

@@ -148,10 +161,10 @@ public static function extractGzipFile($archive, $destination) {
148161

149162
// Check if file was extracted.
150163
if (file_exists($destination . '/' . $filename)) {
151-
self::$status = '<span class="status--OK">File unzipped successfully.</span>';
164+
$GLOBALS['status'] = array('success' => 'File unzipped successfully.');
152165
}
153166
else {
154-
self::$status = '<span class="status--ERROR">Error unzipping file.</span>';
167+
$GLOBALS['status'] = array('error' => 'Error unzipping file.');
155168
}
156169

157170
}
@@ -165,7 +178,7 @@ public static function extractGzipFile($archive, $destination) {
165178
public static function extractRarArchive($archive, $destination) {
166179
// Check if webserver supports unzipping.
167180
if (!class_exists('RarArchive')) {
168-
self::$status = '<span class="status--ERROR">Error: Your PHP version does not support .rar archive functionality. <a class="info" href="http://php.net/manual/en/rar.installation.php" target="_blank">How to install RarArchive</a></span>';
181+
$GLOBALS['status'] = array('error' => 'Error: Your PHP version does not support .rar archive functionality. <a class="info" href="http://php.net/manual/en/rar.installation.php" target="_blank">How to install RarArchive</a>');
169182
return;
170183
}
171184
// Check if archive is readable.
@@ -177,25 +190,96 @@ public static function extractRarArchive($archive, $destination) {
177190
$entry->extract($destination);
178191
}
179192
$rar->close();
180-
self::$status = '<span class="status--OK">Files extracted successfully</span>';
193+
$GLOBALS['status'] = array('success' => 'Files extracted successfully.');
181194
}
182195
else {
183-
self::$status = '<span class="status--ERROR">Error: Directory not writeable by webserver.</span>';
196+
$GLOBALS['status'] = array('error' => 'Error: Directory not writeable by webserver.');
184197
}
185198
}
186199
else {
187-
self::$status = '<span class="status--ERROR">Error: Cannot read .rar archive.</span>';
200+
$GLOBALS['status'] = array('error' => 'Error: Cannot read .rar archive.');
188201
}
189202
}
190203

191204
}
192205

206+
/**
207+
* Class Zipper
208+
*
209+
* Copied and slightly modified from http://at2.php.net/manual/en/class.ziparchive.php#110719
210+
* @author umbalaconmeogia
211+
*/
212+
class Zipper
213+
{
214+
/**
215+
* Add files and sub-directories in a folder to zip file.
216+
* @param string $folder
217+
* @param ZipArchive $zipFile
218+
* @param int $exclusiveLength Number of text to be exclusived from the file path.
219+
*/
220+
private static function folderToZip($folder, &$zipFile, $exclusiveLength) {
221+
$handle = opendir($folder);
222+
223+
while (false !== $f = readdir($handle)) {
224+
// Check for local/parent path or zipping file itself and skip.
225+
if ($f != '.' && $f != '..' && $f != basename(__FILE__)) {
226+
$filePath = "$folder/$f";
227+
// Remove prefix from file path before add to zip.
228+
$localPath = substr($filePath, $exclusiveLength);
229+
230+
if (is_file($filePath)) {
231+
$zipFile->addFile($filePath, $localPath);
232+
} elseif (is_dir($filePath)) {
233+
// Add sub-directory.
234+
$zipFile->addEmptyDir($localPath);
235+
self::folderToZip($filePath, $zipFile, $exclusiveLength);
236+
}
237+
}
238+
}
239+
closedir($handle);
240+
}
241+
242+
/**
243+
* Zip a folder (include itself).
244+
* Usage:
245+
* Zipper::zipDir('path/to/sourceDir', 'path/to/out.zip');
246+
*
247+
* @param string $sourcePath
248+
* Relative path of directory to be zipped.
249+
*
250+
* @param string $outZipPath
251+
* Relative path of the resulting output zip file.
252+
*/
253+
public static function zipDir($sourcePath, $outZipPath)
254+
{
255+
$pathInfo = pathinfo($sourcePath);
256+
$parentPath = $pathInfo['dirname'];
257+
$dirName = $pathInfo['basename'];
258+
259+
$z = new ZipArchive();
260+
$z->open($outZipPath, ZipArchive::CREATE);
261+
$z->addEmptyDir($dirName);
262+
if ($sourcePath == $dirName) {
263+
self::folderToZip($sourcePath, $z, 0);
264+
} else {
265+
self::folderToZip($sourcePath, $z, strlen("$parentPath/"));
266+
}
267+
$z->close();
268+
269+
$GLOBALS['status'] = array('success' => 'Successfully created archive ' . $outZipPath);
270+
}
271+
}
272+
273+
class Status {
274+
public static $messages = array();
275+
}
276+
193277
?>
194278

195279
<!DOCTYPE html>
196280
<html>
197281
<head>
198-
<title>File Unzipper</title>
282+
<title>File Unzipper + Zipper</title>
199283
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
200284
<style type="text/css">
201285
<!--
@@ -211,6 +295,8 @@ public static function extractRarArchive($archive, $destination) {
211295

212296
fieldset {
213297
border: 0;
298+
background-color: #EEE;
299+
margin: 10px 0 10px 0;
214300
}
215301

216302
.select {
@@ -219,25 +305,36 @@ public static function extractRarArchive($archive, $destination) {
219305
}
220306

221307
.status {
222-
margin-top: 20px;
223-
padding: 5px;
308+
margin: 0;
309+
margin-bottom: 20px;
310+
padding: 10px;
224311
font-size: 80%;
225312
background: #EEE;
226313
border: 1px dotted #DDD;
227314
}
228315

229316
.status--ERROR {
230-
color: red;
231-
font-weight: bold;
317+
background-color: red;
318+
color: white;
232319
font-size: 120%;
233320
}
234321

235-
.status--OK {
236-
color: green;
322+
.status--SUCCESS {
323+
background-color: green;
237324
font-weight: bold;
325+
color: white;
238326
font-size: 120%
239327
}
240328

329+
.small {
330+
font-size: 0.7rem;
331+
font-weight: normal;
332+
}
333+
334+
.version {
335+
font-size: 80%;
336+
}
337+
241338
.form-field {
242339
border: 1px solid #AAA;
243340
padding: 8px;
@@ -268,9 +365,13 @@ public static function extractRarArchive($archive, $destination) {
268365
</style>
269366
</head>
270367
<body>
271-
<h1>Archive Unzipper</h1>
368+
<p class="status status--<?php echo strtoupper(key($GLOBALS['status'])); ?>">
369+
Status: <?php echo reset($GLOBALS['status']); ?><br/>
370+
<span class="small">Processing Time: <?php echo $time; ?> seconds</span>
371+
</p>
272372
<form action="" method="POST">
273373
<fieldset>
374+
<h1>Archive Unzipper</h1>
274375
<label for="zipfile">Select .zip or .rar archive or .gz file you want to extract:</label>
275376
<select name="zipfile" size="1" class="select">
276377
<?php foreach ($arc->zipfiles as $zip) {
@@ -281,13 +382,19 @@ public static function extractRarArchive($archive, $destination) {
281382
<label for="extpath">Extraction path (optional):</label>
282383
<input type="text" name="extpath" class="form-field"
283384
placeholder="mypath"/>
284-
<p class="info">Enter extraction path without leading or trailing slashes (e.g. "mypath"). If left blank current directory will be used.</p>
285-
<input type="submit" name="submit" class="submit" value="Unzip Archive"/>
385+
<p class="info">Enter extraction path without leading or trailing slashes (e.g. "mypath"). If left empty current directory will be used.</p>
386+
<input type="submit" name="dounzip" class="submit" value="Unzip Archive"/>
387+
</fieldset>
388+
389+
<fieldset>
390+
<h1>Archive Zipper</h1>
391+
<label for="zippath">Path that should be zipped (optional):</label>
392+
<input type="text" name="zippath" class="form-field"
393+
placeholder="zippath"/>
394+
<p class="info">Enter path to be zipped without leading or trailing slashes (e.g. "zippath"). If left empty current directory will be used.</p>
395+
<input type="submit" name="dozip" class="submit" value="Zip Archive"/>
286396
</fieldset>
287397
</form>
288-
<p class="status">
289-
Status: <?php echo $arc::$status; ?> <br/>
290-
Processing Time: <?php echo $time; ?> ms
291-
</p>
398+
<p class="version">Unzipper version: <?php echo VERSION; ?></p>
292399
</body>
293400
</html>

0 commit comments

Comments
 (0)