Hi @sorenmalling
That approach within the repository seems to be nearly the same that I used for my application.
The only big difference is that I registered a custom configuration type for the Menu specifications.
Have a look at my current menu configuration, you will see it’s more or less similar:
'main':
type: complex
items:
'admin':
type: group
label: 'Admin'
icon: 'wrench'
privilege: 'Vendor.App:Access.Administration'
items:
-
type: link
label: 'User Management'
icon: 'users'
target:
package: Vendor.App
controller: Admin\User
action: index
'general':
type: group
label: 'General'
icon: 'asterisk'
expanded: true
items:
-
type: link
label: 'Homepage'
icon: 'globe'
target:
package: Vendor.App
controller: Backend
action: index
-
type: link
label: 'Google'
icon: 'google'
target: 'https://www.google.com/'
'user':
type: dropdown
class: 'dropdown-menu-right account-actions-menu'
labelledby: 'userMenuButton'
items:
-
type: link
label: 'Settings'
icon: 'cogs'
target:
package: Vendor.App
controller: UserSettings
action: index
-
type: link
label: 'Logout'
icon: 'sign-out-alt'
target:
package: Vendor.App
controller: Auth
action: logout
In addition, I added the type
property at root-level of any menu to allow rendering of different menu-types. There you can decide if it shall result in a dropdown menu or alternatively a grouped main-menu (would be possible to add more but the both suffice for my context).
By now it’s not possible to add menu-types dynamically as they are hard-coded within the ViewHelper class, but it would be easily possible to change that behaviour I think.
If anything is still unclear, I will be happy to answer any questions you may have, even though I think that the example configuration shows which features are supported by this implementation.
To return to my original topic, this is the current beginning of the MenuViewHelper
class:
(Please don’t blame me for creating such dirty code, it was kind of clean in the beginning before I tried to solve my problem)
/**
* @Flow\Scope("singleton")
*/
class MenuViewHelper extends AbstractViewHelper
{
const MENU_CONFIG_TYPE = 'Menus';
/**
* @var UriBuilder
*/
protected $uriBuilder;
/**
* @var ConfigurationManager
*/
protected $configurationManager;
/**
* @var ComplexMenuRenderer
*/
protected $complexMenuRenderer;
/**
* @var DropdownMenuRenderer
*/
protected $dropdownMenuRenderer;
public function __construct()
{
$this->objectManager = Bootstrap::$staticObjectManager;
$this->injectUriBuilder($this->objectManager->get(UriBuilder::class));
$this->configurationManager = $this->objectManager->get(ConfigurationManager::class);
$this->dropdownMenuRenderer = $this->objectManager->get(DropdownMenuRenderer::class);
$this->complexMenuRenderer = $this->objectManager->get(ComplexMenuRenderer::class);
if ($this->renderingContext instanceof FlowAwareRenderingContextInterface) {
$this->controllerContext = $renderingContext->getControllerContext();
$this->complexMenuRenderer->setControllerContext($this->controllerContext);
}
}
/**
* @param string $menu
* @return string
*/
public function render(string $menu)
{
$menuConfig = $this->configurationManager->getConfiguration(self::MENU_CONFIG_TYPE);
Assert::keyExists($menuConfig, $menu, 'No menu named %s could be found!');
$menuConfig = $menuConfig[$menu];
switch ($type = $menuConfig['type']) {
case 'complex':
return $this->complexMenuRenderer->render($menuConfig);
case 'dropdown':
return $this->dropdownMenuRenderer->render($menuConfig);
default:
throw new InvalidConfigurationException(
"Encountered an invalid menu type: $type!",
1545944440
);
}
}
/**
* Inject the UriBuilder
*
* @param UriBuilder $uriBuilder
* @return void
*/
public function injectUriBuilder(UriBuilder $uriBuilder)
{
$this->uriBuilder = $uriBuilder;
$this->uriBuilder->setRequest(
new ActionRequest(Request::createFromEnvironment())
);
}
However, I don’t think that the source code is too meaningful, as I already tried all known variants for dependency injection.
If I specify the dependencies as constructor parameters I get an error that too few arguments were passed to the constructor.
Otherwise, if I want to get the dependencies via injectSomeProperty
functions or if I specify the @Flow\Inject
annotation, the properties are simply not filled and remain null
, which then leads to an error when I want to execute a method on one of these properties.
I don’t know about any other option to inject dependencies, thus I switched to dependency fetching instead of injection for my ViewHelpers.
Actually my code is working like that, and even if it is not a very good solution, I can arrange myself to stay with this variant if no other one works.
Thank you very much for your participation in my problem.