diff --git a/src/Glpi/Asset/AssetDefinitionManager.php b/src/Glpi/Asset/AssetDefinitionManager.php index f9cdd28402b..d846c009338 100644 --- a/src/Glpi/Asset/AssetDefinitionManager.php +++ b/src/Glpi/Asset/AssetDefinitionManager.php @@ -390,6 +390,32 @@ public function getCapacity(string $classname): ?CapacityInterface return $this->capacities[$classname] ?? null; } + public function getAssetClassNameFromLegacyClassName(string $legacy): ?string + { + /** @var \DBmysql $DB */ + global $DB; + + // Try to load glpi_plugin_genericobject_types row for this legacy item + if (!$DB->tableExists('glpi_plugin_genericobject_types')) { + return null; + } + $rows = $DB->request([ + 'FROM' => 'glpi_plugin_genericobject_types', + 'WHERE' => ['itemtype' => $legacy], + ]); + if (count($rows) !== 1) { + return null; + } + + $row = $rows->current(); + $name = $row['name']; + return AssetDefinition::getCustomObjectNamespace() + . "\\" + . $name + . AssetDefinition::getCustomObjectClassSuffix() + ; + } + private function loadConcreteClass(AssetDefinition $definition): void { $rightname = $definition->getCustomObjectRightname(); diff --git a/src/Glpi/Form/QuestionType/QuestionTypeItem.php b/src/Glpi/Form/QuestionType/QuestionTypeItem.php index 79e9d924d37..0fda3d4c9f4 100644 --- a/src/Glpi/Form/QuestionType/QuestionTypeItem.php +++ b/src/Glpi/Form/QuestionType/QuestionTypeItem.php @@ -42,6 +42,7 @@ use DbUtils; use Dropdown; use Glpi\Application\View\TemplateRenderer; +use Glpi\Asset\AssetDefinitionManager; use Glpi\DBAL\JsonFieldInterface; use Glpi\Form\Condition\ConditionHandler\ItemAsTextConditionHandler; use Glpi\Form\Condition\ConditionHandler\ItemConditionHandler; @@ -132,8 +133,15 @@ public function convertExtraData(array $rawData): mixed $selectable_tree_root = (bool) $values['selectable_tree_root']; } + $itemtype = $rawData['itemtype'] ?? null; + // Replace generic object name with asset name if migrated + if (str_starts_with($itemtype, 'PluginGenericobject')) { + $manager = AssetDefinitionManager::getInstance(); + $itemtype = $manager->getAssetClassNameFromLegacyClassName($itemtype); + } + return (new QuestionTypeItemExtraDataConfig( - itemtype: $rawData['itemtype'] ?? null, + itemtype: $itemtype, root_items_id: $root_items_id, subtree_depth: $subtree_depth, selectable_tree_root: $selectable_tree_root diff --git a/tests/functional/Glpi/Form/Migration/FormMigrationTest.php b/tests/functional/Glpi/Form/Migration/FormMigrationTest.php index 4e5019fee3d..1f85ebc1180 100644 --- a/tests/functional/Glpi/Form/Migration/FormMigrationTest.php +++ b/tests/functional/Glpi/Form/Migration/FormMigrationTest.php @@ -85,6 +85,7 @@ use Glpi\Form\QuestionType\QuestionTypeUrgency; use Glpi\Form\Section; use Glpi\Message\MessageType; +use Glpi\Migration\GenericobjectPluginMigration; use Glpi\Migration\PluginMigrationResult; use Glpi\Tests\FormTesterTrait; use GlpiPlugin\Tester\Form\QuestionTypeIpConverter; @@ -111,6 +112,13 @@ public static function setUpBeforeClass(): void foreach ($queries as $query) { $DB->doQuery($query); } + + // Some tests in this file also require generic objects migration so + // we also load its tables. + $queries = $DB->getQueriesFromFile(sprintf('%s/tests/fixtures/genericobject-migration/genericobject-db.sql', GLPI_ROOT)); + foreach ($queries as $query) { + $DB->doQuery($query); + } } public static function tearDownAfterClass(): void @@ -122,6 +130,11 @@ public static function tearDownAfterClass(): void $DB->dropTable($table['TABLE_NAME']); } + $tables = $DB->listTables('glpi\_plugin\_genericobject\_%'); + foreach ($tables as $table) { + $DB->dropTable($table['TABLE_NAME']); + } + parent::tearDownAfterClass(); } @@ -3453,6 +3466,42 @@ public function testFormWithConditionOnCategories(): void ], $condition_data->getValue()); } + public function testFormWithQuestionReferencingGenericObject(): void + { + /** @var \DBmysql $DB */ + global $DB; + + // Arrange: create a form with a reference to generic object assets + $this->createSimpleFormcreatorForm("With generic object", [ + [ + 'name' => 'Generic object', + 'fieldtype' => 'glpiselect', + 'itemtype' => "PluginGenericobjectSmartphone", + ], + ]); + // Migrated asset definition + $asset_migrations = new GenericobjectPluginMigration($DB); + $asset_migrations->execute(); + + // Act: try to import the form + $migration = new FormMigration($DB, FormAccessControlManager::getInstance()); + $migration->execute(); + + // Assert: make sure the question was imported with the correct type + $form = getItemByTypeName(Form::class, "With generic object"); + $question_id = $this->getQuestionId($form, "Generic object"); + $question = Question::getById($question_id); + + $config = $question->getExtraDataConfig(); + if (!$config instanceof QuestionTypeItemExtraDataConfig) { + $this->fail("Unexpected config class"); + } + $this->assertEquals( + "Glpi\CustomAsset\smartphoneAsset", + $config->getItemtype() + ); + } + protected function createSimpleFormcreatorForm( string $name, array $questions,