Completed
Push — master ( d8b95b...caeb59 )
by Axel
09:34 queued 04:32
created

AdminController::adminpanelAction()   F

Complexity

Conditions 20
Paths 3208

Size

Total Lines 108
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
eloc 60
nc 3208
nop 8
dl 0
loc 108
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - 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 Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
17
use Symfony\Component\HttpFoundation\RedirectResponse;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\Routing\Annotation\Route;
21
use Symfony\Component\Routing\Exception\RouteNotFoundException;
22
use Symfony\Component\Routing\RouterInterface;
23
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
24
use Zikula\AdminModule\Entity\AdminCategoryEntity;
25
use Zikula\AdminModule\Entity\RepositoryInterface\AdminCategoryRepositoryInterface;
26
use Zikula\AdminModule\Entity\RepositoryInterface\AdminModuleRepositoryInterface;
27
use Zikula\AdminModule\Form\Type\AdminCategoryType;
28
use Zikula\AdminModule\Helper\AdminLinksHelper;
29
use Zikula\Bundle\CoreBundle\Controller\AbstractController;
30
use Zikula\Bundle\CoreBundle\Doctrine\PaginatorInterface;
31
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
32
use Zikula\Bundle\FormExtensionBundle\Form\Type\DeletionType;
33
use Zikula\ExtensionsModule\Api\ApiInterface\CapabilityApiInterface;
34
use Zikula\MenuModule\ExtensionMenu\ExtensionMenuCollector;
35
use Zikula\MenuModule\ExtensionMenu\ExtensionMenuInterface;
36
use Zikula\PermissionsModule\Annotation\PermissionCheck;
37
use Zikula\ThemeModule\Engine\Annotation\Theme;
38
39
/**
40
 * Administrative controllers for the admin module
41
 * NOTE: intentionally no class level route setting here
42
 */
43
class AdminController extends AbstractController
44
{
45
    /**
46
     * @Route("")
47
     *
48
     * The main administration function.
49
     */
50
    public function index(): RedirectResponse
51
    {
52
        // Security check will be done in view()
53
        return $this->redirectToRoute('zikulaadminmodule_admin_view');
54
    }
55
56
    /**
57
     * @Route("/categories/{page}", methods = {"GET"}, requirements={"page" = "\d+"})
58
     * @PermissionCheck("edit")
59
     * @Theme("admin")
60
     * @Template("@ZikulaAdminModule/Admin/view.html.twig")
61
     *
62
     * Views all admin categories.
63
     */
64
    public function view(AdminCategoryRepositoryInterface $repository, int $page = 1): array
65
    {
66
        $pageSize = $this->getVar('itemsperpage');
67
68
        /** @var PaginatorInterface $paginator */
69
        $paginator = $repository->getPagedCategories(['sortorder' => 'ASC'], $page, $pageSize);
0 ignored issues
show
Bug introduced by
It seems like $pageSize can also be of type false; however, parameter $pageSize of Zikula\AdminModule\Entit...e::getPagedCategories() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
        $paginator = $repository->getPagedCategories(['sortorder' => 'ASC'], $page, /** @scrutinizer ignore-type */ $pageSize);
Loading history...
70
        $paginator->setRoute('zikulaadminmodule_admin_view');
71
72
        return [
73
            'paginator' => $paginator
74
        ];
75
    }
76
77
    /**
78
     * @Route("/newcategory")
79
     * @PermissionCheck({"$_zkModule::Item", "::", "add"})
80
     * @Theme("admin")
81
     * @Template("@ZikulaAdminModule/Admin/editCategory.html.twig")
82
     *
83
     * Displays and handles a form for the user to input the details of the new category.
84
     *
85
     * @return array|RedirectResponse
86
     */
87
    public function create(Request $request)
88
    {
89
        $form = $this->createForm(AdminCategoryType::class, new AdminCategoryEntity());
90
        $form->handleRequest($request);
91
        if ($form->isSubmitted() && $form->isValid()) {
92
            if ($form->get('save')->isClicked()) {
0 ignored issues
show
Bug introduced by
The method isClicked() does not exist on Symfony\Component\Form\FormInterface. It seems like you code against a sub-type of Symfony\Component\Form\FormInterface such as Symfony\Component\Form\SubmitButton. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

92
            if ($form->get('save')->/** @scrutinizer ignore-call */ isClicked()) {
Loading history...
93
                $adminCategory = $form->getData();
94
                $this->getDoctrine()->getManager()->persist($adminCategory);
95
                $this->getDoctrine()->getManager()->flush();
96
                $this->addFlash('status', 'Done! Created new category.');
97
            } elseif ($form->get('cancel')->isClicked()) {
98
                $this->addFlash('status', 'Operation cancelled.');
99
            }
100
101
            return $this->redirectToRoute('zikulaadminmodule_admin_view');
102
        }
103
104
        return [
105
            'form' => $form->createView()
106
        ];
107
    }
108
109
    /**
110
     * @Route("/modifycategory/{cid}", requirements={"cid" = "^[1-9]\d*$"})
111
     * @Theme("admin")
112
     * @Template("@ZikulaAdminModule/Admin/editCategory.html.twig")
113
     *
114
     * Displays and handles a modify category form.
115
     *
116
     * @return array|RedirectResponse
117
     * @throws AccessDeniedException Thrown if the user doesn't have permission to edit a category
118
     */
119
    public function modify(Request $request, AdminCategoryEntity $category)
120
    {
121
        if (!$this->hasPermission('ZikulaAdminModule::Category', $category['name'] . '::' . $category->getCid(), ACCESS_EDIT)) {
122
            throw new AccessDeniedException();
123
        }
124
125
        $form = $this->createForm(AdminCategoryType::class, $category);
126
        $form->handleRequest($request);
127
        if ($form->isSubmitted() && $form->isValid()) {
128
            if ($form->get('save')->isClicked()) {
129
                $category = $form->getData();
130
                if (!$this->hasPermission('ZikulaAdminModule::Category', $category->getName() . '::' . $category->getCid(), ACCESS_EDIT)) {
131
                    throw new AccessDeniedException();
132
                }
133
                $this->getDoctrine()->getManager()->flush();
134
                $this->addFlash('status', 'Done! Saved category.');
135
            } elseif ($form->get('cancel')->isClicked()) {
136
                $this->addFlash('status', 'Operation cancelled.');
137
            }
138
139
            return $this->redirectToRoute('zikulaadminmodule_admin_view');
140
        }
141
142
        return [
143
            'form' => $form->createView()
144
        ];
145
    }
146
147
    /**
148
     * @Route("/deletecategory/{cid}", requirements={"cid" = "^[1-9]\d*$"})
149
     * @Theme("admin")
150
     * @Template("@ZikulaAdminModule/Admin/delete.html.twig")
151
     *
152
     * Deletes an admin category.
153
     *
154
     * @return array|RedirectResponse
155
     * @throws AccessDeniedException Thrown if the user doesn't have permission to edit a category
156
     */
157
    public function delete(Request $request, AdminCategoryEntity $category)
158
    {
159
        if (!$this->hasPermission('ZikulaAdminModule::Category', $category->getName() . '::' . $category->getCid(), ACCESS_DELETE)) {
160
            throw new AccessDeniedException();
161
        }
162
163
        $form = $this->createForm(DeletionType::class, $category);
164
        $form->handleRequest($request);
165
        if ($form->isSubmitted() && $form->isValid()) {
166
            if ($form->get('delete')->isClicked()) {
167
                $category = $form->getData();
168
                $this->getDoctrine()->getManager()->remove($category);
169
                $this->getDoctrine()->getManager()->flush();
170
                $this->addFlash('status', 'Done! Category deleted.');
171
            } elseif ($form->get('cancel')->isClicked()) {
172
                $this->addFlash('status', 'Operation cancelled.');
173
            }
174
175
            return $this->redirectToRoute('zikulaadminmodule_admin_view');
176
        }
177
178
        return [
179
            'form' => $form->createView(),
180
            'category' => $category
181
        ];
182
    }
183
184
    /**
185
     * @Route("/panel/{acid}", methods = {"GET"}, requirements={"acid" = "^[1-9]\d*$"})
186
     * @PermissionCheck("edit")
187
     * @Theme("admin")
188
     * @Template("@ZikulaAdminModule/Admin/adminpanel.html.twig")
189
     *
190
     * Displays main admin panel for a category.
191
     *
192
     * @return array|Response
193
     * @throws AccessDeniedException Thrown if the user doesn't have edit permission for the module
194
     */
195
    public function adminpanel(
196
        ZikulaHttpKernelInterface $kernel,
197
        AdminCategoryRepositoryInterface $adminCategoryRepository,
198
        AdminModuleRepositoryInterface $adminModuleRepository,
199
        CapabilityApiInterface $capabilityApi,
200
        RouterInterface $router,
201
        AdminLinksHelper $adminLinksHelper,
202
        ExtensionMenuCollector $extensionMenuCollector,
203
        int $acid = null
204
    ) {
205
        if (empty($acid)) {
206
            $acid = $this->getVar('startcategory', 1);
207
        }
208
209
        // Check to see if we have access to the requested category.
210
        if (!$this->hasPermission('ZikulaAdminModule::', "::${acid}", ACCESS_ADMIN)) {
211
            $acid = -1;
212
        }
213
214
        // Get details for selected category
215
        $category = null;
216
        if ($acid > 0) {
217
            $category = $adminCategoryRepository->findOneBy(['cid' => $acid]);
218
        }
219
220
        if (!$category) {
221
            // get the default category
222
            $acid = $this->getVar('startcategory');
223
224
            // Check to see if we have access to the requested category.
225
            if (!$this->hasPermission('ZikulaAdminModule::', "::${acid}", ACCESS_ADMIN)) {
226
                throw new AccessDeniedException();
227
            }
228
229
            $category = $adminCategoryRepository->findOneBy(['cid' => $acid]);
230
        }
231
232
        $templateParameters = [];
233
234
        // assign the category
235
        $templateParameters['category'] = $category;
236
237
        $displayNameType = $this->getVar('displaynametype', 1);
238
        $moduleEntities = $adminModuleRepository->findAll();
239
240
        // get admin capable modules
241
        $adminModules = $capabilityApi->getExtensionsCapableOf('admin');
242
        $adminLinks = [];
243
        foreach ($adminModules as $adminModule) {
244
            if (!$this->hasPermission($adminModule['name'] . '::', 'ANY', ACCESS_EDIT)) {
245
                continue;
246
            }
247
248
            $moduleId = (int)$adminModule['id'];
249
            $moduleCategory = $adminCategoryRepository->getModuleCategory($moduleId);
250
            $catid = null !== $moduleCategory ? $moduleCategory['cid'] : 0;
251
252
            $sortOrder = -1;
253
            foreach ($moduleEntities as $association) {
254
                if ($association['mid'] !== $adminModule['id']) {
255
                    continue;
256
                }
257
258
                $sortOrder = $association['sortorder'];
259
                break;
260
            }
261
262
            if ($catid === $acid || (false === $catid && $acid === $this->getVar('defaultcategory'))) {
263
                $menuText = '';
264
                if (1 === $displayNameType) {
265
                    $menuText = $adminModule['displayname'];
266
                } elseif (2 === $displayNameType) {
267
                    $menuText = $adminModule['name'];
268
                } elseif (3 === $displayNameType) {
269
                    $menuText = $adminModule['displayname'] . ' (' . $adminModule['name'] . ')';
270
                }
271
272
                try {
273
                    $menuTextUrl = isset($adminModule['capabilities']['admin']['route'])
274
                        ? $router->generate($adminModule['capabilities']['admin']['route'])
275
                        : '';
276
                } catch (RouteNotFoundException $routeNotFoundException) {
277
                    $menuTextUrl = 'javascript:void(0)';
278
                    $menuText .= ' (<i class="fas fa-exclamation-triangle"></i> ' . $this->trans('invalid route') . ')';
279
                }
280
281
                $moduleName = (string)$adminModule['name'];
282
                /** @var \Knp\Menu\ItemInterface $extensionMenu */
283
                $extensionMenu = $extensionMenuCollector->get($moduleName, ExtensionMenuInterface::TYPE_ADMIN);
284
                if (isset($extensionMenu)) {
285
                    $extensionMenu->setChildrenAttribute('class', 'dropdown-menu');
286
                }
287
288
                $adminLinks[] = [
289
                    'menuTextUrl' => $menuTextUrl,
290
                    'menuText' => $menuText,
291
                    'menuTextTitle' => $adminModule['description'],
292
                    'moduleName' => $adminModule['name'],
293
                    'adminIcon' => $adminModule['icon'],
294
                    'id' => $adminModule['id'],
295
                    'order' => $sortOrder,
296
                    'extensionMenu' => $extensionMenu
297
                ];
298
            }
299
        }
300
        $templateParameters['adminLinks'] = $adminLinksHelper->sortAdminModsByOrder($adminLinks);
301
302
        return $templateParameters;
303
    }
304
305
    /**
306
     * @Route("/categorymenu/{acid}", methods = {"GET"}, requirements={"acid" = "^[1-9]\d*$"})
307
     * @Theme("admin")
308
     *
309
     * Displays main category menu.
310
     */
311
    public function categorymenu(
312
        AdminCategoryRepositoryInterface $adminCategoryRepository,
313
        AdminModuleRepositoryInterface $adminModuleRepository,
314
        CapabilityApiInterface $capabilityApi,
315
        RouterInterface $router,
316
        AdminLinksHelper $adminLinksHelper,
317
        int $acid = null
318
    ): Response {
319
        $acid = empty($acid) ? $this->getVar('startcategory') : $acid;
320
321
        // Get all categories
322
        $categories = [];
323
        $items = $adminCategoryRepository->findBy([], ['sortorder' => 'ASC']);
324
        foreach ($items as $item) {
325
            if ($this->hasPermission('ZikulaAdminModule::', $item['name'] . '::' . $item['cid'], ACCESS_READ)) {
326
                $categories[] = $item;
327
            }
328
        }
329
330
        $moduleEntities = $adminModuleRepository->findAll();
331
332
        // get admin capable modules
333
        $adminModules = $capabilityApi->getExtensionsCapableOf('admin');
334
        $adminLinks = [];
335
        foreach ($adminModules as $adminModule) {
336
            if (!$this->hasPermission($adminModule['name'] . '::', '::', ACCESS_EDIT)) {
337
                continue;
338
            }
339
340
            $menuText = $adminModule['displayname'];
341
            try {
342
                $menuTextUrl = isset($adminModule['capabilities']['admin']['route'])
343
                    ? $router->generate($adminModule['capabilities']['admin']['route'])
344
                    : '';
345
            } catch (RouteNotFoundException $routeNotFoundException) {
346
                $menuTextUrl = 'javascript:void(0)';
347
                $menuText .= ' (<i class="fas fa-exclamation-triangle"></i> ' . $this->trans('invalid route') . ')';
348
            }
349
350
            $moduleId = (int)$adminModule['id'];
351
            $moduleCategory = $adminCategoryRepository->getModuleCategory($moduleId);
352
            $catid = null !== $moduleCategory ? $moduleCategory['cid'] : 0;
353
354
            $sortOrder = -1;
355
            foreach ($moduleEntities as $association) {
356
                if ($association['mid'] !== $adminModule['id']) {
357
                    continue;
358
                }
359
360
                $sortOrder = $association['sortorder'];
361
                break;
362
            }
363
364
            $adminLinks[$catid][] = [
365
                'menuTextUrl' => $menuTextUrl,
366
                'menuText' => $menuText,
367
                'menuTextTitle' => $adminModule['description'],
368
                'moduleName' => $adminModule['name'],
369
                'order' => $sortOrder,
370
                'id' => $adminModule['id'],
371
                'icon' => $adminModule['icon']
372
            ];
373
        }
374
375
        foreach ($adminLinks as $categoryId => $links) {
376
            $adminLinks[$categoryId] = $adminLinksHelper->sortAdminModsByOrder($links);
377
        }
378
379
        $menuOptions = [];
380
        $possibleCategoryIds = [];
381
        $permission = false;
382
383
        if (isset($categories) && is_array($categories)) {
384
            foreach ($categories as $category) {
385
                // only categories containing modules where the current user has permissions will
386
                // be shown, all others will be hidden
387
                // admin will see all categories
388
                if ($this->hasPermission('.*', '.*', ACCESS_ADMIN)
389
                    || (isset($adminLinks[$category['cid']]) && count($adminLinks[$category['cid']]))
390
                ) {
391
                    $menuOption = [
392
                        'url' => $router->generate('zikulaadminmodule_admin_adminpanel', ['acid' => $category['cid']]),
393
                        'title' => $category['name'],
394
                        'description' => $category['description'],
395
                        'cid' => $category['cid'],
396
                        'items' => $adminLinks[$category['cid']] ?? []
397
                    ];
398
399
                    $menuOptions[$category['cid']] = $menuOption;
400
                    $possibleCategoryIds[] = $category['cid'];
401
402
                    if ($acid === $category['cid']) {
403
                        $permission = true;
404
                    }
405
                }
406
            }
407
        }
408
409
        // if permission is false we are not allowed to see this category because its
410
        // empty and we are not admin
411
        if (false === $permission) {
0 ignored issues
show
introduced by
The condition false === $permission is always true.
Loading history...
412
            // show the first category
413
            $acid = !empty($possibleCategoryIds) ? (int)$possibleCategoryIds[0] : null;
414
        }
415
416
        return $this->render('@ZikulaAdminModule/Admin/categoryMenu.html.twig', [
417
            'currentCategory' => $acid,
418
            'menuOptions' => $menuOptions
419
        ]);
420
    }
421
}
422