Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
57 / 57
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
MainMenuBuilder
100.00% covered (success)
100.00%
57 / 57
100.00% covered (success)
100.00%
4 / 4
15
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 buildMenu
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
4
 buildMenuForBoundedContext
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
5
 createUrlList
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2namespace Apie\Cms\MenuStructure;
3
4use Apie\Cms\RouteDefinitions\AbstractCmsRouteDefinition;
5use Apie\Cms\RouteDefinitions\CmsRouteDefinitionProvider;
6use Apie\Common\MenuStructure\MenuBuilder;
7use Apie\Common\MenuStructure\MenuNode;
8use Apie\Core\BoundedContext\BoundedContext;
9use Apie\Core\BoundedContext\BoundedContextHashmap;
10use Apie\Core\BoundedContext\BoundedContextId;
11use Apie\Core\Context\ApieContext;
12use Apie\Core\ContextConstants;
13use Apie\Core\Enums\RequestMethod;
14use Apie\Core\ValueObjects\UrlRouteDefinition;
15
16class MainMenuBuilder
17{
18    public function __construct(
19        private CmsRouteDefinitionProvider $routeDefinitionProvider,
20        private BoundedContextHashmap $boundedContextHashmap
21    ) {
22    }
23
24    public function buildMenu(ApieContext $apieContext, ?BoundedContextId $prio = null): MenuNode
25    {
26        $menu = new MenuNode(
27            id: 'root',
28            name: '',
29            route: null,
30            icon: null,
31        );
32        $children = $menu->children;
33        $prioBoundedContext = $this->boundedContextHashmap[$prio?->toNative()] ?? null;
34        if ($prioBoundedContext) {
35            $subcontext = $apieContext->withContext(ContextConstants::BOUNDED_CONTEXT_ID, $prio?->toNative())
36                ->registerInstance($prioBoundedContext);
37            $children[$prio?->toNative()] = $this->buildMenuForBoundedContext($prioBoundedContext, $subcontext);
38        }
39        foreach ($this->boundedContextHashmap as $key => $boundedContext) {
40            if ($key === $prio?->toNative()) {
41                continue;
42            }
43            $subcontext = $apieContext->withContext(ContextConstants::BOUNDED_CONTEXT_ID, $key)
44                ->registerInstance($boundedContext);
45            $children[$key] = $this->buildMenuForBoundedContext($boundedContext, $subcontext);
46        }
47        $menu->children = $children;
48        return $menu;
49    }
50
51    public function buildMenuForBoundedContext(BoundedContext $boundedContext, ApieContext $apieContext): MenuNode
52    {
53        $prefix = $boundedContext->getId()->toNative() . '.';
54        $menuBuilder = new MenuBuilder($prefix);
55        $apieContext = $apieContext->withContext(
56            ContextConstants::MAIN_MENU_BUILDER,
57            1
58        )->registerInstance($this);
59        $routeDefinitions = $this->routeDefinitionProvider->getActionsForBoundedContext(
60            $boundedContext,
61            $apieContext,
62        );
63        
64        /** @var AbstractCmsRouteDefinition $routeDefinition */
65        foreach ($routeDefinitions as $routeDefinition) {
66            $url = $routeDefinition->getMainMenuUri();
67            if (!$url || !in_array($routeDefinition->getMethod(), [RequestMethod::ANY, RequestMethod::GET])) {
68                continue;
69            }
70            foreach ($this->createUrlList($boundedContext, $url) as $suffix => $createdUrl) {
71                $createdList = $createdUrl->toStringList();
72                $menuBuilder->addLeaf($createdList, new MenuNode(
73                    id: $prefix . $routeDefinition->getOperationId() . $suffix,
74                    name: $createdList->last(),
75                    route: $createdUrl->toNative(),
76                    icon: null,
77                ));
78            }
79        }
80        return $menuBuilder->getRoot();
81    }
82
83    /**
84     * @return UrlRouteDefinition[]
85     */
86    private function createUrlList(BoundedContext $boundedContext, UrlRouteDefinition $url): array
87    {
88        $placeholders = $url->getPlaceholders();
89        $urlList = [];
90        $replacements = [
91            'extension' => 'csv',
92        ];
93        foreach ($placeholders as $placeholder) {
94            if ($placeholder === ContextConstants::RESOURCE_NAME) {
95                foreach ($boundedContext->resources as $resource) {
96                    $urlList['.' . $resource->getShortName()] = $url->withFilledInPlaceholders([
97                        ContextConstants::RESOURCE_NAME => $resource->getShortName(),
98                        ...$replacements,
99                    ]);
100                }
101            }
102        }
103        return $urlList ? : ['' => $url];
104    }
105}