Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/hkd 6/integration #2505

Merged
merged 99 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
4a6ce7e
chore: add form modifiers
shpran Sep 9, 2024
7566e7e
chore: rename modifier, extend abstract class
shpran Sep 10, 2024
87d4100
chore: do not replace unique ID
shpran Sep 10, 2024
b1d7231
chore: use proxies instead of manager
shpran Sep 10, 2024
90660f3
chore: fix cs
shpran Sep 10, 2024
8d869cc
chore: add unit tests for modifier
shpran Sep 11, 2024
0cc5a0f
chore: add dev-dependencies
shpran Sep 11, 2024
7741895
chore: add dev-dependencies
shpran Sep 11, 2024
968daa9
chore: add event listener to set unique identifier
shpran Sep 11, 2024
ff16c56
chore: register listener
shpran Sep 11, 2024
6be1682
chore: use direct event class, add unit test
shpran Sep 12, 2024
6e7186b
chore: update unit tests in accordance with latest changes, add new u…
shpran Sep 12, 2024
33b97b0
chore: throw an exception during retrieving, update unit test
shpran Sep 12, 2024
f97c561
chore: fix cs
shpran Sep 13, 2024
f81583b
Merge pull request #2503 from oat-sa/feature/ADF-1780/create-necessar…
gabrielfs7 Sep 13, 2024
4f0f47f
feat: create translatable test
shpran Sep 13, 2024
e54c005
chore: check for empty
shpran Sep 13, 2024
a8d93d4
chore: cache resources from the test to avoid unnecessary calls to DB
shpran Sep 16, 2024
db8b62f
chore: update dependencies
gabrielfs7 Sep 16, 2024
7988cab
chore: use standard feature flag name
gabrielfs7 Sep 16, 2024
e825534
chore: use callable class
shpran Sep 17, 2024
a3b2fe8
chore: remove unnecessary import
shpran Sep 17, 2024
430218c
chore: add exception class to logs, simplify code
shpran Sep 18, 2024
799560e
chore: add unit tests
shpran Sep 18, 2024
58b0420
Merge branch 'feat/HKD-6/integration' of https://github.com/oat-sa/ex…
shpran Sep 18, 2024
147593a
chore: adapt code to new changes
shpran Sep 18, 2024
e447f2a
chore: extract unique ID form modifiers as a separate feature
shpran Sep 19, 2024
f3cdc69
Merge pull request #2506 from oat-sa/feat/ADF-1787/create-translatabl…
gabrielfs7 Sep 19, 2024
1636ccf
chore: fix unit tests
shpran Sep 19, 2024
bc709d6
chore: fix events
shpran Sep 19, 2024
4e7a750
Merge branch 'develop' of https://github.com/oat-sa/extension-tao-tes…
gabrielfs7 Oct 14, 2024
58da18b
feat: forward the translation parameters through the config
jsconan Oct 14, 2024
64839bb
feat: forward the translation parameters to the creator factory
jsconan Oct 16, 2024
27766af
Merge pull request #2516 from oat-sa/feature/ADF-1789/forward-transla…
jsconan Oct 16, 2024
b69a123
feat: render two preview buttons for translated tests
shaveko Oct 16, 2024
11ce5eb
chore: prettify code
shaveko Oct 16, 2024
4561244
Merge pull request #2517 from oat-sa/feat/ADF-1790/preview-test-trans…
shaveko Oct 17, 2024
a239f1b
feat: manage the test translation status
jsconan Oct 18, 2024
221b0ee
feat: style for the test translation status
jsconan Oct 18, 2024
b9ff3fd
fix: height of the side bar overflow the page when the test translati…
jsconan Oct 18, 2024
e2634a0
feat: first implementation for translating titles in the test
jsconan Oct 18, 2024
707516d
fix: console error when validating a field not having DOM identifier
jsconan Oct 21, 2024
6cb5f8a
feat: set the identifiers to readonly when the translation flag is set
jsconan Oct 21, 2024
5d1e0df
feat: apply the translation mode to all titles and keep connection wi…
jsconan Oct 21, 2024
db187fd
refactor: move the translation related model preparation to a shared …
jsconan Oct 21, 2024
5545355
refactor: invert the order of original/translation to translation/ori…
jsconan Oct 22, 2024
5e42561
feat: add support for translating rubric blocks
jsconan Oct 22, 2024
7a54761
refactor: move most of the translation management to the helpers, get…
jsconan Oct 23, 2024
1076156
fix: properties mismatch when getting the translation language
jsconan Oct 23, 2024
df76a8a
feat: show the translation language with the test title
jsconan Oct 23, 2024
418d216
fix: use a better semantic selector for the configuration problems in…
jsconan Oct 23, 2024
db6bd1e
feat: add the translation status for each item
jsconan Oct 23, 2024
1237cf5
feat: split and expose more translation helpers, keep the origin mode…
jsconan Oct 23, 2024
59bda45
feat: sync new parts with the original model if they exist
jsconan Oct 23, 2024
18881ec
refactor: use a single request when getting the items status instead …
jsconan Oct 24, 2024
d5bd58c
fix: better connect the translation status with items in the test model
jsconan Oct 29, 2024
c6973c3
fix: support test items in subsections for translations
gabrielfs7 Oct 29, 2024
ebe6c90
feat: hide the actions on the testparts/sections/items/rubrics
jsconan Oct 29, 2024
3b503e0
chore: remove comments
gabrielfs7 Oct 29, 2024
da3c89a
Merge pull request #2519 from oat-sa/fix/HKD-6/support-subsection-ite…
gabrielfs7 Oct 29, 2024
32eb00a
Merge branch 'feat/HKD-6/integration' into feature/ADF-1789/side-by-s…
jsconan Oct 29, 2024
6930c99
fix: adjust size of reduced toolbars in side-by-side authoring
jsconan Oct 29, 2024
31fef68
feat: hide properties in side-by-side authoring
jsconan Oct 29, 2024
998ee1c
feat: hide the items panel in side-by-side authoring
jsconan Oct 29, 2024
425101b
fix: restore the back button in side-by-side authoring
jsconan Oct 30, 2024
000be2d
Merge pull request #2518 from oat-sa/feature/ADF-1789/side-by-side-au…
jsconan Oct 30, 2024
059fd3c
chore: bundle the assets
jsconan Oct 31, 2024
8404c50
feat: make test identifier readonly by config
shaveko Oct 31, 2024
f3cc31c
feat: rely readonly identifer on context.featureFlag.FEATURE_FLAG_UNI…
shaveko Nov 1, 2024
d720d9d
chore: add bundles
shaveko Nov 1, 2024
650a5b9
chore: prettify
shaveko Nov 4, 2024
cc44063
feat: synchronize the translated test upon edition
jsconan Nov 4, 2024
2829fa0
Merge pull request #2521 from oat-sa/feature/ADF-1789/sync-items-tran…
jsconan Nov 4, 2024
e2b1ba2
fix: call the sync action before loading the model
jsconan Nov 4, 2024
bb09f0e
chore: bundle the assets
jsconan Nov 4, 2024
82e801f
Merge pull request #2522 from oat-sa/fix/ADF-1789/sync-items-translat…
jsconan Nov 4, 2024
b9884ca
feat: better handling of unique IDs
shpran Nov 4, 2024
a665ca2
chore: do not change unique ID for translations
shpran Nov 5, 2024
e6b89dc
chore: rename migration class
shpran Nov 5, 2024
f45d3ce
fix: do not change translated test state
gabrielfs7 Nov 5, 2024
ca10e86
Merge pull request #2523 from oat-sa/feat/adf-1802/unique-identifier
gabrielfs7 Nov 5, 2024
7e31e01
fix: install the tooltips for the translation form
jsconan Nov 5, 2024
4e50a19
feat: add a clearer mention for the translation status properties
jsconan Nov 5, 2024
bba9f6a
chore: bundle the assets
jsconan Nov 5, 2024
cff4588
fix: unique identifiers
shpran Nov 6, 2024
192fffc
Merge pull request #2524 from oat-sa/fix/ADF-1789/ui-glitches
jsconan Nov 6, 2024
4f58a59
chore: refactor
shpran Nov 6, 2024
019d208
chore: move service provider to root QTI level
shpran Nov 6, 2024
b9745e7
Merge pull request #2525 from oat-sa/fix/hkd-6/unique-identifiers
shpran Nov 6, 2024
25dfe9e
chore: use generator proxy instead of separate private method
shpran Nov 6, 2024
c981321
chore: add and fix unit tests
shpran Nov 7, 2024
9301af0
chore: merge target branch and rebuild bundles
shaveko Nov 7, 2024
698fe8a
Merge pull request #2520 from oat-sa/feat/ADF-1801/backend-supplied-i…
shaveko Nov 7, 2024
50efa0b
chore: update bundle
gabrielfs7 Nov 7, 2024
07e52fa
fix: use legacy id creation method in case the container is not avail…
gabrielfs7 Nov 8, 2024
1052c35
chore: fix cs
shpran Nov 11, 2024
6551635
chore: use dev branch
shpran Nov 11, 2024
fb83f8f
chore: fix unit test
shpran Nov 11, 2024
f29c1a2
chore: update composer with releases
shpran Nov 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 30 additions & 24 deletions actions/class.Creator.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<?php

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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) 2013 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*/
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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) 2013-2024 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*/

use oat\taoQtiTest\models\TestCategoryPresetProvider;
use oat\taoQtiTest\models\TestModelService;
Expand Down Expand Up @@ -45,6 +45,11 @@ public function index()
$testUri = $this->getRequestParameter('uri');
$testModel = $this->getServiceManager()->get(TestModelService::SERVICE_ID);

// Add support for translation and side-by-side view
$originResourceUri = $this->getRequestParameter('originResourceUri');
$this->setData('translation', $this->getRequestParameter('translation') ?? "false");
$this->setData('originResourceUri', json_encode($originResourceUri));

$items = $testModel->getItems(new core_kernel_classes_Resource(tao_helpers_Uri::decode($testUri)));
foreach ($items as $item) {
$labels[$item->getUri()] = $item->getLabel();
Expand All @@ -59,6 +64,7 @@ public function index()
$this->setData('categoriesPresets', json_encode($categoriesPresetService->getAvailablePresets($runtimeConfig)));

$this->setData('loadUrl', _url('getTest', null, null, ['uri' => $testUri]));
$this->setData('loadOriginUrl', _url('getTest', null, null, ['uri' => $originResourceUri]));
$this->setData('saveUrl', _url('saveTest', null, null, ['uri' => $testUri]));

if (common_ext_ExtensionsManager::singleton()->isInstalled('taoBlueprints')) {
Expand Down Expand Up @@ -91,9 +97,9 @@ public function index()
$this->setView('creator.tpl');
}

/**
* Get json's test content, the uri of the test must be provided in parameter
*/
/**
* Get json's test content, the uri of the test must be provided in parameter
*/
public function getTest()
{
$test = $this->getCurrentTest();
Expand All @@ -104,11 +110,11 @@ public function getTest()
$this->response = $this->getPsrResponse()->withBody(stream_for($qtiTestService->getJsonTest($test)));
}

/**
* Save a test, test uri and
* The request must use the POST method and contains
* the test uri and a json string that represents the QTI Test in the model parameter.
*/
/**
* Save a test, test uri and
* The request must use the POST method and contains
* the test uri and a json string that represents the QTI Test in the model parameter.
*/
public function saveTest()
{
$saved = false;
Expand Down
14 changes: 7 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@
"oat-sa/lib-test-cat": "2.4.0",
"oat-sa/oatbox-extension-installer": "~1.1||dev-master",
"qtism/qtism": ">=0.28.3",
"oat-sa/generis": ">=15.36.4",
"oat-sa/tao-core": ">=54.21.0",
"oat-sa/extension-tao-item" : ">=12.1.0",
"oat-sa/extension-tao-itemqti" : ">=30.12.0",
"oat-sa/extension-tao-test" : ">=16.0.0",
"oat-sa/extension-tao-delivery" : ">=15.0.0",
"oat-sa/extension-tao-outcome" : ">=13.0.0",
"oat-sa/generis": ">=15.39.0",
"oat-sa/tao-core": ">=54.23.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",
"oat-sa/extension-tao-delivery": ">=15.0.0",
"oat-sa/extension-tao-outcome": ">=13.0.0",
"league/flysystem": "~1.0",
"slim/slim": "^3.0"
},
Expand Down
17 changes: 12 additions & 5 deletions manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,28 @@
*
* Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
* phpcs:disable Generic.Files.LineLength
*/

use oat\tao\model\user\TaoRoles;
use oat\taoQtiTest\model\Container\TestQtiServiceProvider;
use oat\taoQtiTest\models\classes\metadata\MetadataServiceProvider;
// phpcs:disable Generic.Files.LineLength
use oat\taoQtiTest\models\classes\render\CustomInteraction\ServiceProvider\CustomInteractionPostProcessingServiceProvider;
// phpcs:enable Generic.Files.LineLength
use oat\taoQtiTest\models\IdentifierGenerator\ServiceProvider\IdentifierGeneratorServiceProvider;
use oat\taoQtiTest\models\Qti\ServiceProvider\QtiServiceProvider;
use oat\taoQtiTest\models\render\ItemsReferencesServiceProvider;
use oat\taoQtiTest\models\TestSessionState\Container\TestSessionStateServiceProvider;
use oat\taoQtiTest\models\Translation\ServiceProvider\TranslationServiceProvider;
use oat\taoQtiTest\models\UniqueId\ServiceProvider\UniqueIdServiceProvider;
use oat\taoQtiTest\models\xmlEditor\XmlEditorInterface;
use oat\taoQtiTest\scripts\install\RegisterResultTransmissionEventHandlers;
use oat\taoQtiTest\scripts\install\SetupProvider;
use oat\taoQtiTest\scripts\install\CreateTestSessionFilesystem;
use oat\taoQtiTest\scripts\install\DisableBRSinTestAuthoring;
use oat\taoQtiTest\scripts\install\RegisterCreatorServices;
use oat\taoQtiTest\scripts\install\RegisterFrontendPaths;
use oat\taoQtiTest\scripts\install\RegisterQtiCategoryPresetProviders;
use oat\taoQtiTest\scripts\install\RegisterQtiFlysystemManager;
use oat\taoQtiTest\scripts\install\RegisterQtiPackageExporter;
use oat\taoQtiTest\scripts\install\RegisterResultTransmissionEventHandlers;
use oat\taoQtiTest\scripts\install\RegisterSectionPauseService;
use oat\taoQtiTest\scripts\install\RegisterTestCategoryPresetProviderService;
use oat\taoQtiTest\scripts\install\RegisterTestContainer;
Expand All @@ -50,6 +52,7 @@
use oat\taoQtiTest\scripts\install\SetSynchronisationService;
use oat\taoQtiTest\scripts\install\SetupDefaultTemplateConfiguration;
use oat\taoQtiTest\scripts\install\SetupEventListeners;
use oat\taoQtiTest\scripts\install\SetupProvider;
use oat\taoQtiTest\scripts\install\SetUpQueueTasks;
use oat\taoQtiTest\scripts\install\SetupStateOffloadQueue;
use oat\taoQtiTest\scripts\install\SyncChannelInstaller;
Expand Down Expand Up @@ -185,6 +188,10 @@
ItemsReferencesServiceProvider::class,
TestQtiServiceProvider::class,
TestSessionStateServiceProvider::class,
MetadataServiceProvider::class
MetadataServiceProvider::class,
TranslationServiceProvider::class,
UniqueIdServiceProvider::class,
IdentifierGeneratorServiceProvider::class,
QtiServiceProvider::class,
],
];
74 changes: 74 additions & 0 deletions migrations/Version202409111328132261_taoQtiTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace oat\taoQtiTest\migrations;

use Doctrine\DBAL\Schema\Schema;
use oat\oatbox\event\EventManager;
use oat\tao\model\resources\Event\InstanceCopiedEvent;
use oat\tao\scripts\tools\migrations\AbstractMigration;
use oat\taoQtiTest\models\classes\event\TestImportedEvent;
use oat\taoQtiTest\models\UniqueId\Listener\TestCreationListener;
use oat\taoTests\models\event\TestCreatedEvent;
use oat\taoTests\models\event\TestDuplicatedEvent;

/**
* phpcs:disable Squiz.Classes.ValidClassName
*/
final class Version202409111328132261_taoQtiTest extends AbstractMigration
{
public function getDescription(): string
{
return 'Add new listener to populate translation properties';
}

public function up(Schema $schema): void
{
/** @var EventManager $eventManager */
$eventManager = $this->getServiceManager()->get(EventManager::SERVICE_ID);

$eventManager->attach(
TestCreatedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);
$eventManager->attach(
TestDuplicatedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);
$eventManager->attach(
TestImportedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);
$eventManager->attach(
InstanceCopiedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);

$this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager);
}

public function down(Schema $schema): void
{
/** @var EventManager $eventManager */
$eventManager = $this->getServiceManager()->get(EventManager::SERVICE_ID);

$eventManager->detach(
TestCreatedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);
$eventManager->detach(
TestDuplicatedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);
$eventManager->detach(
TestImportedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);
$eventManager->detach(
InstanceCopiedEvent::class,
[TestCreationListener::class, 'populateUniqueId']
);
$this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace oat\taoQtiTest\models\IdentifierGenerator\Generator;

use core_kernel_classes_Resource;
use InvalidArgumentException;
use oat\generis\model\data\Ontology;
use oat\tao\model\IdentifierGenerator\Generator\IdentifierGeneratorInterface;
use qtism\common\utils\Format;

class QtiIdentifierGenerator implements IdentifierGeneratorInterface
{
private Ontology $ontology;

public function __construct(Ontology $ontology)
{
$this->ontology = $ontology;
}

public function generate(array $options = []): string
{
$resource = $this->getResource($options);
$label = $resource->getLabel();

$identifier = null;

if (preg_match('/^\d/', $label)) {
$identifier = 't_' . $label;
}

return str_replace('_', '-', Format::sanitizeIdentifier($identifier));
}

private function getResource(array $options): core_kernel_classes_Resource
{
if (isset($options[self::OPTION_RESOURCE_ID]) && is_string($options[self::OPTION_RESOURCE_ID])) {
return $this->ontology->getResource($options[self::OPTION_RESOURCE_ID]);
}

if (
isset($options[self::OPTION_RESOURCE])
&& $options[self::OPTION_RESOURCE] instanceof core_kernel_classes_Resource
) {
return $options[self::OPTION_RESOURCE];
}

throw new InvalidArgumentException(
'Test QTI Identifier generation failure: resource is required'
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace oat\taoQtiTest\models\IdentifierGenerator\ServiceProvider;

use oat\generis\model\data\Ontology;
use oat\generis\model\DependencyInjection\ContainerServiceProviderInterface;
use oat\tao\model\IdentifierGenerator\Generator\IdentifierGeneratorProxy;
use oat\tao\model\TaoOntology;
use oat\taoQtiTest\models\IdentifierGenerator\Generator\QtiIdentifierGenerator;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

use function Symfony\Component\DependencyInjection\Loader\Configurator\service;

class IdentifierGeneratorServiceProvider implements ContainerServiceProviderInterface
{
public function __invoke(ContainerConfigurator $configurator): void
{
$services = $configurator->services();

$services
->set(QtiIdentifierGenerator::class, QtiIdentifierGenerator::class)
->args([
service(Ontology::SERVICE_ID),
]);

$services
->get(IdentifierGeneratorProxy::class)
->call(
'addIdentifierGenerator',
[
service(QtiIdentifierGenerator::class),
TaoOntology::CLASS_URI_TEST,
]
);
}
}
50 changes: 50 additions & 0 deletions models/classes/Qti/Identifier/Service/QtiIdentifierSetter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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) 2024 (original work) Open Assessment Technologies SA.
*/

declare(strict_types=1);

namespace oat\taoQtiTest\models\Qti\Identifier\Service;

use oat\tao\model\Translation\Service\AbstractQtiIdentifierSetter;
use Psr\Log\LoggerInterface;
use taoQtiTest_models_classes_QtiTestService;

class QtiIdentifierSetter extends AbstractQtiIdentifierSetter
{
private taoQtiTest_models_classes_QtiTestService $qtiTestService;

public function __construct(taoQtiTest_models_classes_QtiTestService $qtiTestService, LoggerInterface $logger)
{
parent::__construct($logger);

$this->qtiTestService = $qtiTestService;
}

protected function applyIdentifier(array $options): void
{
$test = $this->getResource($options);
$jsonTest = $this->qtiTestService->getJsonTest($test);

$decodedTest = json_decode($jsonTest, true, 512, JSON_THROW_ON_ERROR);
$decodedTest['identifier'] = $this->getIdentifier($options);

$this->qtiTestService->saveJsonTest($test, json_encode($decodedTest));
}
}
Loading
Loading