Failed Conditions
Push — sf/last-boss ( 98c677...e157b8 )
by Kiyotaka
05:51
created

TwigInitializeListener::setFrontVariables()   C

Complexity

Conditions 11
Paths 288

Size

Total Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 288
nop 1
dl 0
loc 56
rs 5.2666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Layout;
20
use Eccube\Entity\Master\DeviceType;
21
use Eccube\Entity\Member;
22
use Eccube\Entity\Page;
23
use Eccube\Entity\PageLayout;
24
use Eccube\Repository\AuthorityRoleRepository;
25
use Eccube\Repository\BaseInfoRepository;
26
use Eccube\Repository\LayoutRepository;
27
use Eccube\Repository\Master\DeviceTypeRepository;
28
use Eccube\Repository\PageRepository;
29
use Eccube\Request\Context;
30
use SunCat\MobileDetectBundle\DeviceDetector\MobileDetector;
31
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
32
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
33
use Symfony\Component\HttpKernel\KernelEvents;
34
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
35
use Twig\Environment;
36
37
class TwigInitializeListener implements EventSubscriberInterface
38
{
39
    /**
40
     * @var bool 初期化済かどうか.
41
     */
42
    protected $initialized = false;
43
44
    /**
45
     * @var Environment
46
     */
47
    protected $twig;
48
49
    /**
50
     * @var BaseInfoRepository
51
     */
52
    protected $baseInfoRepository;
53
54
    /**
55
     * @var DeviceTypeRepository
56
     */
57
    protected $deviceTypeRepository;
58
59
    /**
60
     * @var PageRepository
61
     */
62
    protected $pageRepository;
63
64
    /**
65
     * @var Context
66
     */
67
    protected $requestContext;
68
69
    /**
70
     * @var AuthorityRoleRepository
71
     */
72
    private $authorityRoleRepository;
73
74
    /**
75
     * @var EccubeConfig
76
     */
77
    private $eccubeConfig;
78
79
    /**
80
     * @var MobileDetector
81
     */
82
    private $mobileDetector;
83
84
    /**
85
     * @var UrlGeneratorInterface
86
     */
87
    private $router;
88
89
    /**
90
     * @var LayoutRepository
91
     */
92
    private $layoutRepository;
93
94
    /**
95
     * TwigInitializeListener constructor.
96
     *
97
     * @param Environment $twig
98
     * @param BaseInfoRepository $baseInfoRepository
99
     * @param PageRepository $pageRepository
100
     * @param DeviceTypeRepository $deviceTypeRepository
101
     * @param AuthorityRoleRepository $authorityRoleRepository
102
     * @param EccubeConfig $eccubeConfig
103
     * @param Context $context
104
     * @param MobileDetector $mobileDetector
105
     * @param UrlGeneratorInterface $router
106
     * @param LayoutRepository $layoutRepository
107
     */
108
    public function __construct(
109
        Environment $twig,
110
        BaseInfoRepository $baseInfoRepository,
111
        PageRepository $pageRepository,
112
        DeviceTypeRepository $deviceTypeRepository,
113
        AuthorityRoleRepository $authorityRoleRepository,
114
        EccubeConfig $eccubeConfig,
115
        Context $context,
116
        MobileDetector $mobileDetector,
117
        UrlGeneratorInterface $router,
118
        LayoutRepository $layoutRepository
119
    ) {
120
        $this->twig = $twig;
121
        $this->baseInfoRepository = $baseInfoRepository;
122
        $this->pageRepository = $pageRepository;
123
        $this->deviceTypeRepository = $deviceTypeRepository;
124
        $this->authorityRoleRepository = $authorityRoleRepository;
125
        $this->eccubeConfig = $eccubeConfig;
126
        $this->requestContext = $context;
127
        $this->mobileDetector = $mobileDetector;
128
        $this->router = $router;
129
        $this->layoutRepository = $layoutRepository;
130
    }
131
132
    /**
133
     * @param GetResponseEvent $event
134
     *
135
     * @throws NoResultException
136
     * @throws \Doctrine\ORM\NonUniqueResultException
137
     */
138
    public function onKernelRequest(GetResponseEvent $event)
139
    {
140
        if ($this->initialized) {
141
            return;
142
        }
143
144
        $this->twig->addGlobal('BaseInfo', $this->baseInfoRepository->get());
145
146
        if ($this->requestContext->isAdmin()) {
147
            $this->setAdminGlobals($event);
148
        } else {
149
            $this->setFrontVariables($event);
150
        }
151
152
        $this->initialized = true;
153
    }
154
155
    /**
156
     * @param GetResponseEvent $event
157
     *
158
     * @throws \Doctrine\ORM\NonUniqueResultException
159
     */
160
    public function setFrontVariables(GetResponseEvent $event)
161
    {
162
        /** @var \Symfony\Component\HttpFoundation\ParameterBag $attributes */
163
        $attributes = $event->getRequest()->attributes;
164
        $route = $attributes->get('_route');
165
        if ($route == 'user_data') {
166
            $routeParams = $attributes->get('_route_params', []);
167
            $route = isset($routeParams['route']) ? $routeParams['route'] : $attributes->get('route', '');
168
        }
169
170
        $type = DeviceType::DEVICE_TYPE_PC;
171
        if ($this->mobileDetector->isMobile()) {
172
            $type = DeviceType::DEVICE_TYPE_MB;
173
        }
174
175
        // URLからPageを取得
176
        /** @var Page $Page */
177
        $Page = $this->pageRepository->findOneBy(['url' => $route]);
178
179
        // 該当するPageがない場合は空のページをセット
180
        if (!$Page) {
181
            $Page = $this->pageRepository->newPage();
182
        }
183
184
        /** @var PageLayout[] $PageLayouts */
185
        $PageLayouts = $Page->getPageLayouts();
186
187
        // Pageに紐づくLayoutからDeviceTypeが一致するLayoutを探す
188
        $Layout = null;
189
        foreach ($PageLayouts as $PageLayout) {
190
            if ($PageLayout->getDeviceTypeId() == $type) {
191
                $Layout = $PageLayout->getLayout();
192
                break;
193
            }
194
        }
195
196
        // Pageに紐づくLayoutにDeviceTypeが一致するLayoutがない場合はPCのレイアウトを探す
197
        if (!$Layout) {
198
            log_info('fallback to PC layout');
199
            foreach ($PageLayouts as $PageLayout) {
200
                if ($PageLayout->getDeviceTypeId() == DeviceType::DEVICE_TYPE_PC) {
201
                    $Layout = $PageLayout->getLayout();
202
                    break;
203
                }
204
            }
205
        }
206
207
        // Layoutのデータがない場合は空のLayoutをセット
208
        if (!$Layout) {
209
            $Layout = new Layout();
210
        }
211
212
        $this->twig->addGlobal('Layout', $Layout);
213
        $this->twig->addGlobal('Page', $Page);
214
        $this->twig->addGlobal('title', $Page->getName());
215
    }
216
217
    /**
218
     * @param GetResponseEvent $event
219
     */
220
    public function setAdminGlobals(GetResponseEvent $event)
221
    {
222
        // メニュー表示用配列.
223
        $menus = [];
224
        $this->twig->addGlobal('menus', $menus);
225
226
        // メニューの権限制御.
227
        $eccubeNav = $this->eccubeConfig['eccube_nav'];
228
229
        $Member = $this->requestContext->getCurrentUser();
230
        if ($Member instanceof Member) {
231
            $AuthorityRoles = $this->authorityRoleRepository->findBy(['Authority' => $Member->getAuthority()]);
232
            $baseUrl = $event->getRequest()->getBaseUrl().'/'.$this->eccubeConfig['eccube_admin_route'];
233
            $eccubeNav = $this->getDisplayEccubeNav($eccubeNav, $AuthorityRoles, $baseUrl);
234
        }
235
        $this->twig->addGlobal('eccubeNav', $eccubeNav);
236
    }
237
238
    /**
239
     * URLに対する権限有無チェックして表示するNavを返す
240
     *
241
     * @param array $parentNav
242
     * @param AuthorityRole[] $AuthorityRoles
243
     * @param string $baseUrl
244
     *
245
     * @return array
246
     */
247
    private function getDisplayEccubeNav($parentNav, $AuthorityRoles, $baseUrl)
248
    {
249
        foreach ($parentNav as $key => $childNav) {
250
            if (array_key_exists('children', $childNav) && count($childNav['children']) > 0) {
251
                // 子のメニューがある場合は子の権限チェック
252
                $parentNav[$key]['children'] = $this->getDisplayEccubeNav($childNav['children'], $AuthorityRoles, $baseUrl);
253
254
                if (count($parentNav[$key]['children']) <= 0) {
255
                    // 子が存在しない場合は配列から削除
256
                    unset($parentNav[$key]);
257
                }
258
            } elseif (array_key_exists('url', $childNav)) {
259
                // 子のメニューがなく、URLが設定されている場合は権限があるURLか確認
260
                $param = array_key_exists('param', $childNav) ? $childNav['param'] : [];
261
                $url = $this->router->generate($childNav['url'], $param);
262
                foreach ($AuthorityRoles as $AuthorityRole) {
263
                    $denyUrl = str_replace('/', '\/', $baseUrl.$AuthorityRole->getDenyUrl());
264
                    if (preg_match("/^({$denyUrl})/i", $url)) {
265
                        // 権限がないURLの場合は配列から削除
266
                        unset($parentNav[$key]);
267
                        break;
268
                    }
269
                }
270
            }
271
        }
272
273
        return $parentNav;
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279
    public static function getSubscribedEvents()
280
    {
281
        return [
282
            KernelEvents::REQUEST => [
283
                // SecurityServiceProviderで、認証処理が完了した後に実行.
284
                ['onKernelRequest', 6],
285
            ],
286
        ];
287
    }
288
}
289