diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 7829b6f1f..21e227954 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -14,9 +14,9 @@ jobs: fail-fast: false matrix: operating-system: [ ubuntu-latest ] - php-version: [ '7.4', '8.0', '8.1' ] + php-version: [ '8.1', '8.2', '8.3' ] include: - - php-version: '8.1' + - php-version: '8.3' coverage: true steps: diff --git a/composer.json b/composer.json index 60cf2854a..87f5d50cc 100755 --- a/composer.json +++ b/composer.json @@ -26,8 +26,8 @@ "require": { "oat-sa/oatbox-extension-installer": "~1.1||dev-master", "oat-sa/lib-generis-search": "^2.1.2", - "oat-sa/generis": ">=15.39.0", - "oat-sa/tao-core": ">=54.23.0", + "oat-sa/generis": ">=16.0.0", + "oat-sa/tao-core": ">=54.26.0", "oat-sa/extension-tao-item": ">=12.4.0", "oat-sa/extension-tao-itemqti": ">=30.22.0", "oat-sa/extension-tao-test": ">=16.3.0", diff --git a/model/export/service/SharedStimulusCSSExporter.php b/model/export/service/SharedStimulusCSSExporter.php index a7434f7d0..4f4e6f31f 100644 --- a/model/export/service/SharedStimulusCSSExporter.php +++ b/model/export/service/SharedStimulusCSSExporter.php @@ -23,7 +23,7 @@ namespace oat\taoMediaManager\model\export\service; use core_kernel_classes_Resource; -use League\Flysystem\FilesystemInterface; +use oat\oatbox\filesystem\FilesystemInterface; use oat\oatbox\filesystem\FileSystemService; use oat\oatbox\service\ConfigurableService; use oat\taoMediaManager\model\fileManagement\FlySystemManagement; @@ -44,11 +44,11 @@ public function pack(core_kernel_classes_Resource $mediaResource, string $link, $fs = $this->getFileSystem(); $cssPath = dirname($link) . DIRECTORY_SEPARATOR . StoreService::CSS_DIR_NAME; - if (!$fs->has($cssPath)) { + if (!$fs->directoryExists($cssPath)) { return; } - $files = $fs->listContents($cssPath); + $files = $fs->listContents($cssPath)->toArray(); if (!count($files)) { return; } @@ -56,8 +56,8 @@ public function pack(core_kernel_classes_Resource $mediaResource, string $link, $zip->addEmptyDir(self::CSS_ZIP_DIR_NAME); foreach ($files as $file) { - $content = $fs->read($cssPath . DIRECTORY_SEPARATOR . $file['basename']); - $zip->addFromString(self::CSS_ZIP_DIR_NAME . DIRECTORY_SEPARATOR . $file['basename'], $content); + $content = $fs->read($cssPath . DIRECTORY_SEPARATOR . basename($file['path'])); + $zip->addFromString(self::CSS_ZIP_DIR_NAME . DIRECTORY_SEPARATOR . basename($file['path']), $content); } } diff --git a/model/fileManagement/FlySystemManagement.php b/model/fileManagement/FlySystemManagement.php index f5eeae3fe..a3b0c6e77 100644 --- a/model/fileManagement/FlySystemManagement.php +++ b/model/fileManagement/FlySystemManagement.php @@ -23,8 +23,9 @@ namespace oat\taoMediaManager\model\fileManagement; use oat\oatbox\filesystem\File; +use oat\oatbox\filesystem\FilesystemException; +use oat\oatbox\filesystem\FilesystemInterface; use oat\oatbox\service\ConfigurableService; -use League\Flysystem\Filesystem; use Slim\Http\Stream; use Psr\Http\Message\StreamInterface; use oat\oatbox\filesystem\FileSystemService; @@ -37,7 +38,7 @@ class FlySystemManagement extends ConfigurableService implements FileManagement * @param string|File $fileSource * @param string $label * @return string - * @throws \League\Flysystem\FileExistsException + * @throws FilesystemException */ public function storeFile($fileSource, $label) { @@ -54,12 +55,23 @@ public function storeFile($fileSource, $label) public function deleteDirectory(string $directoryPath): bool { - return $this->getFilesystem()->deleteDir($directoryPath); + try { + $this->getFilesystem()->deleteDirectory($directoryPath); + return true; + } catch (FilesystemException $e) { + $this->logWarning($e->getMessage()); + return false; + } } public function getFileSize($link) { - return $this->getFilesystem()->getSize($link); + try { + return $this->getFilesystem()->fileSize($link); + } catch (FilesystemException $e) { + $this->logWarning($e->getMessage()); + return null; + } } /** @@ -89,13 +101,16 @@ public function retrieveFile($link) */ public function deleteFile($link) { - return $this->getFilesystem()->delete($link); + try { + $this->getFilesystem()->delete($link); + return true; + } catch (FilesystemException $e) { + $this->logWarning($e->getMessage()); + return false; + } } - /** - * @return Filesystem - */ - protected function getFilesystem() + protected function getFilesystem(): FilesystemInterface { $fs = $this->getServiceLocator()->get(FileSystemService::SERVICE_ID); return $fs->getFileSystem($this->getOption(self::OPTION_FS)); diff --git a/model/sharedStimulus/css/repository/StylesheetRepository.php b/model/sharedStimulus/css/repository/StylesheetRepository.php index 41dc00275..d7fd149e0 100644 --- a/model/sharedStimulus/css/repository/StylesheetRepository.php +++ b/model/sharedStimulus/css/repository/StylesheetRepository.php @@ -22,12 +22,10 @@ namespace oat\taoMediaManager\model\sharedStimulus\css\repository; -use core_kernel_classes_Resource; use oat\generis\model\data\Ontology; -use League\Flysystem\FilesystemInterface; +use oat\oatbox\filesystem\FilesystemException; +use oat\oatbox\filesystem\FilesystemInterface; use oat\oatbox\service\ConfigurableService; -use oat\taoMediaManager\model\MediaService; -use League\Flysystem\FileNotFoundException; use oat\oatbox\filesystem\FileSystemService; use oat\taoMediaManager\model\fileManagement\FlySystemManagement; use oat\taoMediaManager\model\fileManagement\FileSourceUnserializer; @@ -48,35 +46,41 @@ public function getPath(string $uri): string return dirname((string) $link); } - public function listContents(string $path): array + public function listContents(string $path): iterable { return $this->getFileSystem()->listContents($path); } /** - * @throws FileNotFoundException + * @throws FilesystemException */ public function read(string $path): string { return $this->getFileSystem()->read($path); } - public function put(string $path, string $contents): bool + /** + * @throws FilesystemException + */ + public function write(string $path, string $contents): void { - return $this->getFileSystem()->put($path, $contents); + $this->getFileSystem()->write($path, $contents); } - public function putStream(string $path, $streamResource): bool + /** + * @throws FilesystemException + */ + public function writeStream(string $path, $streamResource): void { - return $this->getFileSystem()->putStream($path, $streamResource); + $this->getFileSystem()->writeStream($path, $streamResource); } /** - * @throws FileNotFoundException + * @throws FilesystemException */ - public function delete(string $path): bool + public function delete(string $path): void { - return $this->getFileSystem()->delete($path); + $this->getFileSystem()->delete($path); } private function getFileSystem(): FilesystemInterface diff --git a/model/sharedStimulus/css/service/ListStylesheetsService.php b/model/sharedStimulus/css/service/ListStylesheetsService.php index b27c8ffcd..c139055b0 100644 --- a/model/sharedStimulus/css/service/ListStylesheetsService.php +++ b/model/sharedStimulus/css/service/ListStylesheetsService.php @@ -35,23 +35,23 @@ public function getList(ListStylesheets $listStylesheetsDTO): array $path = $stylesheetRepository->getPath($listStylesheetsDTO->getUri()); $list = $stylesheetRepository->listContents( $path . DIRECTORY_SEPARATOR . StylesheetRepository::STYLESHEETS_DIRECTORY - ); + )->toArray(); /** * here sorting files by creation date so that in case of css .selector collisions * the rules will be applied from the last stylesheet added to the passage */ usort($list, function ($a, $b) { - return ($a['timestamp'] < $b['timestamp']) ? -1 : 1; + return ($a['lastModified'] < $b['lastModified']) ? -1 : 1; }); $data = []; foreach ($list as $file) { $data[] = [ - 'name' => $file['basename'], - 'uri' => DIRECTORY_SEPARATOR . $file['basename'], + 'name' => basename($file['path']), + 'uri' => DIRECTORY_SEPARATOR . basename($file['path']), 'mime' => 'text/css', - 'filePath' => DIRECTORY_SEPARATOR . $file['basename'], - 'size' => $file['size'] + 'filePath' => DIRECTORY_SEPARATOR . basename($file['path']), + 'size' => $file['fileSize'] ]; } diff --git a/model/sharedStimulus/css/service/LoadStylesheetClassesService.php b/model/sharedStimulus/css/service/LoadStylesheetClassesService.php index 5975eccef..096369812 100644 --- a/model/sharedStimulus/css/service/LoadStylesheetClassesService.php +++ b/model/sharedStimulus/css/service/LoadStylesheetClassesService.php @@ -22,7 +22,7 @@ namespace oat\taoMediaManager\model\sharedStimulus\css\service; -use League\Flysystem\FileNotFoundException; +use oat\oatbox\filesystem\FilesystemException; use oat\oatbox\service\ConfigurableService; use oat\taoMediaManager\model\sharedStimulus\css\dto\LoadStylesheet; use oat\taoMediaManager\model\sharedStimulus\css\repository\StylesheetRepository; @@ -45,7 +45,7 @@ public function load(LoadStylesheet $loadStylesheetDTO): array ); return $this->cssToArray($content); - } catch (FileNotFoundException $e) { + } catch (FilesystemException $e) { $this->logDebug( sprintf( 'Passage %s does not contain stylesheet %s. An empty array will be returned.', diff --git a/model/sharedStimulus/css/service/SaveStylesheetClassesService.php b/model/sharedStimulus/css/service/SaveStylesheetClassesService.php index d2d81b556..04921d589 100644 --- a/model/sharedStimulus/css/service/SaveStylesheetClassesService.php +++ b/model/sharedStimulus/css/service/SaveStylesheetClassesService.php @@ -23,7 +23,7 @@ namespace oat\taoMediaManager\model\sharedStimulus\css\service; use Exception; -use League\Flysystem\FileNotFoundException; +use oat\oatbox\filesystem\FilesystemException; use oat\oatbox\service\ConfigurableService; use oat\taoMediaManager\model\sharedStimulus\css\dto\SaveStylesheetClasses; use oat\taoMediaManager\model\sharedStimulus\css\repository\StylesheetRepository; @@ -52,7 +52,7 @@ public function save(SaveStylesheetClasses $saveStylesheetClassesDTO): void } $content = $this->getCssContentFromArray($cssClassesArray); - $this->getStylesheetRepository()->put( + $this->getStylesheetRepository()->write( $path . DIRECTORY_SEPARATOR . $saveStylesheetClassesDTO->getStylesheetUri(), $content ); @@ -62,7 +62,7 @@ private function removeStoredStylesheet(string $path): void { try { $this->getStylesheetRepository()->delete($path); - } catch (FileNotFoundException $exception) { + } catch (FilesystemException $exception) { $this->logDebug(sprintf('Stylesheet %s to delete was not found when trying to clear styles', $path)); } } diff --git a/model/sharedStimulus/css/service/UploadStylesheetService.php b/model/sharedStimulus/css/service/UploadStylesheetService.php index 5a249075c..f13b86b93 100644 --- a/model/sharedStimulus/css/service/UploadStylesheetService.php +++ b/model/sharedStimulus/css/service/UploadStylesheetService.php @@ -39,7 +39,7 @@ public function save(UploadedStylesheet $uploadedStylesheetDTO): array $tmpResource = $uploadedStylesheetDTO->getFileResource(); $size = filesize($uploadedStylesheetDTO->getTmpFileLink()); - $this->getStylesheetRepository()->putStream($link, $tmpResource); + $this->getStylesheetRepository()->writeStream($link, $tmpResource); if (is_resource($tmpResource)) { fclose($tmpResource); diff --git a/model/sharedStimulus/factory/CommandFactory.php b/model/sharedStimulus/factory/CommandFactory.php index eb3484b7c..af08ef778 100644 --- a/model/sharedStimulus/factory/CommandFactory.php +++ b/model/sharedStimulus/factory/CommandFactory.php @@ -22,7 +22,6 @@ namespace oat\taoMediaManager\model\sharedStimulus\factory; -use League\Flysystem\FilesystemInterface; use oat\generis\model\fileReference\FileReferenceSerializer; use oat\oatbox\filesystem\Directory; use oat\oatbox\filesystem\FileSystemService; @@ -38,7 +37,7 @@ class CommandFactory extends ConfigurableService { public const DEFAULT_DIRECTORY = 'sharedStimulusUploads'; - /** @var FilesystemInterface */ + /** @var Directory */ private $directory; public function makeCreateCommandByRequest(ServerRequestInterface $request): CreateCommand diff --git a/model/sharedStimulus/service/PatchService.php b/model/sharedStimulus/service/PatchService.php index 9f73c1651..c6ebf7db1 100644 --- a/model/sharedStimulus/service/PatchService.php +++ b/model/sharedStimulus/service/PatchService.php @@ -26,11 +26,12 @@ use core_kernel_classes_Resource as Resource; use core_kernel_persistence_Exception; use InvalidArgumentException; -use League\Flysystem\FilesystemInterface; use LogicException; use oat\generis\model\fileReference\FileReferenceSerializer; use oat\generis\model\OntologyAwareTrait; use oat\oatbox\filesystem\File; +use oat\oatbox\filesystem\FileSystem; +use oat\oatbox\filesystem\FilesystemInterface; use oat\oatbox\filesystem\FileSystemService; use oat\oatbox\service\ConfigurableService; use oat\tao\model\media\TaoMediaException; @@ -82,7 +83,7 @@ public function patch(PatchCommand $command): SharedStimulus ); $sharedStimulusStoredSourceFile = $this->getFileSourceUnserializer()->unserialize((string)$link); - $this->getFileSystem()->putStream($sharedStimulusStoredSourceFile, $file->readStream()); + $this->getFileSystem()->writeStream($sharedStimulusStoredSourceFile, $file->readStream()); $content = $file->read(); $resource->editPropertyValues( diff --git a/model/sharedStimulus/service/StoreService.php b/model/sharedStimulus/service/StoreService.php index f2dc10bf8..602ec193f 100644 --- a/model/sharedStimulus/service/StoreService.php +++ b/model/sharedStimulus/service/StoreService.php @@ -22,8 +22,9 @@ namespace oat\taoMediaManager\model\sharedStimulus\service; -use League\Flysystem\FilesystemInterface; use oat\oatbox\filesystem\File; +use oat\oatbox\filesystem\FileSystem; +use oat\oatbox\filesystem\FilesystemInterface; use oat\oatbox\filesystem\FileSystemService; use oat\oatbox\service\ConfigurableService; use oat\taoMediaManager\model\fileManagement\FlySystemManagement; @@ -69,15 +70,15 @@ public function storeStream( $fs = $this->getFileSystem(); $dirname = $this->getUniqueName($stimulusFilename); - $fs->createDir($dirname); + $fs->createDirectory($dirname); - $fs->putStream( + $fs->writeStream( $dirname . DIRECTORY_SEPARATOR . $stimulusFilename, $stimulusXmlStream ); if (count($cssFiles)) { - $fs->createDir($dirname . DIRECTORY_SEPARATOR . self::CSS_DIR_NAME); + $fs->createDirectory($dirname . DIRECTORY_SEPARATOR . self::CSS_DIR_NAME); foreach ($cssFiles as $file) { if (!file_exists($file)) { $this->getLogger()->notice(sprintf("file %s does not exist", $file)); @@ -89,7 +90,7 @@ public function storeStream( continue; } - $fs->putStream( + $fs->writeStream( $dirname . DIRECTORY_SEPARATOR . self::CSS_DIR_NAME . DIRECTORY_SEPARATOR . basename($file), fopen($file, 'r') ); diff --git a/test/unit/model/sharedStimulus/export/SharedStimulusCSSExporterTest.php b/test/unit/model/sharedStimulus/export/SharedStimulusCSSExporterTest.php index c87c49cce..335e2c691 100644 --- a/test/unit/model/sharedStimulus/export/SharedStimulusCSSExporterTest.php +++ b/test/unit/model/sharedStimulus/export/SharedStimulusCSSExporterTest.php @@ -23,6 +23,7 @@ namespace oat\taoMediaManager\test\unit\model\export; use core_kernel_classes_Resource; +use League\Flysystem\DirectoryListing; use oat\generis\test\MockObject; use oat\generis\test\TestCase; use oat\oatbox\filesystem\FileSystem; @@ -57,12 +58,12 @@ public function tearDown(): void /** * @dataProvider packTestDataProvider */ - public function testPack(string $link, string $expectedDir, array $fileNames, array $expectedZippedFiles): void + public function testPack(string $link, string $expectedDir, iterable $fileNames, array $expectedZippedFiles): void { $fileSystemMock = $this->initFileSystemMock(); $fileSystemMock->expects(self::once()) - ->method('has') + ->method('directoryExists') ->with($expectedDir) ->willReturn(true); @@ -72,7 +73,7 @@ public function testPack(string $link, string $expectedDir, array $fileNames, ar $fileSystemMock->expects(self::once()) ->method('listContents') - ->willReturn($fileNames); + ->willReturn(new DirectoryListing($fileNames)); $sharedStimulusCSSExporterService = $this->getPreparedServiceInstance($fileSystemMock); @@ -89,7 +90,7 @@ public function packTestDataProvider(): array [ 'test_path/stimulus.xml', 'test_path/' . StoreService::CSS_DIR_NAME, - [['basename' => 'file1.css'], ['basename' => 'file2.css']], + [['path' => 'file1.css'], ['path' => 'file2.css']], [ $cssZipFolder, $cssZipFolder . 'file1.css', @@ -105,7 +106,16 @@ public function packTestDataProvider(): array [ 'test_path/stimulusFile', 'test_path/' . StoreService::CSS_DIR_NAME, - [['basename' => 'fileX']], + [['path' => 'fileX']], + [ + $cssZipFolder, + $cssZipFolder . 'fileX' + ], + ], + [ + 'test_path/stimulusFile', + 'test_path/' . StoreService::CSS_DIR_NAME, + $this->createGenerator([['path' => 'fileX']]), [ $cssZipFolder, $cssZipFolder . 'fileX' @@ -131,7 +141,7 @@ private function initFileSystemMock(): FileSystem { return $this->getMockBuilder(FileSystem::class) ->disableOriginalConstructor() - ->onlyMethods(['has', 'listContents', 'read']) + ->onlyMethods(['directoryExists', 'listContents', 'read']) ->getMock(); } @@ -159,4 +169,11 @@ private function getPreparedServiceInstance(FileSystem $fileSystemMock): SharedS ); return $service; } + + private function createGenerator(array $values): \Generator + { + foreach ($values as $value) { + yield $value; + } + } } diff --git a/test/unit/model/sharedStimulus/service/StoreServiceTest.php b/test/unit/model/sharedStimulus/service/StoreServiceTest.php index 08e934018..93e5e7808 100644 --- a/test/unit/model/sharedStimulus/service/StoreServiceTest.php +++ b/test/unit/model/sharedStimulus/service/StoreServiceTest.php @@ -54,12 +54,11 @@ public function testStoreSharedStimulus(): void $fileSystemMock = $this->initFileSystemMock(); $fileSystemMock->expects(self::once()) - ->method('createDir') + ->method('createDirectory') ->with($fakeUniqueName); $fileSystemMock->expects(self::once()) - ->method('putStream') - ->willReturn(true); + ->method('writeStream'); $stimulusStoreService = $this->getPreparedServiceInstance($fileSystemMock); $stimulusStoreService->expects(self::once()) @@ -78,7 +77,7 @@ private function initFileSystemMock(): FileSystem { return $this->getMockBuilder(FileSystem::class) ->disableOriginalConstructor() - ->onlyMethods(['createDir', 'putStream']) + ->onlyMethods(['createDirectory', 'writeStream']) ->getMock(); }