Skip to content

Commit 8ff70d1

Browse files
Handle generic object references in forms migrations
1 parent cc634f8 commit 8ff70d1

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

src/Glpi/Asset/AssetDefinitionManager.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,32 @@ public function getCapacity(string $classname): ?CapacityInterface
390390
return $this->capacities[$classname] ?? null;
391391
}
392392

393+
public function getAssetClassNameFromLegacyClassName(string $legacy): ?string
394+
{
395+
/** @var \DBmysql $DB */
396+
global $DB;
397+
398+
// Try to load glpi_plugin_genericobject_types row for this legacy item
399+
if (!$DB->tableExists('glpi_plugin_genericobject_types')) {
400+
return null;
401+
}
402+
$rows = $DB->request([
403+
'FROM' => 'glpi_plugin_genericobject_types',
404+
'WHERE' => ['itemtype' => $legacy],
405+
]);
406+
if (count($rows) !== 1) {
407+
return null;
408+
}
409+
410+
$row = $rows->current();
411+
$name = $row['name'];
412+
return AssetDefinition::getCustomObjectNamespace()
413+
. "\\"
414+
. $name
415+
. AssetDefinition::getCustomObjectClassSuffix()
416+
;
417+
}
418+
393419
private function loadConcreteClass(AssetDefinition $definition): void
394420
{
395421
$rightname = $definition->getCustomObjectRightname();

src/Glpi/Form/QuestionType/QuestionTypeItem.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
use DbUtils;
4343
use Dropdown;
4444
use Glpi\Application\View\TemplateRenderer;
45+
use Glpi\Asset\AssetDefinitionManager;
4546
use Glpi\DBAL\JsonFieldInterface;
4647
use Glpi\Form\Condition\ConditionHandler\ItemAsTextConditionHandler;
4748
use Glpi\Form\Condition\ConditionHandler\ItemConditionHandler;
@@ -132,8 +133,15 @@ public function convertExtraData(array $rawData): mixed
132133
$selectable_tree_root = (bool) $values['selectable_tree_root'];
133134
}
134135

136+
$itemtype = $rawData['itemtype'] ?? null;
137+
// Replace generic object name with asset name if migrated
138+
if (str_starts_with($itemtype, 'PluginGenericobject')) {
139+
$manager = AssetDefinitionManager::getInstance();
140+
$itemtype = $manager->getAssetClassNameFromLegacyClassName($itemtype);
141+
}
142+
135143
return (new QuestionTypeItemExtraDataConfig(
136-
itemtype: $rawData['itemtype'] ?? null,
144+
itemtype: $itemtype,
137145
root_items_id: $root_items_id,
138146
subtree_depth: $subtree_depth,
139147
selectable_tree_root: $selectable_tree_root

tests/functional/Glpi/Form/Migration/FormMigrationTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
use Glpi\Form\QuestionType\QuestionTypeUrgency;
8686
use Glpi\Form\Section;
8787
use Glpi\Message\MessageType;
88+
use Glpi\Migration\GenericobjectPluginMigration;
8889
use Glpi\Migration\PluginMigrationResult;
8990
use Glpi\Tests\FormTesterTrait;
9091
use GlpiPlugin\Tester\Form\QuestionTypeIpConverter;
@@ -111,6 +112,13 @@ public static function setUpBeforeClass(): void
111112
foreach ($queries as $query) {
112113
$DB->doQuery($query);
113114
}
115+
116+
// Some tests in this file also require generic objects migration so
117+
// we also load its tables.
118+
$queries = $DB->getQueriesFromFile(sprintf('%s/tests/fixtures/genericobject-migration/genericobject-db.sql', GLPI_ROOT));
119+
foreach ($queries as $query) {
120+
$DB->doQuery($query);
121+
}
114122
}
115123

116124
public static function tearDownAfterClass(): void
@@ -122,6 +130,11 @@ public static function tearDownAfterClass(): void
122130
$DB->dropTable($table['TABLE_NAME']);
123131
}
124132

133+
$tables = $DB->listTables('glpi\_plugin\_genericobject\_%');
134+
foreach ($tables as $table) {
135+
$DB->dropTable($table['TABLE_NAME']);
136+
}
137+
125138
parent::tearDownAfterClass();
126139
}
127140

@@ -3453,6 +3466,42 @@ public function testFormWithConditionOnCategories(): void
34533466
], $condition_data->getValue());
34543467
}
34553468

3469+
public function testFormWithQuestionReferencingGenericObject(): void
3470+
{
3471+
/** @var \DBmysql $DB */
3472+
global $DB;
3473+
3474+
// Arrange: create a form with a reference to generic object assets
3475+
$this->createSimpleFormcreatorForm("With generic object", [
3476+
[
3477+
'name' => 'Generic object',
3478+
'fieldtype' => 'glpiselect',
3479+
'itemtype' => "PluginGenericobjectSmartphone",
3480+
],
3481+
]);
3482+
// Migrated asset definition
3483+
$asset_migrations = new GenericobjectPluginMigration($DB);
3484+
$asset_migrations->execute();
3485+
3486+
// Act: try to import the form
3487+
$migration = new FormMigration($DB, FormAccessControlManager::getInstance());
3488+
$migration->execute();
3489+
3490+
// Assert: make sure the question was imported with the correct type
3491+
$form = getItemByTypeName(Form::class, "With generic object");
3492+
$question_id = $this->getQuestionId($form, "Generic object");
3493+
$question = Question::getById($question_id);
3494+
3495+
$config = $question->getExtraDataConfig();
3496+
if (!$config instanceof QuestionTypeItemExtraDataConfig) {
3497+
$this->fail("Unexpected config class");
3498+
}
3499+
$this->assertEquals(
3500+
"Glpi\CustomAsset\smartphoneAsset",
3501+
$config->getItemtype()
3502+
);
3503+
}
3504+
34563505
protected function createSimpleFormcreatorForm(
34573506
string $name,
34583507
array $questions,

0 commit comments

Comments
 (0)