$value ) { $central_file_header[$key] &= 0xffffffff; } /* extracting filename */ $filename = substr( $file_contents , $pointer + 46 , $central_file_header['filename_len'] ); /* extracting extrafield */ $extra = substr( $file_contents , $pointer + 46 + $central_file_header['filename_len'] , $central_file_header['extra_len'] ); /* extracting comment */ $comment = substr( $file_contents , $pointer + 46 + $central_file_header['filename_len'] + $central_file_header['extra_len'] , $central_file_header['comment_len'] ); $pointer += 46 + $central_file_header['filename_len'] + $central_file_header['extra_len'] + $central_file_header['comment_len']; /* filter directories */ if ( $filename{strlen( $filename ) - 1} != '/' ) { /* calculating position of compressed content */ $content_start = $central_file_header['offset'] + 30 + $central_file_header['filename_len'] + $central_file_header['extra_len']; if ( $central_file_header['compression'] == 0 ) { /* extracting uncompressed content */ $content = substr( $file_contents , $content_start , $central_file_header['compressed_size'] ); } else { /* extracting compressed content */ $content = substr( $file_contents , $content_start , $central_file_header['compressed_size'] ); $content .= pack( 'VV' , $central_file_header['crc'] , $central_file_header['size'] ); /* decompressing content */ $content = @gzinflate( $content ); } /* getting filestatus */ $status = 'ok'; if ( $content === FALSE && $status == 'ok' ) { $status = 'err_decompress'; } if ( crc32( $content ) != $central_file_header['crc'] && $status == 'ok' ) { $status = 'err_crc'; } if ( strlen( $content ) != $central_file_header['size'] && $status == 'ok' ) { $status = 'err_length'; } if ( $status == 'ok' ) { if ( !is_null( $strSavePath ) ) { $strDirName = dirname( $strSavePath . "/" . $filename ); if ( !in_array( $strDirName , $arrCreatedDirectory ) ) { @mkdir( $strDirName , 0700 , true ); $arrCreatedDirectory[] = $strDirName; } file_put_contents( $strSavePath . "/" . $filename , $content ); $archive_data[$filename] = true; } else { $archive_data[$filename] = $content; } } } } if ( !is_null( $strSavePath ) ) { return $arrCreatedDirectory; } return $archive_data; } public function add_dir( $name ) // adds "directory" to archive - do this before putting any files in directory! // $name - name of directory... like this: "path/" // ...then you can add files using add_file with names like "path/file.txt" { $name = str_replace( "\\" , "/" , $name ); if ( substr( $name , 0 , 1 ) == "/" ) { $name = substr( $name , 1 ); } if ( is_array( $this->arrSkipDirectories ) ) { foreach( $this->arrSkipDirectories as $strSkipDir ) { $name = str_replace( $strSkipDir , "" , $name ); } } $fr = "\x50\x4b\x03\x04"; $fr .= "\x0a\x00"; // ver needed to extract $fr .= "\x00\x00"; // gen purpose bit flag $fr .= "\x00\x00"; // compression method $fr .= "\x00\x00\x00\x00"; // last mod time and date $fr .= pack( "V" , 0 ); // crc32 $fr .= pack( "V" , 0 ); //compressed filesize $fr .= pack( "V" , 0 ); //uncompressed filesize $fr .= pack( "v" , strlen( $name ) ); //length of pathname $fr .= pack( "v" , 0 ); //extra field length $fr .= $name; // end of "local file header" segment // no "file data" segment for path // "data descriptor" segment (optional but necessary if archive is not served as file) $fr .= pack( "V" , $crc ); //crc32 $fr .= pack( "V" , $c_len ); //compressed filesize $fr .= pack( "V" , $unc_len ); //uncompressed filesize // add this entry to array $this->datasec[] = $fr; $new_offset = strlen( implode( "" , $this->datasec ) ); // ext. file attributes mirrors MS-DOS directory attr byte, detailed // at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp // now add to central record $cdrec = "\x50\x4b\x01\x02"; $cdrec .= "\x00\x00"; // version made by $cdrec .= "\x0a\x00"; // version needed to extract $cdrec .= "\x00\x00"; // gen purpose bit flag $cdrec .= "\x00\x00"; // compression method $cdrec .= "\x00\x00\x00\x00"; // last mod time & date $cdrec .= pack( "V" , 0 ); // crc32 $cdrec .= pack( "V" , 0 ); //compressed filesize $cdrec .= pack( "V" , 0 ); //uncompressed filesize $cdrec .= pack( "v" , strlen( $name ) ); //length of filename $cdrec .= pack( "v" , 0 ); //extra field length $cdrec .= pack( "v" , 0 ); //file comment length $cdrec .= pack( "v" , 0 ); //disk number start $cdrec .= pack( "v" , 0 ); //internal file attributes $ext = "\x00\x00\x10\x00"; $ext = "\xff\xff\xff\xff"; $cdrec .= pack( "V" , 16 ); //external file attributes - 'directory' bit set $cdrec .= pack( "V" , $this->old_offset ); //relative offset of local header $this->old_offset = $new_offset; $cdrec .= $name; // optional extra field, file comment goes here // save to array $this->ctrl_dir[] = $cdrec; } public function read_File( $file ) { if ( is_file( $file ) && filesize( $file) > 0 ) { $intFilesize = filesize( $file ); $fp = fopen( $file , 'rb' ); $content = fread( $fp , $intFilesize ); fclose( $fp ); return $content; } } // oliver hat die deepdir rausgeschmissen, brauchen wir net mehr public function getDirContent( $dirName = './' ) { if ( is_dir( $dirName ) ) { if ( $handle = opendir( $dirName ) ) { while (false !== ($file = readdir( $handle ))) { if ( ($file != '.') && ($file != '..') && (is_file( $file )) ) { $content[] = $file; } } closedir( $handle ); return $content; } } } public function addDirContent( $dir = './' ) { foreach( $this->getDirContent( $dir ) as $input ) { $this->addFileAndRead( str_replace( './/' , NULL , $input ) ); } } /** * @param string $file * @param null $filepath * @return void */ public function addFileAndRead( $file, $filepath = null ) { if( !is_null( $filepath)) { if ( is_file( $filepath ) ) { $this->addFile( $this->read_File( $filepath ) , $filepath ); } } else { if ( is_file( $file ) ) { $this->addFile( $this->read_File( $file ) , $file ); } } } private function unix2DosTime( $unixtime = 0 ) { date_default_timezone_set( 'Europe/Berlin' ); $timearray = ($unixtime == 0) ? getdate( ) : getdate( $unixtime ); if ( $timearray['year'] < 1980 ) { $timearray['year'] = 1980; $timearray['mon'] = 1; $timearray['mday'] = 1; $timearray['hours'] = 0; $timearray['minutes'] = 0; $timearray['seconds'] = 0; } return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); } private $arrFileTest = array(); public function addFile( $data , $name , $time = 0 ) { if ( in_array( $name , $this->arrFileTest ) ) { return false; } $this->arrFileTest[] = $name; $name = str_replace( '\\' , '/' , $name ); if ( substr( $name , 0 , 1 ) == "/" ) { $name = substr( $name , 1 ); } if ( is_array( $this->arrSkipDirectories ) ) { foreach( $this->arrSkipDirectories as $strSkipDir ) { $name = str_replace( $strSkipDir , "" , $name ); } } $dtime = dechex( $this->unix2DosTime( $time ) ); $hexdtime = '\x' . $dtime[6] . $dtime[7] . '\x' . $dtime[4] . $dtime[5] . '\x' . $dtime[2] . $dtime[3] . '\x' . $dtime[0] . $dtime[1]; eval( '$hexdtime = "' . $hexdtime . '";' ); $fr = "\x50\x4b\x03\x04"; $fr .= "\x14\x00"; // ver needed to extract $fr .= "\x00\x00"; // gen purpose bit flag $fr .= "\x08\x00"; // compression method $fr .= $hexdtime; // last mod time and date // "local file header" segment $unc_len = strlen( $data ); $crc = crc32( $data ); $zdata = gzcompress( $data ); $zdata = substr( substr( $zdata , 0 , strlen( $zdata ) - 4 ) , 2 ); // fix crc bug $c_len = strlen( $zdata ); $fr .= pack( 'V' , $crc ); // crc32 $fr .= pack( 'V' , $c_len ); // compressed filesize $fr .= pack( 'V' , $unc_len ); // uncompressed filesize $fr .= pack( 'v' , strlen( $name ) ); // length of filename $fr .= pack( 'v' , 0 ); // extra field length $fr .= $name; // "file data" segment $fr .= $zdata; // "data descriptor" segment (optional but necessary if archive is not // served as file) $fr .= pack( 'V' , $crc ); // crc32 $fr .= pack( 'V' , $c_len ); // compressed filesize $fr .= pack( 'V' , $unc_len ); // uncompressed filesize // add this entry to array $this->datasec[] = $fr; $new_offset = strlen( implode( '' , $this->datasec ) ); // now add to central directory record $cdrec = "\x50\x4b\x01\x02"; $cdrec .= "\x00\x00"; // version made by $cdrec .= "\x14\x00"; // version needed to extract $cdrec .= "\x00\x00"; // gen purpose bit flag $cdrec .= "\x08\x00"; // compression method $cdrec .= $hexdtime; // last mod time & date $cdrec .= pack( 'V' , $crc ); // crc32 $cdrec .= pack( 'V' , $c_len ); // compressed filesize $cdrec .= pack( 'V' , $unc_len ); // uncompressed filesize $cdrec .= pack( 'v' , strlen( $name ) ); // length of filename $cdrec .= pack( 'v' , 0 ); // extra field length $cdrec .= pack( 'v' , 0 ); // file comment length $cdrec .= pack( 'v' , 0 ); // disk number start $cdrec .= pack( 'v' , 0 ); // internal file attributes $cdrec .= pack( 'V' , 32 ); // external file attributes - 'archive' bit set $cdrec .= pack( 'V' , $this->old_offset ); // relative offset of local header $this->old_offset = $new_offset; $cdrec .= $name; // optional extra field, file comment goes here // save to central directory $this->ctrl_dir[] = $cdrec; return true; } public function getString( ) { $data = implode( NULL , $this->datasec ); $ctrldir = implode( NULL , $this->ctrl_dir ); return $data . $ctrldir . $this->eof_ctrl_dir . pack( 'v' , sizeof( $this->ctrl_dir ) ) . // total # of entries "on this disk" pack( 'v' , sizeof( $this->ctrl_dir ) ) . // total # of entries overall pack( 'V' , strlen( $ctrldir ) ) . // size of central dir pack( 'V' , strlen( $data ) ) . // offset to start of central dir "\x00\x00"; // .zip file comment length } private function dir_rekursiv( $verzeichnis ) { #global $arrFileNames; #global $arrEmptyDirs; $handle = opendir( $verzeichnis ); while ($datei = readdir( $handle )) { if ( $datei != "." && $datei != ".." ) { if ( is_dir( $verzeichnis . $datei ) ) // Wenn Verzeichniseintrag ein Verzeichnis ist { // Erneuter Funktionsaufruf, um das aktuelle Verzeichnis auszulesen if ( $datei != "./" ) { $this->arrEmptyDirs[] = $verzeichnis . $datei; } $this->dir_rekursiv( $verzeichnis . $datei . '/' ); } else { // Wenn Verzeichnis-Eintrag eine Datei ist, diese ausgeben $this->arrFileNames[] = $verzeichnis . $datei; } } } closedir( $handle ); } public function addRecursivFiles( $strStartverzeichnis = "./" ) { $this->dir_rekursiv( $strStartverzeichnis ); // f�gt die Verzeichnisse in das ZIP File foreach( $this->arrEmptyDirs as $value ) { if ( strpos( $value , ".." ) === 0 ) { $value = substr( $value , 2 ); } $this->add_dir( $value ); } // und jetzt die Dateien auslesen und in das Zip file schreiben foreach( $this->arrFileNames as $value ) { if ( strpos( $value , ".." ) === 0 ) { $value = substr( $value , 2 ); } $this->addFileAndRead( $value ); } } public function addFileAndReplace( $strFile2Parse , $arrReplaces ) { $strFileContent = file_get_contents( $strFile2Parse ); foreach( $arrReplaces AS $replaceKey => $replaceValue ) { $strFileContent = str_replace( $replaceKey , $replaceValue , $strFileContent ); } $this->addFile( $strFileContent , $strFile2Parse ); } public function setSkipDirectories( $arrDirectories ) { if ( is_array( $arrDirectories ) ) { foreach( $arrDirectories as $intKey => $strSkipDir ) { if ( substr( $strSkipDir , 0 , 1 ) == "/" || substr( $strSkipDir , 0 , 1 ) == "\\" ) { $strSkipDir = substr( $strSkipDir , 1 ); } if ( substr( $strSkipDir , -1 , 1 ) != "/" || substr( $strSkipDir , -1 , 1 ) != "\\" ) { $strSkipDir = $strSkipDir . "/"; } $arrDirectories[$intKey] = $strSkipDir; } $this->arrSkipDirectories = $arrDirectories; } } } ?>