Completed
Push — sf/composer-install-update ( a1e834 )
by Kiyotaka
10:44
created

TwigInitializeListener::getDisplayEccubeNav()   B

Complexity

Conditions 9
Paths 10

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 10
nop 3
dl 0
loc 28
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\EventListener;
15
16
use Doctrine\ORM\NoResultException;
17
use Eccube\Common\EccubeConfig;
18
use Eccube\Entity\AuthorityRole;
19
use Eccube\Entity\Master\DeviceType;
20
use Eccube\Entity\Member;
21
use Eccube\Repository\AuthorityRoleRepository;
22
use Eccube\Repository\BaseInfoRepository;
23
use Eccube\Repository\Master\DeviceTypeRepository;
24
use Eccube\Repository\PageRepository;
25
use Eccube\Request\Context;
26
use SunCat\MobileDetectBundle\DeviceDetector\MobileDetector;
27
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
28
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
29
use Symfony\Component\HttpKernel\KernelEvents;
30
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
31
use Twig\Environment;
32
33
class TwigInitializeListener implements EventSubscriberInterface
34
{
35
    /**
36
     * @var Environment
37
     */
38
    protected $twig;
39
40
    /**
41
     * @var BaseInfoRepository
42
     */
43
    protected $baseInfoRepository;
44
45
    /**
46
     * @var DeviceTypeRepository
47
     */
48
    protected $deviceTypeRepository;
49
50
    /**
51
     * @var PageRepository
52
     */
53
    protected $pageRepository;
54
55
    /**
56
     * @var Context
57
     */
58
    protected $requestContext;
59
60
    /**
61
     * @var AuthorityRoleRepository
62
     */
63
    private $authorityRoleRepository;
64
65
    /**
66
     * @var EccubeConfig
67
     */
68
    private $eccubeConfig;
69
70
    /**
71
     * @var MobileDetector
72
     */
73
    private $mobileDetector;
74
75
    /**
76
     * @var UrlGeneratorInterface
77
     */
78
    private $router;
79
80
    /**
81
     * TwigInitializeListener constructor.
82
     *
83
     * @param Environment $twig
84
     * @param BaseInfoRepository $baseInfoRepository
85
     * @param PageRepository $pageRepository
86
     * @param DeviceTypeRepository $deviceTypeRepository
87
     * @param AuthorityRoleRepository $authorityRoleRepository
88
     * @param EccubeConfig $eccubeConfig
89
     * @param Context $context
90
     * @param MobileDetector $mobileDetector
91
     * @param UrlGeneratorInterface $router
92
     */
93
    public function __construct(
94
        Environment $twig,
95
        BaseInfoRepository $baseInfoRepository,
96
        PageRepository $pageRepository,
97
        DeviceTypeRepository $deviceTypeRepository,
98
        AuthorityRoleRepository $authorityRoleRepository,
99
        EccubeConfig $eccubeConfig,
100
        Context $context,
101
        MobileDetector $mobileDetector,
102
        UrlGeneratorInterface $router
103
    ) {
104
        $this->twig = $twig;
105
        $this->baseInfoRepository = $baseInfoRepository;
106
        $this->pageRepository = $pageRepository;
107
        $this->deviceTypeRepository = $deviceTypeRepository;
108
        $this->authorityRoleRepository = $authorityRoleRepository;
109
        $this->eccubeConfig = $eccubeConfig;
110
        $this->requestContext = $context;
111
        $this->mobileDetector = $mobileDetector;
112
        $this->router = $router;
113
    }
114
115
    /**
116
     * @param GetResponseEvent $event
117
     *
118
     * @throws NoResultException
119
     * @throws \Doctrine\ORM\NonUniqueResultException
120
     */
121
    public function onKernelRequest(GetResponseEvent $event)
122
    {
123
        $globals = $this->twig->getGlobals();
124
        if (array_key_exists('BaseInfo', $globals) && $globals['BaseInfo'] === null) {
125
            $this->twig->addGlobal('BaseInfo', $this->baseInfoRepository->get());
126
        }
127
128
        if (!$event->isMasterRequest()) {
129
            return;
130
        }
131
132
        if ($this->requestContext->isAdmin()) {
133
            $this->setAdminGlobals($event);
134
        } else {
135
            $this->setFrontVaribales($event);
136
        }
137
    }
138
139
    /**
140
     * @param GetResponseEvent $event
141
     *
142
     * @throws \Doctrine\ORM\NonUniqueResultException
143
     */
144
    public function setFrontVaribales(GetResponseEvent $event)
145
    {
146
        /** @var \Symfony\Component\HttpFoundation\ParameterBag $attributes */
147
        $attributes = $event->getRequest()->attributes;
148
        $route = $attributes->get('_route');
149
        if ($route == 'user_data') {
150
            $routeParams = $attributes->get('_route_params', []);
151
            $route = isset($routeParams['route']) ? $routeParams['route'] : $attributes->get('route', '');
152
        }
153
154
        $type = DeviceType::DEVICE_TYPE_PC;
155
        if ($this->mobileDetector->isMobile()) {
156
            $type = DeviceType::DEVICE_TYPE_MB;
157
        }
158
        $DeviceType = $this->deviceTypeRepository->find($type);
159
160
        try {
161
            $Page = $this->pageRepository->getByUrl($DeviceType, $route);
0 ignored issues
show
Documentation introduced by
$DeviceType is of type object|null, but the function expects a object<Eccube\Entity\Master\DeviceType>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
162
        } catch (NoResultException $e) {
163
            try {
164
                log_info('fallback to PC layout');
165
                $DeviceType = $this->deviceTypeRepository->find(DeviceType::DEVICE_TYPE_PC);
166
                $Page = $this->pageRepository->getByUrl($DeviceType, $route);
0 ignored issues
show
Documentation introduced by
$DeviceType is of type object|null, but the function expects a object<Eccube\Entity\Master\DeviceType>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
167
            } catch (NoResultException $e) {
168
                $Page = $this->pageRepository->newPage($DeviceType);
0 ignored issues
show
Documentation introduced by
$DeviceType is of type object|null, but the function expects a object<Eccube\Entity\Master\DeviceType>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
169
            }
170
        }
171
172
        $this->twig->addGlobal('Page', $Page);
173
        $this->twig->addGlobal('title', $Page->getName());
174
    }
175
176
    /**
177
     * @param GetResponseEvent $event
178
     */
179
    public function setAdminGlobals(GetResponseEvent $event)
180
    {
181
        // メニュー表示用配列.
182
        $menus = [];
183
        $this->twig->addGlobal('menus', $menus);
184
185
        // メニューの権限制御.
186
        $eccubeNav = $this->eccubeConfig['eccube_nav'];
187
188
        $Member = $this->requestContext->getCurrentUser();
189
        if ($Member instanceof Member) {
190
            $AuthorityRoles = $this->authorityRoleRepository->findBy(['Authority' => $Member->getAuthority()]);
191
            $baseUrl = $event->getRequest()->getBaseUrl() . '/' . $this->eccubeConfig['eccube_admin_route'];
192
            $eccubeNav = $this->getDisplayEccubeNav($eccubeNav, $AuthorityRoles, $baseUrl);
193
        }
194
        $this->twig->addGlobal('eccubeNav', $eccubeNav);
195
    }
196
197
    /**
198
     * URLに対する権限有無チェックして表示するNavを返す
199
     *
200
     * @param array $parentNav
201
     * @param AuthorityRole[] $AuthorityRoles
202
     * @param string $baseUrl
203
     *
204
     * @return array
205
     */
206
    private function getDisplayEccubeNav($parentNav, $AuthorityRoles, $baseUrl)
207
    {
208
        foreach ($parentNav as $key => $childNav) {
209
            if (array_key_exists('children', $childNav) && count($childNav['children']) > 0) {
210
                // 子のメニューがある場合は子の権限チェック
211
                $parentNav[$key]['children'] = $this->getDisplayEccubeNav($childNav['children'], $AuthorityRoles, $baseUrl);
212
213
                if (count($parentNav[$key]['children']) <= 0) {
214
                    // 子が存在しない場合は配列から削除
215
                    unset($parentNav[$key]);
216
                }
217
            } elseif (array_key_exists('url', $childNav)) {
218
                // 子のメニューがなく、URLが設定されている場合は権限があるURLか確認
219
                $param = array_key_exists('param', $childNav) ? $childNav['param'] : [];
220
                $url = $this->router->generate($childNav['url'], $param);
221
                foreach ($AuthorityRoles as $AuthorityRole) {
222
                    $denyUrl = str_replace('/', '\/', $baseUrl . $AuthorityRole->getDenyUrl());
223
                    if (preg_match("/^({$denyUrl})/i", $url)) {
224
                        // 権限がないURLの場合は配列から削除
225
                        unset($parentNav[$key]);
226
                        break;
227
                    }
228
                }
229
            }
230
        }
231
232
        return $parentNav;
233
    }
234
235
    /**
236
     * {@inheritdoc}
237
     */
238
    public static function getSubscribedEvents()
239
    {
240
        return [
241
            KernelEvents::REQUEST => [
242
                // SecurityServiceProviderで、認証処理が完了した後に実行.
243
                ['onKernelRequest', 6],
244
            ],
245
        ];
246
    }
247
}
248