@@ -44,6 +44,32 @@ public function receiveAction($action, $httpVars, $fileVars)
44
44
$ currentDirPath = AJXP_Utils::safeDirname ($ userSelection ->getUniqueNode ()->getPath ());
45
45
$ currentDirPath = rtrim ($ currentDirPath , "/ " ) . "/ " ;
46
46
$ currentDirUrl = $ userSelection ->currentBaseUrl ().$ currentDirPath ;
47
+
48
+ # Multi-platform function taken from stackoverflow
49
+ # http://stackoverflow.com/questions/12424787/how-to-check-if-a-shell-command-exists-from-php
50
+ # Check that a command exists on the system for use with shell_exec
51
+ function command_exists ($ command ) {
52
+ $ whereIsCommand = (PHP_OS == 'WINNT ' ) ? 'where ' : 'which ' ;
53
+ $ process = proc_open (
54
+ "$ whereIsCommand $ command " ,
55
+ array (
56
+ 0 => array ("pipe " , "r " ), //STDIN
57
+ 1 => array ("pipe " , "w " ), //STDOUT
58
+ 2 => array ("pipe " , "w " ), //STDERR
59
+ ),
60
+ $ pipes
61
+ );
62
+ if ($ process !== false ) {
63
+ $ stdout = stream_get_contents ($ pipes [1 ]);
64
+ $ stderr = stream_get_contents ($ pipes [2 ]);
65
+ fclose ($ pipes [1 ]);
66
+ fclose ($ pipes [2 ]);
67
+ proc_close ($ process );
68
+ return $ stdout != '' ;
69
+ }
70
+ return false ;
71
+ }
72
+
47
73
if (empty ($ httpVars ["compression_id " ])) {
48
74
$ compressionId = sha1 (rand ());
49
75
$ httpVars ["compression_id " ] = $ compressionId ;
@@ -119,44 +145,85 @@ public function receiveAction($action, $httpVars, $fileVars)
119
145
file_put_contents ($ progressCompressionFileName , "Error : " . $ messages ["compression.17 " ]);
120
146
throw new AJXP_Exception ($ messages ["compression.17 " ]);
121
147
}
122
- try {
123
- $ tmpArchiveName = tempnam (AJXP_Utils::getAjxpTmpDir (), "tar-compression " ) . ".tar " ;
124
- $ archive = new PharData ($ tmpArchiveName );
125
- } catch (Exception $ e ) {
126
- file_put_contents ($ progressCompressionFileName , "Error : " . $ e ->getMessage ());
127
- throw $ e ;
128
- }
129
- $ counterCompression = 0 ;
130
- //THE TWO ARRAY ARE MERGED FOR THE FOREACH LOOP
131
- $ tabAllFiles = array_combine ($ tabAllRecursiveFiles , $ tabFilesNames );
132
- foreach ($ tabAllFiles as $ fullPath => $ fileName ) {
148
+ // Builds a shell command that changes to the workspace location in the filesystem, and then
149
+ // compresses with tar and any parallel compression utilities that are installed.
150
+ if (command_exists ("tar " )) {
151
+ $ FileNames = array ();
152
+ $ FolderNames = array ();
153
+ foreach ($ nodes as $ node ) {
154
+ $ nodeUrl = $ node ->getUrl ();
155
+ if (is_file ($ nodeUrl ) && filesize ($ nodeUrl ) < $ maxAuthorizedSize ) {
156
+ array_push ($ FileNames , escapeshellarg (substr ($ nodeUrl , $ currentDirUrlLength )));
157
+ }
158
+ if (is_dir ($ nodeUrl )) {
159
+ array_push ($ FolderNames , escapeshellarg (substr ($ nodeUrl , $ currentDirUrlLength )));
160
+ }
161
+ }
162
+ if ($ archiveFormat == ".tar.gz " ) {
163
+ if (command_exists ("pigz " )) {
164
+ $ tarcommand = "tar -I pigz -cf " ;
165
+ } else {
166
+ $ tarcommand = "tar -czf " ;
167
+ }
168
+ } elseif ($ archiveFormat == ".tar.bz2 " ) {
169
+ if (command_exists ("lbzip2 " )) {
170
+ $ tarcommand = "tar -I lbzip2 -cf " ;
171
+ } elseif (command_exists ("pbzip2 " )) {
172
+ $ tarcommand = "tar -I pbzip2 -cf " ;
173
+ } else {
174
+ $ tarcommand = "tar -cjf " ;
175
+ }
176
+ } elseif ($ archiveFormat == ".tar " ) {
177
+ $ tarcommand = "tar -cf " ;
178
+ } else {
179
+ file_put_contents ($ progressExtractFileName , "Error : " . $ messages ["compression.15 " ]);
180
+ throw new AJXP_Exception ($ messages ["compression.15 " ]);
181
+ }
182
+ $ changedircommand = "cd " . AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl ) . " && " ;
183
+ $ finalcommand = $ changedircommand . $ tarcommand . escapeshellarg ($ archiveName ) . " " . implode (" " , $ FolderNames ) . " " . implode (" " , $ FileNames );
184
+ shell_exec ($ finalcommand );
185
+ } else {
186
+ // If tar command is not found, compress with PHP Phar instead
133
187
try {
134
- $ archive ->addFile (AJXP_MetaStreamWrapper::getRealFSReference ($ fullPath ), $ fileName );
135
- $ counterCompression ++;
136
- file_put_contents ($ progressCompressionFileName , sprintf ($ messages ["compression.6 " ], round (($ counterCompression / count ($ tabAllFiles )) * 100 , 0 , PHP_ROUND_HALF_DOWN ) . " % " ));
188
+ $ tmpArchiveName = tempnam (AJXP_Utils::getAjxpTmpDir (), "tar-compression " ) . ".tar " ;
189
+ $ archive = new PharData ($ tmpArchiveName );
137
190
} catch (Exception $ e ) {
138
- unlink ($ tmpArchiveName );
139
191
file_put_contents ($ progressCompressionFileName , "Error : " . $ e ->getMessage ());
140
192
throw $ e ;
141
193
}
142
- }
143
- $ finalArchive = $ tmpArchiveName ;
144
- if ($ typeArchive != ".tar " ) {
145
- $ archiveTypeCompress = substr (strrchr ($ typeArchive , ". " ), 1 );
146
- file_put_contents ($ progressCompressionFileName , sprintf ($ messages ["compression.7 " ], strtoupper ($ archiveTypeCompress )));
147
- if ($ archiveTypeCompress == "gz " ) {
148
- $ archive ->compress (Phar::GZ );
149
- } elseif ($ archiveTypeCompress == "bz2 " ) {
150
- $ archive ->compress (Phar::BZ2 );
194
+ $ counterCompression = 0 ;
195
+ //THE TWO ARRAY ARE MERGED FOR THE FOREACH LOOP
196
+ $ tabAllFiles = array_combine ($ tabAllRecursiveFiles , $ tabFilesNames );
197
+ foreach ($ tabAllFiles as $ fullPath => $ fileName ) {
198
+ try {
199
+ $ archive ->addFile (AJXP_MetaStreamWrapper::getRealFSReference ($ fullPath ), $ fileName );
200
+ $ counterCompression ++;
201
+ file_put_contents ($ progressCompressionFileName , sprintf ($ messages ["compression.6 " ], round (($ counterCompression / count ($ tabAllFiles )) * 100 , 0 , PHP_ROUND_HALF_DOWN ) . " % " ));
202
+ } catch (Exception $ e ) {
203
+ unlink ($ tmpArchiveName );
204
+ file_put_contents ($ progressCompressionFileName , "Error : " . $ e ->getMessage ());
205
+ throw $ e ;
206
+ }
151
207
}
152
- $ finalArchive = $ tmpArchiveName . ". " . $ archiveTypeCompress ;
153
- }
154
- $ destArchive = AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl . $ archiveName );
155
- rename ($ finalArchive , $ destArchive );
156
- AJXP_Controller::applyHook ("node.before_create " , array ($ destArchive , filesize ($ destArchive )));
157
- if (file_exists ($ tmpArchiveName )) {
158
- unlink ($ tmpArchiveName );
159
- unlink (substr ($ tmpArchiveName , 0 , -4 ));
208
+ $ finalArchive = $ tmpArchiveName ;
209
+ if ($ typeArchive != ".tar " ) {
210
+ $ archiveTypeCompress = substr (strrchr ($ typeArchive , ". " ), 1 );
211
+ file_put_contents ($ progressCompressionFileName , sprintf ($ messages ["compression.7 " ], strtoupper ($ archiveTypeCompress )));
212
+ if ($ archiveTypeCompress == "gz " ) {
213
+ $ archive ->compress (Phar::GZ );
214
+ } elseif ($ archiveTypeCompress == "bz2 " ) {
215
+ $ archive ->compress (Phar::BZ2 );
216
+ }
217
+ $ finalArchive = $ tmpArchiveName . ". " . $ archiveTypeCompress ;
218
+ }
219
+ $ destArchive = AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl . $ archiveName );
220
+ rename ($ finalArchive , $ destArchive );
221
+ AJXP_Controller::applyHook ("node.before_create " , array ($ destArchive , filesize ($ destArchive )));
222
+ if (file_exists ($ tmpArchiveName )) {
223
+ unlink ($ tmpArchiveName );
224
+ unlink (substr ($ tmpArchiveName , 0 , -4 ));
225
+ }
226
+ // End of Phar compression section
160
227
}
161
228
$ newNode = new AJXP_Node ($ currentDirUrl . $ archiveName );
162
229
AJXP_Controller::applyHook ("node.change " , array (null , $ newNode , false ));
@@ -244,27 +311,55 @@ public function receiveAction($action, $httpVars, $fileVars)
244
311
}
245
312
mkdir ($ currentDirUrl . $ onlyFileName , 0777 , true );
246
313
chmod (AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl . $ onlyFileName ), 0777 );
247
- try {
248
- $ archive = new PharData (AJXP_MetaStreamWrapper:: getRealFSReference ( $ currentAllPydioPath ));
249
- $ fichiersArchive = new RecursiveIteratorIterator ( new RecursiveDirectoryIterator ( $ pharCurrentAllPydioPath ));
250
- foreach ( $ fichiersArchive as $ file ) {
251
- $ fileGetPathName = $ file -> getPathname () ;
252
- if ( $ file -> isDir ()) {
253
- continue ;
314
+ // Builds a command that will use any parallel extraction utilities installed to extract an archive file though tar.
315
+ if ( command_exists ( " tar " )) {
316
+ if ( $ pathInfoCurrentAllPydioPath == " gz " ) {
317
+ if ( command_exists ( " pigz " ) ) {
318
+ $ tarcommand = " tar -I pigz -xf " ;
319
+ } else {
320
+ $ tarcommand = " tar -xzf " ;
254
321
}
255
- $ fileNameInArchive = substr (strstr ($ fileGetPathName , $ fileArchive ), strlen ($ fileArchive ) + 1 );
256
- try {
257
- $ archive ->extractTo (AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl . $ onlyFileName ), $ fileNameInArchive , false );
258
- } catch (Exception $ e ) {
259
- file_put_contents ($ progressExtractFileName , "Error : " . $ e ->getMessage ());
260
- throw new AJXP_Exception ($ e );
322
+ } elseif ($ pathInfoCurrentAllPydioPath == "bz2 " ) {
323
+ if (command_exists ("lbzip2 " )) {
324
+ $ tarcommand = "tar -I lbzip2 -xf " ;
325
+ } elseif (command_exists ("pbzip2 " )) {
326
+ $ tarcommand = "tar -I pbzip2 -xf " ;
327
+ } else {
328
+ $ tarcommand = "tar -xjf " ;
329
+ }
330
+ } elseif ($ pathInfoCurrentAllPydioPath == "tar " ) {
331
+ $ tarcommand = "tar -xf " ;
332
+ } else {
333
+ file_put_contents ($ progressExtractFileName , "Error : " . $ messages ["compression.15 " ]);
334
+ throw new AJXP_Exception ($ messages ["compression.15 " ]);
335
+ }
336
+ $ extractCommand = $ tarcommand . escapeshellarg (AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl . $ fileArchive )) . " -C " . escapeshellarg (AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl . $ onlyFileName ));
337
+ shell_exec ($ extractCommand );
338
+ } else {
339
+ // If tar command is not found, extract using PHP Phar instead
340
+ try {
341
+ $ archive = new PharData (AJXP_MetaStreamWrapper::getRealFSReference ($ currentAllPydioPath ));
342
+ $ fichiersArchive = new RecursiveIteratorIterator (new RecursiveDirectoryIterator ($ pharCurrentAllPydioPath ));
343
+ foreach ($ fichiersArchive as $ file ) {
344
+ $ fileGetPathName = $ file ->getPathname ();
345
+ if ($ file ->isDir ()) {
346
+ continue ;
347
+ }
348
+ $ fileNameInArchive = substr (strstr ($ fileGetPathName , $ fileArchive ), strlen ($ fileArchive ) + 1 );
349
+ try {
350
+ $ archive ->extractTo (AJXP_MetaStreamWrapper::getRealFSReference ($ currentDirUrl . $ onlyFileName ), $ fileNameInArchive , false );
351
+ } catch (Exception $ e ) {
352
+ file_put_contents ($ progressExtractFileName , "Error : " . $ e ->getMessage ());
353
+ throw new AJXP_Exception ($ e );
354
+ }
355
+ $ counterExtract ++;
356
+ file_put_contents ($ progressExtractFileName , sprintf ($ messages ["compression.13 " ], round (($ counterExtract / $ archive ->count ()) * 100 , 0 , PHP_ROUND_HALF_DOWN ) . " % " ));
261
357
}
262
- $ counterExtract ++;
263
- file_put_contents ($ progressExtractFileName , sprintf ($ messages ["compression.13 " ], round (($ counterExtract / $ archive ->count ()) * 100 , 0 , PHP_ROUND_HALF_DOWN ) . " % " ));
358
+ } catch (Exception $ e ) {
359
+ file_put_contents ($ progressExtractFileName , "Error : " . $ e ->getMessage ());
360
+ throw new AJXP_Exception ($ e );
264
361
}
265
- } catch (Exception $ e ) {
266
- file_put_contents ($ progressExtractFileName , "Error : " . $ e ->getMessage ());
267
- throw new AJXP_Exception ($ e );
362
+ // End of Phar extraction section
268
363
}
269
364
file_put_contents ($ progressExtractFileName , "SUCCESS " );
270
365
$ newNode = new AJXP_Node ($ currentDirUrl . $ onlyFileName );
@@ -309,3 +404,4 @@ public function receiveAction($action, $httpVars, $fileVars)
309
404
}
310
405
}
311
406
}
407
+
0 commit comments