/application/libraries/Engine/Package/Archive.php
https://github.com/grandison/budo16 · PHP · 194 lines · 138 code · 21 blank · 35 comment · 45 complexity · 89fd239e285d8b3b6eeca5b3d8d18f17 MD5 · raw file
- <?php
- /**
- * SocialEngine
- *
- * @category Engine
- * @package Engine_Package
- * @copyright Copyright 2006-2010 Webligo Developments
- * @license http://www.socialengine.net/license/
- * @version $Id: Archive.php 7244 2010-09-01 01:49:53Z john $
- * @author John Boehr <j@webligo.com>
- */
- /**
- * @category Engine
- * @package Engine_Filter
- * @copyright Copyright 2006-2010 Webligo Developments
- * @license http://www.socialengine.net/license/
- * @author John Boehr <j@webligo.com>
- */
- class Engine_Package_Archive
- {
- static public function inflate($file, $outputPath)
- {
- // Sanity
- if( !file_exists($file) || !is_file($file) || strtolower(pathinfo($file, PATHINFO_EXTENSION)) != 'tar' ) {
- throw new Engine_Package_Exception('File does not exist or is not a tar file');
- }
- if( !file_exists($outputPath) || !is_dir($outputPath) || !is_writeable($outputPath) ) {
- throw new Engine_Package_Exception('Output path does not exist, is not a directory, or is not writeable');
- }
- self::_loadArchiveClass();
- // Make other paths
- $outputSubPath = substr(basename($file), 0, strrpos(basename($file), '.'));
- $outputFullPath = rtrim($outputPath, '/\\') . DIRECTORY_SEPARATOR . $outputSubPath;
- // If output path already exists, remove
- if( file_exists($outputFullPath) ) {
- self::_rmdirRecursive($outputFullPath, true);
- }
- // Try to make full output path
- if( !is_dir($outputFullPath) ) {
- if( !mkdir($outputFullPath, 0777, true) ) {
- throw new Engine_Package_Exception('Unable to create output folder');
- }
- }
- // Extract
- $archive = new Archive_Tar($file);
- $rval = $archive->extract($outputFullPath);
- // Throw error if failed
- if( $archive->isError($rval) ) {
- throw new Engine_Package_Exception('Error in archive: ' . $rval->getMessage());
- }
- return $outputFullPath;
- }
- static public function deflate(Engine_Package_Manifest $package, $outputPath)
- {
- // Sanity
- if( !file_exists($outputPath) || !is_dir($outputPath) || !is_writeable($outputPath) ) {
- throw new Engine_Package_Exception('Output path does not exist, is not a directory, or is not writeable');
- }
- if( !is_dir($package->getBasePath()) ) {
- throw new Engine_Package_Exception('Missing package base path');
- }
- self::_loadArchiveClass();
- // Make filenames and paths
- $basePath = $package->getBasePath();
- $archiveFile = $package->getKey() . '.tar';
- $archiveFullPath = $outputPath . DIRECTORY_SEPARATOR . $archiveFile;
- if( file_exists($archiveFullPath) && !unlink($archiveFullPath) ) {
- throw new Engine_Package_Exception('Target archive already exists and unable to remove');
- }
- // Start packing
- $archive = new Archive_Tar($archiveFullPath);
- $archive->setIgnoreList(array('CVS', '.svn'));
- // Add all directories, files, and subpackages
- $package->addToArchive($archive);
- return $archiveFullPath;
- }
- static public function readPackageFile($file)
- {
- // Sanity
- if( !file_exists($file) || !is_file($file) || strtolower(pathinfo($file, PATHINFO_EXTENSION)) != 'tar' ) {
- throw new Engine_Package_Exception('File does not exist or is not a tar file');
- }
- self::_loadArchiveClass();
- // Create archive object
- $archive = new Archive_Tar($file);
- // List files
- $fileList = $archive->listContent();
- if( empty($fileList) ) {
- throw new Engine_Package_Exception('Unable to open archive');
- }
- // Check for root package file
- $rootPackageFile = null;
- foreach( $fileList as $arFile ) {
- if( $arFile['filename'] == 'package.json' ) {
- $rootPackageFile = $arFile['filename'];
- break;
- }
- }
- if( null === $rootPackageFile ) {
- throw new Engine_Package_Exception('Root package file not found.');
- }
- // Start building package stuff
- $packageFileObject = new Engine_Package_Manifest();
- $packageFileObject->fromString($archive->extractInString($rootPackageFile), 'json');
- return $packageFileObject;
- }
- static protected function _loadArchiveClass()
- {
- include_once 'Archive/Tar.php';
- if( !class_exists('Archive_Tar', false) ) {
- throw new Engine_Package_Exception('Unable to load Archive_Tar class');
- }
- }
- static protected function _addPackageToArchive(Engine_Package_Manifest $package, Archive_Tar $archive, $basePath)
- {
- $rval = null;
- foreach( $package->getStructure() as $name => $contents ) {
- if( !($contents instanceof Engine_Package_Manifest_Entity_Abstract) ) {
- continue;
- }
- switch( $contents->getType() ) {
- case 'package':
- $subPackageObject = new Engine_Package_Manifest($basePath . DIRECTORY_SEPARATOR . $contents['path'] . DIRECTORY_SEPARATOR . $contents['packageFile']);
- $subPackageObject->setBasePath($basePath);
- self::_addPackageToArchive($subPackageObject, $archive, $basePath);
- break;
- case 'directory':
- // Add directory
- $rval = $archive->addModify($basePath . DIRECTORY_SEPARATOR . $contents['path'], null, $basePath);
- if( $archive->isError($rval) ) {
- throw new Engine_Package_Exception(sprintf('Unable to add path "%s" to archive', $contents['path']));
- }
- break;
- case 'file':
- // Add file
- $rval = $archive->addModify($basePath . DIRECTORY_SEPARATOR . $contents['path'], null, $basePath);
- if( $archive->isError($rval) ) {
- throw new Engine_Package_Exception(sprintf('Unable to add path "%s" to archive', $contents['path']));
- }
- break;
- default:
- throw new Engine_Package_Exception('unknown contents type');
- break;
- }
- }
-
- // Throw error if failed
- if( $archive->isError($rval) ) {
- throw new Engine_Package_Exception('Error in archive: ' . $rval->getMessage());
- }
- }
- static protected function _rmdirRecursive($path, $includeSelf = false)
- {
- $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME), RecursiveIteratorIterator::CHILD_FIRST);
- foreach( $it as $key => $child ) {
- if( $child->getFilename() == '.' || $child->getFilename() == '..' || $child->getFilename() == '.svn' ) {
- continue;
- } else if( $child->isDir() ) {
- if( !rmdir($key) ) {
- throw new Engine_Package_Exception(sprintf('Unable to remove directory: %s', $key));
- }
- } else if( $child->isFile() ) {
- if( !unlink($key) ) {
- throw new Engine_Package_Exception(sprintf('Unable to remove file: %s', $key));
- }
- }
- }
- if( $includeSelf ) {
- if( is_dir($path) && !rmdir($path) ) {
- throw new Engine_Package_Exception(sprintf('Unable to remove directory: %s', $path));
- }
- }
- }
- }