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

AdminController::categorymenuAction()   F

Complexity

Conditions 21
Paths 1872

Size

Total Lines 108
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 21
eloc 61
nc 1872
nop 6
dl 0
loc 108
rs 0
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
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