getFileSystemId(), $this->getFullPath($path)); $subDirectory->setServiceLocator($this->getServiceLocator()); return $subDirectory; } /** * Get file located into $this->directory (existing or not) * * @param $path * @return File */ public function getFile($path) { $file = new File($this->getFileSystemId(), $this->getFullPath($path)); $file->setServiceLocator($this->getServiceLocator()); return $file; } /** * Method constraints by IteratorAggregator, wrapper to getFlyIterator * * @return \ArrayIterator */ public function getIterator() { return $this->getFlyIterator(); } /** * Get an iterator of $this directory * Flags are combinable like that $this->getFlyIterator(self::ITERATOR_DIRECTORY|self::ITERATOR_DIRECTORY) * By default iterator is not recursive and includes directories & files * * @param null $flags * @return \ArrayIterator */ public function getFlyIterator($flags = null) { if (is_null($flags)) { $flags = self::ITERATOR_DIRECTORY | self::ITERATOR_FILE; } $recursive = ($flags & self::ITERATOR_RECURSIVE); $withDirectories = ($flags & self::ITERATOR_DIRECTORY); $withFiles = ($flags & self::ITERATOR_FILE); $iterator = []; $contents = $this->getFileSystem()->listContents($this->getPrefix(), $recursive); if (!empty($contents)) { $dirPath = $this->getFileSystem()->get($this->getPrefix())->getPath(); foreach ($contents as $content) { if ($withDirectories && $content['type'] == 'dir') { $iterator[] = $this->getDirectory(str_replace($dirPath, '', $content['path'])); } if ($withFiles && $content['type'] == 'file') { $iterator[] = $this->getFile(str_replace($dirPath, '', $content['path'])); } } } return new \ArrayIterator($iterator); } /** * Get relative path from $this directory to given content * * @param Directory|File $content * @return mixed * @throws \common_Exception * @throws \tao_models_classes_FileNotFoundException */ public function getRelPath($content) { if (! $content instanceof File && ! $content instanceof Directory) { throw new \common_Exception('Content for ' . __FUNCTION__ . ' has to be a file or directory object. ' . is_object($content) ? get_class($content) : gettype($content) . ' given.'); } return str_replace($this->getPrefix(), '', $content->getPrefix()); } /** * Check if current directory exists * * @return bool */ public function exists() { return $this->getFileSystem()->has($this->getPrefix()); } /** * Delete the current directory * * @return bool */ public function deleteSelf() { return $this->getFileSystem()->deleteDir($this->getPrefix()); } /** * Return a sanitized full path from main directory * * @param $path * @return string */ protected function getFullPath($path) { return $this->getPrefix() . '/' . $this->sanitizePath($path); } /** * Rename * * Rename directory into $path * * @param $path * @return bool * @throws \common_exception_FileSystemError */ public function rename($path) { // This implementation supersedes the Flysystem's one. Indeed, while using connectors // such as the Amazon S3 (v3) connector, rename on directories does not work. A custom // implementation is then needed. $contents = $this->getFileSystem()->listContents($this->getPrefix(), true); $fileSystemId = $this->getFileSystemId().'/'; // Filter files only. $filePaths = []; foreach ($contents as $content) { if ($content['type'] === 'file') { $contentPath = $content['path']; if(strpos($contentPath, $fileSystemId) === 0) { $contentPath = substr($contentPath, strlen($fileSystemId)); } $filePaths[] = [ 'source' => $contentPath, 'destination' => str_replace($this->getPrefix(), $path, $content['path'])]; } } foreach ($filePaths as $renaming) { try { if ($this->getFileSystem()->rename($renaming['source'], $renaming['destination']) === false) { throw new \common_exception_FileSystemError("Unable to rename '" . $renaming['source'] . "' into '".$renaming['destination']."'."); } } catch (FileExistsException $e) { throw new \common_exception_FileSystemError("Unable to rename '" . $renaming['source'] . "' into '".$renaming['destination']."'. File already exists."); } } if (!$this->deleteSelf()) { throw new \common_exception_FileSystemError("Could not finalize renaming of '" . $this->getPrefix() . "' into '${path}'."); } return true; } }