Completed
Push — master ( 3a65e8...9f4bbe )
by Grégoire
16s
created

GroupMenuProvider::has()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\AdminBundle\Menu\Provider;
13
14
use Knp\Menu\FactoryInterface;
15
use Knp\Menu\Provider\MenuProviderInterface;
16
use Sonata\AdminBundle\Admin\Pool;
17
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
18
19
/**
20
 * Menu provider based on group options.
21
 *
22
 * @author Alexandru Furculita <[email protected]>
23
 */
24
class GroupMenuProvider implements MenuProviderInterface
25
{
26
    /**
27
     * @var FactoryInterface
28
     */
29
    private $menuFactory;
30
31
    /**
32
     * @var Pool
33
     */
34
    private $pool;
35
36
    /**
37
     * @var AuthorizationCheckerInterface
38
     */
39
    private $checker;
40
41
    /**
42
     * NEXT_MAJOR: Remove default value null of $checker.
43
     *
44
     * @param FactoryInterface                   $menuFactory
45
     * @param Pool                               $pool
46
     * @param AuthorizationCheckerInterface|null $checker
47
     */
48
    public function __construct(FactoryInterface $menuFactory, Pool $pool, $checker = null)
49
    {
50
        $this->menuFactory = $menuFactory;
51
        $this->pool = $pool;
52
53
        /*
54
         * NEXT_MAJOR: Remove this if blocks.
55
         * NEXT_MAJOR: Move AuthorizationCheckerInterface check to method signature.
56
         */
57
        if (null === $checker) {
58
            @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
59
                'Passing no 3rd argument is deprecated since version 3.10 and will be mandatory in 4.0.
60
                Pass Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface as 3rd argument.',
61
                E_USER_DEPRECATED
62
            );
63
        } elseif (!$checker instanceof AuthorizationCheckerInterface) {
64
            throw new \InvalidArgumentException(
65
                'Argument 3 must be an instance of \Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'
66
            );
67
        }
68
69
        $this->checker = $checker;
70
    }
71
72
    /**
73
     * Retrieves the menu based on the group options.
74
     *
75
     * @param string $name
76
     * @param array  $options
77
     *
78
     * @return \Knp\Menu\ItemInterface
79
     *
80
     * @throws \InvalidArgumentException if the menu does not exists
81
     */
82
    public function get($name, array $options = [])
83
    {
84
        $group = $options['group'];
85
86
        $menuItem = $this->menuFactory->createItem(
87
            $options['name'],
88
            [
89
                'label' => $group['label'],
90
            ]
91
        );
92
93
        if (empty($group['on_top'])) {
94
            foreach ($group['items'] as $item) {
95
                if (isset($item['admin']) && !empty($item['admin'])) {
96
                    $admin = $this->pool->getInstance($item['admin']);
97
98
                    // skip menu item if no `list` url is available or user doesn't have the LIST access rights
99
                    if (!$admin->hasRoute('list') || !$admin->hasAccess('list')) {
100
                        continue;
101
                    }
102
103
                    $label = $admin->getLabel();
104
                    $options = $admin->generateMenuUrl('list', [], $item['route_absolute']);
105
                    $options['extras'] = [
106
                        'label_catalogue' => $admin->getTranslationDomain(),
107
                        'admin' => $admin,
108
                    ];
109
                } else {
110
                    //NEXT_MAJOR: Remove if statement of null checker.
111
                    if (null !== $this->checker) {
112
                        if ((!empty($item['roles']) && !$this->checker->isGranted($item['roles']))
113
                            || (!empty($group['roles']) && !$this->checker->isGranted($group['roles'], $item['route']))
114
                        ) {
115
                            continue;
116
                        }
117
                    }
118
119
                    $label = $item['label'];
120
                    $options = [
121
                        'route' => $item['route'],
122
                        'routeParameters' => $item['route_params'],
123
                        'routeAbsolute' => $item['route_absolute'],
124
                        'extras' => [
125
                            'label_catalogue' => $group['label_catalogue'],
126
                        ],
127
                    ];
128
                }
129
130
                $menuItem->addChild($label, $options);
131
            }
132
133
            if (false === $menuItem->hasChildren()) {
134
                $menuItem->setDisplay(false);
135
            } elseif (!empty($group['keep_open'])) {
136
                $menuItem->setAttribute('class', 'keep-open');
137
                $menuItem->setExtra('keep_open', $group['keep_open']);
138
            }
139
        } else {
140
            foreach ($group['items'] as $item) {
141
                if (isset($item['admin']) && !empty($item['admin'])) {
142
                    $admin = $this->pool->getInstance($item['admin']);
143
144
                    // Do not display group if no `list` url is available or user doesn't have the LIST access rights
145
                    if (!$admin->hasRoute('list') || !$admin->hasAccess('list')) {
146
                        $menuItem->setDisplay(false);
147
148
                        continue;
149
                    }
150
151
                    $options = $admin->generateUrl('list');
152
                    $menuItem->setExtra('route', $admin->getBaseRouteName().'_list');
153
                    $menuItem->setExtra('on_top', $group['on_top']);
154
                    $menuItem->setUri($options);
155
                } else {
156
                    $router = $this->pool->getContainer()->get('router');
157
                    $menuItem->setUri($router->generate($item['route']));
158
                }
159
            }
160
        }
161
162
        return $menuItem;
163
    }
164
165
    /**
166
     * Checks whether a menu exists in this provider.
167
     *
168
     * @param string $name
169
     * @param array  $options
170
     *
171
     * @return bool
172
     */
173
    public function has($name, array $options = [])
174
    {
175
        return 'sonata_group_menu' === $name;
176
    }
177
}
178