diff --git a/composer.json b/composer.json index 6f7ca653e..4a0609e46 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,7 @@ "oat-sa/oatbox-extension-installer": "~1.1||dev-master", "naneau/semver": "~0.0.7", "oat-sa/generis": ">=15.39.0", - "oat-sa/tao-core": ">=54.23.0", + "oat-sa/tao-core": ">=54.25.0", "oat-sa/extension-tao-item": ">=12.4.0", "oat-sa/extension-tao-test": ">=16.3.0" }, diff --git a/model/Translation/Service/ResourceTranslatableStatusHandler.php b/model/Translation/Service/ResourceTranslatableStatusHandler.php new file mode 100644 index 000000000..2fbc0bd0b --- /dev/null +++ b/model/Translation/Service/ResourceTranslatableStatusHandler.php @@ -0,0 +1,65 @@ +qtiItemService = $qtiItemService; + $this->logger = $logger; + $this->ontology = $ontology; + } + + public function __invoke(ResourceTranslatableStatus $status): void + { + try { + $item = $this->ontology->getResource($status->getUri()); + + $itemData = $this->qtiItemService->getDataItemByRdfItem($item); + + $status->setEmpty(!$itemData || $itemData->isEmpty()); + } catch (Throwable $exception) { + $this->logger->error( + sprintf( + 'An error occurred while retrieving item data: %s. Trace: %s', + $exception->getMessage(), + $exception->getTraceAsString() + ) + ); + + throw $exception; + } + } +} diff --git a/model/Translation/ServiceProvider/TranslationServiceProvider.php b/model/Translation/ServiceProvider/TranslationServiceProvider.php index eb88f2ca0..ec2de7085 100644 --- a/model/Translation/ServiceProvider/TranslationServiceProvider.php +++ b/model/Translation/ServiceProvider/TranslationServiceProvider.php @@ -27,12 +27,14 @@ use oat\oatbox\log\LoggerService; use oat\tao\model\TaoOntology; use oat\tao\model\Translation\Service\ResourceLanguageRetriever; +use oat\tao\model\Translation\Service\ResourceTranslatableStatusRetriever; use oat\tao\model\Translation\Service\TranslationCreationService; use oat\tao\model\Translation\Service\TranslationUniqueIdSetter; use oat\taoQtiItem\model\qti\Identifier\Service\QtiIdentifierSetter; use oat\taoQtiItem\model\qti\Service; use oat\taoQtiItem\model\Translation\Service\QtiLanguageRetriever; use oat\taoQtiItem\model\Translation\Service\QtiLanguageSetter; +use oat\taoQtiItem\model\Translation\Service\ResourceTranslatableStatusHandler; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use tao_models_classes_LanguageService; @@ -70,6 +72,14 @@ public function __invoke(ContainerConfigurator $configurator): void service(tao_models_classes_LanguageService::class), ]); + $services + ->set(ResourceTranslatableStatusHandler::class, ResourceTranslatableStatusHandler::class) + ->args([ + service(Service::class), + service(LoggerService::SERVICE_ID), + service(Ontology::SERVICE_ID), + ]); + $services ->get(TranslationUniqueIdSetter::class) ->call( @@ -96,5 +106,15 @@ public function __invoke(ContainerConfigurator $configurator): void service(TranslationUniqueIdSetter::class), ] ); + + $services + ->get(ResourceTranslatableStatusRetriever::class) + ->call( + 'addCallable', + [ + TaoOntology::CLASS_URI_ITEM, + service(ResourceTranslatableStatusHandler::class), + ] + ); } } diff --git a/model/qti/Item.php b/model/qti/Item.php index 9e74a407e..6b0e70625 100755 --- a/model/qti/Item.php +++ b/model/qti/Item.php @@ -759,4 +759,9 @@ public function validateOutcomes() throw new \Exception('ExternalScored attribute is not allowed for multiple outcomes in item'); } } + + public function isEmpty(): bool + { + return empty($this->getBody()) || strpos((string)$this->getBody(), '
item = $this->createMock(core_kernel_classes_Resource::class); + $this->item + ->method('getUri') + ->willReturn('itemUri'); + + $this->qtiItemService = $this->createMock(Service::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->ontology = $this->createMock(Ontology::class); + + $this->status = new ResourceTranslatableStatus( + 'itemUri', + TaoOntology::CLASS_URI_ITEM, + 'languageUri', + true, + true + ); + + $this->sut = new ResourceTranslatableStatusHandler( + $this->qtiItemService, + $this->logger, + $this->ontology + ); + } + + public function testWillSetEmptyToFalseIfItemHasContent(): void + { + $itemData = $this->createMock(Item::class); + $itemData + ->expects($this->once()) + ->method('isEmpty') + ->willReturn(false); + + $this->ontology + ->expects($this->once()) + ->method('getResource') + ->with('itemUri') + ->willReturn($this->item); + + $this->qtiItemService + ->expects($this->once()) + ->method('getDataItemByRdfItem') + ->with($this->item) + ->willReturn($itemData); + + $this->assertTrue($this->status->isEmpty()); + + $this->sut->__invoke($this->status); + + $this->assertFalse($this->status->isEmpty()); + } + + public function testWillSetEmptyToTrueIfItemHasEmptyContentSaved(): void + { + $itemData = $this->createMock(Item::class); + $itemData + ->expects($this->once()) + ->method('isEmpty') + ->willReturn(true); + + $this->ontology + ->expects($this->once()) + ->method('getResource') + ->with('itemUri') + ->willReturn($this->item); + + $this->qtiItemService + ->expects($this->once()) + ->method('getDataItemByRdfItem') + ->with($this->item) + ->willReturn($itemData); + + $this->sut->__invoke($this->status); + + $this->assertTrue($this->status->isEmpty()); + } + + public function testWillSetEmptyToTrueIfItemHasNoContent(): void + { + $this->ontology + ->expects($this->once()) + ->method('getResource') + ->with('itemUri') + ->willReturn($this->item); + + $this->qtiItemService + ->expects($this->once()) + ->method('getDataItemByRdfItem') + ->with($this->item) + ->willReturn(null); + + $this->sut->__invoke($this->status); + + $this->assertTrue($this->status->isEmpty()); + } +}