diff --git a/lib/Controller/ExtractionController.php b/lib/Controller/ExtractionController.php index 1d5b68b..b77b2ec 100755 --- a/lib/Controller/ExtractionController.php +++ b/lib/Controller/ExtractionController.php @@ -1,31 +1,22 @@ l = $l; $this->logger = $logger; - //$this->encryptionManager = $encryptionManager; $this->userId = $UserId; $this->extractionService = $extractionService; $this->rootFolder = $rootFolder; $this->userFolder = $this->rootFolder->getUserFolder($this->userId); } - private function getFile($directory, $fileName){ + private function getFile($directory, $fileName) + { $fileNode = $this->userFolder->get($directory . '/' . $fileName); return $fileNode->getStorage()->getLocalFile($fileNode->getInternalPath()); } @@ -75,7 +65,7 @@ private function getFile($directory, $fileName){ * * @param string $fileName The Nextcloud file name. * - * @param srting $directory The Nextcloud directory name. + * @param string $directory The Nextcloud directory name. * * @param string $extractTo The local file-system path of the directory * with the extracted data, i.e. this is the OS path. @@ -83,8 +73,8 @@ private function getFile($directory, $fileName){ * @param null|string $tmpPath The Nextcloud temporary path. This is only * non-null when extracting from external storage. */ - private function postExtract(string $fileName, string $directory, string $extractTo, ?string $tmpPath){ - + private function postExtract(string $fileName, string $directory, string $extractTo, ?string $tmpPath, string $nameOfFile) + { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($extractTo)); foreach ($iterator as $file) { /** @var \SplFileInfo $file */ @@ -96,21 +86,56 @@ private function postExtract(string $fileName, string $directory, string $extrac } $NCDestination = $directory . '/' . $fileName; - if($tmpPath != ""){ + if ($tmpPath != "") { $tmpFolder = $this->rootFolder->get($tmpPath); $tmpFolder->move($this->userFolder->getFullPath($NCDestination)); - }else{ - $scanner = new \OC\Files\Utils\Scanner($this->userId, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); - $scanner->scan($this->userFolder->getFullPath($NCDestination)); + } else { + $filePath = "$directory/$fileName"; + if($directory == "/") { + $filePath = "$nameOfFile"; + } + $info = Filesystem::getView()->getFileInfo("$filePath"); + $ownerUID = $info->getOwner()->getUID(); + if ($ownerUID != $this->userId) { + $scanner = new \OC\Files\Utils\Scanner($ownerUID, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); + $matches = preg_split("/^.*\/$ownerUID\//U", $extractTo); + $scanPath = $ownerUID . "/" . $matches[1]; + $this->logger->debug("Extracting a shared file, share owner is: $ownerUID, extracted to: $scanPath"); + $scanner->scan($scanPath); + } else { + $scanner = new \OC\Files\Utils\Scanner($this->userId, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); + $scanner->scan($this->userFolder->getFullPath($NCDestination)); + } } } + /** + * get all storages for $dir + * + * @param string $dir + * @return \OC\Files\Mount\MountPoint[] + */ + protected function getMounts($dir) + { + //TODO: move to the node based fileapi once that's done + \OC_Util::tearDownFS(); + \OC_Util::setupFS($this->user); + + $mountManager = Filesystem::getMountManager(); + $mounts = $mountManager->findIn($dir); + $mounts[] = $mountManager->find($dir); + $mounts = \array_reverse($mounts); //start with the mount of $dir + + return $mounts; + } + /** * The only AJAX callback. This is a hook for ordinary cloud-users, os no admin required. * * @NoAdminRequired */ - public function extract($nameOfFile, $directory, $external, $type){ + public function extract($nameOfFile, $directory, $external, $type) + { $this->logger->warning(\OC::$server->getEncryptionManager()->isEnabled()); if (\OC::$server->getEncryptionManager()->isEnabled()) { $response = array(); @@ -124,15 +149,14 @@ public function extract($nameOfFile, $directory, $external, $type){ $extractTo = $dir . '/' . $fileName; // if the file is un external storage - if($external){ - + if ($external) { $appPath = $this->userId . '/' . $this->appName; try { $appDirectory = $this->rootFolder->get($appPath); } catch (\OCP\Files\NotFoundException $e) { $appDirectory = $this->rootFolder->newFolder($appPath); } - if(pathinfo($fileName, PATHINFO_EXTENSION) == "tar"){ + if (pathinfo($fileName, PATHINFO_EXTENSION) == "tar") { $archiveDir = pathinfo($fileName, PATHINFO_FILENAME); } else { $archiveDir = $fileName; @@ -150,33 +174,33 @@ public function extract($nameOfFile, $directory, $external, $type){ } else { $tmpPath = ""; } - + switch ($type) { case 'zip': - $response = $this->extractionService->extractZip($file, $fileName, $extractTo); + $response = $this->extractionService->extractZip($file, $extractTo); break; case 'rar': - $response = $this->extractionService->extractRar($file, $fileName, $extractTo); + $response = $this->extractionService->extractRar($file, $extractTo); break; default: // Check if the file is .tar.gz in order to do the extraction on a single step - if(pathinfo($fileName, PATHINFO_EXTENSION) == "tar"){ + if (pathinfo($fileName, PATHINFO_EXTENSION) == "tar") { $cleanFileName = pathinfo($fileName, PATHINFO_FILENAME); $extractTo = dirname($extractTo) . '/' . $cleanFileName; $response = $this->extractionService->extractOther($file, $cleanFileName, $extractTo); $file = $extractTo . '/' . pathinfo($file, PATHINFO_FILENAME); $fileName = $cleanFileName; - $response = $this->extractionService->extractOther($file, $fileName, $extractTo); + $response = $this->extractionService->extractOther($file, $extractTo); // remove .tar file unlink($file); - }else{ - $response = $this->extractionService->extractOther($file, $fileName, $extractTo); + } else { + $response = $this->extractionService->extractOther($file, $extractTo); } break; } - $this->postExtract($fileName, $directory, $extractTo, $tmpPath); + $this->postExtract($fileName, $directory, $extractTo, $tmpPath, $nameOfFile); return new DataResponse($response); } diff --git a/lib/Service/ExtractionService.php b/lib/Service/ExtractionService.php index c6b4377..aef727c 100755 --- a/lib/Service/ExtractionService.php +++ b/lib/Service/ExtractionService.php @@ -1,4 +1,5 @@ @@ -26,9 +27,9 @@ use OCP\IL10N; use ZipArchive; -use Rar; -class ExtractionService { +class ExtractionService +{ /** @var IL10N */ private $l; @@ -37,47 +38,51 @@ class ExtractionService { private $logger; public function __construct( - IL10N $l - , ILogger $logger + IL10N $l, + ILogger $logger ) { $this->l = $l; $this->logger = $logger; } - public function extractZip($file, $filename, $extractTo){ + public function extractZip($file, $extractTo) + { $response = array(); - if (!extension_loaded("zip")){ + if (!extension_loaded("zip")) { $response = array_merge($response, array("code" => 0, "desc" => $this->l->t("Zip extension is not available"))); return $response; } $zip = new ZipArchive(); - if (!$zip->open($file) === TRUE){ + if (!$zip->open($file) === TRUE) { $response = array_merge($response, array("code" => 0, "desc" => $this->l->t("Cannot open Zip file"))); return $response; } - $zip->extractTo($extractTo); + $success = $zip->extractTo($extractTo); $zip->close(); $response = array_merge($response, array("code" => 1)); return $response; } - public function extractRar($file, $filename, $extractTo){ + public function extractRar($file, $extractTo) + { $response = array(); - if (!extension_loaded("rar")){ - exec('unrar x ' .escapeshellarg($file). ' -R ' .escapeshellarg($extractTo). '/ -o+',$output,$return); - if(sizeof($output) <= 4){ - $response = array_merge($response, array("code" => 0, "desc" => $this->l->t("Oops something went wrong. Check that you have rar extension or unrar installed"))); - return $response; - } - }else{ + if (!extension_loaded("rar")) { + $output = []; + $return = -1; + exec('unrar x ' . escapeshellarg($file) . ' -R ' . escapeshellarg($extractTo) . '/ -o+', $output, $return); + if (sizeof($output) <= 4) { + $response = array_merge($response, array("code" => 0, "desc" => $this->l->t("Oops something went wrong. Check that you have rar extension or unrar installed"))); + return $response; + } + } else { $rar_file = rar_open($file); $list = rar_list($rar_file); - foreach($list as $archive_file) { + foreach ($list as $archive_file) { $entry = rar_entry_get($rar_file, $archive_file->getName()); $entry->extract($extractTo); } @@ -88,14 +93,16 @@ public function extractRar($file, $filename, $extractTo){ return $response; } - public function extractOther($file, $filename, $extractTo){ + public function extractOther($file, $extractTo) + { $response = array(); + $output = []; + $return = -1; + exec('7za -y x ' . escapeshellarg($file) . ' -o' . escapeshellarg($extractTo), $output, $return); - exec('7za -y x ' .escapeshellarg($file). ' -o' .escapeshellarg($extractTo),$output,$return); - - if(sizeof($output) <= 5){ + if (sizeof($output) <= 5) { $response = array_merge($response, array("code" => 0, "desc" => $this->l->t("Oops something went wrong. Check that you have p7zip installed"))); - $this->logger->error(__METHOD__ . ': ' . $output); + $this->logger->error(__METHOD__ . ': ' . print_r($output, true)); return $response; } $response = array_merge($response, array("code" => 1));