Completed
Pull Request — dev (#19)
by Arnaud
14:27 queued 06:29
created

MenuFactory   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 80.77%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 12
c 1
b 0
f 1
lcom 1
cbo 10
dl 0
loc 168
ccs 42
cts 52
cp 0.8077
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B create() 0 49 5
A guessItemText() 0 23 3
B createMenuItemConfiguration() 0 27 3
1
<?php
2
3
namespace LAG\AdminBundle\Menu\Factory;
4
5
use Exception;
6
use Knp\Menu\FactoryInterface;
7
use Knp\Menu\ItemInterface;
8
use LAG\AdminBundle\Admin\Behaviors\TranslationKeyTrait;
9
use LAG\AdminBundle\Admin\Factory\AdminFactory;
10
use LAG\AdminBundle\Configuration\Factory\ConfigurationFactory;
11
use LAG\AdminBundle\Menu\Configuration\MenuConfiguration;
12
use LAG\AdminBundle\Menu\Configuration\MenuItemConfiguration;
13
use Symfony\Component\OptionsResolver\OptionsResolver;
14
use Symfony\Component\Translation\TranslatorInterface;
15
16
/**
17
 * Create KNP menus from given options.
18
 */
19
class MenuFactory
20
{
21
    use TranslationKeyTrait;
22
23
    /**
24
     * @var AdminFactory
25
     */
26
    protected $adminFactory;
27
28
    /**
29
     * @var FactoryInterface
30
     */
31
    protected $menuFactory;
32
33
    /**
34
     * @var ConfigurationFactory
35
     */
36
    protected $configurationFactory;
37
38
    /**
39
     * @var TranslatorInterface
40
     */
41
    protected $translator;
42
43
    /**
44
     * MenuBuilder constructor.
45
     *
46
     * @param FactoryInterface $menuFactory
47
     * @param AdminFactory $adminFactory
48
     * @param ConfigurationFactory $configurationFactory
49
     * @param TranslatorInterface $translator
50
     */
51 2
    public function __construct(
52
        FactoryInterface $menuFactory,
53
        AdminFactory $adminFactory,
54
        ConfigurationFactory $configurationFactory,
55
        TranslatorInterface $translator
56
    ) {
57 2
        $this->adminFactory = $adminFactory;
58 2
        $this->menuFactory = $menuFactory;
59 2
        $this->configurationFactory = $configurationFactory;
60 2
        $this->translator = $translator;
61 2
    }
62
63
    /**
64
     * Create a menu according to the given configuration.
65
     *
66
     * @param string $name
67
     * @param array $configuration
68
     * @return ItemInterface
69
     */
70 2
    public function create($name, array $configuration)
71
    {
72 2
        $resolver = new OptionsResolver();
73 2
        $menuConfiguration = new MenuConfiguration();
74 2
        $menuConfiguration->configureOptions($resolver);
75 2
        $menuConfiguration->setParameters($resolver->resolve($configuration));
76
77
        $menu = $this
78 2
            ->menuFactory
79 2
            ->createItem($name, [
80 2
                'childrenAttributes' => $menuConfiguration->getParameter('attr')
81
            ]);
82
83
        /**
84
         * @var string $itemName
85
         * @var MenuItemConfiguration $itemConfiguration
86
         */
87 2
        foreach ($menuConfiguration->getParameter('items') as $itemName => $itemConfiguration) {
88
            // guess item text from configuration
89 1
            $text = $this->guessItemText($itemName, $itemConfiguration);
90
91
            // item children
92 1
            $subItems = $itemConfiguration->getParameter('items');
93 1
            $hasChildren = count($subItems);
94
95
            // create menu item configuration
96 1
            $menuItemConfiguration = $this->createMenuItemConfiguration($itemConfiguration);
97
98 1
            if ($hasChildren) {
99 1
                $menuItemConfiguration['childrenAttributes']['class'] = 'nav nav-second-level collapse in';
100
            }
101
102 1
            $menu->addChild($text, $menuItemConfiguration);
103
104 1
            if ($hasChildren) {
105
106 1
                foreach ($subItems as $subItemName => $subItemConfiguration) {
107 1
                    $subMenuItemConfiguration = $this->createMenuItemConfiguration($subItemConfiguration);
108
109 1
                    $menu[$text]->addChild(
110 1
                        $this->guessItemText($subItemName, $subItemConfiguration),
111
                        $subMenuItemConfiguration
112
                    );
113
                }
114
            }
115
        }
116
117 2
        return $menu;
118
    }
119
120
    /**
121
     * Guess an item text according to the configuration.
122
     *
123
     * @param string $name
124
     * @param MenuItemConfiguration $itemConfiguration
125
     * @return string
126
     */
127 1
    protected function guessItemText($name, MenuItemConfiguration $itemConfiguration)
128
    {
129 1
        $text = $itemConfiguration->getParameter('text');
130
131 1
        if ($text) {
132
            return $text;
133
        }
134
135
        // if an admin is defined, we get the text using the translation pattern and the admin action's name
136 1
        if ($admin = $itemConfiguration->getParameter('admin')) {
137
            $translationPattern = $this
138
                ->configurationFactory
139
                ->getApplicationConfiguration()
140
                ->getParameter('translation')['pattern'];
141
            $action = $itemConfiguration->getParameter('action');
142
143
            $text = $this->getTranslationKey($translationPattern, $action, $admin);
144
        } else {
145 1
            $text = $name;
146
        }
147
148 1
        return $text;
149
    }
150
151
152
    /**
153
     * Create a knp menu item configuration from the configured options.
154
     *
155
     * @param MenuItemConfiguration $itemConfiguration
156
     * @return array
157
     * @throws Exception
158
     */
159 1
    protected function createMenuItemConfiguration(MenuItemConfiguration $itemConfiguration)
160
    {
161
        $menuItemConfiguration = [
162 1
            'childrenAttributes' => $itemConfiguration->getParameter('attr'),
163 1
            'routeParameters' => $itemConfiguration->getParameter('parameters'),
164
            'attributes' => [
165 1
                'icon' => $itemConfiguration->getParameter('icon'),
166
            ]
167
        ];
168
169 1
        if ($adminName = $itemConfiguration->getParameter('admin')) {
170
            // retrieve an existing admin
171
            $admin = $this
172
                ->adminFactory
173
                ->getAdmin($adminName);
174
175
            $menuItemConfiguration['route'] = $admin->generateRouteName($itemConfiguration->getParameter('action'));
176 1
        } else if ($route = $itemConfiguration->getParameter('route')) {
177
            // route is provided so we take it
178
            $menuItemConfiguration['route'] = $route;
179
        } else {
180
            // if no admin and no route is provided, we take the url. In knp configuration, the url parameter is uri
181 1
            $menuItemConfiguration['uri'] = $itemConfiguration->getParameter('url');
182
        }
183
184 1
        return $menuItemConfiguration;
185
    }
186
}
187