[geeklog-cvs] geeklog: Zip/Tar Unpacker

geeklog-cvs at lists.geeklog.net geeklog-cvs at lists.geeklog.net
Tue Mar 31 10:52:28 EDT 2009


details:   http://project.geeklog.net/cgi-bin/hgweb.cgi/rev/15db5ecc0f2d
changeset: 6880:15db5ecc0f2d
user:      jcarlson <justin.carlson at gmail.com>
date:      Tue Mar 31 09:47:35 2009 -0500
description:
Zip/Tar Unpacker

diffstat:

1 file changed, 457 insertions(+)
system/classes/unpacker.class.php |  457 +++++++++++++++++++++++++++++++++++++

diffs (truncated from 462 to 300 lines):

diff -r 5bd37d01b2d5 -r 15db5ecc0f2d system/classes/unpacker.class.php
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/system/classes/unpacker.class.php	Tue Mar 31 09:47:35 2009 -0500
@@ -0,0 +1,457 @@
+<?php
+
+/*Reminder: always indent with 4 spaces (no tabs). */
+//+---------------------------------------------------------------------------+
+//| Geeklog 1.6                                                               |
+//+---------------------------------------------------------------------------+
+//| unpacker.php                                                              |
+//|                                                                           |
+//| unpacker - archive libs wrapper                                           |
+//| This class wraps calls to pecl Zip, pear Zip, pear Tar, using the best    |
+//| package available to unpack or list information about the archive.        |
+//+---------------------------------------------------------------------------+
+//| Copyright (C) 2009 by the following authors:                              |
+//|                                                                           |
+//| Authors: Justin Carlson        - justin DOT carlson AT gmail DOT com      |
+//+---------------------------------------------------------------------------+
+//|                                                                           |
+//| This program is free software; you can redistribute it and/or             |
+//| modify it under the terms of the GNU General Public License               |
+//| as published by the Free Software Foundation; either version 2            |
+//| of the License, or (at your option) any later version.                    |
+//|                                                                           |
+//| This program is distributed in the hope that it will be useful,           |
+//| but WITHOUT ANY WARRANTY; without even the implied warranty of            |
+//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             |
+//| GNU General Public License for more details.                              |
+//|                                                                           |
+//| You should have received a copy of the GNU General Public License         |
+//| along with this program; if not, write to the Free Software Foundation,   |
+//| Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.           |
+//|                                                                           |
+//+---------------------------------------------------------------------------+
+
+
+/**
+ * geeklog plugin unpacker - Archive Libs Wrapper
+ * 
+ * This class wraps calls to pecl Zip, pear Zip, pear Tar, using the best 
+ * package available to unpack or list information about the archive.
+ * 
+ * @author Justin Carlson <justin DOT carlson AT gmail DOT com>
+ * 
+ */
+class unpacker {
+    
+    // mime types ( these are not very reliable, varies browser to browser )
+    // for the best results, pass the real filename as well as the mime type
+    var $mime_def = array('application/zip' => 'zip', 'application/x-zip' => 'zip', 'application/x-zip-compressed' => 'zip', 'multipart/x-zip' => 'zip', 'application/gzip' => 'tar', 'application/tar' => 'tar', 'application/x-tar' => 'tar', 'application/x-gzip' => 'tar', 'application/octet-stream' => 'tar', 'application/x-compress' => 'tar', 'application/x-compressed' => 'tar');
+    
+    var $file = null; // archive name 
+    var $filesize = null; // archive size (in bytes)
+    var $ext = null; // archive ext 
+    var $contents = null; // archive contents 
+    var $archive = null; // archive resource handle
+    var $errorno = null; // error number ( set when returned false )
+    var $error = null; // error text ( set when returned false )
+    var $u_size = null; // uncompressed archive size 
+    var $d_sep = null; // directory separator default
+    var $type = null; // archive type  
+    var $comp = null; // archive compression type (private)
+
+    
+    /**
+     * Constructor
+     * 
+     * @param string $file full path to archive
+     * @param string $optional_type mime type ( application/zip, /tar, etc )
+     * @return bool $success result of loading archive passed
+     */
+    function unpacker($file, $mime_type = null) {
+
+        // default directory separator
+        if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) {
+            $this->d_sep = '\\';
+        } else {
+            $this->d_sep = '/';
+        }
+        
+        // if the file doesn't have it's path, assume local
+        if (! strstr($file, $this->d_sep)) {
+            $file = getcwd() . $this->d_sep . $file;
+        }
+        
+        // make sure the file exists
+        if (file_exists($file)) {
+            
+            // copy vars
+            $this->file = $file;
+            $this->filesize = filesize($file);
+            $this->ext = strtolower(substr($file, - 4));
+            
+            // if the type is passed, store it
+            if ($mime_type != null) {
+                
+                if (isset($this->mime_def[$mime_type])) {
+                    $this->type = $this->mime_def[$mime_type];
+                } else {
+                    return $this->setError('400', 'Invalid MIME Type');
+                }
+            
+            }
+            
+            if ($this->type == null || $this->type == 'other') {
+                
+                // if a known mime type was not provided, expect real filename
+                // mime types are not reliable so this is the reccommended way
+                // for example: unpacker($_FILES['foo']['name'],$type); 
+                // .tar, .tgz, .tar.gz, .tar.bz2, and .tar.bz are supported
+                if ($this->ext == 'r.gz' || $this->ext == '.tgz') {
+                    $this->type = 'tar';
+                    $this->comp = 'gz';
+                } elseif ($this->ext == 'r.bz' || $this->ext == '.bz2') {
+                    $this->type = 'tar';
+                    $this->comp = 'bz2';
+                } else {
+                    $this->type = str_replace('.', '', $this->ext);
+                }
+                
+                // see if we know of a mime type for this ext
+                if (in_array($this->type, $this->mime_def) === false) {
+                    return $this->setError('400', 'Invalid File Extension');
+                }
+            }
+            
+            // call the load wrapper, return result
+            return $this->load_file();
+        
+        } else {
+            // file did not exist
+            return false;
+        }
+    
+    }
+
+    /**
+     * Open - Constructor Wrapper
+     * This clears the vars and loads another file.
+     * ( May never be used )
+     * 
+     * @param string $file full path to archive
+     * @param string $optional_type mime type ( application/zip, /tar, etc )
+     * @return bool $success result of loading archive passed
+     */
+    function open($file, $optional_type = false) {
+
+        $this->ext = null;
+        $this->file = null;
+        $this->filesize = null;
+        $this->contents = null;
+        $this->archive = null;
+        $this->errorno = null;
+        $this->error = null;
+        $this->u_size = null;
+        $this->d_sep = null;
+        $this->type = null;
+        return $this->unpacker($file, $optional_type);
+    }
+
+    /**
+     * 
+     * Decides which loader to call, or returns false if one isn't found.
+     * 
+     * @return bool $success result of loading archive passed
+     */
+    function load_file() {
+
+        $handler = 'load_' . $this->type;
+        if (method_exists($this, $handler)) {
+            return $this->$handler();
+        } else {
+            return $this->setError('406', 'Unacceptable archive.');
+        }
+    }
+
+    /**
+     * load a zip archive
+     * 
+     * @return bool $success result of loading archive passed
+     */
+    function load_zip() {
+
+        if (function_exists('zip_open')) {
+            
+            // Use PECL ZIP
+            $this->archive = new ZipArchive();
+            $result = $this->archive->open($this->file);
+            if ($result === false) {
+                return $this->setError($result, 'ZipArchive Error');
+            }
+        
+        } else {
+            
+            // use Pear Archive_Zip     
+            require_once 'Archive/Zip.php';
+            $this->archive = new Archive_Zip($this->file);
+            // unfortunaty, we can't tell if it succeeded
+        
+
+        }
+        
+        // return resource handle or result
+        return true;
+    }
+
+    /**
+     * load a tar archive
+     * 
+     * @return bool $success result of loading archive passed
+     */
+    function load_tar() {
+
+        // use Pear Archive_Tar 
+        require_once 'Archive/Tar.php';
+        $this->archive = new Archive_Tar($this->file, $this->comp);
+        
+        // unfortunaty, we can't tell if it succeeded
+        return ($this->archive);
+    
+    }
+
+    /**
+     * return contents of archive (wrapper)
+     * 
+     * @return array(array('filename','size','etc')) archive contents
+     */
+    function getlist() {
+
+        // see if content are cached
+        if (is_array($this->contents)) {
+            return $this->contents;
+        }        
+        
+        // not cached, load and cache the content list
+        $handler = 'list_' . $this->type;
+        if (method_exists($this, $handler)) {
+            $this->contents = $this->$handler();
+            return $this->contents;
+        } else {
+            return $this->setError('405', 'Unpacker called getlist ' . 'with unknown handler.');
+        }
+    
+    }
+
+    /**
+     * return contents of zip archive
+     * 
+     * @return array(array('filename','size','etc')) archive contents
+     */
+    function list_zip() {
+
+        // using PECL::ZipArchive
+        if (function_exists('zip_open')) {
+            
+            // catch empty archive
+            if ($this->archive->numFiles < 1) {
+                return $this->setError('411', 'Archive is empty.');
+            }
+            
+            // reset cache
+            $this->contents = array();
+            for ($i = 0; $i < $this->archive->numFiles; $i ++) {
+                
+                // Make ZipArchive's info look like Archive_Zip's 
+                $zip_entry = $this->archive->statIndex($i);
+                $this->contents[$i]['filename'] = $zip_entry['name'];
+                $this->contents[$i]['size'] = $zip_entry['size'];
+                $this->contents[$i]['compressed'] = $zip_entry['comp_size'];
+                $this->contents[$i]['method'] = $zip_entry['comp_method'];
+            
+            }
+            // return the contents list            
+            return $this->contents;
+            
+        // using PEAR::Archive_Zip
+        } else {
+            
+            $this->contents = $this->archive->listContent();
+            if (is_array($this->contents)) {
+                return $this->contents;
+            } else {
+                return $this->setError('411', 'Archive is empty.');
+            }
+        
+        }
+    }
+
+    /**
+     * return contents of tar archive
+     * 
+     * @return array(array('filename','size','etc')) archive contents
+     */
+    function list_tar() {
+
+        $this->contents = $this->archive->listContent();
+        if (is_array($this->contents)) {
+            return $this->contents;



More information about the geeklog-cvs mailing list