Вход Регистрация
Файл: admin/inc/ZipArchive.php
Строк: 1219
<?php

/**
 * 
 * This class implements PHP's zip module. It is usefull if zip module is not available.
 * Requires zip and unzip binaries.
 * 
 * @author vadik56
 * SVN: $Id: ZipArchive.php 2 2009-03-06 00:52:03Z vadik56 $
 */
class ZipArchive  {
    const 
CREATE 1;
    const 
EXCL 2;
    const 
CHECKCONS 4;
    const 
OVERWRITE 8;

    const 
FL_NOCASE 1;
    const 
FL_NODIR 2;
    const 
FL_COMPRESSED 4;
    const 
FL_UNCHANGED 8;

    const 
CM_DEFAULT = -1;
    const 
CM_STORE 0;
    const 
CM_SHRINK 1;
    const 
CM_REDUCE_1 2;
    const 
CM_REDUCE_2 3;
    const 
CM_REDUCE_3 4;
    const 
CM_REDUCE_4 5;
    const 
CM_IMPLODE 6;
    const 
CM_DEFLATE 8;
    const 
CM_DEFLATE64 9;
    const 
CM_PKWARE_IMPLODE 10;

    const 
ER_OK 0;
    const 
ER_MULTIDISK 1;
    const 
ER_RENAME 2;
    const 
ER_CLOSE 3;
    const 
ER_SEEK 4;
    const 
ER_READ 5;
    const 
ER_WRITE 6;
    const 
ER_CRC 7;
    const 
ER_ZIPCLOSED 8;
    const 
ER_NOENT 9;
    const 
ER_EXISTS 10;
    const 
ER_OPEN 11;
    const 
ER_TMPOPEN 12;
    const 
ER_ZLIB 13;
    const 
ER_MEMORY 14;
    const 
ER_CHANGED 15;
    const 
ER_COMPNOTSUPP 16;
    const 
ER_EOF 17;
    const 
ER_INVAL 18;
    const 
ER_NOZIP 19;
    const 
ER_INTERNAL 20;
    const 
ER_INCONS 21;
    const 
ER_REMOVE 22;
    const 
ER_DELETED 23;


    private static 
$unzip_exec="unzip"//path to unzip executable
    
private static $zip_exec="zip"//path to zip executable

    /**
     * Absolute path to requested zip file.
     * 
     * @var string
     */
    
private $zipFilePath;
    
/**
     * Directory containing temporary zip directory structure(absolute path).
     * It should not contain trailing slash.
     * 
     * @var string
     */
    
private $tempDirPath;
    private 
$zip_is_open=false;
    
    private 
$fileIndex = array();
    
    
    public static function 
setup(){
        if( 
defined(ZIP_MODULE_IMPLEMENTATION_PATH) ){
            
$possible_zip_locations explode(":"ZIP_MODULE_IMPLEMENTATION_PATH);
            
//try to find zip executable
            
foreach($possible_zip_locations as $loc){
                if( 
is_executable($loc.DIRECTORY_SEPARATOR."zip") ){
                    
self::$zip_exec $loc.DIRECTORY_SEPARATOR."zip";
                }else if( 
is_executable($loc.DIRECTORY_SEPARATOR."unzip") ){
                    
self::$unzip_exec $loc.DIRECTORY_SEPARATOR."unzip";
                }
            }
        }
    }

        
    
/**
     * Open a ZIP file archive
     * @link http://php.net/manual/en/function.ziparchive-open.php
     * @param filename string <p>
     * The file name of the ZIP archive to open.
     * </p>
     * @param flags int[optional] <p>
     * The mode to use to open the archive.
     * <p>
     * ZIPARCHIVE::OVERWRITE
     * </p>
     * @return mixed Error codes
     * <p>
     * Returns true on success or the error code.
     * <p>
     * ZIPARCHIVE::ER_EXISTS
     * </p>
     * <p>
     * ZIPARCHIVE::ER_INCONS
     * </p>
     * <p>
     * ZIPARCHIVE::ER_INVAL
     * </p>
     * <p>
     * ZIPARCHIVE::ER_MEMORY
     * </p>
     * <p>
     * ZIPARCHIVE::ER_NOENT
     * </p>
     * <p>
     * ZIPARCHIVE::ER_NOZIP
     * </p>
     * <p>
     * ZIPARCHIVE::ER_OPEN
     * </p>
     * <p>
     * ZIPARCHIVE::ER_READ
     * </p>
     * <p>
     * ZIPARCHIVE::ER_SEEK
     * </p>
     * </p>
     */
    
public function open ($filename$flags null) {
                
        if( 
is_dir($filename) ){
            return 
self::ER_NOZIP;
        }

            
//if zip file exists already exists
        
if( is_file($filename) ){
            
            if( !
is_readable($filename) ){
                return 
self::ER_READ;
            }
    
            
//if user asked for error then return it
            
if( $flags self::EXCL  ){
                return 
self::ER_EXISTS;
            }
            
//if need to create new file but overwrite flag is not defined
            
if(($flags self::CREATE) && !($flags self::OVERWRITE) ){
                return 
self::ER_EXISTS;
            }
        }
        
        
//if overwrite then remove file
        
if($flags self::OVERWRITE){
            if( 
is_file($filename) ){
                if ( !(@
unlink($filename)) ){
                    return 
self::ER_READ;
                }
            }
        }


        
//create/extract directory layout in temporary folder 
        
        
        //create temp dir
        
$tempDir sys_get_temp_dir();
        if( 
$tempDir[strlen($tempDir)-1] != DIRECTORY_SEPARATOR ){
            
$tempDir $tempDir DIRECTORY_SEPARATOR;
        }
        
$this->tempDirPath =  $tempDir.__CLASS__uniqid();
        if( @
mkdir($this->tempDirPath) !== true ) {
            return 
self::ER_OPEN;
        }

        if( 
is_file($filename) ){
            
//extract zip file to tempDir
            
if( !$this->__extractTo($filename,$this->tempDirPath) ){
                return 
self::ER_OPEN;
            }
        }
        
        if(
$filename[0] == '/'){
            
$this->zipFilePath $filename;
        }else{
            
$this->zipFilePath getcwd() .DIRECTORY_SEPARATOR$filename;
        }
        
$this->zip_is_open true;
        
        return 
true;
    }

    
/**
     * Close the active archive (opened or newly created)
     * @link http://php.net/manual/en/function.ziparchive-close.php
     * @return bool Returns true on success or false on failure.
     */
    
public function close () {
        if(!
$this->zip_is_open){
            return 
false;
        }
        
 
        if(  
strtolower(substr($this->zipFilePathstrlen($this->zipFilePath)-4)) == ".zip" ){
            
//if $this->zipFilePath has .zip in the end then use this path for zip
            
$target_zip_file $this->zipFilePath;
        }else{
            
//else use {$this->tempDirPath}.zip as zip file and then move it to final location
            
$target_zip_file $this->tempDirPath ".zip"
        }
         
        
        
$currentWorkingDir getcwd();
        if( @
chdir($this->tempDirPath) !== True){
            
//unable to chdir to temp directory
            
return false;
        }
        
        
exec(self::$zip_exec." -m -r {$target_zip_file} * 2>&1"$output$return_value);
        
chdir($currentWorkingDir);
        
        if(
$target_zip_file != $this->zipFilePath){
            if( @
rename($target_zip_file$this->zipFilePath) !== true){
                
//if unable to copy zip to final destination then return false
                
return false;
            }
        }
        
        if(
$return_value != 0){
            return 
false;
        }
        
        
//remove trailing tempdir
        
@rmdir($this->tempDirPath);

        
//do cleanup
        
$this->zip_is_open false;
        
$this->zipFilePath "";
        
$this->tempDirPath "";
        
$this->fileIndex = array();
        
        return 
true;
    }

    
/**
     * Add a new directory
     * @link http://php.net/manual/en/function.ziparchive-addemptydir.php
     * @param dirname string <p>
     * The directory to add.
     * </p>
     * @return bool Returns true on success or false on failure.
     */
    
public function addEmptyDir ($dirname) {
        if(!
$this->zip_is_open){
            return 
false;
        }
        return 
mkdir($this->tempDirPath .DIRECTORY_SEPARATOR$dirname );
    }

    
/**
     * Add a file to a ZIP archive using its contents
     * @link http://php.net/manual/en/function.ziparchive-addfromstring.php
     * @param localname string <p>
     * The name of the entry to create.
     * </p>
     * @param contents string <p>
     * The contents to use to create the entry. It is used in a binary
     * safe mode.
     * </p>
     * @return bool Returns true on success or false on failure.
     */
    
public function addFromString ($localname$contents) {
        if(!
$this->zip_is_open){
            return 
false;
        }
        
$target_dir $this->tempDirPath .DIRECTORY_SEPARATORdirname($localname);
        
$taget_file basename($localname);
        
        
//create directory if it does not exist
        
if( ! is_dir($target_dir) ){
            if(! 
mkdir($target_dir,0777,true) ){
                return 
false;
            }
        }
        
//create file from string
        
if( file_put_contents($target_dir.DIRECTORY_SEPARATOR.$taget_file,$contents) === False){
            return 
false;
        }
        return 
true;
    }

    
/**
     * Adds a file to a ZIP archive from the given path
     * @link http://php.net/manual/en/function.ziparchive-addfile.php
     * @param filename string <p>
     * The path to the file to add.
     * </p>
     * @param localname string[optional] <p>
     * local name inside ZIP archive.
     * </p>
     * @return bool Returns true on success or false on failure.
     */
    
public function addFile ($filename$localname null) {}

    
/**
     * Renames an entry defined by its index
     * @link http://php.net/manual/en/function.ziparchive-renameindex.php
     * @param index int <p>
     * Index of the entry to rename.
     * </p>
     * @param newname string <p>
     * New name.
     * </p>
     * @return bool Returns true on success or false on failure.
     */
    
public function renameIndex ($index$newname) {}

    
/**
     * Renames an entry defined by its name
     * @link http://php.net/manual/en/function.ziparchive-renamename.php
     * @param name string <p>
     * Name of the entry to rename.
     * </p>
     * @param newname string <p>
     * New name.
     * </p>
     * @return bool Returns true on success or false on failure.
     */
    
public function renameName ($name$newname) {}

    
/**
     * Set the comment of a ZIP archive
     * @link http://php.net/manual/en/function.ziparchive-setarchivecomment.php
     * @param comment string <p>
     * The contents of the comment.
     * </p>
     * @return mixed Returns true on success or false on failure.
     */
    
public function setArchiveComment ($comment) {}

    
/**
     * Returns the Zip archive comment
     * @link http://php.net/manual/en/function.ziparchive-getarchivecomment.php
     * @return string the Zip archive comment or false on failure.
     */
    
public function getArchiveComment () {}

    
/**
     * Set the comment of an entry defined by its index
     * @link http://php.net/manual/en/function.ziparchive-setcommentindex.php
     * @param index int <p>
     * Index of the entry.
     * </p>
     * @param comment string <p>
     * The contents of the comment.
     * </p>
     * @return mixed Returns true on success or false on failure.
     */
    
public function setCommentIndex ($index$comment) {}

    
/**
     * Set the comment of an entry defined by its name
     * @link http://php.net/manual/en/function.ziparchive-setCommentName.php
     * @param name string <p>
     * Name of the entry.
     * </p>
     * @param comment string <p>
     * The contents of the comment.
     * </p>
     * @return mixed Returns true on success or false on failure.
     */
    
public function setCommentName ($name$comment) {}

    
/**
     * Returns the comment of an entry using the entry index
     * @link http://php.net/manual/en/function.ziparchive-getcommentindex.php
     * @param index int <p>
     * Index of the entry
     * </p>
     * @param flags int[optional] <p>
     * If flags is set to ZIPARCHIVE::FL_UNCHANGED, the original unchanged
     * comment is returned.
     * </p>
     * @return string the comment on success or false on failure.
     */
    
public function getCommentIndex ($index$flags null) {}

    
/**
     * Returns the comment of an entry using the entry name
     * @link http://php.net/manual/en/function.ziparchive-getcommentname.php
     * @param name string <p>
     * Name of the entry
     * </p>
     * @param flags int[optional] <p>
     * If flags is set to ZIPARCHIVE::FL_UNCHANGED, the original unchanged
     * comment is returned.
     * </p>
     * @return string the comment on success or false on failure.
     */
    
public function getCommentName ($name$flags null) {}

    
/**
     * delete an entry in the archive using its index
     * @link http://php.net/manual/en/function.ziparchive-deleteindex.php
     * @param index int <p>
     * Index of the entry to delete.
     * </p>
     * @return bool Returns true on success or false on failure.
     */
    
public function deleteIndex ($index) {}

    
/**
     * delete an entry in the archive using its name
     * @link http://php.net/manual/en/function.ziparchive-deletename.php
     * @param name string <p>
     * Name of the entry to delete.
     * </p>
     * @return bool Returns true on success or false on failure.
     */
    
public function deleteName ($name) {}

    
/**
     * Get the details of an entry defined by its name.
     * @link http://php.net/manual/en/function.ziparchive-statname.php
     * @param name name <p>
     * Name of the entry
     * </p>
     * @param flags int[optional] <p>
     * The flags argument specifies how the name lookup should be done.
     * Also, ZIPARCHIVE::FL_UNCHANGED may be ORed to it to request
     * information about the original file in the archive,
     * ignoring any changes made.
     * <p>
     * ZIPARCHIVE::FL_NOCASE
     * </p>
     * @return mixed an array containing the entry details or false on failure.
     */
    
public function statName ($name$flags null) {}

    
/**
     * Get the details of an entry defined by its index.
     * @link http://php.net/manual/en/function.ziparchive-statindex.php
     * @param index int <p>
     * Index of the entry
     * </p>
     * @param flags int[optional] <p>
     * ZIPARCHIVE::FL_UNCHANGED may be ORed to it to request
     * information about the original file in the archive,
     * ignoring any changes made.
     * </p>
     * @return mixed an array containing the entry details or false on failure.
     */
    
public function statIndex ($index$flags null) {}

    
/**
     * Returns the index of the entry in the archive
     * @link http://php.net/manual/en/function.ziparchive-locatename.php
     * @param name string <p>
     * The name of the entry to look up
     * </p>
     * @param flags int[optional] <p>
     * The function returns the index of the file named fname in
     * archive. The flags are specified by ORing the following values,
     * or 0 for none of them.
     * <p>
     * ZIPARCHIVE::FL_NOCASE
     * </p>
     * @return mixed the index of the entry on success or false on failure.
     */
    
public function locateName ($name$flags null) {
        if(!
$this->zip_is_open){
            return 
false;
        }
        
$noDir = ($flags self::FL_NODIR) ? true:false;
        
$noCase =  ($flags self::FL_NOCASE) ? true:false;
        
        
$loopFile = ($noDir) ? basename($name) : $name ;
        if(
$noCase){
            
$search strtolower($search);
        }
        foreach(
$this->fileIndex as $ind => $fileRelPath){
            
$loopFile = ($noDir) ? basename($fileRelPath) : $fileRelPath ;
            if(
$noCase){
                
$loopFile strtolower($loopFile);
            }
            if( 
$loopFile == $search ){
                return 
$ind;
            }
        }
    }

    
/**
     * Returns the name of an entry using its index
     * @link http://php.net/manual/en/function.ziparchive-getnameindex.php
     * @param index int <p>
     * Index of the entry.
     * </p>
     * @return string the name on success or false on failure.
     */
    
public function getNameIndex ($index) {
        if(!
$this->zip_is_open){
            return 
false;
        }
        if(! 
is_set($this->fileIndex[$index]) ){
            return 
false;
        }
        return 
$this->fileIndex[$index];
    }

    
/**
     * Revert all global changes done in the archive.
     * @link http://php.net/manual/en/function.ziparchive-unchangearchive.php
     * @return mixed Returns true on success or false on failure.
     */
    
public function unchangeArchive () {}

    
/**
     * Undo all changes done in the archive.
     * @link http://php.net/manual/en/function.ziparchive-unchangeall.php
     * @return mixed Returns true on success or false on failure.
     */
    
public function unchangeAll () {}

    
/**
     * Revert all changes done to an entry at the given index.
     * @link http://php.net/manual/en/function.ziparchive-unchangeindex.php
     * @param index int <p>
     * Index of the entry.
     * </p>
     * @return mixed Returns true on success or false on failure.
     */
    
public function unchangeIndex ($index) {}

    
/**
     * Revert all changes done to an entry with the given name.
     * @link http://php.net/manual/en/function.ziparchive-unchangename.php
     * @param name string <p>
     * Name of the entry.
     * </p>
     * @return mixed Returns true on success or false on failure.
     */
    
public function unchangeName ($name) {}

    
/**
     * Extract the archive contents
     * @link http://php.net/manual/en/function.ziparchive-extractto.php
     * @param destination string <p>
     * Location where to extract the files.
     * </p>
     * @param entries mixed[optional] <p>
     * The entries to extract. It accepts either a single entry name or
     * an array of names.
     * </p>
     * @return mixed Returns true on success or false on failure.
     */
    
public function extractTo ($destination$entries null) {
        if(!
$this->zip_is_open){
            return 
false;
        }
        return 
$this->__extractTo($this->zipFilePath$destination$entries);
    }

    private function 
__extractTo($zip_path$destination$entries null) {
        
$return_value=0;
        
$output = array();
                
        
//determine list of files to extract
        
$list "";
        if( 
is_string($entries) ){
            
$list "'$entries'";
        }
        if(
is_array($entries)){
            
$list "'".implode("' '"$entries)."'";
        }
        
        
exec(self::$unzip_exec." -o {$zip_path} -d {$destination} {$list}  2>&1"$output$return_value);
        
        if(
$return_value != 0){
            return 
false;
        }
        return 
true;
    }
    
/**
     * Returns the entry contents using its name.
     * @link http://php.net/manual/en/function.ziparchive-getfromname.php
     * @param name string <p>
     * Name of the entry
     * </p>
     * @param flags int[optional] <p>
     * The flags to use to open the archive. the following values may
     * be ORed to it.
     * <p>
     * ZIPARCHIVE::FL_UNCHANGED
     * </p>
     * @return mixed the contents of the entry on success or false on failure.
     */
    
public function getFromName ($name$flags null) {
        if(!
$this->zip_is_open){
            return 
false;
        }
        return @
file_get_contents($this->tempDirPath .DIRECTORY_SEPARATOR$name );
    }

    
/**
     * Returns the entry contents using its index.
     * @link http://php.net/manual/en/function.ziparchive-getfromindex.php
     * @param index int <p>
     * Index of the entry
     * </p>
     * @param flags int[optional] <p>
     * The flags to use to open the archive. the following values may
     * be ORed to it.
     * <p>
     * ZIPARCHIVE::FL_UNCHANGED
     * </p>
     * @return mixed the contents of the entry on success or false on failure.
     */
    
public function getFromIndex ($index$flags null) {
        if(!
$this->zip_is_open){
            return 
false;
        }
        
$localFilePath =  $this->getNameIndex($index);
        if(
$localFilePath === false){
            return 
false;
        }
        return 
$this->getFromName($localFilePath);
    }

    
/**
     * Get a file handler to the entry defined by its name (read only).
     * @link http://php.net/manual/en/function.ziparchive-getstream.php
     * @param name string <p>
     * The name of the entry to use.
     * </p>
     * @return resource a file pointer (resource) on success or false on failure.
     */
    
public function getStream ($name) {}

    
/**
     * 
     * @param $dir_path absolute path to zip directory
     */
    
private function __indexDirRec($dir_path){
        
$dirEntries scandir($dir_path);
        
        foreach(
$dirEntries as $dirEntriy){
            if( 
$dirEntriy == "." || $dirEntriy == ".."){
                continue;
            }
            
$subject $dir_path .DIRECTORY_SEPARATOR$dirEntriy;
            
            
//if this is directory then index its contents
            
if( is_dir($subject) ){
                
$this->__indexDirRec($subject);
            }else{
                
//save path as relative path inside zip
                
$this->fileIndex[] = str_replace($this->tempDirPath.DIRECTORY_SEPARATOR""$subject);
            }
        }
    }
}

ZipArchive::setup(); //try to find locations of zip/unzip binaries

/**
 * Open a ZIP file archive
 * @link http://php.net/manual/en/function.zip-open.php
 * @param filename string <p>
 * The file name of the ZIP archive to open.
 * </p>
 * @return mixed a resource handle for later use with
 * zip_read and zip_close
 * or returns the number of error if filename does not
 * exist or in case of other error.
 */
function zip_open ($filename) {}

/**
 * Close a ZIP file archive
 * @link http://php.net/manual/en/function.zip-close.php
 * @param zip resource <p>
 * A ZIP file previously opened with zip_open.
 * </p>
 * @return void
 */
function zip_close ($zip) {}

/**
 * Read next entry in a ZIP file archive
 * @link http://php.net/manual/en/function.zip-read.php
 * @param zip resource <p>
 * A ZIP file previously opened with zip_open.
 * </p>
 * @return mixed a directory entry resource for later use with the
 * zip_entry_... functions or false if
 * there's no more entries to read or number of error in case of other error.
 */
function zip_read ($zip) {}

/**
 * Open a directory entry for reading
 * @link http://php.net/manual/en/function.zip-entry-open.php
 * @param zip resource <p>
 * A valid resource handle returned by zip_open.
 * </p>
 * @param zip_entry resource <p>
 * A directory entry returned by zip_read.
 * </p>
 * @param mode string[optional] <p>
 * Any of the modes specified in the documentation of
 * fopen.
 * </p>
 * <p>
 * Currently, mode is ignored and is always
 * "rb". This is due to the fact that zip support
 * in PHP is read only access.
 * </p>
 * @return bool Returns true on success or false on failure.
 * </p>
 * <p>
 * Unlike fopen and other similar functions,
 * the return value of zip_entry_open only
 * indicates the result of the operation and is not needed for
 * reading or closing the directory entry.
 */
function zip_entry_open ($zip$zip_entry$mode null) {}

/**
 * Close a directory entry
 * @link http://php.net/manual/en/function.zip-entry-close.php
 * @param zip_entry resource <p>
 * A directory entry previously opened zip_entry_open.
 * </p>
 * @return bool Returns true on success or false on failure.
 */
function zip_entry_close ($zip_entry) {}

/**
 * Read from an open directory entry
 * @link http://php.net/manual/en/function.zip-entry-read.php
 * @param zip_entry resource <p>
 * A directory entry returned by zip_read.
 * </p>
 * @param length int[optional] <p>
 * The number of bytes to return. If not specified, this function will
 * attempt to read 1024 bytes.
 * </p>
 * <p>
 * This should be the uncompressed length you wish to read.
 * </p>
 * @return string the data read, or false if the end of the file is
 * reached.
 */
function zip_entry_read ($zip_entry$length null) {}

/**
 * Retrieve the actual file size of a directory entry
 * @link http://php.net/manual/en/function.zip-entry-filesize.php
 * @param zip_entry resource <p>
 * A directory entry returned by zip_read.
 * </p>
 * @return int The size of the directory entry.
 */
function zip_entry_filesize ($zip_entry) {}

/**
 * Retrieve the name of a directory entry
 * @link http://php.net/manual/en/function.zip-entry-name.php
 * @param zip_entry resource <p>
 * A directory entry returned by zip_read.
 * </p>
 * @return string The name of the directory entry.
 */
function zip_entry_name ($zip_entry) {}

/**
 * Retrieve the compressed size of a directory entry
 * @link http://php.net/manual/en/function.zip-entry-compressedsize.php
 * @param zip_entry resource <p>
 * A directory entry returned by zip_read.
 * </p>
 * @return int The compressed size.
 */
function zip_entry_compressedsize ($zip_entry) {}

/**
 * Retrieve the compression method of a directory entry
 * @link http://php.net/manual/en/function.zip-entry-compressionmethod.php
 * @param zip_entry resource <p>
 * A directory entry returned by zip_read.
 * </p>
 * @return string The compression method.
 */
function zip_entry_compressionmethod ($zip_entry) {}
Онлайн: 0
Реклама