-
-
Notifications
You must be signed in to change notification settings - Fork 30
Open
Description
I'm trying to solve recursive schema validation in menu library when you have tree structure of menu (submenu items).
Here's what I did as temporary solution:
final class MenuExtension extends CompilerExtension
{
public function getConfigSchema(): Schema
{
return Expect::arrayOf(Expect::structure([
'loader' => Expect::string(DefaultMenuLoader::class),
'items' => Expect::array()->required(),
]));
}
public function getItemSchema(): Schema
{
return Expect::structure([
'title' => Expect::string(),
'link' => Expect::string(),
'items' => Expect::array(),
]);
}
public function loadConfiguration(): void
{
$config = $this->getConfig();
$builder = $this->getContainerBuilder();
$processor = new Processor;
foreach ($config as $menuName => $menu) {
$container->addSetup('addMenu', [
$this->loadMenuConfiguration($builder, $processor, $menuName, $menu),
]);
}
}
private function loadMenuConfiguration(
ContainerBuilder $builder,
Processor $processor,
string $menuName,
stdClass $config
): ServiceDefinition {
$loader = $config->loader;
if (!Strings::startsWith($config->loader, '@')) {
$loader = $builder->addDefinition($this->prefix('menu.'. $menuName. '.loader'))
->setType($config->loader)
->setAutowired(false);
}
if ($loader->getType() === DefaultMenuLoader::class) {
$loader->setArguments([$this->normalizeMenuItems($processor, $config->items)]);
}
}
private function normalizeMenuItems(Processor $processor, array $items): array
{
array_walk($items, function(array &$item, string $key) use ($processor): void {
$item = $processor->process($this->getItemSchema(), $item);
if ($item->title === null) {
$item->title = $key;
}
$item->items = $this->normalizeMenuItems($processor, $item->items);
});
return $items;
}
}Full file is here
- It would be nice if I could use something like
Expect::schemaFactory([$this, 'getItemSchema'])so functiongetItemSchema()could be called recursively as long as submenu's are present. - It would be nice if I could get
ProcessorinCompilerExtensionso I don't need to create one when I have custom config.
RosemaryOrchard
Metadata
Metadata
Assignees
Labels
No labels