diff --git a/CHANGELOG.md b/CHANGELOG.md
index 99ef6902..102600be 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- Fix search crash when two containers share a dropdown field with the same name.
+- Prevent table and file regeneration when label and/or name is updated.
## [1.24.2] - 2026-06-30
diff --git a/inc/container.class.php b/inc/container.class.php
index 6f38c4dd..0cd19aba 100644
--- a/inc/container.class.php
+++ b/inc/container.class.php
@@ -648,7 +648,12 @@ public function defineTabs($options = [])
public function prepareInputForUpdate($input)
{
- return PluginFieldsToolbox::prepareLabel($input);
+ if (isAPI() || isset($input['form_submission'])) {
+ unset($input['label']);
+ unset($input['name']);
+ }
+
+ return $input;
}
public function prepareInputForAdd($input)
@@ -970,10 +975,23 @@ public function showForm($ID, $options = [])
echo '
';
echo "| " . __('Label') . ' : | ';
echo "";
+ $label_options = [
+ 'value' => $this->fields['label'],
+ ];
+
+ if (!$this->isNewID($ID)) {
+ $label_options['readonly'] = true;
+ }
+
echo Html::input(
'label',
+ $label_options,
+ );
+
+ echo Html::hidden(
+ 'form_submission',
[
- 'value' => $this->fields['label'],
+ 'value' => true,
],
);
echo ' | ';
diff --git a/tests/Units/ContainerTest.php b/tests/Units/ContainerTest.php
index a7fa7098..3c3465c8 100644
--- a/tests/Units/ContainerTest.php
+++ b/tests/Units/ContainerTest.php
@@ -106,4 +106,60 @@ public function testAddWithValidItemtypesSucceeds(): void
$this->assertGreaterThan(0, $container->getID());
}
+
+ public function testPrepareInputForUpdateStripsLabelAndNameOnFormSubmission(): void
+ {
+ $container = new PluginFieldsContainer();
+ $input = [
+ 'label' => 'New Label',
+ 'name' => 'new_name',
+ 'form_submission' => true,
+ 'is_active' => 1,
+ ];
+
+ $result = $container->prepareInputForUpdate($input);
+
+ $this->assertArrayNotHasKey('label', $result);
+ $this->assertArrayNotHasKey('name', $result);
+ $this->assertArrayHasKey('is_active', $result);
+ }
+
+ public function testPrepareInputForUpdatePreservesNameAndLabelForMigration(): void
+ {
+ $container = new PluginFieldsContainer();
+ $input = [
+ 'name' => 'migration_corrected_name',
+ 'label' => 'Some Label',
+ 'itemtypes' => '["Computer"]',
+ ];
+
+ $result = $container->prepareInputForUpdate($input);
+
+ $this->assertSame('migration_corrected_name', $result['name']);
+ $this->assertArrayHasKey('label', $result);
+ }
+
+ public function testUpdateNameViaMigrationPathPersistsInDatabase(): void
+ {
+ $container = $this->createFieldContainer([
+ 'label' => 'MigrationPath ' . $this->getUniqueString(),
+ 'type' => 'tab',
+ 'itemtypes' => [Computer::class],
+ 'is_active' => 1,
+ 'entities_id' => 0,
+ 'is_recursive' => 1,
+ ]);
+
+ $original_name = $container->fields['name'];
+ $new_name = 'mig_' . substr((string) $original_name, 0, 20);
+
+ $container->update(['id' => $container->getID(), 'name' => $new_name]);
+
+ $refreshed = new PluginFieldsContainer();
+ $refreshed->getFromDB($container->getID());
+ $this->assertSame($new_name, $refreshed->fields['name']);
+
+ // Restore original name so teardown can locate and drop the physical table
+ $container->update(['id' => $container->getID(), 'name' => $original_name]);
+ }
}