MenuExtension   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 0 Features 1
Metric Value
eloc 59
c 6
b 0
f 1
dl 0
loc 93
ccs 39
cts 39
cp 1
rs 10
wmc 13

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfig() 0 2 1
A __construct() 0 9 3
B loadConfiguration() 0 27 6
A beforeCompile() 0 11 3
1
<?php
2
declare(strict_types=1);
3
4
namespace Nexendrie\Menu\DI;
5
6
use Nexendrie\Menu\IMenuControlFactory;
7
use Nexendrie\Menu\Menu;
8
use Nette\DI\Config\Helpers;
9
use Nexendrie\Menu\ConditionUserLoggedIn;
10
use Nexendrie\Menu\ConditionUserInRole;
11
use Nexendrie\Menu\ConditionPermission;
12
use Nexendrie\Menu\ConditionCallback;
13
use Nexendrie\Menu\LinkRenderPresenterAction;
14
use Nexendrie\Menu\LinkRenderJavaScriptAction;
15
use Nexendrie\Menu\LinkRenderUrl;
16
use Nette\DI\Definitions\FactoryDefinition;
17
18
/**
19
 * MenuExtension
20
 *
21
 * @author Jakub Konečný
22
 */
23 1
final class MenuExtension extends \Nette\DI\CompilerExtension {
24
  public const SERVICE_COMPONENT_FACTORY = "componentFactory";
25
  public const SERVICE_MENU_FACTORY = "menuFactory";
26
  public const SECTION_MENU_TYPES = "menu_types";
27
28
  private array $defaults = [
29
    "default" => [],
30
  ];
31
32
  private array $menuDefaults = [
33
    "title" => "",
34
    "htmlId" => "menu",
35
    "translate" => false,
36
    "items" => [],
37
  ];
38
  
39
  /** @var string[] */
40
  private array $specialSections = [];
41
  
42
  /** @var string[] */
43
  private array $defaultConditions = [
44
    "loggedIn" => ConditionUserLoggedIn::class,
45
    "role" => ConditionUserInRole::class,
46
    "acl" => ConditionPermission::class,
47
    "callback" => ConditionCallback::class,
48
  ];
49
  
50
  /** @var string[] */
51
  private array $linkRenders = [
52
    "javascript" => LinkRenderJavaScriptAction::class,
53
    "url" => LinkRenderUrl::class,
54
    "presenterAction" => LinkRenderPresenterAction::class,
55
  ];
56
  
57
  public function __construct() {
58 1
    $this->defaults[static::SECTION_MENU_TYPES] = [
59
      "inline" => __DIR__ . "/../menuInline.latte",
60
      "list" => __DIR__ . "/../menuList.latte",
61
    ];
62 1
    $constants = (new \ReflectionClass(static::class))->getConstants();
63 1
    foreach($constants as $name => $value) {
64 1
      if(str_starts_with($name, "SECTION_")) {
65 1
        $this->specialSections[] = $value;
66
      }
67
    }
68 1
  }
69
70
  public function getConfig(): array {
71 1
    return Helpers::merge($this->config, $this->defaults);
72
  }
73
74
  public function loadConfiguration(): void {
75 1
    $config = $this->getConfig();
76 1
    $builder = $this->getContainerBuilder();
77 1
    $builder->addFactoryDefinition($this->prefix(static::SERVICE_COMPONENT_FACTORY))
78 1
      ->setImplement(IMenuControlFactory::class);
79 1
    $builder->addDefinition($this->prefix(static::SERVICE_MENU_FACTORY))
80 1
      ->setType(MenuFactory::class)
81 1
      ->setAutowired(false);
82 1
    foreach($this->defaultConditions as $name => $class) {
83 1
      $builder->addDefinition($this->prefix("condition.$name"))
84 1
        ->setType($class);
85
    }
86 1
    foreach($this->linkRenders as $name => $class) {
87 1
      $builder->addDefinition($this->prefix("linkRender.$name"))
88 1
        ->setType($class);
89
    }
90 1
    foreach($config as $name => $menu) {
91 1
      if(in_array($name, $this->specialSections, true)) {
92 1
        continue;
93
      }
94
      /** @var array $data */
95 1
      $data = Helpers::merge($menu, $this->menuDefaults);
96 1
      $service = $builder->addDefinition($this->prefix($name))
97 1
        ->setFactory("@" . $this->prefix(static::SERVICE_MENU_FACTORY) . "::createMenu", [$name, $data])
98 1
        ->setAutowired(($name === "default"));
99 1
      if($data["translate"]) {
100 1
        $service->addSetup("setTranslator");
101
      }
102
    }
103 1
  }
104
  
105
  public function beforeCompile(): void {
106 1
    $builder = $this->getContainerBuilder();
107 1
    $config = $this->getConfig();
108
    /** @var FactoryDefinition $control */
109 1
    $control = $builder->getDefinition($this->prefix(static::SERVICE_COMPONENT_FACTORY));
110 1
    $menus = $builder->findByType(Menu::class);
111 1
    foreach($menus as $menuName => $menu) {
112 1
      $control->getResultDefinition()->addSetup('?->addMenu(?);', ["@self", "@$menuName"]);
113
    }
114 1
    foreach($config[static::SECTION_MENU_TYPES] as $type => $template) {
115 1
      $control->getResultDefinition()->addSetup('?->addMenuType(?,?);', ["@self", $type, $template]);
116
    }
117 1
  }
118
}
119
?>