<?php
// last edit: 05.11.2018

class ZipUtils{
	/**
	* Получить список вложенных папок/файлов в указанном ZIP-архиве
	* @param string $zipFile     - путь к архиву
	* @param string $path        - путь каталога в архиве ('' - корень архива)
	* @param bool $notsubfolders - если передать как TRUE, то список будет состоять только из файлов
	* @return array [array[string(имя) ,array(info: STATS)],... ]
	* STATS:
	*	[name] => полное имя файла в архиве с путем
	*	[index] => индекс файла в архиве
	*	[crc] => время создания файла
	*	[size] => исходный размер файла
	*	[mtime] => время изменения файла
	*	[comp_size] => сжатый размер файла
	*	[comp_method] => метод сжатия файла
	*/
	static function getLinks($zipFile, $path = '',$notsubfolders = false){
		$result = [];
		$zip = new ZipArchive;
		if($path != '')
			$len = strlen($path);
		if($zip->open($zipFile)){
			for($i = 0, $ct = $zip->numFiles; $i < $ct; $i++){
				$temp =  $zip->getNameIndex($i);
				if($path == '' || ($temp != $path && substr($temp, 0, $len) == $path)){
					$name = ($path == '' ? $temp : substr($temp, $len));
					if($notsubfolders){
						$temp = explode('/',$name);
						if(count($temp)==1 || $temp[1]=='')
							$result[] = [$name, $zip->statIndex($i,ZipArchive::FL_UNCHANGED)];
					}else $result[] = [$name, $zip->statIndex($i,ZipArchive::FL_UNCHANGED)];

				}
			}
			$zip->close();

			usort($result, function($a,$b){
				$isA = $a[0]{-1} == '/';
				$isB = $b[0]{-1} == '/';
				return $isA == $isB ? 0 : ($isA ? -1 : 1);
			});
			return $result;
		}
		return [];
	}


	/**
	* Получить содержимое файла из архива
	* @param string $zipFile     - путь к архиву
	* @param string $fileName    - путь к файлу в архиве
	* @return string/binary
	*/
	static function getFile($zipFile,$fileName){
		$zip = new ZipArchive;
		if ($zip->open($zipFile)) {
		    $temp = $zip->getFromName($fileName);
		    $zip->close();

		    return $temp;
		} 
		return '';	
	}

}