Completed
Push — master ( bb2bf5...2dc087 )
by Jakub
08:33
created

MenuExtension::getConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 2
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
eloc 1
nc 1
nop 0
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 Nette\Utils\Strings;
14
use Nexendrie\Menu\LinkRenderPresenterAction;
15
use Nexendrie\Menu\LinkRenderJavaScriptAction;
16
use Nexendrie\Menu\LinkRenderUrl;
17
use Nette\DI\Definitions\FactoryDefinition;
18
19
/**
20
 * MenuExtension
21
 *
22
 * @author Jakub Konečný
23
 */
24 1
final class MenuExtension extends \Nette\DI\CompilerExtension {
25
  public const SERVICE_COMPONENT_FACTORY = "componentFactory";
26
  public const SERVICE_MENU_FACTORY = "menuFactory";
27
  public const SECTION_MENU_TYPES = "menu_types";
28
  
29
  /** @var array */
30
  protected $defaults = [
31
    "default" => [],
32
  ];
33
  
34
  /** @var array */
35
  protected $menuDefaults = [
36
    "title" => "",
37
    "htmlId" => "menu",
38
    "translate" => false,
39
    "items" => [],
40
  ];
41
  
42
  /** @var string[] */
43
  protected $specialSections = [];
44
  
45
  /** @var string[] */
46
  protected $defaultConditions = [
47
    "loggedIn" => ConditionUserLoggedIn::class,
48
    "role" => ConditionUserInRole::class,
49
    "acl" => ConditionPermission::class,
50
    "callback" => ConditionCallback::class,
51
  ];
52
  
53
  /** @var string[] */
54
  protected $linkRenders = [
55
    "javascript" => LinkRenderJavaScriptAction::class,
56
    "url" => LinkRenderUrl::class,
57
    "presenterAction" => LinkRenderPresenterAction::class,
58
  ];
59
  
60
  public function __construct() {
61 1
    $this->defaults[static::SECTION_MENU_TYPES] = [
62
      "inline" => __DIR__ . "/../menuInline.latte",
63
      "list" => __DIR__ . "/../menuList.latte",
64
    ];
65 1
    $constants = (new \ReflectionClass(static::class))->getConstants();
66 1
    foreach($constants as $name => $value) {
67 1
      if(Strings::startsWith($name, "SECTION_")) {
68 1
        $this->specialSections[] = $value;
69
      }
70
    }
71 1
  }
72
73
  public function getConfig(): array {
74 1
    return Helpers::merge($this->config, $this->defaults);
1 ignored issue
show
Bug Best Practice introduced by
The expression return Nette\DI\Config\H...onfig, $this->defaults) could return the type string which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
75
  }
76
77
  public function loadConfiguration(): void {
78 1
    $config = $this->getConfig();
79 1
    $builder = $this->getContainerBuilder();
80 1
    $builder->addFactoryDefinition($this->prefix(static::SERVICE_COMPONENT_FACTORY))
81 1
      ->setImplement(IMenuControlFactory::class);
82 1
    $builder->addDefinition($this->prefix(static::SERVICE_MENU_FACTORY))
83 1
      ->setType(MenuFactory::class)
84 1
      ->setAutowired(false);
85 1
    foreach($this->defaultConditions as $name => $class) {
86 1
      $builder->addDefinition($this->prefix("condition.$name"))
87 1
        ->setType($class);
88
    }
89 1
    foreach($this->linkRenders as $name => $class) {
90 1
      $builder->addDefinition($this->prefix("linkRender.$name"))
91 1
        ->setType($class);
92
    }
93 1
    foreach($config as $name => $menu) {
94 1
      if(in_array($name, $this->specialSections, true)) {
95 1
        continue;
96
      }
97
      /** @var array $data */
98 1
      $data = Helpers::merge($menu, $this->menuDefaults);
99 1
      $service = $builder->addDefinition($this->prefix($name))
100 1
        ->setFactory("@" . $this->prefix(static::SERVICE_MENU_FACTORY) . "::createMenu", [$name, $data])
101 1
        ->setAutowired(($name === "default"));
102 1
      if($data["translate"]) {
103 1
        $service->addSetup("setTranslator");
104
      }
105
    }
106 1
  }
107
  
108
  public function beforeCompile(): void {
109 1
    $builder = $this->getContainerBuilder();
110 1
    $config = $this->getConfig();
111
    /** @var FactoryDefinition $control */
112 1
    $control = $builder->getDefinition($this->prefix(static::SERVICE_COMPONENT_FACTORY));
113 1
    $menus = $builder->findByType(Menu::class);
114 1
    foreach($menus as $menuName => $menu) {
115 1
      $control->getResultDefinition()->addSetup('?->addMenu(?);', ["@self", "@$menuName"]);
116
    }
117 1
    foreach($config[static::SECTION_MENU_TYPES] as $type => $template) {
118 1
      $control->getResultDefinition()->addSetup('?->addMenuType(?,?);', ["@self", $type, $template]);
119
    }
120 1
  }
121
}
122
?>