Skip to content

fix/fields massive action multiple tab blocks - #1313

Open
Herafia wants to merge 2 commits into
11.0/bugfixesfrom
fix/fields-massive-action-multiple-tab-blocks
Open

Herafia wants to merge 2 commits into
11.0/bugfixesfrom
fix/fields-massive-action-multiple-tab-blocks

Conversation

@Herafia

@Herafia Herafia commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Checklist before requesting a review

Please delete options that are not relevant.

  • I have performed a self-review of my code.
  • I have added tests (when available) that prove my fix is effective or that my feature works.
  • I have updated the CHANGELOG with a short functional description of the fix or new feature.
  • This change requires a documentation update.

Description

  • It fixes !45895

Fixes the bulk action on a field in an “Add a Tab” block; previously, when the item had multiple blocks of this type, the value was not saved (e.g., the “Tickets” field).
Without a c_id, the plugin now also retains tab blocks for which a field is submitted, rather than just the last block.

@Herafia Herafia self-assigned this Oct 22, 2026
@Herafia Herafia added the bug label Oct 22, 2026
@Herafia

Herafia commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Do the same on the V12

@Herafia
Herafia removed the request for review from ccailly October 22, 2026 09:41
Comment thread inc/container.class.php
Comment on lines +2030 to +2054
!in_array($item::class, PluginFieldsToolbox::decodeJSONItemtypes($data['itemtypes']))
|| !Session::haveAccessToEntity($data['entities_id'], $data['is_recursive'])
) {
continue;
}

$fields = (new PluginFieldsField())->find([
'plugin_fields_containers_id' => $data['id'],
'is_active' => 1,
'type' => ['!=', 'header'],
]);
foreach ($fields as $field) {
$input_keys = [
$field['name'],
sprintf('plugin_fields_%sdropdowns_id', $field['name']),
sprintf('items_id_%s', $field['name']),
];
if (array_intersect($input_keys, array_keys($item->input)) !== []) {
$c_ids[] = (int) $data['id'];
break;
}
}
}

return $c_ids;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One fields query for all containers instead of one per container.

Suggested change
!in_array($item::class, PluginFieldsToolbox::decodeJSONItemtypes($data['itemtypes']))
|| !Session::haveAccessToEntity($data['entities_id'], $data['is_recursive'])
) {
continue;
}
$fields = (new PluginFieldsField())->find([
'plugin_fields_containers_id' => $data['id'],
'is_active' => 1,
'type' => ['!=', 'header'],
]);
foreach ($fields as $field) {
$input_keys = [
$field['name'],
sprintf('plugin_fields_%sdropdowns_id', $field['name']),
sprintf('items_id_%s', $field['name']),
];
if (array_intersect($input_keys, array_keys($item->input)) !== []) {
$c_ids[] = (int) $data['id'];
break;
}
}
}
return $c_ids;
in_array($item::class, PluginFieldsToolbox::decodeJSONItemtypes($data['itemtypes']))
&& Session::haveAccessToEntity($data['entities_id'], $data['is_recursive'])
) {
$c_ids[] = (int) $data['id'];
}
}
if ($c_ids === []) {
return [];
}
$fields = (new PluginFieldsField())->find([
'plugin_fields_containers_id' => $c_ids,
'is_active' => 1,
'type' => ['!=', 'header'],
], 'plugin_fields_containers_id');
$submitted = [];
foreach ($fields as $field) {
$input_keys = [
$field['name'],
sprintf('plugin_fields_%sdropdowns_id', $field['name']),
sprintf('items_id_%s', $field['name']),
];
if (array_intersect($input_keys, array_keys($item->input)) !== []) {
$submitted[] = (int) $field['plugin_fields_containers_id'];
}
}
return array_values(array_unique($submitted));

Comment thread inc/container.class.php
Comment on lines 2188 to +2195
$c_ids = array_filter(
[self::findContainer($item::class, 'dom'), self::findContainer($item::class, 'tab')],
static fn($id) => $id !== false,
);

// other tab containers whose fields are submitted (ex: massive action on a GLPI item
// dropdown field for which the core never displays the plugin field nor its c_id input)
$c_ids = array_values(array_unique(array_merge($c_ids, self::findSubmittedTabContainers($item))));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the default tab container last: it should still win when several are submitted.

Suggested change
$c_ids = array_values(array_unique(array_merge($c_ids, self::findSubmittedTabContainers($item))));
// other tab containers whose fields are submitted (ex: massive action on a GLPI item
// dropdown field for which the core never displays the plugin field nor its c_id input)
$c_ids = array_values(array_unique(array_filter(
[
self::findContainer($item::class, 'dom'),
...self::findSubmittedTabContainers($item),
self::findContainer($item::class, 'tab'),
],
static fn($id) => $id !== false,
)));

foreach (array_keys($this->containers) as $container_key) {
$this->assertNull($this->getStoredValues($container_key, $computer), sprintf('Unexpected values stored in "%s" container', $container_key));
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test updating fields of two tab containers in a single update()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants