*/ class taoTests_models_classes_TestsService extends OntologyClassService { public const CLASS_TEST_MODEL = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestModel'; public const PROPERTY_TEST_MODEL_IMPLEMENTATION = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestModelImplementation'; public const PROPERTY_TEST_TESTMODEL = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestTestModel'; /** @deprecated self::PROPERTY_TEST_CONTENT should be used */ public const TEST_TESTCONTENT_PROP = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestContent'; public const PROPERTY_TEST_CONTENT = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestContent'; /** * @author Joel Bout, */ public function deleteTest(core_kernel_classes_Resource $test): bool { $returnValue = false; if (!is_null($test)) { try { //delete the associated content $model = $this->getTestModel($test); $impl = $this->getTestModelImplementation($model); $impl->deleteContent($test); } catch (MissingTestmodelException $e) { // no content present, skip } $returnValue = $test->delete(); $this->getEventManager()->trigger(new TestRemovedEvent($test->getUri())); } return (bool) $returnValue; } public function deleteResource(core_kernel_classes_Resource $resource): bool { return $this->deleteTest($resource); } /** * @author Joel Bout, */ public function getRootClass(): core_kernel_classes_Class { return $this->getClass(TaoOntology::CLASS_URI_TEST); } /** * Check if the Class in parameter is a subclass of Test * * @author Joel Bout, */ public function isTestClass(core_kernel_classes_Class $clazz): bool { if ($clazz->getUri() == $this->getClass(TaoOntology::CLASS_URI_TEST)->getUri()) { return true; } foreach ($this->getClass(TaoOntology::CLASS_URI_TEST)->getSubClasses(true) as $subclass) { if ($clazz->getUri() == $subclass->getUri()) { return true; } } return false; } /** * @author Joel Bout, * @deprecated use $this->deleteClass instead */ public function deleteTestClass(core_kernel_classes_Class $clazz): bool { return $this->deleteClass($clazz); } /** * @author Joel Bout, */ public function getAllItems(): array { $returnValue = []; $itemClazz = $this->getClass(TaoOntology::CLASS_URI_ITEM); foreach ($itemClazz->getInstances(true) as $instance) { $returnValue[$instance->getUri()] = $instance->getLabel(); } return $returnValue; } /** * Used to be called whenever the label of the Test changed * Deprecated in favor of eventmanager * * @author Joel Bout, * @deprecated */ public function onChangeTestLabel(core_kernel_classes_Resource $test = null) { common_Logger::w('Call to deprecated ' . __FUNCTION__); return false; } /** * @author Joel Bout, */ public function cloneInstance(core_kernel_classes_Resource $instance, core_kernel_classes_Class $clazz = null): ?core_kernel_classes_Resource { $returnValue = null; //call the parent create instance to prevent useless process test to be created: $label = $instance->getLabel(); $cloneLabel = "$label bis"; $clone = parent::createInstance($clazz, $cloneLabel); if (!is_null($clone)) { $noCloningProperties = [ self::PROPERTY_TEST_CONTENT, OntologyRdf::RDF_TYPE ]; foreach ($clazz->getProperties(true) as $property) { if (!in_array($property->getUri(), $noCloningProperties)) { //allow clone of every property value but the deliverycontent, which is a process: foreach ($instance->getPropertyValues($property) as $propertyValue) { $clone->setPropertyValue($property, $propertyValue); } } } //Fix label if (preg_match("/bis/", $label)) { $cloneNumber = (int)preg_replace("/^(.?)*bis/", "", $label); $cloneNumber++; $cloneLabel = preg_replace("/bis(.?)*$/", "", $label) . "bis $cloneNumber" ; } $clone->setLabel($cloneLabel); $impl = $this->getTestModelImplementation($this->getTestModel($instance)); $impl->cloneContent($instance, $clone); $this->getEventManager()->trigger(new TestDuplicatedEvent($instance->getUri(), $clone->getUri())); $returnValue = $clone; } return $returnValue; } /** * @author Lionel Lecaque, lionel@taotesting.com */ protected function setDefaultModel(core_kernel_classes_Resource $test) { $testModelClass = $this->getClass(self::CLASS_TEST_MODEL); $models = $testModelClass->getInstances(); if (count($models) > 0) { $this->setTestModel($test, current($models)); } } /** * @author Joel Bout, */ public function createInstance(core_kernel_classes_Class $clazz, $label = ''): core_kernel_classes_Resource { $test = parent::createInstance($clazz, $label); $this->setDefaultModel($test); $this->getEventManager()->trigger(new TestCreatedEvent($test->getUri())); return $test; } /** * @author Joel Bout, */ public function getTestItems(core_kernel_classes_Resource $test): array { try { $model = $this->getTestModel($test); $returnValue = $this->getTestModelImplementation($model)->getItems($test); } catch (MissingTestmodelException $e) { $returnValue = []; } return $returnValue; } /** * Changes the model of the test, while trying * to carry over the items of the test */ public function setTestModel(core_kernel_classes_Resource $test, core_kernel_classes_Resource $testModel): void { $current = $test->getOnePropertyValue($this->getProperty(self::PROPERTY_TEST_TESTMODEL)); // did the model change? if (is_null($current) || !$current->equals($testModel)) { $items = []; if (!is_null($current)) { $former = $this->getTestModelImplementation($current); if (!empty($former)) { $items = $former->getItems($test); $former->deleteContent($test); } } $test->editPropertyValues($this->getProperty(self::PROPERTY_TEST_TESTMODEL), $testModel); $newImpl = $this->getTestModelImplementation($testModel); if (!empty($newImpl)) { $newImpl->prepareContent($test, $items); } } } /** * Returns a compiler instance for a given test */ public function getCompiler(core_kernel_classes_Resource $test, ServiceFileStorage $storage): tao_models_classes_Compiler { $testModel = $this->getTestModelImplementation($this->getTestModel($test)); if ($testModel instanceof TestModel) { $compiler = $testModel->getCompiler($test, $storage); } else { $testCompilerClass = $testModel->getCompilerClass(); $compiler = new $testCompilerClass($test, $storage); $compiler->setServiceLocator($storage->getServiceLocator()); } return $compiler; } /** * Returns the class of the compiler * @deprecated $this->getCompiler should be used */ public function getCompilerClass(core_kernel_classes_Resource $test): string { $testModel = $this->getTestModel($test); return $this->getTestModelImplementation($testModel)->getCompilerClass(); } /** * Returns the model of the current test * * @throws MissingTestmodelException */ public function getTestModel(core_kernel_classes_Resource $test): core_kernel_classes_Resource { $testModel = $test->getOnePropertyValue($this->getPropertyByUri(self::PROPERTY_TEST_TESTMODEL)); if (is_null($testModel)) { throw new MissingTestmodelException('Undefined testmodel for test ' . $test->getUri()); } return $testModel; } /** * Returns the implementation of an items test model */ public function getTestModelImplementation(core_kernel_classes_Resource $testModel): taoTests_models_classes_TestModel { $serviceId = (string)$testModel->getOnePropertyValue($this->getPropertyByUri(self::PROPERTY_TEST_MODEL_IMPLEMENTATION)); if (empty($serviceId)) { throw new common_exception_NoImplementation('No implementation found for testmodel ' . $testModel->getUri()); } try { $testModelService = $this->getServiceManager()->get($serviceId); } catch (\oat\oatbox\service\ServiceNotFoundException $e) { if (!class_exists($serviceId)) { throw new common_exception_Error('Test model service ' . $serviceId . ' not found'); } // for backward compatibility support classname instead of a serviceid common_Logger::w('Outdated model definition "' . $serviceId . '", please use test model service'); $testModelService = new $serviceId(); } if (!$testModelService instanceof \taoTests_models_classes_TestModel) { throw new common_exception_Error('Test model service ' . get_class($testModelService) . ' not compatible for test model ' . $testModel->getUri()); } return $testModelService; } /** * @deprecated $this->getProperty should be used */ public function getPropertyByUri(string $uri): core_kernel_classes_Property { return $this->getProperty($uri); } /** * Get serializer to persist filesystem object */ protected function getFileReferenceSerializer(): FileReferenceSerializer { return $this->getServiceManager()->get(FileReferenceSerializer::SERVICE_ID); } public function hasItems(core_kernel_classes_Resource $test): bool { return !empty($this->getTestItems($test)); } }