/** * Extracts the compressed file and copies the files from the root directory * only if the compressed file contains a single directory. * @param string $file Compressed file. * @param string $path Destination path. * @param Format\FormatInterface $format Format. * * @throws Exception\IO\Input\FileEmptyException * @throws Exception\IO\Input\FileFormatNotSupportedException * @throws Exception\IO\Input\FileNotFoundException * @throws Exception\IO\Input\FileNotReadableException * @throws Exception\IO\Output\NotSingleDirectoryException * @throws Exception\IO\Output\TargetDirectoryNotWritableException * * @return bool */ public function extractWithoutRootDirectory($file, $path, FormatInterface $format = null) { $this->initializeIfNotInitialized(); // extract to a temporary place $tempDirectory = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid(time()) . DIRECTORY_SEPARATOR; $this->extract($file, $tempDirectory, $format); // move directory $iterator = new \FilesystemIterator($tempDirectory, \FilesystemIterator::SKIP_DOTS); $hasSingleRootDirectory = true; $singleRootDirectoryName = null; $numberDirectories = 0; while ($iterator->valid() && $hasSingleRootDirectory) { $uncompressedResource = $iterator->current(); if (false === $uncompressedResource->isDir()) { $hasSingleRootDirectory = false; } $singleRootDirectoryName = $uncompressedResource->getRealPath(); $numberDirectories++; if ($numberDirectories > 1) { $hasSingleRootDirectory = false; } $iterator->next(); } if (false === $hasSingleRootDirectory) { // it is not a compressed file with a single directory $this->filesystem->remove($tempDirectory); throw new Exception\IO\Output\NotSingleDirectoryException($file); } $this->filesystem->remove($path); $this->filesystem->rename($singleRootDirectoryName, $path); return true; }