1 | <?php |
||
2 | declare(strict_types=1); |
||
3 | |||
4 | namespace Nexendrie\Menu\DI; |
||
5 | |||
6 | use Nexendrie\Menu\Menu; |
||
7 | use Nexendrie\Menu\MenuItem; |
||
8 | use Nexendrie\Menu\IMenuItemCondition; |
||
9 | use Nexendrie\Menu\InvalidMenuItemDefinitionException; |
||
10 | use Nexendrie\Menu\MenuItemConditionNotSupportedException; |
||
11 | use Nexendrie\Menu\IMenuItemLinkRender; |
||
12 | |||
13 | /** |
||
14 | * MenuFactory |
||
15 | * |
||
16 | * @author Jakub Konečný |
||
17 | * @internal |
||
18 | */ |
||
19 | 1 | final class MenuFactory { |
|
20 | use \Nette\SmartObject; |
||
21 | |||
22 | private const SECTION_CONDITIONS = "conditions"; |
||
23 | |||
24 | /** @var IMenuItemLinkRender[] */ |
||
25 | private array $linkRenders; |
||
26 | /** @var IMenuItemCondition[] */ |
||
27 | private array $conditions; |
||
28 | |||
29 | /** |
||
30 | * @param IMenuItemLinkRender[] $linkRenders |
||
31 | * @param IMenuItemCondition[] $conditions |
||
32 | */ |
||
33 | public function __construct(array $linkRenders, array $conditions) { |
||
34 | 1 | $this->linkRenders = $linkRenders; |
|
35 | 1 | $this->conditions = $conditions; |
|
36 | 1 | } |
|
37 | |||
38 | /** |
||
39 | * @throws MenuItemConditionNotSupportedException |
||
40 | */ |
||
41 | private function getCondition(string $name): IMenuItemCondition { |
||
42 | 1 | foreach($this->conditions as $condition) { |
|
43 | 1 | if($condition->getName() === $name) { |
|
44 | 1 | return $condition; |
|
45 | } |
||
46 | } |
||
47 | 1 | throw new MenuItemConditionNotSupportedException("Condition $name is not defined."); |
|
48 | } |
||
49 | |||
50 | /** |
||
51 | * @throws MenuItemConditionNotSupportedException |
||
52 | */ |
||
53 | private function insertConditions(MenuItem &$item, array $definition): void { |
||
54 | 1 | if(!array_key_exists(static::SECTION_CONDITIONS, $definition) || !is_array($definition[static::SECTION_CONDITIONS])) { |
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
55 | 1 | return; |
|
56 | } |
||
57 | 1 | foreach($definition[static::SECTION_CONDITIONS] as $condition => $value) { |
|
58 | try { |
||
59 | 1 | $conditionService = $this->getCondition($condition); |
|
60 | 1 | } catch(MenuItemConditionNotSupportedException $e) { |
|
61 | 1 | throw $e; |
|
62 | } |
||
63 | 1 | $item->addCondition($conditionService, $value); |
|
64 | } |
||
65 | 1 | } |
|
66 | |||
67 | /** |
||
68 | * @param string|array $definition |
||
69 | * @throws \InvalidArgumentException |
||
70 | * @throws InvalidMenuItemDefinitionException |
||
71 | * @throws MenuItemConditionNotSupportedException |
||
72 | */ |
||
73 | private function createItem(string $text, $definition): MenuItem { |
||
74 | 1 | if(is_string($definition)) { |
|
75 | 1 | return new MenuItem($definition, $text); |
|
76 | 1 | } elseif(!is_array($definition)) { |
|
77 | 1 | throw new \InvalidArgumentException("Menu item has to be either string or array."); |
|
78 | 1 | } elseif(!array_key_exists("link", $definition)) { |
|
79 | 1 | throw new InvalidMenuItemDefinitionException("Menu item is missing link."); |
|
80 | } |
||
81 | 1 | $item = new MenuItem($definition["link"], $text); |
|
82 | 1 | $this->insertConditions($item, $definition); |
|
83 | 1 | if(isset($definition["items"]) && is_array($definition["items"])) { |
|
84 | 1 | foreach($definition["items"] as $subtext => $subdefinition) { |
|
85 | 1 | $item[] = $this->createItem($subtext, $subdefinition); |
|
86 | } |
||
87 | } |
||
88 | 1 | return $item; |
|
89 | } |
||
90 | |||
91 | /** |
||
92 | * @throws \InvalidArgumentException |
||
93 | * @throws InvalidMenuItemDefinitionException |
||
94 | * @throws MenuItemConditionNotSupportedException |
||
95 | */ |
||
96 | public function createMenu(string $name, array $config): Menu { |
||
97 | 1 | $menu = new Menu($name, $config["htmlId"]); |
|
98 | 1 | $menu->title = $config["title"]; |
|
99 | 1 | foreach($config["items"] as $text => $definition) { |
|
100 | 1 | $item = $this->createItem($text, $definition); |
|
101 | 1 | foreach($this->linkRenders as $render) { |
|
102 | 1 | $item->addLinkRender($render); |
|
103 | } |
||
104 | 1 | $menu[] = $item; |
|
105 | } |
||
106 | 1 | return $menu; |
|
107 | } |
||
108 | } |
||
109 | ?> |