Completed
Push — master ( b0a972...bf504f )
by Craig
05:20
created

AdminInterfaceController   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 303
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 149
dl 0
loc 303
rs 9.2
c 0
b 0
f 0
wmc 40

6 Methods

Rating   Name   Duplication   Size   Complexity  
A footerAction() 0 11 1
A breadcrumbsAction() 0 28 6
A headerAction() 0 4 1
A updatecheckAction() 0 18 2
B securityanalyzerAction() 0 43 7
F menuAction() 0 147 23

How to fix   Complexity   

Complex Class

Complex classes like AdminInterfaceController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AdminInterfaceController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
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 Zikula\AdminModule\Controller;
15
16
use Exception;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpKernel\Kernel;
21
use Symfony\Component\Routing\Annotation\Route;
22
use Symfony\Component\Routing\Exception\RouteNotFoundException;
23
use Symfony\Component\Routing\RouterInterface;
24
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
25
use Zikula\AdminModule\Entity\AdminCategoryEntity;
26
use Zikula\AdminModule\Entity\RepositoryInterface\AdminCategoryRepositoryInterface;
27
use Zikula\AdminModule\Entity\RepositoryInterface\AdminModuleRepositoryInterface;
28
use Zikula\AdminModule\Helper\UpdateCheckHelper;
29
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
30
use Zikula\Core\Controller\AbstractController;
31
use Zikula\Core\LinkContainer\LinkContainerCollector;
32
use Zikula\ExtensionsModule\Api\ApiInterface\CapabilityApiInterface;
33
use Zikula\ExtensionsModule\Api\ApiInterface\VariableApiInterface;
34
use Zikula\ExtensionsModule\Entity\RepositoryInterface\ExtensionRepositoryInterface;
35
use Zikula\ThemeModule\Engine\Asset;
36
37
/**
38
 * @Route("/admininterface")
39
 */
40
class AdminInterfaceController extends AbstractController
41
{
42
    /**
43
     * @Route("/header")
44
     *
45
     * Open the admin container
46
     */
47
    public function headerAction(RequestStack $requestStack): Response
48
    {
49
        return $this->render('@ZikulaAdminModule/AdminInterface/header.html.twig', [
50
            'caller' => $requestStack->getMasterRequest()->attributes->all()
51
        ]);
52
    }
53
54
    /**
55
     * @Route("/footer")
56
     *
57
     * Close the admin container
58
     */
59
    public function footerAction(
60
        RequestStack $requestStack,
61
        ExtensionRepositoryInterface $extensionRepository
62
    ): Response {
63
        $caller = $requestStack->getMasterRequest()->attributes->all();
64
        $caller['info'] = $extensionRepository->get($caller['_zkModule']);
65
66
        return $this->render('@ZikulaAdminModule/AdminInterface/footer.html.twig', [
67
            'caller' => $caller,
68
            'symfonyVersion' => Kernel::VERSION,
69
            'phpVersion' => PHP_VERSION
70
        ]);
71
    }
72
73
    /**
74
     * @Route("/breadcrumbs", methods = {"GET"})
75
     *
76
     * Admin breadcrumbs
77
     */
78
    public function breadcrumbsAction(
79
        RequestStack $requestStack,
80
        ExtensionRepositoryInterface $extensionRepository,
81
        AdminModuleRepositoryInterface $adminModuleRepository,
82
        AdminCategoryRepositoryInterface $adminCategoryRepository
83
    ): Response {
84
        if (!$this->hasPermission('ZikulaAdminModule::', '::', ACCESS_ADMIN)) {
85
            throw new AccessDeniedException();
86
        }
87
88
        $masterRequest = $requestStack->getMasterRequest();
89
        $caller = $masterRequest->attributes->all();
90
        $caller['info'] = $extensionRepository->get($caller['_zkModule']);
91
92
        $requestedCid = $masterRequest->attributes->get('acid');
93
        $defaultCid = empty($requestedCid) ? $this->getVar('startcategory') : $requestedCid;
94
95
        $categoryId = $defaultCid;
96
        if (!empty($caller['_zkModule']) && 'ZikulaAdminModule' !== $caller['_zkModule']) {
97
            $moduleRelation = $adminModuleRepository->findOneBy(['mid' => $caller['info']['id']]);
98
            if (null !== $moduleRelation) {
99
                $categoryId = $moduleRelation->getCid();
100
            }
101
        }
102
        $caller['category'] = $adminCategoryRepository->find($categoryId);
103
104
        return $this->render('@ZikulaAdminModule/AdminInterface/breadCrumbs.html.twig', [
105
            'caller' => $caller
106
        ]);
107
    }
108
109
    /**
110
     * @Route("/securityanalyzer")
111
     *
112
     * Display security analyzer
113
     */
114
    public function securityanalyzerAction(
115
        Request $request,
116
        ZikulaHttpKernelInterface $kernel,
117
        VariableApiInterface $variableApi
118
    ): Response {
119
        if (!$this->hasPermission('ZikulaAdminModule::', '::', ACCESS_ADMIN)) {
120
            throw new AccessDeniedException();
121
        }
122
123
        // check for .htaccess in app directory
124
        $appDir = $kernel->getProjectDir() . '/app';
125
        if ($appDir) {
126
            // check if we have an absolute path which is possibly not within the document root
127
            $docRoot = $request->server->get('DOCUMENT_ROOT');
128
            if (0 === mb_strpos($appDir, '/') && false === mb_strpos($appDir, $docRoot)) {
129
                // temp dir is outside the webroot, no .htaccess file needed
130
                $app_htaccess = true;
131
            } else {
132
                if (false === mb_strpos($appDir, $docRoot)) {
133
                    $ldir = __DIR__;
134
                    $p = mb_strpos($ldir, DIRECTORY_SEPARATOR . 'system'); // we are in system/AdminModule
135
                    $b = mb_substr($ldir, 0, $p);
136
                    $filePath = $b . '/' . $appDir . '/.htaccess';
137
                } else {
138
                    $filePath = $appDir . '/.htaccess';
139
                }
140
                $app_htaccess = file_exists($filePath);
141
            }
142
        } else {
143
            // already customised, admin should know about what he's doing...
144
            $app_htaccess = true;
145
        }
146
147
        $hasSecurityCenter = $kernel->isBundle('ZikulaSecurityCenterModule');
148
149
        return $this->render('@ZikulaAdminModule/AdminInterface/securityAnalyzer.html.twig', [
150
            'security' => [
151
                'app_htaccess' => $app_htaccess,
152
                'updatecheck' => $variableApi->getSystemVar('updatecheck'),
153
                'scactive' => $hasSecurityCenter,
154
                // check for outputfilter
155
                'useids' => $hasSecurityCenter && 1 === $variableApi->getSystemVar('useids'),
156
                'idssoftblock' => $variableApi->getSystemVar('idssoftblock')
157
            ]
158
        ]);
159
    }
160
161
    /**
162
     * @Route("/updatecheck")
163
     *
164
     * Display update check
165
     *
166
     * @throws AccessDeniedException Thrown if the user doesn't have admin permission for the module
167
     */
168
    public function updatecheckAction(
169
        RequestStack $requestStack,
170
        ZikulaHttpKernelInterface $kernel,
171
        UpdateCheckHelper $updateCheckHelper
172
    ): Response {
173
        if (!$this->hasPermission('ZikulaAdminModule::', '::', ACCESS_ADMIN)) {
174
            throw new AccessDeniedException();
175
        }
176
177
        $masterRequest = $requestStack->getMasterRequest();
178
179
        return $this->render('@ZikulaAdminModule/AdminInterface/updateCheck.html.twig', [
180
            'mode' => $kernel->getEnvironment(),
181
            'caller' => [
182
                '_route' => $masterRequest->attributes->get('_route'),
183
                '_route_params' => $masterRequest->attributes->get('_route_params')
184
            ],
185
            'updateCheckHelper' => $updateCheckHelper
186
        ]);
187
    }
188
189
    /**
190
     * @Route("/menu")
191
     *
192
     * Display admin menu
193
     *
194
     * @throws AccessDeniedException Thrown if the user doesn't have admin permission for the module
195
     */
196
    public function menuAction(
197
        RequestStack $requestStack,
198
        RouterInterface $router,
199
        ExtensionRepositoryInterface $extensionRepository,
200
        LinkContainerCollector $linkContainerCollector,
201
        CapabilityApiInterface $capabilityApi,
202
        AdminModuleRepositoryInterface $adminModuleRepository,
203
        AdminCategoryRepositoryInterface $adminCategoryRepository,
204
        Asset $assetHelper
205
    ): Response {
206
        if (!$this->hasPermission('ZikulaAdminModule::', '::', ACCESS_ADMIN)) {
207
            throw new AccessDeniedException();
208
        }
209
210
        $masterRequest = $requestStack->getMasterRequest();
211
        $currentRequest = $requestStack->getCurrentRequest();
212
213
        // get caller info
214
        $caller = [];
215
        $caller['_zkModule'] = $masterRequest->attributes->get('_zkModule');
216
        $caller['_zkType'] = $masterRequest->attributes->get('_zkType');
217
        $caller['_zkFunc'] = $masterRequest->attributes->get('_zkFunc');
218
        $caller['path'] = $masterRequest->getPathInfo();
219
        $caller['info'] = !empty($caller['_zkModule']) ? $extensionRepository->get($caller['_zkModule']) : [];
220
221
        // category we are in
222
        $requestedCid = $masterRequest->attributes->get('acid');
223
        $defaultCid = empty($requestedCid) ? $this->getVar('startcategory') : $requestedCid;
224
225
        $categoryId = $defaultCid;
226
        if (!empty($caller['_zkModule']) && 'ZikulaAdminModule' !== $caller['_zkModule']) {
227
            $moduleRelation = $adminModuleRepository->findOneBy(['mid' => $caller['info']['id']]);
228
            if (null !== $moduleRelation) {
229
                $categoryId = $moduleRelation->getCid();
230
            }
231
        }
232
        $caller['category'] = $adminCategoryRepository->find($categoryId);
233
234
        // mode requested
235
        $mode = $currentRequest->attributes->has('mode') ? $currentRequest->attributes->get('mode') : 'categories';
236
        $mode = in_array($mode, ['categories', 'modules']) ? $mode : 'categories';
237
        // template requested
238
        $template = $currentRequest->attributes->has('template') ? $currentRequest->attributes->get('template') : 'tabs';
239
        $template = in_array($template, ['tabs', 'panel']) ? $template : 'tabs';
240
241
        // get admin capable modules
242
        $adminModules = $capabilityApi->getExtensionsCapableOf('admin');
243
244
        // sort modules by displayname
245
        $moduleNames = [];
246
        foreach ($adminModules as $key => $module) {
247
            $moduleNames[$key] = $module['displayname'];
248
        }
249
        array_multisort($moduleNames, SORT_ASC, $adminModules);
250
251
        $moduleCategories = $adminCategoryRepository->getIndexedCollection('cid');
252
        $menuModules = [];
253
        $menuCategories = [];
254
        foreach ($adminModules as $adminModule) {
255
            if (!$this->hasPermission($adminModule['name'] . '::', '::', ACCESS_EDIT)) {
256
                continue;
257
            }
258
259
            $categoryAssignment = $adminModuleRepository->findOneBy(['mid' => $adminModule['id']]);
260
            if (null !== $categoryAssignment) {
261
                $catid = $categoryAssignment->getCid();
262
                $order = $categoryAssignment->getSortorder();
263
            } else {
264
                $catid = $this->getVar('startcategory');
265
                $order = 999;
266
            }
267
268
            $menuText = $adminModule['displayname'];
269
270
            // url
271
            try {
272
                $menuTextUrl = isset($adminModule['capabilities']['admin']['route']) ? $router->generate($adminModule['capabilities']['admin']['route']) : $adminModule['capabilities']['admin']['url'];
273
            } catch (RouteNotFoundException $routeNotFoundException) {
274
                $menuTextUrl = 'javascript:void(0)';
275
                $menuText .= ' (<i class="fa fa-exclamation-triangle"></i> ' . $this->trans('invalid route') . ')';
276
            }
277
278
            $moduleName = (string)$adminModule['name'];
279
            $links = $linkContainerCollector->getLinks($moduleName, 'admin');
280
            try {
281
                $adminIconPath = $assetHelper->resolve('@' . $adminModule['name'] . ':images/admin.png');
282
            } catch (Exception $exception) {
283
                // use default icon
284
                $adminIconPath = $assetHelper->resolve('bundles/core/images/admin.png');
285
            }
286
287
            $module = [
288
                'menutexturl' => $menuTextUrl,
289
                'menutext' => $menuText,
290
                'menutexttitle' => $adminModule['description'],
291
                'modname' => $adminModule['name'],
292
                'order' => $order,
293
                'id' => $adminModule['id'],
294
                'links' => $links,
295
                'icon' => $adminIconPath
296
            ];
297
298
            $menuModules[$adminModule['name']] = $module;
299
300
            // category menu
301
            if (!$this->hasPermission('ZikulaAdminModule:Category:', $moduleCategories[$catid]['name'] . '::' . $moduleCategories[$catid]['cid'], ACCESS_ADMIN)) {
302
                continue;
303
            }
304
305
            $categorySortOrder = $moduleCategories[$catid]['sortorder'];
306
            $menuCategories[$categorySortOrder]['title'] = $moduleCategories[$catid]['name'];
307
            $menuCategories[$categorySortOrder]['url'] = $router->generate('zikulaadminmodule_admin_adminpanel', [
308
                'acid' => $moduleCategories[$catid]['cid']
309
            ]);
310
            $menuCategories[$categorySortOrder]['description'] = $moduleCategories[$catid]['description'];
311
            $menuCategories[$categorySortOrder]['icon'] = $moduleCategories[$catid]['icon'];
312
            $menuCategories[$categorySortOrder]['cid'] = $moduleCategories[$catid]['cid'];
313
            $menuCategories[$categorySortOrder]['modules'][$adminModule['name']] = $module;
314
        }
315
316
        // add empty categories
317
        /** @var AdminCategoryEntity[] $moduleCategories */
318
        foreach ($moduleCategories as $moduleCategory) {
319
            if (array_key_exists($moduleCategory->getSortorder(), $menuCategories)) {
320
                continue;
321
            }
322
            if (!$this->hasPermission('ZikulaAdminModule:Category:', $moduleCategory->getName() . '::' . $moduleCategory->getCid(), ACCESS_ADMIN)) {
323
                continue;
324
            }
325
326
            $menuCategories[$moduleCategory->getSortOrder()] = [
327
                'title' => $moduleCategory->getName(),
328
                'url' => $router->generate('zikulaadminmodule_admin_adminpanel', [
329
                    'acid' => $moduleCategory->getCid()
330
                ]),
331
                'description' => $moduleCategory->getDescription(),
332
                'cid' => $moduleCategory->getCid(),
333
                'modules' => []
334
            ];
335
        }
336
        ksort($menuCategories);
337
        $fullTemplateName = $mode . '.' . $template;
338
339
        return $this->render("@ZikulaAdminModule/AdminInterface/${fullTemplateName}.html.twig", [
340
            'adminMenu' => ('categories' === $mode) ? $menuCategories : $menuModules,
341
            'mode' => $mode,
342
            'caller' => $caller
343
        ]);
344
    }
345
}
346