Skip to content

Commit c86b190

Browse files
Handle generic object references in forms migrations
1 parent 2827028 commit c86b190

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;
@@ -110,6 +111,13 @@ public static function setUpBeforeClass(): void
110111
foreach ($queries as $query) {
111112
$DB->doQuery($query);
112113
}
114+
115+
// Some tests in this file also require generic objects migration so
116+
// we also load its tables.
117+
$queries = $DB->getQueriesFromFile(sprintf('%s/tests/fixtures/genericobject-migration/genericobject-db.sql', GLPI_ROOT));
118+
foreach ($queries as $query) {
119+
$DB->doQuery($query);
120+
}
113121
}
114122

115123
public static function tearDownAfterClass(): void
@@ -121,6 +129,11 @@ public static function tearDownAfterClass(): void
121129
$DB->dropTable($table['TABLE_NAME']);
122130
}
123131

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

@@ -3384,6 +3397,42 @@ public function testFormWithConditionsOnInvalidQuestionForSubmitButton(): void
33843397
$this->assertTrue($result->isFullyProcessed());
33853398
}
33863399

3400+
public function testFormWithQuestionReferencingGenericObject(): void
3401+
{
3402+
/** @var \DBmysql $DB */
3403+
global $DB;
3404+
3405+
// Arrange: create a form with a reference to generic object assets
3406+
$this->createSimpleFormcreatorForm("With generic object", [
3407+
[
3408+
'name' => 'Generic object',
3409+
'fieldtype' => 'glpiselect',
3410+
'itemtype' => "PluginGenericobjectSmartphone",
3411+
],
3412+
]);
3413+
// Migrated asset definition
3414+
$asset_migrations = new GenericobjectPluginMigration($DB);
3415+
$asset_migrations->execute();
3416+
3417+
// Act: try to import the form
3418+
$migration = new FormMigration($DB, FormAccessControlManager::getInstance());
3419+
$migration->execute();
3420+
3421+
// Assert: make sure the question was imported with the correct type
3422+
$form = getItemByTypeName(Form::class, "With generic object");
3423+
$question_id = $this->getQuestionId($form, "Generic object");
3424+
$question = Question::getById($question_id);
3425+
3426+
$config = $question->getExtraDataConfig();
3427+
if (!$config instanceof QuestionTypeItemExtraDataConfig) {
3428+
$this->fail("Unexpected config class");
3429+
}
3430+
$this->assertEquals(
3431+
"Glpi\CustomAsset\smartphoneAsset",
3432+
$config->getItemtype()
3433+
);
3434+
}
3435+
33873436
protected function createSimpleFormcreatorForm(
33883437
string $name,
33893438
array $questions,

0 commit comments

Comments
 (0)