[Feature] Allow multiple "Insertion in the form" (dom) blocks per entity#941
[Feature] Allow multiple "Insertion in the form" (dom) blocks per entity#941JeremieMercier wants to merge 18 commits into
Conversation
|
I am questioning the plugin's ability to reconcile the correct container during API calls, an issue we have encountered in the past. For example, when updating a ticket and including the "fields" in the payload, could you verify this point? |
|
Hi @stonebuzz, I retrieve the block row ID like this: Then, I update the field using the following method: So I haven’t encountered any issue with the API — unless I misunderstood how you're updating the fields via the API? |
|
It is also possible to update fields from the fields plugin during ticket update.
|
|
Hello, do you have time to review the PR ? |
|
I applied the changes for PHPStan 🤞 |
|
I don't understand @trasher With php 7.4 : |
|
A syntax error, it was slipped in after applying the suggestion 😅 |
|
Are we good this time ? 😅🤞 |
|
Hi, what's the next step ? |
|
The feature you are proposing is substantial and introduces significant changes. To ensure its smooth integration and functionality, we must be extremely vigilant. This means we need to "lock down" our testing to guarantee that everything works as expected. It is important to acknowledge that the plugin is already complex to maintain, especially with the new features introduced in GLPI. Given this complexity, we must approach any additional features with caution to ensure they do not further complicate maintenance and support. To ensure the proper functioning of this PR, here is a concise list of unit tests that should be added: Unit Tests for
|
|
Hi @stonebuzz Thanks for the message I fully understand the concerns and the importance of thorough testing. While working on the tests already partially in place, I’ve been able to identify and fix some issues especially related to "dropdown" field handling and container restriction management. I’ll keep updating here as I progress. |
|
Hi, @JeremieMercier. Edit: I've done some research and found Postman, as a tool to send HTTP requests and creating API tests |
|
I’ve added all the requested unit tests (except the API ones):
Please note I’m not a testing expert, so the tests may not follow every usual best practice. Feel free to share any feedback so I can improve. The API tests still need to be written by whoever is willing to tackle them. |
051fcd8 to
cf0f71f
Compare
|
Hello, |
Hello @CorentinS6, From my side everything seems good, it remains to be seen if a developer of the project can finalize the tests |
|
And code generated by AI ? |
Hello, All the logic is 100% mine, however for the tests, it's another story, I used AI to learn and understand the use of the tests in addition to videos like this one from Grafikart, but as I said, I'm not an expert..., the tests can also be redone by a more competent person if necessary knowing that basically, there were no tests set up on the plugin. |
|
@stonebuzz , is this work good enough for the merge now? |
af76515 to
1aa2594
Compare
Created a new method findContainers() (based on findContainer()) that returns all 'dom' containers for an item based on its entity (with parent entity handling via getAncestorsOf()).
Adapted hooks (pre_item_add, pre_item_update, post_item_add, post_item_update) to manage multiple containers using the _plugin_fields_data_multi array.
Updated the populateData() function to extract input values by stripping the prefix, ensuring that data is saved into the correct columns of the injection table.
Modified the container.form.php file to "clean" the form data (by removing the prefix) before calling updateFieldsValues(), thereby enabling the saving of domtab containers.
This PR provides the ability to define multiple "Insertion in the form" blocks for the same item based on its entity by leveraging the new findContainers() method and adapting the save process.
…oving the prefix) before calling updateFieldsValues(), thereby enabling the saving of domtab containers.
- Added missing @var annotation for global $DB - Replaced empty() on $entityIds with count() - Removed redundant is_array() check on $entityRestriction - Simplified isset() condition by removing unnecessary !== null check
Note: PHPStan still reports a type error on DB::request() (expects array<string>|string), but this issue already exists elsewhere in the file and was not introduced by this change.
update: showForTab method fix: dropdown field
• New phpunit.xml and bootstrap for the Fields plugin • PluginFieldsContainerTest covers: - Creating / reading containers - Filtering containers by entity, subtype, recursion - Hooks: preItem, postItemAdd, preItemUpdate - populateData (single + multi-dropdown) - showForTab rendering and rights checks
Remove phpunit and require_once unnecessary
7ee0d82 to
aaf0f14
Compare
|
This will be very useful, now I can only add one block to all entities, I need one per entity and this seems to solve the problem, is there something I can help with? |
|
Hi, |
| $containerID = $_POST['plugin_fields_containers_id']; | ||
| $data = []; | ||
| foreach ($_REQUEST as $key => $value) { | ||
| // if key starts with plugin_fields_<containerID>_ remove the prefix | ||
| if (strpos($key, "plugin_fields_{$containerID}_") === 0) { | ||
| $new_key = substr($key, strlen("plugin_fields_{$containerID}_")); | ||
| $data[$new_key] = $value; | ||
| } else { | ||
| $data[$key] = $value; | ||
| } | ||
| } | ||
| $container->updateFieldsValues($_REQUEST, $_REQUEST['itemtype'], false); |
There was a problem hiding this comment.
$data is computed but never used?!
| if (false !== ($data = self::populateData($c_id, $item))) { | ||
| if (!self::validateValues($data, $item->getType(), isset($_REQUEST['massiveaction']))) { | ||
| // if validation fails, we need to remove the data from the item input | ||
| $item->input = []; | ||
|
|
||
| return true; | ||
| return false; | ||
| } | ||
| $all_data[] = $data; | ||
| } |
There was a problem hiding this comment.
When an item has several applicable containers, a validation failure on any single container wipes $item->input and returns immediately, discarding the data already accumulated in $all_data for the other, valid containers. In the single-container world this was the existing behaviour (nothing else to lose), but with multiple containers per item it means one invalid field in container B now also blocks saving valid data in container A. Please confirm whether this all-or-nothing semantics is intentional; if not, previously-validated containers' data should still make it into _plugin_fields_data_multi.
| $fieldTypeName = '_plugin_fields_type_' . $id; | ||
| $fieldSubTypeName = '_plugin_fields_subtype_' . $id; | ||
|
|
||
| echo Html::hidden('_plugin_fields_type', ['value' => $type]); | ||
| echo Html::hidden('_plugin_fields_subtype', ['value' => $subtype]); | ||
| echo Html::hidden($fieldTypeName, ['value' => $type]); | ||
| echo Html::hidden($fieldSubTypeName, ['value' => $subtype]); |
There was a problem hiding this comment.
_plugin_fields_type_{id} / _plugin_fields_subtype_{id} are added alongside the existing non-suffixed hidden fields, but no other code (PHP, Twig, or JS) in the plugin reads them back. Either wire them up (presumably needed to disambiguate type/subtype per container once several dom containers coexist on one page) or drop them.
There was a problem hiding this comment.
The diff downgrades sebastian/diff from 6.0.2 (PHP >=8.2, dev-requires phpunit/phpunit ^11.0) to 4.0.6 (PHP >=7.3, dev-requires phpunit/phpunit ^9.3), alongside an unrelated phpstan/phpstan patch bump. This looks like stale lockfile drift from an out-of-sync branch rather than an intentional change for this feature. Suggest regenerating the lockfile with a clean composer update against current composer.json before merge.
| 'entities_id' => 0, | ||
| ]); | ||
|
|
||
| // 3. Injecter les données comme si elles venaient du formulaire |
There was a problem hiding this comment.
Should be in English per the project's coding conventions.






This PR provides the ability to define multiple "Insertion in the form" blocks for the same item based on its entity
Please test these modifications and verify that everything works as expected for all object types supported by the Fields plugin. Note that my tests were successful, although I focused exclusively on 'Ticket' type objects for my use case.
Checklist before requesting a review
Please delete options that are not relevant.
Issues : #744, #789, #834