1212
1313namespace App \Support ;
1414
15+ use PhpZip \Exception \InvalidArgumentException ;
16+ use PhpZip \Util \FilesUtil ;
1517use PhpZip \ZipFile ;
1618
1719class ZipManager
@@ -32,16 +34,16 @@ public function excludeVendor($exclude = true)
3234
3335 public function compress ($ projectPath , $ packageZipPath )
3436 {
35- $ zipFile = new ZipFile () ;
37+ $ zipFile = null ;
3638
3739 try {
38- $ zipFile-> addDirRecursive ($ projectPath )
40+ $ zipFile = $ this -> addDirRecursiveToZipFile ($ projectPath );
3941
40- // Delete all hidden (Unix) files
41- ->deleteFromRegex (self ::HIDDEN_FILES_PATTERN )
42+ // Delete all hidden (Unix) files
43+ $ zipFile ->deleteFromRegex (self ::HIDDEN_FILES_PATTERN );
4244
43- // Exclude other vendors
44- ->deleteFromRegex (self ::NODE_MODULES_PATTERN );
45+ // Exclude other vendors
46+ $ zipFile ->deleteFromRegex (self ::NODE_MODULES_PATTERN );
4547
4648 // Delete vendor (ignore the Customized vendor case)
4749 if ($ this ->excludeVendor ) {
@@ -53,7 +55,9 @@ public function compress($projectPath, $packageZipPath)
5355
5456 return true ;
5557 } finally {
56- $ zipFile ->close ();
58+ if ($ zipFile ) {
59+ $ zipFile ->close ();
60+ }
5761 }
5862
5963 return false ;
@@ -75,4 +79,115 @@ public function uncompress($file, $path)
7579
7680 return false ;
7781 }
82+
83+ private function addDirRecursiveToZipFile (string $ projectPath ): ZipFile
84+ {
85+ $ zipFile = new ZipFile ();
86+
87+ //$zipFile->addDirRecursive($projectPath)
88+ return $ this ->addDirRecursive ($ zipFile , $ projectPath );
89+ }
90+
91+ private function addDirRecursive (ZipFile $ zipFile , string $ inputDir , string $ localPath = '/ ' , ?int $ compressionMethod = null ): ZipFile
92+ {
93+ if ('' === $ inputDir ) {
94+ throw new InvalidArgumentException ('The input directory is not specified ' );
95+ }
96+
97+ if (!is_dir ($ inputDir )) {
98+ throw new InvalidArgumentException (sprintf ('The "%s" directory does not exist. ' , $ inputDir ));
99+ }
100+ $ inputDir = rtrim ($ inputDir , '/ \\' ).\DIRECTORY_SEPARATOR ;
101+
102+ $ directoryIterator = new \RecursiveDirectoryIterator ($ inputDir );
103+
104+ return $ this ->addFilesFromIterator ($ zipFile , $ directoryIterator , $ localPath , $ compressionMethod );
105+ }
106+
107+ private function addFilesFromIterator (
108+ ZipFile $ zipFile ,
109+ \Iterator $ iterator ,
110+ string $ localPath = '/ ' ,
111+ ?int $ compressionMethod = null
112+ ): ZipFile {
113+ if ('' !== $ localPath ) {
114+ $ localPath = trim ($ localPath , '\\/ ' );
115+ } else {
116+ $ localPath = '' ;
117+ }
118+
119+ $ iterator = $ iterator instanceof \RecursiveIterator
120+ ? new \RecursiveIteratorIterator ($ iterator )
121+ : new \IteratorIterator ($ iterator );
122+ /**
123+ * @var string[] $files
124+ * @var string $path
125+ */
126+ $ files = [];
127+
128+ foreach ($ iterator as $ file ) {
129+ if ($ file instanceof \SplFileInfo) {
130+ if ('.. ' === $ file ->getBasename ()) {
131+ continue ;
132+ }
133+
134+ if ('. ' === $ file ->getBasename ()) {
135+ $ files [] = \dirname ($ file ->getPathname ());
136+
137+ continue ;
138+ }
139+
140+ $ extension = $ file ->getExtension ();
141+ $ filename = $ file ->getFilename ();
142+
143+ if ('php ' !== $ extension && 'composer.json ' !== $ filename && 'composer.lock ' !== $ filename ) {
144+ continue ;
145+ }
146+
147+ $ pathname = $ file ->getPathname ();
148+ $ files [] = $ pathname ;
149+ }
150+ }
151+
152+ if (empty ($ files )) {
153+ return $ this ;
154+ }
155+
156+ natcasesort ($ files );
157+ $ path = array_shift ($ files );
158+
159+ $ this ->doAddFiles ($ zipFile , $ path , $ files , $ localPath , $ compressionMethod );
160+
161+ return $ zipFile ;
162+ }
163+
164+ private function doAddFiles (
165+ ZipFile $ zipFile ,
166+ string $ fileSystemDir ,
167+ array $ files ,
168+ string $ zipPath ,
169+ ?int $ compressionMethod = null
170+ ): void {
171+ $ fileSystemDir = rtrim ($ fileSystemDir , '/ \\' ).\DIRECTORY_SEPARATOR ;
172+
173+ if (!empty ($ zipPath )) {
174+ $ zipPath = trim ($ zipPath , '\\/ ' ).'/ ' ;
175+ } else {
176+ $ zipPath = '/ ' ;
177+ }
178+
179+ /**
180+ * @var string $file
181+ */
182+ foreach ($ files as $ file ) {
183+ $ filename = str_replace ($ fileSystemDir , $ zipPath , $ file );
184+ $ filename = ltrim ($ filename , '\\/ ' );
185+
186+ if (is_dir ($ file ) && FilesUtil::isEmptyDir ($ file )) {
187+ $ zipFile ->addEmptyDir ($ filename );
188+ } elseif (is_file ($ file )) {
189+ $ zipFile ->addFile ($ file , $ filename , $ compressionMethod );
190+ }
191+ }
192+ }
78193}
0 commit comments