/**
  * 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;
 }