Seditio Source
Root |
./othercms/elxis_5.3_atlas_rev2452/includes/libraries/elxis/helpers/zip.helper.php
<?php
/**
* @version        $Id: zip.helper.php 2301 2019-06-12 18:06:00Z IOS $
* @package        Elxis
* @subpackage    Helpers / Zip
* @copyright    Copyright (c) 2006-2019 Elxis CMS (http://www.elxis.org). All rights reserved.
* @license        Elxis Public License ( http://www.elxis.org/elxis-public-license.html )
* @author        Elxis Team ( http://www.elxis.org )
* @description     Elxis CMS is free software. Read the license for copyright notices and details
*/

defined('_ELXIS_') or die ('Direct access to this location is not allowed');


class
elxisZipHelper {

    private
$zip_support = false;
    private
$zip = null;
    private
$errormsg = '';

       
   
/***************/
    /* CONSTRUCTOR */
    /***************/
   
public function __construct() {
       
$this->zip_support = class_exists('ZipArchive', false) ? true : false;
    }


   
/******************************************/
    /* GENERATE ERROR MESSAGE FROM ERROR CODE */
    /******************************************/
   
private function errorMsgFromCode($res) {
        switch (
$res) {
            case
ZIPARCHIVE::ER_EXISTS: return 'Given archive already exists'; break;
            case
ZIPARCHIVE::ER_INVAL: return 'Invalid argument'; break;
            case
ZIPARCHIVE::ER_MEMORY: return 'Memory allocation failure'; break;
            case
ZIPARCHIVE::ER_INCONS: return 'Zip archive inconsistent'; break;
            case
ZIPARCHIVE::ER_NOENT: return 'No such file'; break;
            case
ZIPARCHIVE::ER_NOZIP: return 'Not a zip archive'; break;
            case
ZIPARCHIVE::ER_OPEN: return 'Could not open file'; break;
            case
ZIPARCHIVE::ER_READ: return 'Read error'; break;
            case
ZIPARCHIVE::ER_SEEK: return 'Seek error'; break;
            case
ZIPARCHIVE::ER_CRC: return 'CRC error'; break;
            case
ZIPARCHIVE::ER_WRITE: return 'Write error'; break;
            case
ZIPARCHIVE::ER_MULTIDISK : return 'Multi-disk zip archives not supported'; break;
            case
ZIPARCHIVE::ER_RENAME: return 'Renaming temporary file failed'; break;
            case
ZIPARCHIVE::ER_CLOSE: return 'Closing zip archive failed'; break;
            case
ZIPARCHIVE::ER_ZIPCLOSED: return 'Containing zip archive was closed'; break;
            case
ZIPARCHIVE::ER_TMPOPEN: return 'Failure to create temporary file'; break;
            case
ZIPARCHIVE::ER_ZLIB: return 'Zlib error'; break;
            case
ZIPARCHIVE::ER_CHANGED: return 'Entry has been changed'; break;
            case
ZIPARCHIVE::ER_COMPNOTSUPP: return 'Compression method not supported'; break;
            case
ZIPARCHIVE::ER_EOF: return 'Premature EOF'; break;
            case
ZIPARCHIVE::ER_INTERNAL: return 'Internal error'; break;
            case
ZIPARCHIVE::ER_REMOVE: return 'Could not remove file'; break;
            case
ZIPARCHIVE::ER_DELETED: return 'Entry has been deleted'; break;
            case
ZIPARCHIVE::ER_OK: return ''; break; //No error
           
default: return 'Unknown ZIP error'; break;
        }
    }


   
/********************************/
    /* EXTRACT ARCHIVE TO DIRECTORY */
    /********************************/
   
public function unzip($archive, $dir) {
        if (!
$this->zip_support) {
           
$this->errormsg = 'ZIP is not supported by your PHP installation!';
            return
false;
        }
        if (!
file_exists($archive)) {
           
$this->errormsg = 'Given archive '.$archive.' does not exists!';
            return
false;
        }
       
$dir = rtrim(str_replace("\\", "/", $dir), '/').'/';
        if (!
file_exists($dir)) {
           
$ok = @mkdir($dir, 0755);
            if (!
$ok) {
               
$this->errormsg = 'Could not create extract directory container '.$dir;
                return
false;
            }
        } else if (!
is_dir($dir)) {
           
$this->errormsg = 'Extract path is not a directory '.$dir;
            return
false;
        }

       
$archive = realpath($archive);
       
$this->zip = new ZipArchive();
       
$res = $this->zip->open($archive);
        if (
$res !== true) {
           
$this->errormsg = $this->errorMsgFromCode($res);
            return
false;
        }
       
$ok = $this->zip->extractTo($dir);
       
$this->zip->close();
       
$this->zip = null;
        if (!
$ok) {
           
$this->errormsg = 'Could not extract zip to '.$dir;
            return
false;
        }
        return
true;
    }


   
/*********************/
    /* GET ERROR MESSAGE */
    /*********************/
   
public function getError() {
        return
$this->errormsg;
    }


   
/*********************************************************/
    /* ZIP FILE(S) OR FOLDER(S) OR BUFFERED DATA AND SAVE IT */
    /*********************************************************/
   
public function zip($archive, $source=null, $data=array(), $paths_exclude=array()) {
        if (!
$this->zip_support) {
           
$this->errormsg = 'ZIP is not supported by your PHP installation!';
            return
false;
        }

       
$topack = array();
        if (
$source !== null) {
            if (
is_string($source) && (trim($source) != '')) {
                if (!
file_exists($source)) {
                   
$this->errormsg = 'Given source '.$source.' does not exists!';
                    return
false;
                }
               
$localname = basename($source);
               
$type = (is_dir($source)) ? 'folder' : 'file';
               
$topack[] = array('localname' => $localname, 'type' => $type, 'source' => $source);
            } else if (
is_array($source) && (count($source) > 0)) {
                foreach (
$source as $item) {
                    if (!
file_exists($item)) {
                       
$this->errormsg = 'Given source '.$item.' does not exists!';
                        return
false;
                    }
                   
$localname = basename($item);
                    if (
is_dir($item)) {
                       
$item = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $item), '/').'/';
                       
$type = 'folder';
                    } else {
                       
$type = 'file';                        
                    }
                   
$topack[] = array('localname' => $localname, 'type' => $type, 'source' => $item);
                }
            }
        }
       
        if (
is_array($data) && (count($data) > 0)) {
            foreach (
$data as $localname => $buffer) {
               
$topack[] = array('localname' => $localname, 'type' => 'buffer', 'source' => $buffer);
            }
        }

        if (
count($topack) == 0) {
           
$this->errormsg = 'Nothing provided to zip!';
            return
false;
        }

       
$this->zip = new ZipArchive();
       
$res = $this->zip->open($archive, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
        if (
$res !== true) {
           
$this->errormsg = $this->errorMsgFromCode($res);
            return
false;
        }

        foreach (
$topack as $pack) {
            if (
$pack['type'] == 'file') {
                if (
$paths_exclude) {
                   
$exclude = false;
                    foreach (
$paths_exclude as $xpath) {
                        if (
strpos($pack['source'], $xpath) === 0) { $exclude = true; break; }
                    }
                    if (
$exclude) { continue; }
                }
               
$ok = $this->zip->addFile(realpath($pack['source']), $pack['localname']);
                if (!
$ok) {
                   
$this->zip->close();
                    @
unlink($archive);
                   
$this->errormsg = 'Could not add '.$pack['source'].' in zip archive!';
                    return
false;
                }
            } else if (
$pack['type'] == 'folder') {
                if (
$paths_exclude) {
                   
$exclude = false;
                    foreach (
$paths_exclude as $xpath) {
                        if (
strpos($pack['source'], $xpath) === 0) { $exclude = true; break; }
                    }
                    if (
$exclude) { continue; }
                }

               
$ok = $this->zip->addEmptyDir($pack['localname']);
                if (!
$ok) {
                   
$this->zip->close();
                    @
unlink($archive);
                   
$this->errormsg = 'Could not create folder '.$pack['localname'].' in zip archive!';
                    return
false;
                }
               
$ok = $this->addFolderRecursive($pack['source'], $pack['localname'].'/', $paths_exclude);
                if (!
$ok) {
                   
$this->zip->close();
                    @
unlink($archive);
                   
$this->errormsg = 'Could not zip folder '.$pack['source'].'!';
                    return
false;
                }
            } else if (
$pack['type'] == 'buffer') {
               
$ok = $this->zip->addFromString($pack['localname'], $pack['source']);
                if (!
$ok) {
                   
$this->zip->close();
                    @
unlink($archive);
                   
$this->errormsg = 'Could not create '.$pack['localname'].' in zip archive!';
                    return
false;
                }
            } else {
               
//invalid pack type!
           
}
        }

       
$this->zip->close();
       
$this->zip = null;
        return
true;
    }


   
/*********************************/
    /* RECURSIVELY ADD FOLDER TO ZIP */
    /*********************************/
   
private function addFolderRecursive($dir, $path, $paths_exclude=array()) {
       
$current_dir = @opendir($dir);
        while (
$entry = readdir($current_dir)) {
            if ((
$entry != '.') && ($entry != '..')) {
                if (
is_dir($dir.$entry)) {
                    if (
$paths_exclude) {
                       
$exclude = false;
                        foreach (
$paths_exclude as $xpath) {
                            if (
strpos($dir.$entry.'/', $xpath) === 0) { $exclude = true; break; }
                        }
                        if (
$exclude) { continue; }
                    }
                    if (!
$this->zip->addEmptyDir($path.$entry.'/')) {
                        return
false;
                    }
                   
$this->addFolderRecursive($dir.$entry.'/', $path.$entry.'/', $paths_exclude);
                } else {
                     if (
$paths_exclude) {
                       
$exclude = false;
                        foreach (
$paths_exclude as $xpath) {
                            if (
strpos($dir.$entry.'/', $xpath) === 0) { $exclude = true; break; }
                        }
                        if (
$exclude) { continue; }
                    }
                    if (!
$this->zip->addFile($dir.$entry, $path.$entry)) {
                        return
false;
                    }
                }
            }
        }
        @
closedir($current_dir);
        return
true;
    }

}

?>