From 9baafd9ac5836189fd810ee789c92ab2e56a280c Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Fri, 2 Aug 2024 09:30:34 +0300 Subject: [PATCH 1/9] feat: overwrite test by URI during QTI import --- actions/class.RestQtiTests.php | 57 ++++++++++---------- doc/swagger.json | 8 +-- models/classes/class.CrudQtiTestsService.php | 5 +- models/classes/class.QtiTestService.php | 31 +++-------- models/classes/import/QtiTestImporter.php | 28 +++++----- models/classes/tasks/ImportQtiTest.php | 12 ++--- 6 files changed, 63 insertions(+), 78 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index 447d5c51c7..859f508244 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -38,7 +38,7 @@ class taoQtiTest_actions_RestQtiTests extends AbstractRestQti private const PARAM_TEST_URI = 'testUri'; private const ITEM_CLASS_URI = 'itemClassUri'; - private const OVERWRITE_TEST = 'overwriteTest'; + private const OVERWRITE_TEST_URI = 'overwriteTestUri'; /** * @throws common_exception_NotImplemented @@ -98,7 +98,7 @@ public function import() $this->isMetadataValidatorsEnabled(), $this->isItemMustExistEnabled(), $this->isItemMustBeOverwrittenEnabled(), - $this->isOverwriteTest(), + $this->getOverwriteTestUri(), $this->getItemClassUri() ); @@ -117,9 +117,9 @@ public function import() } return $this->returnSuccess($data); } else { - throw new \common_exception_RestApi($report->getMessage()); + throw new common_exception_RestApi($report->getMessage()); } - } catch (\common_exception_RestApi $e) { + } catch (common_exception_RestApi $e) { return $this->returnFailure($e); } } @@ -129,26 +129,6 @@ protected function getItemClassUri(): ?string return $this->getPostParameter(self::ITEM_CLASS_URI); } - /** - * @throws common_exception_RestApi - */ - protected function isOverwriteTest(): bool - { - $isOverwriteTest = $this->getPostParameter(self::OVERWRITE_TEST); - - if (is_null($isOverwriteTest)) { - return false; - } - - if (!in_array($isOverwriteTest, ['true', 'false'])) { - throw new \common_exception_RestApi( - 'isOverwriteTest parameter should be boolean (true or false).' - ); - } - - return filter_var($isOverwriteTest, FILTER_VALIDATE_BOOLEAN); - } - /** * @inheritdoc */ @@ -175,7 +155,7 @@ public function importDeferred() $this->isMetadataValidatorsEnabled(), $this->isItemMustExistEnabled(), $this->isItemMustBeOverwrittenEnabled(), - $this->isOverwriteTest(), + $this->getOverwriteTestUri(), $this->getItemClassUri() ); @@ -191,7 +171,7 @@ public function importDeferred() } return $this->returnSuccess($result); - } catch (\common_exception_RestApi $e) { + } catch (common_exception_RestApi $e) { return $this->returnFailure($e); } } @@ -295,16 +275,37 @@ private function getUploadedPackageData() $mimeType = tao_helpers_File::getMimeType($fileData['tmp_name']); if (!in_array($mimeType, self::$accepted_types)) { - throw new \common_exception_RestApi(__('Wrong file mime type')); + throw new common_exception_RestApi(__('Wrong file mime type')); } return $fileData; } + /** + * @return string|null + * @throws common_exception_RestApi + */ + private function getOverwriteTestUri(): ?string + { + $overwriteTestUri = $this->getPostParameter(self::OVERWRITE_TEST_URI); + + if (is_null($overwriteTestUri)) { + return null; + } + + if (!is_string($overwriteTestUri)) { + throw new common_exception_RestApi( + sprintf('%s parameter should be string', self::OVERWRITE_TEST_URI) + ); + } + + return $overwriteTestUri; + } + /** * Get class instance to import test - * @throws \common_exception_RestApi * @return \core_kernel_classes_Class + *@throws common_exception_RestApi */ private function getTestClass() { diff --git a/doc/swagger.json b/doc/swagger.json index fc068710b9..882aae9e63 100644 --- a/doc/swagger.json +++ b/doc/swagger.json @@ -212,9 +212,9 @@ "required": false }, { - "name": "overwriteTest", + "name": "overwriteTestUri", "in": "formData", - "description": "Flag that indicates if already existed tests and all related items are removed in a case they have the same title and class as uploaded tests. Can be used to replace existing test and avoid creating a new one with the same title and class. 'true' value counts as true, 'false' as false", + "description": "Test URI, that can be used to replace existing test and avoid creating a new one with the same title and class", "type": "string", "required": false }, @@ -351,9 +351,9 @@ "required": false }, { - "name": "overwriteTest", + "name": "overwriteTestUri", "in": "formData", - "description": "Flag that indicates if already existed tests and all related items are removed in a case they have the same title and class as uploaded tests. Can be used to replace existing test and avoid creating a new one with the same title and class. 'true' value counts as true, 'false' as false", + "description": "Test URI, that can be used to replace existing test and avoid creating a new one with the same title and class", "type": "string", "required": false }, diff --git a/models/classes/class.CrudQtiTestsService.php b/models/classes/class.CrudQtiTestsService.php index ad6febddf4..45c9c73b93 100644 --- a/models/classes/class.CrudQtiTestsService.php +++ b/models/classes/class.CrudQtiTestsService.php @@ -66,7 +66,7 @@ public function importQtiTest( $enableMetadataValidators = true, $itemMustExist = false, $itemMustBeOverwritten = false, - bool $overwriteTest = false, + ?string $overwriteTestUri = null, ?string $itemClassUri = null ) { try { @@ -91,8 +91,9 @@ public function importQtiTest( $importer->enableItemMustBeOverwritten(); } - $report = $importer->importMultipleTests($class, $uploadedFile, $overwriteTest, $itemClassUri); + $report = $importer->importMultipleTests($class, $uploadedFile, $overwriteTestUri, $itemClassUri); helpers_TimeOutHelper::reset(); + return $report; } catch (common_exception_UserReadableException $e) { return new common_report_Report(common_report_Report::TYPE_ERROR, __($e->getUserMessage())); diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index e24ad3d4d6..5f81a9e864 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -354,7 +354,7 @@ private function generateIdentifier(XmlDocument $doc, $qtiType, $offset = 1) public function importMultipleTests( core_kernel_classes_Class $targetClass, $file, - bool $overwriteTest = false, + ?string $overwriteTestUri = null, ?string $itemClassUri = null, array $form = [] ) { @@ -423,7 +423,7 @@ public function importMultipleTests( $qtiManifestParser, $folder, $alreadyImportedQtiResources, - $overwriteTest, + $overwriteTestUri, $itemClassUri, !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false ); @@ -544,7 +544,7 @@ protected function importTest( taoQtiTest_models_classes_ManifestParser $manifestParser, $folder, array $ignoreQtiResources = [], - bool $overwriteTest = false, + ?string $overwriteTestUri = null, ?string $itemClassUri = null, bool $importMetadata = false ) { @@ -623,7 +623,7 @@ protected function importTest( $testDefinition->includeAssessmentSectionRefs(true); $testLabel = $testDefinition->getDocumentComponent()->getTitle(); - if ($overwriteTest) { + if ($overwriteTestUri) { $itemsClassLabel = $testLabel; /** @var oat\taoQtiItem\model\qti\metadata\simple\SimpleMetadataValue $m */ foreach ($reportCtx->testMetadata as $singleMetadata) { @@ -632,7 +632,8 @@ protected function importTest( } } - $this->deleteTestsFromClassByLabel($testLabel, $itemsClassLabel, $testClass, $itemParentClass); + $this->getTestService()->deleteTest(new core_kernel_classes_Resource($overwriteTestUri)); + $this->deleteItemSubclassesByLabel($itemParentClass, $itemsClassLabel); } $targetItemClass = $itemParentClass->createSubClass(self::IN_PROGRESS_LABEL); @@ -905,26 +906,6 @@ protected function importTest( return $report; } - /** - * @throws common_Exception - */ - private function deleteTestsFromClassByLabel( - string $testLabel, - string $itemsClassLabel, - core_kernel_classes_Resource $testClass, - core_kernel_classes_Class $itemClass - ): void { - $testService = $this->getTestService(); - - $this->deleteItemSubclassesByLabel($itemClass, $itemsClassLabel); - - foreach ($testClass->getInstances() as $testInstance) { - if ($testInstance->getLabel() === $testLabel) { - $testService->deleteTest($testInstance); - } - } - } - /** * Import the Test itself by importing its QTI-XML definition into the system, after * the QTI Items composing the test were also imported. diff --git a/models/classes/import/QtiTestImporter.php b/models/classes/import/QtiTestImporter.php index 2ac11f7429..1fd5bb6c28 100644 --- a/models/classes/import/QtiTestImporter.php +++ b/models/classes/import/QtiTestImporter.php @@ -15,14 +15,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Copyright (c) 2017 (original work) Open Assessment Technologies SA; + * Copyright (c) 2017-2024 (original work) Open Assessment Technologies SA; * */ namespace oat\taoQtiTest\models\import; +use common_report_Report; +use core_kernel_classes_Class; use oat\oatbox\filesystem\File; use oat\taoTests\models\import\AbstractTestImporter; +use taoQtiTest_models_classes_CrudQtiTestsService; /** * Class QtiTestImport @@ -35,32 +38,33 @@ class QtiTestImporter extends AbstractTestImporter /** * @param File $file - * @param \core_kernel_classes_Class $class + * @param core_kernel_classes_Class|null $class * @param bool $enableMetadataGuardians * @param bool $enableValidators * @param bool $itemMustExist * @param bool $itemMustBeOverwritten - * @return \common_report_Report + * @param string|null $overwriteTestUri + * @param string|null $itemClassUri + * @return common_report_Report */ public function import( File $file, - \core_kernel_classes_Class $class = null, - $enableMetadataGuardians = true, - $enableValidators = true, - $itemMustExist = false, - $itemMustBeOverwritten = false, - bool $overwriteTest = false, + core_kernel_classes_Class $class = null, + bool $enableMetadataGuardians = true, + bool $enableValidators = true, + bool $itemMustExist = false, + bool $itemMustBeOverwritten = false, + ?string $overwriteTestUri = null, ?string $itemClassUri = null ) { - $service = \taoQtiTest_models_classes_CrudQtiTestsService::singleton(); - return $service->importQtiTest( + return taoQtiTest_models_classes_CrudQtiTestsService::singleton()->importQtiTest( $file, $class, $enableMetadataGuardians, $enableValidators, $itemMustExist, $itemMustBeOverwritten, - $overwriteTest, + $overwriteTestUri, $itemClassUri ); } diff --git a/models/classes/tasks/ImportQtiTest.php b/models/classes/tasks/ImportQtiTest.php index 14cdcb9323..8cb1f903f4 100644 --- a/models/classes/tasks/ImportQtiTest.php +++ b/models/classes/tasks/ImportQtiTest.php @@ -15,9 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Copyright (c) 2016-2018 (original work) Open Assessment Technologies SA; - * - * + * Copyright (c) 2016-2024 (original work) Open Assessment Technologies SA; */ namespace oat\taoQtiTest\models\tasks; @@ -52,7 +50,7 @@ class ImportQtiTest extends AbstractTaskAction implements \JsonSerializable public const PARAM_ITEM_MUST_EXIST = 'item_must_exist'; public const PARAM_ITEM_MUST_BE_OVERWRITTEN = 'item_must_be_overwritten'; public const PARAM_ITEM_CLASS_URI = 'item_class_uri'; - public const PARAM_OVERWRITE_TEST = 'overwrite_test'; + public const PARAM_OVERWRITE_TEST_URI = 'overwrite_test_uri'; protected $service; @@ -90,7 +88,7 @@ public function __invoke($params) $params[self::PARAM_ENABLE_VALIDATORS] ?? true, $params[self::PARAM_ITEM_MUST_EXIST] ?? false, $params[self::PARAM_ITEM_MUST_BE_OVERWRITTEN] ?? false, - $params[self::PARAM_OVERWRITE_TEST] ?? false, + $params[self::PARAM_OVERWRITE_TEST_URI] ?? null, $params[self::PARAM_ITEM_CLASS_URI] ?? false ); @@ -123,7 +121,7 @@ public static function createTask( $enableValidators = true, $itemMustExist = false, $itemMustBeOverwritten = false, - $overwriteTest = false, + ?string $overwriteTestUri = null, ?string $itemClassUri = null ) { $action = new self(); @@ -143,7 +141,7 @@ public static function createTask( self::PARAM_ENABLE_VALIDATORS => $enableValidators, self::PARAM_ITEM_MUST_EXIST => $itemMustExist, self::PARAM_ITEM_MUST_BE_OVERWRITTEN => $itemMustBeOverwritten, - self::PARAM_OVERWRITE_TEST => $overwriteTest, + self::PARAM_OVERWRITE_TEST_URI => $overwriteTestUri, self::PARAM_ITEM_CLASS_URI => $itemClassUri, ], __('Import QTI TEST into "%s"', $class->getLabel()) From 1bdcdeeb6666ce6c31aa8e26dcdd0a5ea07f8ae2 Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Mon, 5 Aug 2024 10:25:34 +0300 Subject: [PATCH 2/9] chore: rollback old parameter to avoid breaking changes --- actions/class.RestQtiTests.php | 36 ++++++++++++++++++-- models/classes/class.CrudQtiTestsService.php | 13 +++++-- models/classes/class.QtiTestService.php | 36 +++++++++++++++----- models/classes/import/QtiTestImporter.php | 13 ++++--- models/classes/tasks/ImportQtiTest.php | 16 ++++++--- 5 files changed, 91 insertions(+), 23 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index 859f508244..d875f78c8d 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -35,9 +35,17 @@ class taoQtiTest_actions_RestQtiTests extends AbstractRestQti { public const PARAM_PACKAGE_NAME = 'qtiPackage'; + private const PARAM_TEST_URI = 'testUri'; private const ITEM_CLASS_URI = 'itemClassUri'; + + /** + * @deprecated Use taoQtiTest_actions_RestQtiTests::OVERWRITE_TEST_URI instead with the URI of the test to be + * replaced + */ + private const OVERWRITE_TEST = 'overwriteTest'; + private const OVERWRITE_TEST_URI = 'overwriteTestUri'; /** @@ -98,8 +106,9 @@ public function import() $this->isMetadataValidatorsEnabled(), $this->isItemMustExistEnabled(), $this->isItemMustBeOverwrittenEnabled(), + $this->isOverwriteTest(), + $this->getItemClassUri(), $this->getOverwriteTestUri(), - $this->getItemClassUri() ); if ($report->getType() === common_report_Report::TYPE_SUCCESS) { @@ -129,6 +138,26 @@ protected function getItemClassUri(): ?string return $this->getPostParameter(self::ITEM_CLASS_URI); } + /** + * @throws common_exception_RestApi + */ + protected function isOverwriteTest(): bool + { + $isOverwriteTest = $this->getPostParameter(self::OVERWRITE_TEST); + + if (is_null($isOverwriteTest)) { + return false; + } + + if (!in_array($isOverwriteTest, ['true', 'false'])) { + throw new \common_exception_RestApi( + 'isOverwriteTest parameter should be boolean (true or false).' + ); + } + + return filter_var($isOverwriteTest, FILTER_VALIDATE_BOOLEAN); + } + /** * @inheritdoc */ @@ -155,8 +184,9 @@ public function importDeferred() $this->isMetadataValidatorsEnabled(), $this->isItemMustExistEnabled(), $this->isItemMustBeOverwrittenEnabled(), - $this->getOverwriteTestUri(), - $this->getItemClassUri() + $this->isOverwriteTest(), + $this->getItemClassUri(), + $this->getOverwriteTestUri() ); $result = [ diff --git a/models/classes/class.CrudQtiTestsService.php b/models/classes/class.CrudQtiTestsService.php index 45c9c73b93..b70c4d1b8c 100644 --- a/models/classes/class.CrudQtiTestsService.php +++ b/models/classes/class.CrudQtiTestsService.php @@ -66,8 +66,9 @@ public function importQtiTest( $enableMetadataValidators = true, $itemMustExist = false, $itemMustBeOverwritten = false, - ?string $overwriteTestUri = null, - ?string $itemClassUri = null + bool $overwriteTest = false, + ?string $itemClassUri = null, + ?string $overwriteTestUri = null ) { try { //The zip extraction is a long process that can exceed the 30s timeout @@ -91,7 +92,13 @@ public function importQtiTest( $importer->enableItemMustBeOverwritten(); } - $report = $importer->importMultipleTests($class, $uploadedFile, $overwriteTestUri, $itemClassUri); + $report = $importer->importMultipleTests( + $class, + $uploadedFile, + $overwriteTest, + $itemClassUri, + $overwriteTestUri + ); helpers_TimeOutHelper::reset(); return $report; diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index 5f81a9e864..3fcee714c0 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -354,9 +354,10 @@ private function generateIdentifier(XmlDocument $doc, $qtiType, $offset = 1) public function importMultipleTests( core_kernel_classes_Class $targetClass, $file, - ?string $overwriteTestUri = null, + bool $overwriteTest = false, ?string $itemClassUri = null, - array $form = [] + array $form = [], + ?string $overwriteTestUri = null ) { $testClass = $targetClass; $report = new common_report_Report(common_report_Report::TYPE_INFO); @@ -423,9 +424,10 @@ public function importMultipleTests( $qtiManifestParser, $folder, $alreadyImportedQtiResources, - $overwriteTestUri, + $overwriteTest, $itemClassUri, - !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false + !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false, + $overwriteTestUri, ); $report->add($importTestReport); @@ -544,9 +546,10 @@ protected function importTest( taoQtiTest_models_classes_ManifestParser $manifestParser, $folder, array $ignoreQtiResources = [], - ?string $overwriteTestUri = null, + bool $overwriteTest = false, ?string $itemClassUri = null, - bool $importMetadata = false + bool $importMetadata = false, + ?string $overwriteTestUri = null ) { /** @var ImportService $itemImportService */ $itemImportService = $this->getServiceLocator()->get(ImportService::SERVICE_ID); @@ -623,8 +626,9 @@ protected function importTest( $testDefinition->includeAssessmentSectionRefs(true); $testLabel = $testDefinition->getDocumentComponent()->getTitle(); - if ($overwriteTestUri) { + if ($overwriteTestUri || $overwriteTest) { $itemsClassLabel = $testLabel; + /** @var oat\taoQtiItem\model\qti\metadata\simple\SimpleMetadataValue $m */ foreach ($reportCtx->testMetadata as $singleMetadata) { if (($singleMetadata->getPath()[1] ?? '') === RDFS_LABEL) { @@ -632,8 +636,10 @@ protected function importTest( } } - $this->getTestService()->deleteTest(new core_kernel_classes_Resource($overwriteTestUri)); $this->deleteItemSubclassesByLabel($itemParentClass, $itemsClassLabel); + $overwriteTestUri + ? $this->getTestService()->deleteTest(new core_kernel_classes_Resource($overwriteTestUri)) + : $this->deleteTestsFromClassByLabel($testLabel, $testClass); } $targetItemClass = $itemParentClass->createSubClass(self::IN_PROGRESS_LABEL); @@ -906,6 +912,20 @@ protected function importTest( return $report; } + /** + * @throws common_Exception + */ + private function deleteTestsFromClassByLabel(string $testLabel, core_kernel_classes_Resource $testClass): void + { + $testService = $this->getTestService(); + + foreach ($testClass->getInstances() as $testInstance) { + if ($testInstance->getLabel() === $testLabel) { + $testService->deleteTest($testInstance); + } + } + } + /** * Import the Test itself by importing its QTI-XML definition into the system, after * the QTI Items composing the test were also imported. diff --git a/models/classes/import/QtiTestImporter.php b/models/classes/import/QtiTestImporter.php index 1fd5bb6c28..f1cb86bd52 100644 --- a/models/classes/import/QtiTestImporter.php +++ b/models/classes/import/QtiTestImporter.php @@ -43,8 +43,9 @@ class QtiTestImporter extends AbstractTestImporter * @param bool $enableValidators * @param bool $itemMustExist * @param bool $itemMustBeOverwritten - * @param string|null $overwriteTestUri + * @param bool $overwriteTest * @param string|null $itemClassUri + * @param string|null $overwriteTestUri * @return common_report_Report */ public function import( @@ -54,8 +55,9 @@ public function import( bool $enableValidators = true, bool $itemMustExist = false, bool $itemMustBeOverwritten = false, - ?string $overwriteTestUri = null, - ?string $itemClassUri = null + bool $overwriteTest = false, + ?string $itemClassUri = null, + ?string $overwriteTestUri = null ) { return taoQtiTest_models_classes_CrudQtiTestsService::singleton()->importQtiTest( $file, @@ -64,8 +66,9 @@ public function import( $enableValidators, $itemMustExist, $itemMustBeOverwritten, - $overwriteTestUri, - $itemClassUri + $overwriteTest, + $itemClassUri, + $overwriteTestUri ); } } diff --git a/models/classes/tasks/ImportQtiTest.php b/models/classes/tasks/ImportQtiTest.php index 8cb1f903f4..bf2b7e3212 100644 --- a/models/classes/tasks/ImportQtiTest.php +++ b/models/classes/tasks/ImportQtiTest.php @@ -50,6 +50,11 @@ class ImportQtiTest extends AbstractTaskAction implements \JsonSerializable public const PARAM_ITEM_MUST_EXIST = 'item_must_exist'; public const PARAM_ITEM_MUST_BE_OVERWRITTEN = 'item_must_be_overwritten'; public const PARAM_ITEM_CLASS_URI = 'item_class_uri'; + /** + * @deprecated Use oat\taoQtiTest\models\tasks\ImportQtiTest::PARAM_OVERWRITE_TEST_URI instead with the URI of the + * test to be replaced + */ + public const PARAM_OVERWRITE_TEST = 'overwrite_test'; public const PARAM_OVERWRITE_TEST_URI = 'overwrite_test_uri'; protected $service; @@ -88,8 +93,9 @@ public function __invoke($params) $params[self::PARAM_ENABLE_VALIDATORS] ?? true, $params[self::PARAM_ITEM_MUST_EXIST] ?? false, $params[self::PARAM_ITEM_MUST_BE_OVERWRITTEN] ?? false, + $params[self::PARAM_OVERWRITE_TEST] ?? false, + $params[self::PARAM_ITEM_CLASS_URI] ?? false, $params[self::PARAM_OVERWRITE_TEST_URI] ?? null, - $params[self::PARAM_ITEM_CLASS_URI] ?? false ); return $report; @@ -121,8 +127,9 @@ public static function createTask( $enableValidators = true, $itemMustExist = false, $itemMustBeOverwritten = false, - ?string $overwriteTestUri = null, - ?string $itemClassUri = null + bool $overwriteTest = false, + ?string $itemClassUri = null, + ?string $overwriteTestUri = null ) { $action = new self(); $action->setServiceLocator(ServiceManager::getServiceManager()); @@ -141,8 +148,9 @@ public static function createTask( self::PARAM_ENABLE_VALIDATORS => $enableValidators, self::PARAM_ITEM_MUST_EXIST => $itemMustExist, self::PARAM_ITEM_MUST_BE_OVERWRITTEN => $itemMustBeOverwritten, - self::PARAM_OVERWRITE_TEST_URI => $overwriteTestUri, + self::PARAM_OVERWRITE_TEST => $overwriteTest, self::PARAM_ITEM_CLASS_URI => $itemClassUri, + self::PARAM_OVERWRITE_TEST_URI => $overwriteTestUri, ], __('Import QTI TEST into "%s"', $class->getLabel()) ); From 589f77ab9b7f1d7c776429be6170cc9c8457e968 Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Tue, 6 Aug 2024 22:30:25 +0300 Subject: [PATCH 3/9] chore: translation location --- actions/class.RestQtiTests.php | 69 +++++++++++++++----- models/classes/class.CrudQtiTestsService.php | 5 ++ models/classes/class.QtiTestService.php | 57 ++++++++++------ models/classes/import/QtiTestImporter.php | 4 ++ models/classes/tasks/ImportQtiTest.php | 8 +++ 5 files changed, 109 insertions(+), 34 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index d875f78c8d..8892c6cea3 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -46,6 +46,8 @@ class taoQtiTest_actions_RestQtiTests extends AbstractRestQti */ private const OVERWRITE_TEST = 'overwriteTest'; + private const PACKAGE_LOCALE = 'packageLocale'; + private const PACKAGE_LABEL = 'packageLabel'; private const OVERWRITE_TEST_URI = 'overwriteTestUri'; /** @@ -108,6 +110,8 @@ public function import() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), + $this->getPackageLocale(), + $this->getPackageLabel(), $this->getOverwriteTestUri(), ); @@ -186,6 +190,8 @@ public function importDeferred() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), + $this->getPackageLocale(), + $this->getPackageLabel(), $this->getOverwriteTestUri() ); @@ -264,27 +270,22 @@ protected function addExtraReturnData(EntityInterface $taskLogEntity) * If parent class parameter is an uri of valid test class, new class will be created under it * If not parent class parameter is provided, class will be created under root class * Comment parameter is not mandatory, used to describe new created class - * - * @return \core_kernel_classes_Class */ - public function createClass() + public function createClass(): void { try { - $class = $this->createSubClass(new \core_kernel_classes_Class(TaoOntology::CLASS_URI_TEST)); + $class = $this->createSubClass(new core_kernel_classes_Class(TaoOntology::CLASS_URI_TEST)); - $result = [ + $this->returnSuccess([ 'message' => __('Class successfully created.'), 'class-uri' => $class->getUri(), - ]; - - $this->returnSuccess($result); - } catch (\common_exception_ClassAlreadyExists $e) { - $result = [ + ]); + } catch (common_exception_ClassAlreadyExists $e) { + $this->returnSuccess([ 'message' => $e->getMessage(), 'class-uri' => $e->getClass()->getUri(), - ]; - $this->returnSuccess($result); - } catch (\Exception $e) { + ]); + } catch (Exception $e) { $this->returnFailure($e); } } @@ -311,6 +312,44 @@ private function getUploadedPackageData() return $fileData; } + /** + * @return string + * @throws common_exception_RestApi + */ + private function getPackageLocale(): string + { + $packageLocale = $this->getPostParameter(self::PACKAGE_LOCALE, ''); + + if (!is_string($packageLocale)) { + throw new common_exception_RestApi( + sprintf('%s parameter should be string', self::PACKAGE_LOCALE) + ); + } + + return $packageLocale; + } + + /** + * @return string + * @throws common_exception_RestApi + */ + private function getPackageLabel(): ?string + { + $packageLabel = $this->getPostParameter(self::PACKAGE_LABEL); + + if (!$packageLabel) { + return null; + } + + if (!is_string($packageLabel)) { + throw new common_exception_RestApi( + sprintf('%s parameter should be string', self::PACKAGE_LABEL) + ); + } + + return $packageLabel; + } + /** * @return string|null * @throws common_exception_RestApi @@ -334,12 +373,12 @@ private function getOverwriteTestUri(): ?string /** * Get class instance to import test - * @return \core_kernel_classes_Class + * @return core_kernel_classes_Class *@throws common_exception_RestApi */ private function getTestClass() { - return $this->getClassFromRequest(new \core_kernel_classes_Class(TaoOntology::CLASS_URI_TEST)); + return $this->getClassFromRequest(new core_kernel_classes_Class(TaoOntology::CLASS_URI_TEST)); } /** diff --git a/models/classes/class.CrudQtiTestsService.php b/models/classes/class.CrudQtiTestsService.php index b70c4d1b8c..390929f877 100644 --- a/models/classes/class.CrudQtiTestsService.php +++ b/models/classes/class.CrudQtiTestsService.php @@ -68,6 +68,8 @@ public function importQtiTest( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, + ?string $locale = null, + ?string $label = null, ?string $overwriteTestUri = null ) { try { @@ -97,6 +99,9 @@ public function importQtiTest( $uploadedFile, $overwriteTest, $itemClassUri, + [], + $locale, + $label, $overwriteTestUri ); helpers_TimeOutHelper::reset(); diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index 3fcee714c0..c2bb203843 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -357,6 +357,8 @@ public function importMultipleTests( bool $overwriteTest = false, ?string $itemClassUri = null, array $form = [], + ?string $locale = null, + ?string $label = null, ?string $overwriteTestUri = null ) { $testClass = $targetClass; @@ -427,7 +429,9 @@ public function importMultipleTests( $overwriteTest, $itemClassUri, !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false, - $overwriteTestUri, + $locale, + $label, + $overwriteTestUri ); $report->add($importTestReport); @@ -549,14 +553,34 @@ protected function importTest( bool $overwriteTest = false, ?string $itemClassUri = null, bool $importMetadata = false, + ?string $locale = null, + ?string $label = null, ?string $overwriteTestUri = null ) { /** @var ImportService $itemImportService */ $itemImportService = $this->getServiceLocator()->get(ImportService::SERVICE_ID); $qtiTestResourceIdentifier = $qtiTestResource->getIdentifier(); + // The class where the items that belong to the test will be imported. + $itemParentClass = $this->getClass($itemClassUri ?: TaoOntology::CLASS_URI_ITEM); + // Create an RDFS resource in the knowledge base that will hold // the information about the imported QTI Test. + + if ($locale) { + foreach ($testClass->getSubClasses() as $subClass) { + if ($subClass->getLabel() === $locale) { + $testClass = $subClass; + } + } + + foreach ($itemParentClass->getSubClasses() as $subClass) { + if ($subClass->getLabel() === $locale) { + $itemParentClass = $subClass; + } + } + } + $testResource = $this->createInstance($testClass, self::IN_PROGRESS_LABEL); $qtiTestModelResource = $this->getResource(self::INSTANCE_TEST_MODEL_QTI); $modelProperty = $this->getProperty(TestService::PROPERTY_TEST_TESTMODEL); @@ -570,9 +594,6 @@ protected function importTest( // of $qtiTestResource in TAO. $report = new common_report_Report(common_report_Report::TYPE_INFO); - // The class where the items that belong to the test will be imported. - $itemParentClass = $this->getClass($itemClassUri ?: TaoOntology::CLASS_URI_ITEM); - // Load and validate the manifest $qtiManifestParser = new taoQtiTest_models_classes_ManifestParser($folder . 'imsmanifest.xml'); $this->propagate($qtiManifestParser); @@ -597,8 +618,6 @@ protected function importTest( $reportCtx->testMetadata = $metadataValues[$qtiTestResourceIdentifier] ?? []; $reportCtx->createdClasses = []; - - // 'uriResource' key is needed by javascript in tao/views/templates/form/import.tpl $reportCtx->uriResource = $testResource->getUri(); @@ -624,19 +643,21 @@ protected function importTest( // If any, assessmentSectionRefs will be resolved and included as part of the main test definition. $testDefinition->includeAssessmentSectionRefs(true); - $testLabel = $testDefinition->getDocumentComponent()->getTitle(); + $testLabel = $label ?? $testDefinition->getDocumentComponent()->getTitle(); if ($overwriteTestUri || $overwriteTest) { $itemsClassLabel = $testLabel; - /** @var oat\taoQtiItem\model\qti\metadata\simple\SimpleMetadataValue $m */ - foreach ($reportCtx->testMetadata as $singleMetadata) { - if (($singleMetadata->getPath()[1] ?? '') === RDFS_LABEL) { - $testLabel = $singleMetadata->getValue(); + if (!$label) { + /** @var oat\taoQtiItem\model\qti\metadata\simple\SimpleMetadataValue $singleMetadata */ + foreach ($reportCtx->testMetadata as $singleMetadata) { + if (($singleMetadata->getPath()[1] ?? '') === RDFS_LABEL) { + $testLabel = $singleMetadata->getValue(); + } } } - $this->deleteItemSubclassesByLabel($itemParentClass, $itemsClassLabel); + $this->deleteItemSubclassesByLabel($itemParentClass, $itemsClassLabel, $locale); $overwriteTestUri ? $this->getTestService()->deleteTest(new core_kernel_classes_Resource($overwriteTestUri)) : $this->deleteTestsFromClassByLabel($testLabel, $testClass); @@ -802,8 +823,8 @@ protected function importTest( $this->importTestAuxiliaryFiles($testContent, $qtiTestResource, $folder, $report); // 3. Give meaningful names to resources. - $testResource->setLabel($testDefinition->getDocumentComponent()->getTitle()); - $targetItemClass->setLabel($testDefinition->getDocumentComponent()->getTitle()); + $testResource->setLabel($label ?? $testDefinition->getDocumentComponent()->getTitle()); + $targetItemClass->setLabel($label ?? $testDefinition->getDocumentComponent()->getTitle()); // 4. Import metadata for the resource (use same mechanics as item resources). // Metadata will be set as property values. @@ -1490,14 +1511,12 @@ private function verifyItemPermissions(core_kernel_classes_Resource $oldTest, st $this->getSecureResourceService()->validatePermissions($ids, ['READ']); } - private function deleteItemSubclassesByLabel( - core_kernel_classes_Class $root, - string $label - ): void { + private function deleteItemSubclassesByLabel(core_kernel_classes_Class $root, string $label, ?string $locale): void + { $itemTreeService = $this->getItemTreeService(); foreach ($root->getSubClasses() as $subClass) { - if ($subClass->getLabel() !== $label) { + if (!in_array($subClass->getLabel(), [$label, $locale], true)) { continue; } diff --git a/models/classes/import/QtiTestImporter.php b/models/classes/import/QtiTestImporter.php index f1cb86bd52..bc77b36213 100644 --- a/models/classes/import/QtiTestImporter.php +++ b/models/classes/import/QtiTestImporter.php @@ -57,6 +57,8 @@ public function import( bool $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, + ?string $locale = null, + ?string $label = null, ?string $overwriteTestUri = null ) { return taoQtiTest_models_classes_CrudQtiTestsService::singleton()->importQtiTest( @@ -68,6 +70,8 @@ public function import( $itemMustBeOverwritten, $overwriteTest, $itemClassUri, + $locale, + $label, $overwriteTestUri ); } diff --git a/models/classes/tasks/ImportQtiTest.php b/models/classes/tasks/ImportQtiTest.php index bf2b7e3212..70c1b867a9 100644 --- a/models/classes/tasks/ImportQtiTest.php +++ b/models/classes/tasks/ImportQtiTest.php @@ -55,6 +55,8 @@ class ImportQtiTest extends AbstractTaskAction implements \JsonSerializable * test to be replaced */ public const PARAM_OVERWRITE_TEST = 'overwrite_test'; + public const PARAM_LOCALE = 'locale'; + public const PARAM_LABEL = 'label'; public const PARAM_OVERWRITE_TEST_URI = 'overwrite_test_uri'; protected $service; @@ -95,6 +97,8 @@ public function __invoke($params) $params[self::PARAM_ITEM_MUST_BE_OVERWRITTEN] ?? false, $params[self::PARAM_OVERWRITE_TEST] ?? false, $params[self::PARAM_ITEM_CLASS_URI] ?? false, + $params[self::PARAM_LOCALE] ?? null, + $params[self::PARAM_LABEL] ?? null, $params[self::PARAM_OVERWRITE_TEST_URI] ?? null, ); @@ -129,6 +133,8 @@ public static function createTask( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, + ?string $locale = null, + ?string $label = null, ?string $overwriteTestUri = null ) { $action = new self(); @@ -150,6 +156,8 @@ public static function createTask( self::PARAM_ITEM_MUST_BE_OVERWRITTEN => $itemMustBeOverwritten, self::PARAM_OVERWRITE_TEST => $overwriteTest, self::PARAM_ITEM_CLASS_URI => $itemClassUri, + self::PARAM_LOCALE => $locale, + self::PARAM_LABEL => $label, self::PARAM_OVERWRITE_TEST_URI => $overwriteTestUri, ], __('Import QTI TEST into "%s"', $class->getLabel()) From 2fa993511f524ee27ec8bd0c4aa32f81531dd0e1 Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Wed, 7 Aug 2024 18:19:13 +0300 Subject: [PATCH 4/9] chore: change classes to subfolder at the beginning, rename props --- actions/class.RestQtiTests.php | 54 ++++++++++++++------ models/classes/class.CrudQtiTestsService.php | 6 +-- models/classes/class.QtiTestService.php | 37 ++++---------- models/classes/import/QtiTestImporter.php | 6 +-- models/classes/tasks/ImportQtiTest.php | 12 ++--- 5 files changed, 55 insertions(+), 60 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index 8892c6cea3..4f0b14a1e9 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -46,8 +46,8 @@ class taoQtiTest_actions_RestQtiTests extends AbstractRestQti */ private const OVERWRITE_TEST = 'overwriteTest'; - private const PACKAGE_LOCALE = 'packageLocale'; - private const PACKAGE_LABEL = 'packageLabel'; + private const SUBCLASS_LABEL = 'subclassLabel'; + private const NEW_PACKAGE_LABEL = 'newPackageLabel'; private const OVERWRITE_TEST_URI = 'overwriteTestUri'; /** @@ -110,8 +110,7 @@ public function import() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), - $this->getPackageLocale(), - $this->getPackageLabel(), + $this->getNewPackageLabel(), $this->getOverwriteTestUri(), ); @@ -139,7 +138,18 @@ public function import() protected function getItemClassUri(): ?string { - return $this->getPostParameter(self::ITEM_CLASS_URI); + $itemClassUri = $this->getPostParameter(self::ITEM_CLASS_URI); + $subclassLabel = $this->getSubclassLabel(); + + if ($subclassLabel) { + foreach ($this->getClass($itemClassUri)->getSubClasses() as $subclass) { + if ($subclass === $subclassLabel) { + $itemClassUri = $subclass->getUri(); + } + } + } + + return $itemClassUri; } /** @@ -190,8 +200,7 @@ public function importDeferred() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), - $this->getPackageLocale(), - $this->getPackageLabel(), + $this->getNewPackageLabel(), $this->getOverwriteTestUri() ); @@ -316,13 +325,13 @@ private function getUploadedPackageData() * @return string * @throws common_exception_RestApi */ - private function getPackageLocale(): string + private function getSubclassLabel(): string { - $packageLocale = $this->getPostParameter(self::PACKAGE_LOCALE, ''); + $packageLocale = $this->getPostParameter(self::SUBCLASS_LABEL, ''); if (!is_string($packageLocale)) { throw new common_exception_RestApi( - sprintf('%s parameter should be string', self::PACKAGE_LOCALE) + sprintf('%s parameter should be string', self::SUBCLASS_LABEL) ); } @@ -333,9 +342,9 @@ private function getPackageLocale(): string * @return string * @throws common_exception_RestApi */ - private function getPackageLabel(): ?string + private function getNewPackageLabel(): ?string { - $packageLabel = $this->getPostParameter(self::PACKAGE_LABEL); + $packageLabel = $this->getPostParameter(self::NEW_PACKAGE_LABEL); if (!$packageLabel) { return null; @@ -343,7 +352,7 @@ private function getPackageLabel(): ?string if (!is_string($packageLabel)) { throw new common_exception_RestApi( - sprintf('%s parameter should be string', self::PACKAGE_LABEL) + sprintf('%s parameter should be string', self::NEW_PACKAGE_LABEL) ); } @@ -373,12 +382,23 @@ private function getOverwriteTestUri(): ?string /** * Get class instance to import test - * @return core_kernel_classes_Class - *@throws common_exception_RestApi + * + * @throws common_exception_RestApi */ - private function getTestClass() + private function getTestClass(): core_kernel_classes_Class { - return $this->getClassFromRequest(new core_kernel_classes_Class(TaoOntology::CLASS_URI_TEST)); + $testClass = $this->getClassFromRequest(new core_kernel_classes_Class(TaoOntology::CLASS_URI_TEST)); + $subclassLabel = $this->getSubclassLabel(); + + if ($subclassLabel) { + foreach ($testClass->getSubClasses() as $subClass) { + if ($subClass->getLabel() === $subclassLabel) { + $testClass = $subClass; + } + } + } + + return $testClass; } /** diff --git a/models/classes/class.CrudQtiTestsService.php b/models/classes/class.CrudQtiTestsService.php index 390929f877..b6873ae725 100644 --- a/models/classes/class.CrudQtiTestsService.php +++ b/models/classes/class.CrudQtiTestsService.php @@ -68,8 +68,7 @@ public function importQtiTest( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $locale = null, - ?string $label = null, + ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { try { @@ -100,8 +99,7 @@ public function importQtiTest( $overwriteTest, $itemClassUri, [], - $locale, - $label, + $newPackageLabel, $overwriteTestUri ); helpers_TimeOutHelper::reset(); diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index c2bb203843..a5067fbdcc 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -357,8 +357,7 @@ public function importMultipleTests( bool $overwriteTest = false, ?string $itemClassUri = null, array $form = [], - ?string $locale = null, - ?string $label = null, + ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { $testClass = $targetClass; @@ -429,8 +428,7 @@ public function importMultipleTests( $overwriteTest, $itemClassUri, !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false, - $locale, - $label, + $newPackageLabel, $overwriteTestUri ); $report->add($importTestReport); @@ -553,8 +551,7 @@ protected function importTest( bool $overwriteTest = false, ?string $itemClassUri = null, bool $importMetadata = false, - ?string $locale = null, - ?string $label = null, + ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { /** @var ImportService $itemImportService */ @@ -567,20 +564,6 @@ protected function importTest( // Create an RDFS resource in the knowledge base that will hold // the information about the imported QTI Test. - if ($locale) { - foreach ($testClass->getSubClasses() as $subClass) { - if ($subClass->getLabel() === $locale) { - $testClass = $subClass; - } - } - - foreach ($itemParentClass->getSubClasses() as $subClass) { - if ($subClass->getLabel() === $locale) { - $itemParentClass = $subClass; - } - } - } - $testResource = $this->createInstance($testClass, self::IN_PROGRESS_LABEL); $qtiTestModelResource = $this->getResource(self::INSTANCE_TEST_MODEL_QTI); $modelProperty = $this->getProperty(TestService::PROPERTY_TEST_TESTMODEL); @@ -643,12 +626,12 @@ protected function importTest( // If any, assessmentSectionRefs will be resolved and included as part of the main test definition. $testDefinition->includeAssessmentSectionRefs(true); - $testLabel = $label ?? $testDefinition->getDocumentComponent()->getTitle(); + $testLabel = $newPackageLabel ?? $testDefinition->getDocumentComponent()->getTitle(); if ($overwriteTestUri || $overwriteTest) { $itemsClassLabel = $testLabel; - if (!$label) { + if (!$newPackageLabel) { /** @var oat\taoQtiItem\model\qti\metadata\simple\SimpleMetadataValue $singleMetadata */ foreach ($reportCtx->testMetadata as $singleMetadata) { if (($singleMetadata->getPath()[1] ?? '') === RDFS_LABEL) { @@ -657,7 +640,7 @@ protected function importTest( } } - $this->deleteItemSubclassesByLabel($itemParentClass, $itemsClassLabel, $locale); + $this->deleteItemSubclassesByLabel($itemParentClass, $itemsClassLabel); $overwriteTestUri ? $this->getTestService()->deleteTest(new core_kernel_classes_Resource($overwriteTestUri)) : $this->deleteTestsFromClassByLabel($testLabel, $testClass); @@ -823,8 +806,8 @@ protected function importTest( $this->importTestAuxiliaryFiles($testContent, $qtiTestResource, $folder, $report); // 3. Give meaningful names to resources. - $testResource->setLabel($label ?? $testDefinition->getDocumentComponent()->getTitle()); - $targetItemClass->setLabel($label ?? $testDefinition->getDocumentComponent()->getTitle()); + $testResource->setLabel($newPackageLabel ?? $testDefinition->getDocumentComponent()->getTitle()); + $targetItemClass->setLabel($newPackageLabel ?? $testDefinition->getDocumentComponent()->getTitle()); // 4. Import metadata for the resource (use same mechanics as item resources). // Metadata will be set as property values. @@ -1511,12 +1494,12 @@ private function verifyItemPermissions(core_kernel_classes_Resource $oldTest, st $this->getSecureResourceService()->validatePermissions($ids, ['READ']); } - private function deleteItemSubclassesByLabel(core_kernel_classes_Class $root, string $label, ?string $locale): void + private function deleteItemSubclassesByLabel(core_kernel_classes_Class $root, string $label): void { $itemTreeService = $this->getItemTreeService(); foreach ($root->getSubClasses() as $subClass) { - if (!in_array($subClass->getLabel(), [$label, $locale], true)) { + if ($subClass->getLabel() !== $label) { continue; } diff --git a/models/classes/import/QtiTestImporter.php b/models/classes/import/QtiTestImporter.php index bc77b36213..f9ef3ea600 100644 --- a/models/classes/import/QtiTestImporter.php +++ b/models/classes/import/QtiTestImporter.php @@ -57,8 +57,7 @@ public function import( bool $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $locale = null, - ?string $label = null, + ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { return taoQtiTest_models_classes_CrudQtiTestsService::singleton()->importQtiTest( @@ -70,8 +69,7 @@ public function import( $itemMustBeOverwritten, $overwriteTest, $itemClassUri, - $locale, - $label, + $newPackageLabel, $overwriteTestUri ); } diff --git a/models/classes/tasks/ImportQtiTest.php b/models/classes/tasks/ImportQtiTest.php index 70c1b867a9..418880511f 100644 --- a/models/classes/tasks/ImportQtiTest.php +++ b/models/classes/tasks/ImportQtiTest.php @@ -55,8 +55,7 @@ class ImportQtiTest extends AbstractTaskAction implements \JsonSerializable * test to be replaced */ public const PARAM_OVERWRITE_TEST = 'overwrite_test'; - public const PARAM_LOCALE = 'locale'; - public const PARAM_LABEL = 'label'; + public const PARAM_NEW_PACKAGE_LABEL = 'new_package_label'; public const PARAM_OVERWRITE_TEST_URI = 'overwrite_test_uri'; protected $service; @@ -97,8 +96,7 @@ public function __invoke($params) $params[self::PARAM_ITEM_MUST_BE_OVERWRITTEN] ?? false, $params[self::PARAM_OVERWRITE_TEST] ?? false, $params[self::PARAM_ITEM_CLASS_URI] ?? false, - $params[self::PARAM_LOCALE] ?? null, - $params[self::PARAM_LABEL] ?? null, + $params[self::PARAM_NEW_PACKAGE_LABEL] ?? null, $params[self::PARAM_OVERWRITE_TEST_URI] ?? null, ); @@ -133,8 +131,7 @@ public static function createTask( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $locale = null, - ?string $label = null, + ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { $action = new self(); @@ -156,8 +153,7 @@ public static function createTask( self::PARAM_ITEM_MUST_BE_OVERWRITTEN => $itemMustBeOverwritten, self::PARAM_OVERWRITE_TEST => $overwriteTest, self::PARAM_ITEM_CLASS_URI => $itemClassUri, - self::PARAM_LOCALE => $locale, - self::PARAM_LABEL => $label, + self::PARAM_NEW_PACKAGE_LABEL => $newPackageLabel, self::PARAM_OVERWRITE_TEST_URI => $overwriteTestUri, ], __('Import QTI TEST into "%s"', $class->getLabel()) From 78db3dcf29ffea992efa63d8605e2e29a2329f77 Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Wed, 7 Aug 2024 19:11:31 +0300 Subject: [PATCH 5/9] chore: fix CI, simplify code --- actions/class.RestQtiTests.php | 6 +----- models/classes/class.QtiTestService.php | 5 +++-- models/classes/import/QtiTestImporter.php | 8 ++++---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index 4f0b14a1e9..577c0057b8 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -367,11 +367,7 @@ private function getOverwriteTestUri(): ?string { $overwriteTestUri = $this->getPostParameter(self::OVERWRITE_TEST_URI); - if (is_null($overwriteTestUri)) { - return null; - } - - if (!is_string($overwriteTestUri)) { + if (!is_null($overwriteTestUri) && !is_string($overwriteTestUri)) { throw new common_exception_RestApi( sprintf('%s parameter should be string', self::OVERWRITE_TEST_URI) ); diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index a5067fbdcc..d521620d91 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -806,8 +806,9 @@ protected function importTest( $this->importTestAuxiliaryFiles($testContent, $qtiTestResource, $folder, $report); // 3. Give meaningful names to resources. - $testResource->setLabel($newPackageLabel ?? $testDefinition->getDocumentComponent()->getTitle()); - $targetItemClass->setLabel($newPackageLabel ?? $testDefinition->getDocumentComponent()->getTitle()); + $testDefinitionTitle = $testDefinition->getDocumentComponent()->getTitle(); + $testResource->setLabel($newPackageLabel ?? $testDefinitionTitle); + $targetItemClass->setLabel($newPackageLabel ?? $testDefinitionTitle); // 4. Import metadata for the resource (use same mechanics as item resources). // Metadata will be set as property values. diff --git a/models/classes/import/QtiTestImporter.php b/models/classes/import/QtiTestImporter.php index f9ef3ea600..c39cacdbaf 100644 --- a/models/classes/import/QtiTestImporter.php +++ b/models/classes/import/QtiTestImporter.php @@ -51,10 +51,10 @@ class QtiTestImporter extends AbstractTestImporter public function import( File $file, core_kernel_classes_Class $class = null, - bool $enableMetadataGuardians = true, - bool $enableValidators = true, - bool $itemMustExist = false, - bool $itemMustBeOverwritten = false, + $enableMetadataGuardians = true, + $enableValidators = true, + $itemMustExist = false, + $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, ?string $newPackageLabel = null, From 8f6a9182cdacd91e8fcc4ee1059faa2f61002cef Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Thu, 8 Aug 2024 00:30:34 +0300 Subject: [PATCH 6/9] chore: remove unnecessary parameter --- actions/class.RestQtiTests.php | 28 ++------------------ models/classes/class.CrudQtiTestsService.php | 2 -- models/classes/class.QtiTestService.php | 20 +++++--------- models/classes/import/QtiTestImporter.php | 2 -- models/classes/tasks/ImportQtiTest.php | 5 ---- 5 files changed, 9 insertions(+), 48 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index 577c0057b8..f8e2b73312 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -47,7 +47,6 @@ class taoQtiTest_actions_RestQtiTests extends AbstractRestQti private const OVERWRITE_TEST = 'overwriteTest'; private const SUBCLASS_LABEL = 'subclassLabel'; - private const NEW_PACKAGE_LABEL = 'newPackageLabel'; private const OVERWRITE_TEST_URI = 'overwriteTestUri'; /** @@ -110,8 +109,7 @@ public function import() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), - $this->getNewPackageLabel(), - $this->getOverwriteTestUri(), + $this->getOverwriteTestUri() ); if ($report->getType() === common_report_Report::TYPE_SUCCESS) { @@ -143,7 +141,7 @@ protected function getItemClassUri(): ?string if ($subclassLabel) { foreach ($this->getClass($itemClassUri)->getSubClasses() as $subclass) { - if ($subclass === $subclassLabel) { + if ($subclass->getLabel() === $subclassLabel) { $itemClassUri = $subclass->getUri(); } } @@ -200,7 +198,6 @@ public function importDeferred() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), - $this->getNewPackageLabel(), $this->getOverwriteTestUri() ); @@ -338,27 +335,6 @@ private function getSubclassLabel(): string return $packageLocale; } - /** - * @return string - * @throws common_exception_RestApi - */ - private function getNewPackageLabel(): ?string - { - $packageLabel = $this->getPostParameter(self::NEW_PACKAGE_LABEL); - - if (!$packageLabel) { - return null; - } - - if (!is_string($packageLabel)) { - throw new common_exception_RestApi( - sprintf('%s parameter should be string', self::NEW_PACKAGE_LABEL) - ); - } - - return $packageLabel; - } - /** * @return string|null * @throws common_exception_RestApi diff --git a/models/classes/class.CrudQtiTestsService.php b/models/classes/class.CrudQtiTestsService.php index b6873ae725..e46bf7a6ea 100644 --- a/models/classes/class.CrudQtiTestsService.php +++ b/models/classes/class.CrudQtiTestsService.php @@ -68,7 +68,6 @@ public function importQtiTest( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { try { @@ -99,7 +98,6 @@ public function importQtiTest( $overwriteTest, $itemClassUri, [], - $newPackageLabel, $overwriteTestUri ); helpers_TimeOutHelper::reset(); diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index d521620d91..e38a5285b1 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -357,7 +357,6 @@ public function importMultipleTests( bool $overwriteTest = false, ?string $itemClassUri = null, array $form = [], - ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { $testClass = $targetClass; @@ -428,7 +427,6 @@ public function importMultipleTests( $overwriteTest, $itemClassUri, !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false, - $newPackageLabel, $overwriteTestUri ); $report->add($importTestReport); @@ -551,7 +549,6 @@ protected function importTest( bool $overwriteTest = false, ?string $itemClassUri = null, bool $importMetadata = false, - ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { /** @var ImportService $itemImportService */ @@ -626,17 +623,15 @@ protected function importTest( // If any, assessmentSectionRefs will be resolved and included as part of the main test definition. $testDefinition->includeAssessmentSectionRefs(true); - $testLabel = $newPackageLabel ?? $testDefinition->getDocumentComponent()->getTitle(); + $testLabel = $testDefinition->getDocumentComponent()->getTitle(); if ($overwriteTestUri || $overwriteTest) { $itemsClassLabel = $testLabel; - if (!$newPackageLabel) { - /** @var oat\taoQtiItem\model\qti\metadata\simple\SimpleMetadataValue $singleMetadata */ - foreach ($reportCtx->testMetadata as $singleMetadata) { - if (($singleMetadata->getPath()[1] ?? '') === RDFS_LABEL) { - $testLabel = $singleMetadata->getValue(); - } + /** @var oat\taoQtiItem\model\qti\metadata\simple\SimpleMetadataValue $singleMetadata */ + foreach ($reportCtx->testMetadata as $singleMetadata) { + if (($singleMetadata->getPath()[1] ?? '') === RDFS_LABEL) { + $testLabel = $singleMetadata->getValue(); } } @@ -806,9 +801,8 @@ protected function importTest( $this->importTestAuxiliaryFiles($testContent, $qtiTestResource, $folder, $report); // 3. Give meaningful names to resources. - $testDefinitionTitle = $testDefinition->getDocumentComponent()->getTitle(); - $testResource->setLabel($newPackageLabel ?? $testDefinitionTitle); - $targetItemClass->setLabel($newPackageLabel ?? $testDefinitionTitle); + $testResource->setLabel($testDefinition->getDocumentComponent()->getTitle()); + $targetItemClass->setLabel($reportCtx->itemClass->getLabel()); // 4. Import metadata for the resource (use same mechanics as item resources). // Metadata will be set as property values. diff --git a/models/classes/import/QtiTestImporter.php b/models/classes/import/QtiTestImporter.php index c39cacdbaf..c15b4d5bbe 100644 --- a/models/classes/import/QtiTestImporter.php +++ b/models/classes/import/QtiTestImporter.php @@ -57,7 +57,6 @@ public function import( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { return taoQtiTest_models_classes_CrudQtiTestsService::singleton()->importQtiTest( @@ -69,7 +68,6 @@ public function import( $itemMustBeOverwritten, $overwriteTest, $itemClassUri, - $newPackageLabel, $overwriteTestUri ); } diff --git a/models/classes/tasks/ImportQtiTest.php b/models/classes/tasks/ImportQtiTest.php index 418880511f..2ff9387dd6 100644 --- a/models/classes/tasks/ImportQtiTest.php +++ b/models/classes/tasks/ImportQtiTest.php @@ -32,7 +32,6 @@ use oat\tao\model\TaoOntology; use oat\tao\model\taskQueue\QueueDispatcherInterface; use oat\tao\model\taskQueue\Task\TaskInterface; -use oat\taoQtiTest\models\render\QtiPackageImportPreprocessing; use oat\taoQtiTest\models\import\QtiTestImporter; /** @@ -55,7 +54,6 @@ class ImportQtiTest extends AbstractTaskAction implements \JsonSerializable * test to be replaced */ public const PARAM_OVERWRITE_TEST = 'overwrite_test'; - public const PARAM_NEW_PACKAGE_LABEL = 'new_package_label'; public const PARAM_OVERWRITE_TEST_URI = 'overwrite_test_uri'; protected $service; @@ -96,7 +94,6 @@ public function __invoke($params) $params[self::PARAM_ITEM_MUST_BE_OVERWRITTEN] ?? false, $params[self::PARAM_OVERWRITE_TEST] ?? false, $params[self::PARAM_ITEM_CLASS_URI] ?? false, - $params[self::PARAM_NEW_PACKAGE_LABEL] ?? null, $params[self::PARAM_OVERWRITE_TEST_URI] ?? null, ); @@ -131,7 +128,6 @@ public static function createTask( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $newPackageLabel = null, ?string $overwriteTestUri = null ) { $action = new self(); @@ -153,7 +149,6 @@ public static function createTask( self::PARAM_ITEM_MUST_BE_OVERWRITTEN => $itemMustBeOverwritten, self::PARAM_OVERWRITE_TEST => $overwriteTest, self::PARAM_ITEM_CLASS_URI => $itemClassUri, - self::PARAM_NEW_PACKAGE_LABEL => $newPackageLabel, self::PARAM_OVERWRITE_TEST_URI => $overwriteTestUri, ], __('Import QTI TEST into "%s"', $class->getLabel()) From 3d5d7696c86ae1cafffe4a6317a2a29fbf477741 Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Thu, 8 Aug 2024 00:35:27 +0300 Subject: [PATCH 7/9] chore: rename props, return null --- actions/class.RestQtiTests.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index f8e2b73312..5d151e91c7 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -319,20 +319,20 @@ private function getUploadedPackageData() } /** - * @return string + * @return string|null * @throws common_exception_RestApi */ - private function getSubclassLabel(): string + private function getSubclassLabel(): ?string { - $packageLocale = $this->getPostParameter(self::SUBCLASS_LABEL, ''); + $subclassLabel = $this->getPostParameter(self::SUBCLASS_LABEL); - if (!is_string($packageLocale)) { + if ($subclassLabel !== null && !is_string($subclassLabel)) { throw new common_exception_RestApi( sprintf('%s parameter should be string', self::SUBCLASS_LABEL) ); } - return $packageLocale; + return $subclassLabel; } /** @@ -343,7 +343,7 @@ private function getOverwriteTestUri(): ?string { $overwriteTestUri = $this->getPostParameter(self::OVERWRITE_TEST_URI); - if (!is_null($overwriteTestUri) && !is_string($overwriteTestUri)) { + if ($overwriteTestUri !== null && !is_string($overwriteTestUri)) { throw new common_exception_RestApi( sprintf('%s parameter should be string', self::OVERWRITE_TEST_URI) ); From d50a809e67c111d765414789d30aeb3f6c946b85 Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Thu, 8 Aug 2024 15:39:40 +0300 Subject: [PATCH 8/9] chore: add custom packageLabel param --- actions/class.RestQtiTests.php | 24 ++++++++++++++++++-- models/classes/class.CrudQtiTestsService.php | 6 +++-- models/classes/class.QtiTestService.php | 16 ++++++++----- models/classes/import/QtiTestImporter.php | 7 ++++-- models/classes/tasks/ImportQtiTest.php | 6 ++++- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/actions/class.RestQtiTests.php b/actions/class.RestQtiTests.php index 5d151e91c7..45d1d7921a 100644 --- a/actions/class.RestQtiTests.php +++ b/actions/class.RestQtiTests.php @@ -48,6 +48,7 @@ class taoQtiTest_actions_RestQtiTests extends AbstractRestQti private const SUBCLASS_LABEL = 'subclassLabel'; private const OVERWRITE_TEST_URI = 'overwriteTestUri'; + private const PACKAGE_LABEL = 'packageLabel'; /** * @throws common_exception_NotImplemented @@ -109,7 +110,8 @@ public function import() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), - $this->getOverwriteTestUri() + $this->getOverwriteTestUri(), + $this->getPackageLabel() ); if ($report->getType() === common_report_Report::TYPE_SUCCESS) { @@ -198,7 +200,8 @@ public function importDeferred() $this->isItemMustBeOverwrittenEnabled(), $this->isOverwriteTest(), $this->getItemClassUri(), - $this->getOverwriteTestUri() + $this->getOverwriteTestUri(), + $this->getPackageLabel() ); $result = [ @@ -352,6 +355,23 @@ private function getOverwriteTestUri(): ?string return $overwriteTestUri; } + /** + * @return string|null + * @throws common_exception_RestApi + */ + private function getPackageLabel(): ?string + { + $packageLabel = $this->getPostParameter(self::PACKAGE_LABEL); + + if ($packageLabel !== null && !is_string($packageLabel)) { + throw new common_exception_RestApi( + sprintf('%s parameter should be string', self::PACKAGE_LABEL) + ); + } + + return $packageLabel; + } + /** * Get class instance to import test * diff --git a/models/classes/class.CrudQtiTestsService.php b/models/classes/class.CrudQtiTestsService.php index e46bf7a6ea..02d071ef86 100644 --- a/models/classes/class.CrudQtiTestsService.php +++ b/models/classes/class.CrudQtiTestsService.php @@ -68,7 +68,8 @@ public function importQtiTest( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $overwriteTestUri = null + ?string $overwriteTestUri = null, + ?string $packageLabel = null ) { try { //The zip extraction is a long process that can exceed the 30s timeout @@ -98,7 +99,8 @@ public function importQtiTest( $overwriteTest, $itemClassUri, [], - $overwriteTestUri + $overwriteTestUri, + $packageLabel ); helpers_TimeOutHelper::reset(); diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index e38a5285b1..c699924823 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -357,7 +357,8 @@ public function importMultipleTests( bool $overwriteTest = false, ?string $itemClassUri = null, array $form = [], - ?string $overwriteTestUri = null + ?string $overwriteTestUri = null, + ?string $packageLabel = null ) { $testClass = $targetClass; $report = new common_report_Report(common_report_Report::TYPE_INFO); @@ -427,7 +428,8 @@ public function importMultipleTests( $overwriteTest, $itemClassUri, !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false, - $overwriteTestUri + $overwriteTestUri, + $packageLabel ); $report->add($importTestReport); @@ -549,7 +551,8 @@ protected function importTest( bool $overwriteTest = false, ?string $itemClassUri = null, bool $importMetadata = false, - ?string $overwriteTestUri = null + ?string $overwriteTestUri = null, + ?string $packageLabel = null ) { /** @var ImportService $itemImportService */ $itemImportService = $this->getServiceLocator()->get(ImportService::SERVICE_ID); @@ -623,7 +626,7 @@ protected function importTest( // If any, assessmentSectionRefs will be resolved and included as part of the main test definition. $testDefinition->includeAssessmentSectionRefs(true); - $testLabel = $testDefinition->getDocumentComponent()->getTitle(); + $testLabel = $packageLabel ?? $testDefinition->getDocumentComponent()->getTitle(); if ($overwriteTestUri || $overwriteTest) { $itemsClassLabel = $testLabel; @@ -801,8 +804,9 @@ protected function importTest( $this->importTestAuxiliaryFiles($testContent, $qtiTestResource, $folder, $report); // 3. Give meaningful names to resources. - $testResource->setLabel($testDefinition->getDocumentComponent()->getTitle()); - $targetItemClass->setLabel($reportCtx->itemClass->getLabel()); + $definitionTitle = $testDefinition->getDocumentComponent()->getTitle(); + $testResource->setLabel($packageLabel ?? $definitionTitle); + $targetItemClass->setLabel($packageLabel ?? $definitionTitle); // 4. Import metadata for the resource (use same mechanics as item resources). // Metadata will be set as property values. diff --git a/models/classes/import/QtiTestImporter.php b/models/classes/import/QtiTestImporter.php index c15b4d5bbe..1da0ee65f2 100644 --- a/models/classes/import/QtiTestImporter.php +++ b/models/classes/import/QtiTestImporter.php @@ -46,6 +46,7 @@ class QtiTestImporter extends AbstractTestImporter * @param bool $overwriteTest * @param string|null $itemClassUri * @param string|null $overwriteTestUri + * @param string|null $packageLabel * @return common_report_Report */ public function import( @@ -57,7 +58,8 @@ public function import( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $overwriteTestUri = null + ?string $overwriteTestUri = null, + ?string $packageLabel = null ) { return taoQtiTest_models_classes_CrudQtiTestsService::singleton()->importQtiTest( $file, @@ -68,7 +70,8 @@ public function import( $itemMustBeOverwritten, $overwriteTest, $itemClassUri, - $overwriteTestUri + $overwriteTestUri, + $packageLabel ); } } diff --git a/models/classes/tasks/ImportQtiTest.php b/models/classes/tasks/ImportQtiTest.php index 2ff9387dd6..a826c988fc 100644 --- a/models/classes/tasks/ImportQtiTest.php +++ b/models/classes/tasks/ImportQtiTest.php @@ -55,6 +55,7 @@ class ImportQtiTest extends AbstractTaskAction implements \JsonSerializable */ public const PARAM_OVERWRITE_TEST = 'overwrite_test'; public const PARAM_OVERWRITE_TEST_URI = 'overwrite_test_uri'; + public const PARAM_PACKAGE_LABEL = 'package_label'; protected $service; @@ -95,6 +96,7 @@ public function __invoke($params) $params[self::PARAM_OVERWRITE_TEST] ?? false, $params[self::PARAM_ITEM_CLASS_URI] ?? false, $params[self::PARAM_OVERWRITE_TEST_URI] ?? null, + $params[self::PARAM_PACKAGE_LABEL] ?? null, ); return $report; @@ -128,7 +130,8 @@ public static function createTask( $itemMustBeOverwritten = false, bool $overwriteTest = false, ?string $itemClassUri = null, - ?string $overwriteTestUri = null + ?string $overwriteTestUri = null, + ?string $packageLabel = null ) { $action = new self(); $action->setServiceLocator(ServiceManager::getServiceManager()); @@ -150,6 +153,7 @@ public static function createTask( self::PARAM_OVERWRITE_TEST => $overwriteTest, self::PARAM_ITEM_CLASS_URI => $itemClassUri, self::PARAM_OVERWRITE_TEST_URI => $overwriteTestUri, + self::PARAM_PACKAGE_LABEL => $packageLabel, ], __('Import QTI TEST into "%s"', $class->getLabel()) ); From f6c647fbb273b52b4e0e2b72399a6812444856da Mon Sep 17 00:00:00 2001 From: Andrei Shapiro Date: Thu, 8 Aug 2024 16:41:44 +0300 Subject: [PATCH 9/9] chore: update swagger, add exception log --- doc/swagger.json | 28 ++++++++++++++++++++ models/classes/class.CrudQtiTestsService.php | 22 +++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/doc/swagger.json b/doc/swagger.json index 882aae9e63..d4fb7a0905 100644 --- a/doc/swagger.json +++ b/doc/swagger.json @@ -211,6 +211,13 @@ "type": "string", "required": false }, + { + "name": "overwriteTest", + "in": "formData", + "description": "Deprecated: use `overwriteTestUri` parameter with the URI of the test to be replaced. Flag that indicates if already existed tests and all related items are removed in a case they have the same title and class as uploaded tests. Can be used to replace existing test and avoid creating a new one with the same title and class. 'true' value counts as true, 'false' as false", + "type": "string", + "required": false + }, { "name": "overwriteTestUri", "in": "formData", @@ -218,6 +225,13 @@ "type": "string", "required": false }, + { + "name": "packageLabel", + "in": "formData", + "description": "Label for items folder and test label, which will be used instead of QTI test title", + "type": "string", + "required": false + }, { "name": "enableMetadataGuardians", "in": "formData", @@ -350,6 +364,13 @@ "type": "string", "required": false }, + { + "name": "overwriteTest", + "in": "formData", + "description": "Deprecated: use `overwriteTestUri` parameter with the URI of the test to be replaced. Flag that indicates if already existed tests and all related items are removed in a case they have the same title and class as uploaded tests. Can be used to replace existing test and avoid creating a new one with the same title and class. 'true' value counts as true, 'false' as false", + "type": "string", + "required": false + }, { "name": "overwriteTestUri", "in": "formData", @@ -357,6 +378,13 @@ "type": "string", "required": false }, + { + "name": "packageLabel", + "in": "formData", + "description": "Label for items folder and test label, which will be used instead of QTI test title", + "type": "string", + "required": false + }, { "name": "enableMetadataGuardians", "in": "formData", diff --git a/models/classes/class.CrudQtiTestsService.php b/models/classes/class.CrudQtiTestsService.php index 02d071ef86..bfc7655e98 100644 --- a/models/classes/class.CrudQtiTestsService.php +++ b/models/classes/class.CrudQtiTestsService.php @@ -19,6 +19,7 @@ * */ +use oat\oatbox\log\LoggerAwareTrait; use oat\tao\model\TaoOntology; /** @@ -32,6 +33,8 @@ */ class taoQtiTest_models_classes_CrudQtiTestsService extends tao_models_classes_CrudService { + use LoggerAwareTrait; + /** (non-PHPdoc) * @see tao_models_classes_CrudSservice::getClassService() */ @@ -106,7 +109,26 @@ public function importQtiTest( return $report; } catch (common_exception_UserReadableException $e) { + $this->logException($e); + return new common_report_Report(common_report_Report::TYPE_ERROR, __($e->getUserMessage())); + } catch (Throwable $exception) { + $this->logException($exception); + + return new common_report_Report(common_report_Report::TYPE_ERROR, __('QTI test import failed')); } } + + private function logException(Throwable $exception): void + { + $this->logError( + sprintf( + 'QTI test import failed: %s. File: %s, Line: %s. Stack trace: %s', + $exception->getMessage(), + $exception->getFile(), + $exception->getLine(), + $exception->getTraceAsString() + ) + ); + } }