Issues (3)

src/DI/MenuFactory.php (1 issue)

Severity
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
Line exceeds 120 characters; contains 122 characters
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
?>