44
55use Nette \FileNotFoundException ;
66use Nette \SmartObject ;
7+ use SplFileInfo ;
78use Wavevision \Utils \FileInfo ;
9+ use Wavevision \Utils \Finder ;
810use Wavevision \Utils \Path ;
911use ZipArchive as Zip ;
1012
@@ -13,25 +15,27 @@ class ZipArchive
1315
1416 use SmartObject;
1517
18+ private const INITIAL_DEPTH = 1 ;
19+
1620 /**
17- * @var ZipArchiveFile []
21+ * @var ZipArchiveItem []
1822 */
19- private array $ files ;
23+ private array $ items ;
2024
2125 private string $ path ;
2226
2327 private Zip $ zip ;
2428
25- public function __construct (string $ path , ZipArchiveFile ...$ files )
29+ public function __construct (string $ path , ZipArchiveItem ...$ items )
2630 {
27- $ this ->files = $ files ;
31+ $ this ->items = $ items ;
2832 $ this ->path = $ path ;
2933 $ this ->zip = new Zip ();
3034 }
3135
32- public function addFile ( ZipArchiveFile $ file ): self
36+ public function addItem ( ZipArchiveItem $ item ): self
3337 {
34- $ this ->files [] = $ file ;
38+ $ this ->items [] = $ item ;
3539 return $ this ;
3640 }
3741
@@ -43,8 +47,13 @@ public function close(): self
4347
4448 public function compress (): self
4549 {
46- foreach ($ this ->files as $ file ) {
47- $ this ->zip ->addFile ($ this ->getFilePath ($ file ), $ file ->getName ());
50+ foreach ($ this ->items as $ item ) {
51+ $ path = $ this ->getItemPath ($ item );
52+ if (is_dir ($ path )) {
53+ $ this ->addDir ($ item , self ::INITIAL_DEPTH );
54+ } else {
55+ $ this ->zip ->addFile ($ path , $ item ->getName ());
56+ }
4857 }
4958 return $ this ->close ();
5059 }
@@ -78,17 +87,40 @@ public function write(): self
7887 return $ this ;
7988 }
8089
90+ /**
91+ * @param string[] $parents
92+ */
93+ private function addDir (ZipArchiveItem $ item , int $ depth , array $ parents = []): void
94+ {
95+ $ deep = $ depth > self ::INITIAL_DEPTH ;
96+ $ dir = $ item ->getName ();
97+ if ($ deep ) {
98+ $ parents = [...$ parents , $ dir ];
99+ $ this ->zip ->addEmptyDir (Path::join (...$ parents ));
100+ }
101+ /** @var SplFileInfo $subItem */
102+ foreach (Finder::find ('* ' )->in ($ item ->getPath ()) as $ subItem ) {
103+ $ path = $ subItem ->getPathname ();
104+ if ($ subItem ->isDir ()) {
105+ $ this ->addDir (new ZipArchiveItem ($ path ), $ depth + 1 , $ parents );
106+ } else {
107+ $ name = $ subItem ->getFilename ();
108+ $ this ->zip ->addFile ($ path , $ deep ? Path::join (...[...$ parents , $ name ]) : $ name );
109+ }
110+ }
111+ }
112+
81113 private function getExtractDir (): string
82114 {
83115 $ fileInfo = new FileInfo ($ this ->getPath ());
84116 return Path::join ($ fileInfo ->getDirName (), $ fileInfo ->getBaseName (true ));
85117 }
86118
87- private function getFilePath ( ZipArchiveFile $ file ): string
119+ private function getItemPath ( ZipArchiveItem $ item ): string
88120 {
89- $ path = $ file ->getPath ();
121+ $ path = $ item ->getPath ();
90122 if (!file_exists ($ path )) {
91- throw new FileNotFoundException ("Zip archive file ' $ path' not found. " );
123+ throw new FileNotFoundException ("Zip archive item ' $ path' not found. " );
92124 }
93125 return $ path ;
94126 }
0 commit comments