12
12
13
13
namespace App \Support ;
14
14
15
+ use PhpZip \Exception \InvalidArgumentException ;
16
+ use PhpZip \Util \FilesUtil ;
15
17
use PhpZip \ZipFile ;
16
18
17
19
class ZipManager
@@ -32,16 +34,16 @@ public function excludeVendor($exclude = true)
32
34
33
35
public function compress ($ projectPath , $ packageZipPath )
34
36
{
35
- $ zipFile = new ZipFile () ;
37
+ $ zipFile = null ;
36
38
37
39
try {
38
- $ zipFile-> addDirRecursive ($ projectPath )
40
+ $ zipFile = $ this -> addDirRecursiveToZipFile ($ projectPath );
39
41
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 );
42
44
43
- // Exclude other vendors
44
- ->deleteFromRegex (self ::NODE_MODULES_PATTERN );
45
+ // Exclude other vendors
46
+ $ zipFile ->deleteFromRegex (self ::NODE_MODULES_PATTERN );
45
47
46
48
// Delete vendor (ignore the Customized vendor case)
47
49
if ($ this ->excludeVendor ) {
@@ -53,7 +55,9 @@ public function compress($projectPath, $packageZipPath)
53
55
54
56
return true ;
55
57
} finally {
56
- $ zipFile ->close ();
58
+ if ($ zipFile ) {
59
+ $ zipFile ->close ();
60
+ }
57
61
}
58
62
59
63
return false ;
@@ -75,4 +79,115 @@ public function uncompress($file, $path)
75
79
76
80
return false ;
77
81
}
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
+ }
78
193
}
0 commit comments