Using two modules: Vendor_ModuleA and Vendor_ModuleB, where Vendor_ModuleA will be a backend main menu/ACL module.
Other modules (in this example Vendor_ModuleB) should use the ACL menu of Vendor_ModuleA and append a child tree entry into the navigation.
The idea is that once this works, I can use resources for Vendor_ModuleC etc as well.
- ACL for
ModuleA:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Vendor_ModuleA::mainacl" title="Vendor Main ACL" sortOrder="1">
<resource id="Vendor_ModuleA::mainmenu" title="Vendor Module A Main Menu" sortOrder="1" />
<resource id="Vendor_ModuleA::systemconfigsettings" title="Vendor Module A Config Settings Access" />
</resource>
</resource>
</resources>
</acl>
</config>
- ACL for
Vendor_ModuleBwhich I am attempting to use the resource parent tree (Vendor_ModuleA) and add a sub node inside.
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Vendor_ModuleA::mainmenu">
<resource id="Vendor_ModuleB::top_level" title="Module B Main Menu" sortOrder="1" />
</resource>
<resource id="Vendor_ModuleA::systemconfigsettings">
<resource id="Vendor_ModuleB::systemconfigsettings" title="Module B Config Settings" />
</resource>
</resources>
</acl>
</config>
Error
This implementation results in the following error:
Could not create an acl object: Resource id 'Vendor_ModuleA::systemconfigsettings'
already exists in the ACL
Issue
Most resources append a sub-node into resource Magento_Backend::admin as shown in ModuleA, but when I try to do the same (append) using the node Vendor_ModuleA::systemconfigsettings it now seems to think I am updating it, which is not the intention.
Question
How do I correctly configure ACL node to append as a child in seperate module/s?
1 Answer 1
I managed to solve it, although unfortunately the original idea to use is now slightly more complicated than I hoped (and less maintainable if the ModuleA ACL parent nodes changes).
Solution
Use the full XML node references used in other modules, for every parent, otherwise Magento 2 currently interprets as you want to override/replace it instead of appending to ACL node
In the above example, to get Vendor_ModuleB to use the ACL nodes of Vendor_ModuleA, take the whole node structure of Vendor_ModuleA,
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Vendor_ModuleA::mainacl">
<resource id="Vendor_ModuleA::mainmenu">
<resource id="Vendor_ModuleB::top_level" title="Module B Main Menu" sortOrder="1" />
</resource>
<resource id="Vendor_ModuleA::systemconfigsettings">
<resource id="Vendor_ModuleB::systemconfigsettings" title="Module B Config Settings" />
</resource>
</resource>
</resource>
</resources>
</acl></config>
Further explanation
The important thing to take note is that the XML is not handled the same way as in layouts.
ACL (at least in ~Magento 2.3) does not use the layout method of appending content into a referenceContainer/referenceBlock'
So, when trying with the parent node to append to : Vendor_ModuleA::systemconfigsettings I assumed the ACL will use a similar loading mechanism as layouts in Magento 2, but it does not.
All parent level nodes are required.