/** * Create a tar archive. * @param $targetPath string * @param $targetFile string * @param $sourceFiles array */ function tarFiles($targetPath, $targetFile, $sourceFiles) { assert($this->_checkedForTar); // GZip compressed result file. $tarCommand = Config::getVar('cli', 'tar'); // Cygwin compatibility. $cygwin = Config::getVar('cli', 'cygwin'); if (is_executable($cygwin)) { $targetPath = cygwinConversion($targetPath); $targetFile = cygwinConversion($targetFile); } $tarCommand .= ' -czf ' . escapeshellarg($targetFile); if (!Core::isWindows()) { // Do not reveal our webserver user by forcing root as owner. $tarCommand .= ' --owner 0 --group 0'; } // Do not reveal our internal export path by exporting only relative filenames. $tarCommand .= ' -C ' . escapeshellarg($targetPath) . ' --'; // Add each file individually so that other files in the directory // will not be included. $dirSep = $cygwin ? '/' : DIRECTORY_SEPARATOR; foreach ($sourceFiles as $sourceFile) { if ($cygwin) { $sourceFile = cygwinConversion($sourceFile); } assert(dirname($sourceFile) . $dirSep === $targetPath); if (dirname($sourceFile) . $dirSep !== $targetPath) { continue; } $tarCommand .= ' ' . escapeshellarg(basename($sourceFile)); } // Execute the command. if ($cygwin) { $tarCommand = $cygwin . " --login -c '" . $tarCommand . "'"; } exec($tarCommand, $dummy, $returnStatus); assert($returnStatus === 0); }
/** * Recursively unpack the given tar file * and return its contents as an array. * @param $tarFile string * @return array */ protected function extractTarFile($tarFile) { $tarBinary = Config::getVar('cli', 'tar'); // Cygwin compat. $cygwin = Config::getVar('cli', 'cygwin'); // Make sure we got the tar binary installed. self::assertTrue(!empty($tarBinary) && is_executable($tarBinary) || is_executable($cygwin), 'tar must be installed'); // Create a temporary directory. do { $tempdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5(time() . mt_rand()); } while (file_exists($tempdir)); $fileManager = new FileManager(); $fileManager->mkdir($tempdir); // Extract the tar to the temporary directory. if ($cygwin) { $tarCommand = $cygwin . " --login -c '" . $tarBinary . ' -C ' . escapeshellarg(cygwinConversion($tempdir)) . ' -xzf ' . escapeshellarg(cygwinConversion($tarFile)) . "'"; } else { $tarCommand = $tarBinary . ' -C ' . escapeshellarg($tempdir) . ' -xzf ' . escapeshellarg($tarFile); } exec($tarCommand); // Read the results into an array. $result = array(); foreach (glob($tempdir . DIRECTORY_SEPARATOR . '*.{tar.gz,xml}', GLOB_BRACE) as $extractedFile) { if (substr($extractedFile, -4) == '.xml') { // Read the XML file into the result array. $result[basename($extractedFile)] = file_get_contents($extractedFile); } else { // Recursively extract tar files. $result[basename($extractedFile)] = $this->extractTarFile($extractedFile); } unlink($extractedFile); } rmdir($tempdir); ksort($result); return $result; }