@@ -162,6 +162,12 @@ public function remove($files)
162
162
} elseif (!\is_array ($ files )) {
163
163
$ files = [$ files ];
164
164
}
165
+
166
+ self ::doRemove ($ files , false );
167
+ }
168
+
169
+ private static function doRemove (array $ files , bool $ isRecursive ): void
170
+ {
165
171
$ files = array_reverse ($ files );
166
172
foreach ($ files as $ file ) {
167
173
if (is_link ($ file )) {
@@ -170,10 +176,35 @@ public function remove($files)
170
176
throw new IOException (sprintf ('Failed to remove symlink "%s": ' , $ file ).self ::$ lastError );
171
177
}
172
178
} elseif (is_dir ($ file )) {
173
- $ this ->remove (new \FilesystemIterator ($ file , \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS ));
179
+ if (!$ isRecursive ) {
180
+ $ tmpName = \dirname (realpath ($ file )).'/. ' .strrev (strtr (base64_encode (random_bytes (2 )), '/= ' , '-. ' ));
181
+
182
+ if (file_exists ($ tmpName )) {
183
+ try {
184
+ self ::doRemove ([$ tmpName ], true );
185
+ } catch (IOException $ e ) {
186
+ }
187
+ }
188
+
189
+ if (!file_exists ($ tmpName ) && self ::box ('rename ' , $ file , $ tmpName )) {
190
+ $ origFile = $ file ;
191
+ $ file = $ tmpName ;
192
+ } else {
193
+ $ origFile = null ;
194
+ }
195
+ }
196
+
197
+ $ files = new \FilesystemIterator ($ file , \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS );
198
+ self ::doRemove (iterator_to_array ($ files , true ), true );
199
+
200
+ if (!self ::box ('rmdir ' , $ file ) && file_exists ($ file ) && !$ isRecursive ) {
201
+ $ lastError = self ::$ lastError ;
202
+
203
+ if (null !== $ origFile && self ::box ('rename ' , $ file , $ origFile )) {
204
+ $ file = $ origFile ;
205
+ }
174
206
175
- if (!self ::box ('rmdir ' , $ file ) && file_exists ($ file )) {
176
- throw new IOException (sprintf ('Failed to remove directory "%s": ' , $ file ).self ::$ lastError );
207
+ throw new IOException (sprintf ('Failed to remove directory "%s": ' , $ file ).$ lastError );
177
208
}
178
209
} elseif (!self ::box ('unlink ' , $ file ) && (false !== strpos (self ::$ lastError , 'Permission denied ' ) || file_exists ($ file ))) {
179
210
throw new IOException (sprintf ('Failed to remove file "%s": ' , $ file ).self ::$ lastError );
0 commit comments