Passed
Push — master ( a7342a...509034 )
by Jakub
01:53
created

MenuFactory::createItem()   C

Complexity

Conditions 11
Paths 8

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 11

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 17
cts 17
cp 1
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 19
nc 8
nop 2
crap 11

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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