diff --git a/model/qti/ImportService.php b/model/qti/ImportService.php index f110bec89..3a8091faf 100755 --- a/model/qti/ImportService.php +++ b/model/qti/ImportService.php @@ -337,6 +337,12 @@ public function importQTIPACKFile( $metaMetadataValues, $itemClass ); + if (empty($mappedMetadataValues)) { + $mappedMetadataValues = $this->getMetaMetadataImportMapper()->mapMetadataToProperties( + $metadataValues, + $itemClass + ); + } } $sharedFiles = []; diff --git a/model/qti/metadata/importer/MetaMetadataImportMapper.php b/model/qti/metadata/importer/MetaMetadataImportMapper.php index f88fb8711..da35f4329 100644 --- a/model/qti/metadata/importer/MetaMetadataImportMapper.php +++ b/model/qti/metadata/importer/MetaMetadataImportMapper.php @@ -22,9 +22,10 @@ namespace oat\taoQtiItem\model\qti\metadata\importer; -use core_kernel_classes_Class; +use core_kernel_classes_Class as kernelClass; use core_kernel_classes_Property as Property; use core_kernel_classes_Resource; +use InvalidArgumentException; use oat\generis\model\GenerisRdf; use oat\taoQtiItem\model\import\ChecksumGenerator; @@ -39,8 +40,8 @@ public function __construct(ChecksumGenerator $checksumGenerator) public function mapMetaMetadataToProperties( array $metaMetadataProperties, - core_kernel_classes_Class $itemClass, - core_kernel_classes_Class $testClass = null + kernelClass $itemClass, + kernelClass $testClass = null ): array { $matchedProperties = []; foreach ($metaMetadataProperties as $metaMetadataProperty) { @@ -48,13 +49,32 @@ public function mapMetaMetadataToProperties( $matchedProperties['itemProperties'][$metaMetadataProperty['uri']] = $match; } - if ($testClass && $match = $this->matchProperty($metaMetadataProperty, $testClass->getProperties(true))) { + if ( + $testClass && + $match = $this->matchProperty($metaMetadataProperty, $testClass->getProperties(true)) + ) { $matchedProperties['testProperties'][$metaMetadataProperty['uri']] = $match; } } return $matchedProperties; } + public function mapMetadataToProperties( + array $metadataProperties, + kernelClass $itemClass, + kernelClass $testClass = null + ): array { + $parsedMetadataProperties = []; + foreach ($metadataProperties as $metadataProperty) { + foreach ($metadataProperty as $property) { + $parsedMetadataProperties[] = [ + 'uri' => $property->getPath()[1], + ]; + } + } + return $this->mapMetaMetadataToProperties($parsedMetadataProperties, $itemClass, $testClass); + } + private function matchProperty(array &$metaMetadataProperty, array $classProperties): ?Property { /** @var Property $itemClassProperty */ @@ -79,14 +99,18 @@ private function matchProperty(array &$metaMetadataProperty, array $classPropert private function isSynced(Property $classProperty, array &$metaMetadataProperty): bool { $multiple = $classProperty->getOnePropertyValue(new Property(GenerisRdf::PROPERTY_MULTIPLE)); - $checksum = $this->checksumGenerator->getRangeChecksum($classProperty); + try { + $checksum = $this->checksumGenerator->getRangeChecksum($classProperty); + } catch (InvalidArgumentException $e) { + return false; + } $metaMetadataProperty['checksum_result'] = $checksum === $metaMetadataProperty['checksum']; $metaMetadataProperty['widget_result'] = - $classProperty->getWidget()->getUri() === $metaMetadataProperty['widget']; + $classProperty->getWidget() && $classProperty->getWidget()->getUri() === $metaMetadataProperty['widget']; return $multiple instanceof core_kernel_classes_Resource && $multiple->getUri() === $metaMetadataProperty['multiple'] && $checksum === $metaMetadataProperty['checksum'] - && $classProperty->getWidget()->getUri() === $metaMetadataProperty['widget']; + && $classProperty->getWidget() && $classProperty->getWidget()->getUri() === $metaMetadataProperty['widget']; } } diff --git a/test/unit/model/qti/metadata/importer/MetaMetadataImportMapperTest.php b/test/unit/model/qti/metadata/importer/MetaMetadataImportMapperTest.php index b3a05db11..fdd301bf2 100644 --- a/test/unit/model/qti/metadata/importer/MetaMetadataImportMapperTest.php +++ b/test/unit/model/qti/metadata/importer/MetaMetadataImportMapperTest.php @@ -25,13 +25,16 @@ use core_kernel_classes_Class; use core_kernel_classes_Property; use core_kernel_classes_Resource; +use InvalidArgumentException; use oat\taoQtiItem\model\import\ChecksumGenerator; use oat\taoQtiItem\model\qti\metadata\importer\MetaMetadataImportMapper; -use oat\taoQtiItem\model\qti\metadata\importer\PropertyDoesNotExistException; use PHPUnit\Framework\TestCase; class MetaMetadataImportMapperTest extends TestCase { + private ChecksumGenerator $checksumGeneratorMock; + private MetaMetadataImportMapper $subject; + public function setUp(): void { $this->checksumGeneratorMock = $this->createMock(ChecksumGenerator::class); @@ -114,4 +117,62 @@ public function testMapMetaMetadataToProperties(): void self::assertNotNull($result); self::assertEquals(1, count($result['itemProperties'])); } + + public function testMapMetadataToProperties(): void + { + $metadataProperty = $this->getMockBuilder(\stdClass::class) + ->addMethods(['getPath']) + ->getMock(); + $metadataProperty->method('getPath')->willReturn(['somePath', 'http://example.com/uri1']); + + $metadataProperties = [[$metadataProperty]]; + + $itemClass = $this->createMock(core_kernel_classes_Class::class); + $propertyMock = $this->createMock(core_kernel_classes_Property::class); + $resourceMock = $this->createMock(core_kernel_classes_Resource::class); + + $itemClass->method('getProperties')->willReturn([$propertyMock]); + $propertyMock->method('getUri')->willReturn('http://example.com/uri1'); + $propertyMock->method('getOnePropertyValue')->willReturn($resourceMock); + $propertyMock->method('getWidget')->willReturn($propertyMock); + + $resourceMock->method('getUri')->willReturn('http://resource.uri/false'); + + $this->checksumGeneratorMock->method('getRangeChecksum')->willReturn('qwerty1234'); + + $result = $this->subject->mapMetadataToProperties($metadataProperties, $itemClass); + + $this->assertArrayHasKey('itemProperties', $result); + $this->assertInstanceOf( + core_kernel_classes_Property::class, + $result['itemProperties']['http://example.com/uri1'] + ); + } + + public function testHandlesInvalidArgumentExceptionInIsSynced(): void + { + $metaMetadataProperties = [ + [ + 'uri' => 'http://example.com/uri1', + 'label' => 'label1', + 'alias' => 'alias1', + 'checksum' => 'qwerty1234', + 'multiple' => 'http://resource.uri/false', + 'widget' => 'http://widget.uri' + ] + ]; + + $itemClass = $this->createMock(core_kernel_classes_Class::class); + $propertyMock = $this->createMock(core_kernel_classes_Property::class); + + $itemClass->method('getProperties')->willReturn([$propertyMock]); + $propertyMock->method('getLabel')->willReturn('label1'); + + $this->checksumGeneratorMock->method('getRangeChecksum') + ->willThrowException(new InvalidArgumentException()); + + $result = $this->subject->mapMetaMetadataToProperties($metaMetadataProperties, $itemClass); + + $this->assertEmpty($result); + } }