mirror of
				https://github.com/gtbu/Typesetter-5.3-p8.git
				synced 2025-11-04 06:48:27 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			331 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			331 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace gp\tool;
 | 
						|
 | 
						|
defined('is_running') or die('Not an entry point...');
 | 
						|
 | 
						|
/**
 | 
						|
 * Handle zip and tar archives with a single class
 | 
						|
 * PharData is suppose to work for both but:
 | 
						|
 * 	- file_get_contents('phar://...') doesn't work for zip archives
 | 
						|
 *  - writing archives when phar.readonly = 1 does not work in hhvm: https://github.com/facebook/hhvm/issues/6647
 | 
						|
 *
 | 
						|
 *
 | 
						|
 * @method bool extractTo( $destination )
 | 
						|
 *
 | 
						|
 */
 | 
						|
class Archive{
 | 
						|
 | 
						|
	protected $path;
 | 
						|
	protected $php_class				= 'PharData';
 | 
						|
	protected $php_object;
 | 
						|
	protected $extension;
 | 
						|
	protected $exists;
 | 
						|
 | 
						|
 | 
						|
	public function __construct($path){
 | 
						|
 | 
						|
		$this->path				= $path;
 | 
						|
		$this->extension		= $this->Extension($path);
 | 
						|
		$this->exists			= file_exists($path);
 | 
						|
 | 
						|
		switch( strtolower($this->extension) ){
 | 
						|
			case 'zip':
 | 
						|
				$this->InitZip();
 | 
						|
			break;
 | 
						|
			default:
 | 
						|
				$this->InitTar();
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Return a list of available
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public static function Available(){
 | 
						|
 | 
						|
		$available = array();
 | 
						|
 | 
						|
		if( class_exists('\ZipArchive') ){
 | 
						|
			$available['zip'] = 'zip';
 | 
						|
		}
 | 
						|
 | 
						|
		// hhvm does not handle phar.readonly the same way as php
 | 
						|
		// see https://github.com/facebook/hhvm/issues/4899
 | 
						|
		if( class_exists('\PharData') ){
 | 
						|
			if( !defined('HHVM_VERSION') || !ini_get('phar.readonly') ){
 | 
						|
 | 
						|
				if( function_exists('gzopen') ){
 | 
						|
					$available['tgz'] = 'gzip';
 | 
						|
				}
 | 
						|
 | 
						|
				if( function_exists('bzopen') ){
 | 
						|
					$available['tbz'] = 'bzip';
 | 
						|
				}
 | 
						|
 | 
						|
				$available['tar'] = 'tar';
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $available;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Initialize tar
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	protected function InitTar(){
 | 
						|
 | 
						|
		if( $this->exists ){
 | 
						|
			$this->php_object	= new \PharData($this->path);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		//start with filename.tar so that when we call $archive->compress(), the .tbz and .tgz file can be created
 | 
						|
		switch( strtolower($this->extension) ){
 | 
						|
			case 'tbz':
 | 
						|
			case 'tgz':
 | 
						|
			case 'tar.gz';
 | 
						|
			case 'tar.bz';
 | 
						|
				$this->path			= preg_replace('#\.(tgz|tbz|tar.bz|tar.gz)$#','.tar',$this->path);
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		$this->php_object	= new \PharData($this->path);
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Initialize a zip archive
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	protected function InitZip(){
 | 
						|
 | 
						|
		if( !class_exists('ZipArchive') ){
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->php_class	= 'ZipArchive';
 | 
						|
		$this->php_object	= new \ZipArchive();
 | 
						|
 | 
						|
		if( $this->exists ){
 | 
						|
			$this->php_object->open($this->path);
 | 
						|
		}else{
 | 
						|
			$this->php_object->open($this->path, \ZipArchive::CREATE);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the extension of the file
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	protected function Extension($path){
 | 
						|
 | 
						|
		$parts =		explode('.',$path);
 | 
						|
		$ext1 = 		array_pop($parts);
 | 
						|
		$ext2 = 		array_pop($parts);
 | 
						|
 | 
						|
		if( strtolower($ext2) == 'tar' ){
 | 
						|
			switch(strtolower($ext1)){
 | 
						|
				case 'bz';
 | 
						|
				return 'tar.bz';
 | 
						|
 | 
						|
				case 'gz';
 | 
						|
				return 'tar.gz';
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $ext1;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Call method on the archive object
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function __call( $name , $arguments ){
 | 
						|
		$call1 =  new \ZipArchive(); 
 | 
						|
		$call1 = $this->php_object; 
 | 
						|
		return call_user_func_array( array($call1,$name), $arguments);
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the contents of a file within the archive
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function getFromName($name){
 | 
						|
 | 
						|
		if( $this->php_class === 'ZipArchive' ){
 | 
						|
			return $this->php_object->getFromName($name);
 | 
						|
		}
 | 
						|
 | 
						|
		$full_path			= 'phar://'.$this->path.'/'.ltrim($name,'/');
 | 
						|
		return file_get_contents($full_path);
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Add the final compression to the archive
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function Compress(){
 | 
						|
 | 
						|
		if( $this->php_class === 'ZipArchive' ){
 | 
						|
			$this->php_object->close();
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		switch($this->extension){
 | 
						|
			case 'tbz':
 | 
						|
			case 'tar.bz':
 | 
						|
				$this->php_object->compress(\Phar::BZ2,$this->extension);
 | 
						|
				unlink($this->path);
 | 
						|
			break;
 | 
						|
 | 
						|
			case 'tar.gz':
 | 
						|
			case 'tgz':
 | 
						|
				$this->php_object->compress(\Phar::GZ,$this->extension);
 | 
						|
				unlink($this->path);
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Count the number of files
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function Count(){
 | 
						|
 | 
						|
		if( method_exists($this->php_object,'Count') ){
 | 
						|
			return $this->php_object->Count();
 | 
						|
		}
 | 
						|
 | 
						|
		return $this->php_object->numFiles;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * List the files in the archive
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function ListFiles(){
 | 
						|
		$list	= array();
 | 
						|
 | 
						|
		if( method_exists($this->php_object,'statIndex') ){
 | 
						|
			$count	= $this->Count();
 | 
						|
			for( $i = 0; $i < $count; $i++ ){
 | 
						|
				$list[] = $this->php_object->statIndex( $i );
 | 
						|
			}
 | 
						|
			return $list;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		return $this->GenList($list);
 | 
						|
	}
 | 
						|
 | 
						|
	public function GenList($list, $dir = ''){
 | 
						|
 | 
						|
		$path = 'phar://'.$this->path.'/'.$dir;
 | 
						|
		$_list = scandir($path);
 | 
						|
		foreach($_list as $file){
 | 
						|
 | 
						|
			$full		= ltrim($dir.'/'.$file,'/');
 | 
						|
			$path		= 'phar://'.$this->path.'/'.$full;
 | 
						|
 | 
						|
 | 
						|
			if( is_dir($path) ){
 | 
						|
				$list = $this->GenList($list, $full);
 | 
						|
			}else{
 | 
						|
				$stat		= stat($path);
 | 
						|
				$stat['name'] = $full;
 | 
						|
				$list[]		= array_intersect_key($stat,array('name'=>'','mtime'=>'','size'=>''));
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $list;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get Archive Root
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function GetRoot($search_file = 'Addon.ini'){
 | 
						|
 | 
						|
		$archive_files	= $this->ListFiles();
 | 
						|
		$archive_root	= null;
 | 
						|
 | 
						|
		foreach( $archive_files as $file ){
 | 
						|
 | 
						|
			if( strpos($file['name'],$search_file) === false ){
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$root = \gp\tool::DirName($file['name']);
 | 
						|
 | 
						|
			if( $root == '.' ){
 | 
						|
				$root = '';
 | 
						|
			}
 | 
						|
 | 
						|
			if( is_null($archive_root) || ( strlen($root) < strlen($archive_root) ) ){
 | 
						|
				$archive_root = $root;
 | 
						|
			}
 | 
						|
 | 
						|
		}
 | 
						|
 | 
						|
		return $archive_root;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Recursively add files to the archive
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function Add( $path, $localname = null){
 | 
						|
 | 
						|
		if( !file_exists($path) ){
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		if( is_null($localname) ){
 | 
						|
			$localname = $path;
 | 
						|
		}
 | 
						|
 | 
						|
		if( is_link($path) ){
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		if( !is_dir($path) ){
 | 
						|
			$localname = ltrim($localname,'\\/'); //so windows can open zip archives
 | 
						|
			return $this->php_object->addFile($path, $localname);
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		$files = scandir($path);
 | 
						|
		foreach($files as $file){
 | 
						|
			if( $file === '.' || $file === '..' ){
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
			$full_path		= $path.'/'.$file;
 | 
						|
			$_localname		= $localname.'/'.$file;
 | 
						|
 | 
						|
			$this->Add( $full_path, $_localname);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Return the php object
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	public function GetObject(){
 | 
						|
		return $this->php_object;
 | 
						|
	}
 | 
						|
}
 |