diff --git a/CHANGELOG.md b/CHANGELOG.md index bf15da11..0896803a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fix an error displayed on the UI when trying to create a bloc display condition based on "Type" or "Model" fields for custom assets +- Fix GenericObject dropdown fields never being migrated to CustomAsset dropdown fields ## [1.24.3] - 2026-07-30 diff --git a/inc/field.class.php b/inc/field.class.php index 043e40de..07f25d69 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -155,11 +155,9 @@ public static function installBaseData(Migration $migration, $version) // Update old genericobject_itemtype dropdown fields to customasset_itemtype dropdown fields $has_genericobject_fields = $DB->tableExists('glpi_plugin_genericobject_types') - && $DB->request([ - 'COUNT' => 'id', - 'FROM' => self::getTable(), - 'WHERE' => ['type' => ['LIKE', 'dropdown-PluginGenericobject%']], - ])->current()['COUNT(id)'] > 0; + && countElementsInTable(self::getTable(), [ + 'type' => ['LIKE', 'dropdown-PluginGenericobject%'], + ]) > 0; if ($has_genericobject_fields) { // Get all types from PluginGenericobject $migration_genericobject_itemtypes = PluginFieldsMigration::getGenericObjectTypes(); diff --git a/tests/Units/FieldGenericObjectMigrationTest.php b/tests/Units/FieldGenericObjectMigrationTest.php new file mode 100644 index 00000000..1009f51c --- /dev/null +++ b/tests/Units/FieldGenericObjectMigrationTest.php @@ -0,0 +1,135 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2013-2023 by Fields plugin team. + * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + * @link https://github.com/pluginsGLPI/fields + * ------------------------------------------------------------------------- + */ + +declare(strict_types=1); + +namespace GlpiPlugin\Field\Tests\Units; + +use DBmysql; +use Glpi\Tests\DbTestCase; +use Glpi\Tests\GLPITestCase; +use GlpiPlugin\Field\Tests\FieldTestTrait; +use PluginFieldsContainer; +use PluginFieldsField; +use PluginFieldsMigration; +use Psr\Log\LogLevel; +use RuntimeException; +use Ticket; + +require_once __DIR__ . '/../FieldTestCase.php'; + +final class FieldGenericObjectMigrationTest extends DbTestCase +{ + use FieldTestTrait; + + public function setUp(): void + { + GLPITestCase::setUp(); + $this->login(); + + /** @var DBmysql $DB */ + global $DB; + $DB->doQuery( + 'CREATE TABLE IF NOT EXISTS `glpi_plugin_genericobject_types` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `itemtype` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4', + ); + } + + public function tearDown(): void + { + $this->tearDownFieldTest(); + + /** @var DBmysql $DB */ + global $DB; + $DB->dropTable('glpi_plugin_genericobject_types'); + + GLPITestCase::tearDown(); + } + + public function testMigrationGuardTriggersWhenGenericobjectFieldsExist(): void + { + $container = $this->createFieldContainer([ + 'label' => 'Genericobject Migration Container', + 'type' => 'tab', + 'itemtypes' => [Ticket::class], + 'is_active' => 1, + 'entities_id' => 0, + ]); + + $this->createField([ + 'label' => 'Genericobject Field', + 'type' => 'dropdown-PluginGenericobjectFoo', + PluginFieldsContainer::getForeignKeyField() => $container->getID(), + 'ranking' => 1, + 'is_active' => 1, + 'is_readonly' => 0, + ]); + + try { + PluginFieldsField::installBaseData(new PluginFieldsMigration('0'), '0'); + $this->fail('Expected RuntimeException was not thrown.'); + } catch (RuntimeException $runtimeException) { + $this->assertStringContainsString('GenericObject plugin cannot be migrated', $runtimeException->getMessage()); + } + + $this->hasPhpLogRecordThatContains( + 'plugin_version_genericobject method must be defined!', + LogLevel::WARNING, + ); + } + + public function testMigrationGuardDoesNotTriggerWithoutGenericobjectFields(): void + { + $container = $this->createFieldContainer([ + 'label' => 'Regular Container', + 'type' => 'tab', + 'itemtypes' => [Ticket::class], + 'is_active' => 1, + 'entities_id' => 0, + ]); + + $this->createField([ + 'label' => 'Plain Field', + 'type' => 'text', + PluginFieldsContainer::getForeignKeyField() => $container->getID(), + 'ranking' => 1, + 'is_active' => 1, + 'is_readonly' => 0, + ]); + + $result = PluginFieldsField::installBaseData(new PluginFieldsMigration('0'), '0'); + + $this->assertTrue($result); + } +}