run(); class ezcArchiver { protected $output; protected $intput; public function run() { $this->init(); $this->output->outputLine( 'ezcArchiver version 1.0devel', 'info' ); $this->output->outputLine(); if ( sizeof( $this->input->getArguments() ) === 0 && sizeof( $this->input->getOptionValues() ) === 0 || $this->input->getOption( 'h' )->value === true ) { $this->printHelp(); exit(0); } if ( sizeof( ( $args = $this->input->getArguments() ) ) === 0 ) { $this->raiseError( 'At least 1 archive to list is required as an argument, but none not provided.' ); } $ignorePaths = array(); if ( is_array( $this->input->getOption( 'i' )->value ) && sizeof( $this->input->getOption( 'i' )->value ) > 0 ) { $ignorePaths = $this->input->getOption( 'i' )->value; } switch ( true ) { case $this->input->getOption( 'e' )->value === true: $this->extractArchive( $args, $ignorePaths ); break; case $this->input->getOption( 'c' )->value === true: $this->createArchive( $args, $ignorePaths ); break; case $this->input->getOption( 'l' )->value === true: case sizeof( $this->input->getOptionValues() ) === 0: $this->listArchive( $args, $ignorePaths ); break; } } protected function listArchive( $args, $ignorePaths ) { try { foreach ( $args as $archivePath ) { $archive = ezcArchive::getInstance( $archivePath ); $this->output->outputLine( "Now listing contents of archive <{$archivePath}>.", 'info' ); foreach ( $archive as $entry ) { foreach ( $ignorePaths as $ignoreRegex ) { if ( preg_match( $ignoreRegex, $entry->getPath() ) ) { continue 2; } } $out = $entry->getPath(); if ( $this->input->getOption( 'a' ) ) { $out = $entry->__toString(); } $this->output->outputLine( $out ); } } } catch ( ezcArchiveException $e ) { $this->raiseError( $e->getMessage() ); } } protected function extractArchive( $args, $ignorePaths ) { try { foreach ( $args as $archivePath ) { $archive = ezcArchive::getInstance( $archivePath ); $this->output->outputLine( "Now extracting contents of archive <{$archivePath}>.", 'info' ); foreach ( $archive as $entry ) { foreach ( $ignorePaths as $ignoreRegex ) { if ( preg_match( $ignoreRegex, $entry->getPath() ) ) { continue 2; } } $archive->extractCurrent( $this->input->getOption( 'o' )->value === false ? './tmp' : $this->input->getOption( 'o' )->value ); $this->output->outputLine( $entry->getPath() ); } } } catch ( ezcArchiveException $e ) { $this->raiseError( $e->getMessage() ); } } protected function createArchive( $args, $ignorePaths ) { $sourceDir = $this->input->getOption( 'd' )->value; if ( !is_dir( $sourceDir ) || !is_readable( $sourceDir ) || !is_executable( $sourceDir ) ) { $this->raiseError( "Source directory <{$sourceDir}> does not exist or is not readable/browsable." ); } if ( sizeof( $args ) > 1 ) { $this->raiseError( "Only 1 archive is supported to be created at once, but <{sizeof( $args )}> where submitted." ); } $archivePath = $args[0]; // Do we have to package after putting into an archive? $postPackage = false; $postPackagePath = false; // Base package type $type = ezcArchive::TAR_USTAR; switch ( true ) { case ( preg_match( '/\.tar.gz$/i', $archivePath ) ): $postPackage = 'compress.zlib'; break; case ( preg_match( '/\.tar.bz2$/i', $archivePath ) ): $postPackage = 'compress.bzip2'; break; case ( preg_match( '/\.zip/i', $archivePath ) ): $type = ezcArchive::ZIP; break; case ( preg_match( '/\.tar$/i', $archivePath ) ): break; default: $this->raiseError( "<{$archivePath}> is of an unknown type. By now only .tar, .tar.gz, .tar.bz2 and .zip are supported." ); break; } $dirListing = $this->getRecursiveDir( $sourceDir, $ignorePaths ); // Prepare post packaging if necessary if ( $postPackage !== false ) { $postPackagePath = $archivePath; $archivePath = dirname( $archivePath ) . DIRECTORY_SEPARATOR . '.tmp' . basename( $archivePath ); } try { $archive = ezcArchive::getInstance( $archivePath, $type ); if ( !$archive->isWritable() ) { $this->raiseError( "Can not write to archive <{$archivePath}>." ); } foreach ( $dirListing as $entry ) { $archive->append( $entry, $sourceDir ); $this->output->outputLine( "Added entry <{$entry}> to archive.", 'info' ); } } catch ( ezcArchiveException $e ) { $this->raiseError( $e->getMessage() ); } if ( $postPackage !== false ) { if ( ( $content = file_get_contents( $archivePath ) ) === false ) { $this->raiseError( "Error while reading temporary archive. Aborting. The temporary archive is still available here: <{$archivePath}>." ); } if ( ( file_put_contents( "$postPackage://$postPackagePath", $content ) ) === 0 ) { $this->raiseError( "Error while writing final archive. Aborting. The temporary archive is still available here: <{$archivePath}>." ); } unlink( $archivePath ); } } protected function getRecursiveDir( $path, $ignorePaths ) { $res = array(); $d = dir( $path ); while (false !== ($entry = $d->read())) { if ( $entry !== '.' && $entry !== '..' ) { $entry = $path . DIRECTORY_SEPARATOR . $entry; foreach ( $ignorePaths as $ignoreRegex ) { if ( preg_match( $ignoreRegex, $entry ) ) { continue 2; } if ( is_dir( $entry ) ) { $res = array_merge( $res, $this->getRecursiveDir( $entry, $ignorePaths ) ); } else { $res[] = $entry; } } } } return $res; } protected function printHelp() { $table = new ezcConsoleTable( $this->output, 78 ); $table->options->widthType = ezcConsoleTable::WIDTH_FIXED; foreach ( $this->input->getOptions() as $id => $option ){ $table[$id][]->content = '-'.$option->short.'/--'.$option->long; $table[$id][]->content = $option->shorthelp; } $this->output->outputLine( 'Commandline help.' ); $this->output->outputLine( $this->input->getSynopsis() ); $table->outputTable(); $this->output->outputLine(); } protected function init() { // Output configuration $this->output = new ezcConsoleOutput(); $this->output->formats->error->color = 'red'; $this->output->formats->error->style = array( 'bold' ); $this->output->formats->info->color = 'blue'; $this->output->formats->info->style = array( 'bold' ); $this->output->formats->log->color = 'gray'; $this->output->formats->log->style = array( 'bold' ); // Option configuration $this->input = new ezcConsoleInput(); $helpOption = $this->input->registerOption( new ezcConsoleOption( 'h', 'help' ) ); $helpOption->shorthelp = 'Get help information.'; $listOption = $this->input->registerOption( new ezcConsoleOption( 'l', 'list' ) ); $listOption->shorthelp = 'List contents of an archive.'; $extractOption = $this->input->registerOption( new ezcConsoleOption( 'e', 'extract' ) ); $extractOption->shorthelp = 'Extract all files from an archive.'; $createOption = $this->input->registerOption( new ezcConsoleOption( 'c', 'create' ) ); $createOption->shorthelp = 'Create a new archive from a directory.'; $directoryOption = $this->input->registerOption( new ezcConsoleOption( 'd', 'directory', ezcConsoleInput::TYPE_STRING ) ); $directoryOption->shorthelp = 'Directory to perform option on (default is <./>).'; $excludeOption = $this->input->registerOption( new ezcConsoleOption( 'i', 'ignore', ezcConsoleInput::TYPE_STRING ) ); $excludeOption->multiple = true; $excludeOption->shorthelp = "Ignore paths matching a PCRE from any action (multiple possible)."; $infoOptions = $this->input->registerOption( new ezcConsoleOption( 'a', 'all-info' ) ); $infoOptions->addDependency( new ezcConsoleOptionRule( $listOption ) ); try { $this->input->process(); } catch ( ezcConsoleOptionException $e ) { $this->raiseError( $e->getMessage() ); } } protected function raiseError( $msg ) { $this->output->outputLine( $msg, 'error' ); die( 255 ); } } ?>