Completed
Push — master ( a128a1...e19108 )
by Craig
16:51
created

ExtensionController::uninstallAction()   B

Complexity

Conditions 11
Paths 15

Size

Total Lines 65
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 34
c 2
b 0
f 0
nc 15
nop 9
dl 0
loc 65
rs 7.3166

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 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\ExtensionsModule\Controller;
15
16
use RuntimeException;
17
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
18
use Symfony\Component\HttpFoundation\RedirectResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\Routing\Annotation\Route;
22
use Symfony\Component\Routing\RouterInterface;
23
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
24
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
25
use Zikula\BlocksModule\Entity\RepositoryInterface\BlockRepositoryInterface;
26
use Zikula\Bundle\CoreBundle\CacheClearer;
27
use Zikula\Bundle\CoreBundle\Composer\MetaData;
28
use Zikula\Bundle\CoreBundle\Controller\AbstractController;
29
use Zikula\Bundle\CoreBundle\Event\GenericEvent;
30
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
31
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaKernel;
32
use Zikula\Bundle\FormExtensionBundle\Form\Type\DeletionType;
33
use Zikula\Component\SortableColumns\Column;
34
use Zikula\Component\SortableColumns\SortableColumns;
35
use Zikula\ExtensionsModule\AbstractExtension;
36
use Zikula\ExtensionsModule\Constant;
37
use Zikula\ExtensionsModule\Entity\ExtensionEntity;
38
use Zikula\ExtensionsModule\Entity\RepositoryInterface\ExtensionRepositoryInterface;
39
use Zikula\ExtensionsModule\Event\ExtensionStateEvent;
40
use Zikula\ExtensionsModule\ExtensionEvents;
41
use Zikula\ExtensionsModule\Form\Type\ExtensionInstallType;
42
use Zikula\ExtensionsModule\Form\Type\ExtensionModifyType;
43
use Zikula\ExtensionsModule\Helper\BundleSyncHelper;
44
use Zikula\ExtensionsModule\Helper\ExtensionDependencyHelper;
45
use Zikula\ExtensionsModule\Helper\ExtensionHelper;
46
use Zikula\ExtensionsModule\Helper\ExtensionStateHelper;
47
use Zikula\ThemeModule\Engine\Annotation\Theme;
48
use Zikula\ThemeModule\Engine\Engine;
49
50
/**
51
 * Class ExtensionController
52
 * @Route("")
53
 */
54
class ExtensionController extends AbstractController
55
{
56
    private const NEW_ROUTES_AVAIL = 'new.routes.avail';
57
58
    /**
59
     * @Route("/list/{pos}")
60
     * @Theme("admin")
61
     * @Template("@ZikulaExtensionsModule/Extension/list.html.twig")
62
     *
63
     * @throws AccessDeniedException Thrown if the user doesn't have admin permissions for the module
64
     */
65
    public function listAction(
66
        Request $request,
67
        EventDispatcherInterface $eventDispatcher,
68
        ExtensionRepositoryInterface $extensionRepository,
69
        BundleSyncHelper $bundleSyncHelper,
70
        RouterInterface $router,
71
        int $pos = 1
72
    ): array {
73
        if (!$this->hasPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
74
            throw new AccessDeniedException();
75
        }
76
        $modulesJustInstalled = $request->query->get('justinstalled');
77
        if (!empty($modulesJustInstalled)) {
78
            // notify the event dispatcher that new routes are available (ids of modules just installed avail as args)
79
            $event = new GenericEvent(null, json_decode($modulesJustInstalled));
80
            $eventDispatcher->dispatch($event, self::NEW_ROUTES_AVAIL);
81
        }
82
83
        $sortableColumns = new SortableColumns($router, 'zikulaextensionsmodule_extension_list');
84
        $sortableColumns->addColumns([new Column('displayname'), new Column('state')]);
85
        $sortableColumns->setOrderByFromRequest($request);
86
87
        $upgradedExtensions = [];
88
        $vetoEvent = new GenericEvent();
89
        $eventDispatcher->dispatch($vetoEvent, ExtensionEvents::REGENERATE_VETO);
90
        if (1 === $pos && !$vetoEvent->isPropagationStopped()) {
91
            // regenerate the extension list only when viewing the first page
92
            $extensionsInFileSystem = $bundleSyncHelper->scanForBundles();
93
            $upgradedExtensions = $bundleSyncHelper->syncExtensions($extensionsInFileSystem);
94
        }
95
96
        $pagedResult = $extensionRepository->getPagedCollectionBy([], [
97
            $sortableColumns->getSortColumn()->getName() => $sortableColumns->getSortDirection()
98
        ], $this->getVar('itemsperpage'), $pos);
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('itemsperpage') can also be of type false; however, parameter $limit of Zikula\ExtensionsModule\...:getPagedCollectionBy() 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

98
        ], /** @scrutinizer ignore-type */ $this->getVar('itemsperpage'), $pos);
Loading history...
99
100
        return [
101
            'sort' => $sortableColumns->generateSortableColumns(),
102
            'pager' => [
103
                'limit' => $this->getVar('itemsperpage'),
104
                'count' => count($pagedResult)
105
            ],
106
            'extensions' => $pagedResult,
107
            'upgradedExtensions' => $upgradedExtensions
108
        ];
109
    }
110
111
    /**
112
     * @Route("/activate/{id}/{token}", methods = {"GET"}, requirements={"id" = "^[1-9]\d*$"})
113
     *
114
     * Activate an extension.
115
     *
116
     * @throws AccessDeniedException Thrown if the user doesn't have admin permissions for the module
117
     */
118
    public function activateAction(
119
        int $id,
120
        string $token,
121
        ExtensionRepositoryInterface $extensionRepository,
122
        ExtensionStateHelper $extensionStateHelper,
123
        CacheClearer $cacheClearer
124
    ): RedirectResponse {
125
        if (!$this->hasPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
126
            throw new AccessDeniedException();
127
        }
128
129
        if (!$this->isCsrfTokenValid('activate-extension', $token)) {
130
            throw new AccessDeniedException();
131
        }
132
133
        /** @var ExtensionEntity $extension */
134
        $extension = $extensionRepository->find($id);
135
        if (Constant::STATE_NOTALLOWED === $extension->getState()) {
136
            $this->addFlash('error', $this->trans('Error! Activation of %name% not allowed.', ['%name%' => $extension->getName()]));
137
        } else {
138
            // Update state
139
            $extensionStateHelper->updateState($id, Constant::STATE_ACTIVE);
140
            $cacheClearer->clear('symfony');
141
            $this->addFlash('status', $this->trans('Done! Activated %name%.', ['%name%' => $extension->getName()]));
142
        }
143
144
        return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
145
    }
146
147
    /**
148
     * @Route("/deactivate/{id}/{token}", methods = {"GET"}, requirements={"id" = "^[1-9]\d*$"})
149
     *
150
     * Deactivate an extension
151
     *
152
     * @throws AccessDeniedException Thrown if the user doesn't have admin permissions for the module
153
     */
154
    public function deactivateAction(
155
        int $id,
156
        string $token,
157
        ExtensionRepositoryInterface $extensionRepository,
158
        ExtensionStateHelper $extensionStateHelper,
159
        CacheClearer $cacheClearer
160
    ): RedirectResponse {
161
        if (!$this->hasPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
162
            throw new AccessDeniedException();
163
        }
164
165
        if (!$this->isCsrfTokenValid('deactivate-extension', $token)) {
166
            throw new AccessDeniedException();
167
        }
168
        // @todo check if this is a theme and currently set as default or admin theme
169
170
        /** @var ExtensionEntity $extension */
171
        $extension = $extensionRepository->find($id);
172
        if (null !== $extension) {
173
            if (ZikulaKernel::isCoreExtension($extension->getName())) {
174
                $this->addFlash('error', $this->trans('Error! You cannot deactivate the %name%. It is required by the system.', ['%name%' => $extension->getName()]));
175
            } else {
176
                // Update state
177
                $extensionStateHelper->updateState($id, Constant::STATE_INACTIVE);
178
                $cacheClearer->clear('symfony');
179
                $this->addFlash('status', $this->trans('Done! Deactivated %name%.', ['%name%' => $extension->getName()]));
180
            }
181
        }
182
183
        return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
184
    }
185
186
    /**
187
     * @Route("/modify/{id}/{forceDefaults}", requirements={"id" = "^[1-9]\d*$", "forceDefaults" = "0|1"})
188
     * @Theme("admin")
189
     * @Template("@ZikulaExtensionsModule/Extension/modify.html.twig")
190
     *
191
     * Modify a module.
192
     *
193
     * @return array|RedirectResponse
194
     * @throws AccessDeniedException Thrown if the user doesn't have admin permissions for modifying the extension
195
     */
196
    public function modifyAction(
197
        Request $request,
198
        ZikulaHttpKernelInterface $kernel,
199
        ExtensionEntity $extension,
200
        CacheClearer $cacheClearer,
201
        bool $forceDefaults = false
202
    ) {
203
        if (!$this->hasPermission('ZikulaExtensionsModule::modify', $extension->getName() . '::' . $extension->getId(), ACCESS_ADMIN)) {
204
            throw new AccessDeniedException();
205
        }
206
207
        /** @var AbstractExtension $extensionBundle */
208
        $extensionBundle = $kernel->getBundle($extension->getName());
209
        $metaData = $extensionBundle->getMetaData()->getFilteredVersionInfoArray();
210
211
        if ($forceDefaults) {
212
            $extension->setName($metaData['name']);
213
            $extension->setUrl($metaData['url']);
214
            $extension->setDescription($metaData['description']);
215
        }
216
217
        $form = $this->createForm(ExtensionModifyType::class, $extension);
218
        $form->handleRequest($request);
219
        if ($form->isSubmitted() && $form->isValid()) {
220
            if ($form->get('defaults')->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

220
            if ($form->get('defaults')->/** @scrutinizer ignore-call */ isClicked()) {
Loading history...
221
                $this->addFlash('info', 'Default values reloaded. Save to confirm.');
222
223
                return $this->redirectToRoute('zikulaextensionsmodule_extension_modify', ['id' => $extension->getId(), 'forceDefaults' => 1]);
224
            }
225
            if ($form->get('save')->isClicked()) {
226
                $em = $this->getDoctrine()->getManager();
227
                $em->persist($extension);
228
                $em->flush();
229
230
                $cacheClearer->clear('symfony');
231
                $this->addFlash('status', 'Done! Extension updated.');
232
            } elseif ($form->get('cancel')->isClicked()) {
233
                $this->addFlash('status', 'Operation cancelled.');
234
            }
235
236
            return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
237
        }
238
239
        return [
240
            'form' => $form->createView()
241
        ];
242
    }
243
244
    /**
245
     * @Route("/compatibility/{id}", methods = {"GET"}, requirements={"id" = "^[1-9]\d*$"})
246
     * @Theme("admin")
247
     * @Template("@ZikulaExtensionsModule/Extension/compatibility.html.twig")
248
     *
249
     * Display information of a module compatibility with the version of the core
250
     *
251
     * @throws AccessDeniedException Thrown if the user doesn't have admin permission to the requested module
252
     */
253
    public function compatibilityAction(ExtensionEntity $extension): array
254
    {
255
        if (!$this->hasPermission('ZikulaExtensionsModule::', $extension->getName() . '::' . $extension->getId(), ACCESS_ADMIN)) {
256
            throw new AccessDeniedException();
257
        }
258
259
        return [
260
            'extension' => $extension
261
        ];
262
    }
263
264
    /**
265
     * @Route("/install/{id}/{token}", requirements={"id" = "^[1-9]\d*$"})
266
     * @Theme("admin")
267
     * @Template("@ZikulaExtensionsModule/Extension/install.html.twig")
268
     *
269
     * Install and initialise an extension.
270
     *
271
     * @return array|RedirectResponse
272
     * @throws AccessDeniedException Thrown if the user doesn't have admin permission for the module
273
     */
274
    public function installAction(
275
        Request $request,
276
        ExtensionEntity $extension,
277
        string $token,
278
        ZikulaHttpKernelInterface $kernel,
279
        ExtensionRepositoryInterface $extensionRepository,
280
        ExtensionHelper $extensionHelper,
281
        ExtensionStateHelper $extensionStateHelper,
282
        ExtensionDependencyHelper $dependencyHelper,
283
        CacheClearer $cacheClearer
284
    ) {
285
        if (!$this->hasPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
286
            throw new AccessDeniedException();
287
        }
288
289
        $id = $extension->getId();
290
        if (!$this->isCsrfTokenValid('install-extension', $token)) {
291
            throw new AccessDeniedException();
292
        }
293
294
        if (!$kernel->isBundle($extension->getName())) {
295
            $extensionStateHelper->updateState($id, Constant::STATE_TRANSITIONAL);
296
            $cacheClearer->clear('symfony');
297
298
            return $this->redirectToRoute('zikulaextensionsmodule_extension_install', ['id' => $id, 'token' => $token]);
299
        }
300
        $unsatisfiedDependencies = $dependencyHelper->getUnsatisfiedExtensionDependencies($extension);
301
        $form = $this->createForm(ExtensionInstallType::class, [
302
            'dependencies' => $this->formatDependencyCheckboxArray($extensionRepository, $unsatisfiedDependencies)
303
        ]);
304
        $hasNoUnsatisfiedDependencies = empty($unsatisfiedDependencies);
305
        $form->handleRequest($request);
306
        if ($hasNoUnsatisfiedDependencies || ($form->isSubmitted() && $form->isValid())) {
307
            if ($hasNoUnsatisfiedDependencies || $form->get('install')->isClicked()) {
308
                $extensionsInstalled = [];
309
                $data = $form->getData();
310
                foreach ($data['dependencies'] as $dependencyId => $installSelected) {
311
                    if (!$installSelected && MetaData::DEPENDENCY_REQUIRED !== $unsatisfiedDependencies[$dependencyId]->getStatus()) {
312
                        continue;
313
                    }
314
                    $dependencyExtensionEntity = $extensionRepository->get($unsatisfiedDependencies[$dependencyId]->getModname());
315
                    if (isset($dependencyExtensionEntity)) {
316
                        if (!$extensionHelper->install($dependencyExtensionEntity)) {
317
                            $this->addFlash('error', $this->trans('Failed to install dependency "%name%"!', ['%name%' => $dependencyExtensionEntity->getName()]));
318
319
                            return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
320
                        }
321
                        $extensionsInstalled[] = $dependencyExtensionEntity->getId();
322
                        $this->addFlash('status', $this->trans('Installed dependency "%name%".', ['%name%' => $dependencyExtensionEntity->getName()]));
323
                    } else {
324
                        $this->addFlash('warning', $this->trans('Warning: could not install selected dependency "%name%".', ['%name%' => $unsatisfiedDependencies[$dependencyId]->getModname()]));
325
                    }
326
                }
327
                if ($extensionHelper->install($extension)) {
328
                    $this->addFlash('status', $this->trans('Done! Installed "%name%".', ['%name%' => $extension->getName()]));
329
                    $extensionsInstalled[] = $id;
330
                    $cacheClearer->clear('symfony');
331
332
                    return $this->redirectToRoute('zikulaextensionsmodule_extension_postinstall', ['extensions' => json_encode($extensionsInstalled)]);
333
                }
334
                $extensionStateHelper->updateState($id, Constant::STATE_UNINITIALISED);
335
                $this->addFlash('error', $this->trans('Initialization of "%name%" failed!', ['%name%' => $extension->getName()]));
336
            }
337
            if ($form->get('cancel')->isClicked()) {
338
                $extensionStateHelper->updateState($id, Constant::STATE_UNINITIALISED);
339
                $this->addFlash('status', 'Operation cancelled.');
340
            }
341
342
            return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
343
        }
344
345
        return [
346
            'dependencies' => $unsatisfiedDependencies,
347
            'extension' => $extension,
348
            'form' => $form->createView()
349
        ];
350
    }
351
352
    /**
353
     * Post-installation action to trigger the MODULE_POSTINSTALL event.
354
     * The additional Action is required because this event must occur AFTER the rebuild of the cache which occurs on Request.
355
     *
356
     * @Route("/postinstall/{extensions}", methods = {"GET"})
357
     */
358
    public function postInstallAction(
359
        ExtensionRepositoryInterface $extensionRepository,
360
        ZikulaHttpKernelInterface $kernel,
361
        EventDispatcherInterface $eventDispatcher,
362
        string $extensions = null
363
    ): RedirectResponse {
364
        if (!empty($extensions)) {
365
            $extensions = json_decode($extensions);
366
            foreach ($extensions as $extensionId) {
367
                /** @var ExtensionEntity $extensionEntity */
368
                $extensionEntity = $extensionRepository->find($extensionId);
369
                if (null === $extensionRepository) {
370
                    continue;
371
                }
372
                /** @var AbstractExtension $extensionBundle */
373
                $extensionBundle = $kernel->getBundle($extensionEntity->getName());
374
                if (null === $extensionBundle) {
375
                    continue;
376
                }
377
                $event = new ExtensionStateEvent($extensionBundle, $extensionEntity->toArray());
378
                $eventDispatcher->dispatch($event, ExtensionEvents::EXTENSION_POSTINSTALL);
379
            }
380
        }
381
382
        return $this->redirectToRoute('zikulaextensionsmodule_extension_list', ['justinstalled' => json_encode($extensions)]);
383
    }
384
385
    /**
386
     * Create array suitable for checkbox FormType [[ID => bool][ID => bool]].
387
     */
388
    private function formatDependencyCheckboxArray(
389
        ExtensionRepositoryInterface $extensionRepository,
390
        array $dependencies
391
    ): array {
392
        $return = [];
393
        foreach ($dependencies as $dependency) {
394
            /** @var ExtensionEntity $dependencyExtension */
395
            $dependencyExtension = $extensionRepository->get($dependency->getModname());
396
            $return[$dependency->getId()] = null !== $dependencyExtension;
397
        }
398
399
        return $return;
400
    }
401
402
    /**
403
     * @Route("/upgrade/{id}/{token}", requirements={"id" = "^[1-9]\d*$"})
404
     *
405
     * Upgrade an extension.
406
     *
407
     * @throws AccessDeniedException Thrown if the user doesn't have admin permission for the module
408
     */
409
    public function upgradeAction(
410
        ExtensionEntity $extension,
411
        $token,
412
        ExtensionHelper $extensionHelper
413
    ): RedirectResponse {
414
        if (!$this->hasPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
415
            throw new AccessDeniedException();
416
        }
417
418
        if (!$this->isCsrfTokenValid('upgrade-extension', $token)) {
419
            throw new AccessDeniedException();
420
        }
421
422
        $result = $extensionHelper->upgrade($extension);
423
        if ($result) {
424
            $this->addFlash('status', $this->trans('%name% upgraded to new version and activated.', ['%name%' => $extension->getDisplayname()]));
425
        } else {
426
            $this->addFlash('error', 'Extension upgrade failed!');
427
        }
428
429
        return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
430
    }
431
432
    /**
433
     * @Route("/uninstall/{id}/{token}", requirements={"id" = "^[1-9]\d*$"})
434
     * @Theme("admin")
435
     * @Template("@ZikulaExtensionsModule/Extension/uninstall.html.twig")
436
     *
437
     * Uninstall an extension.
438
     *
439
     * @return array|Response|RedirectResponse
440
     * @throws AccessDeniedException Thrown if the user doesn't have admin permission for the module
441
     */
442
    public function uninstallAction(
443
        Request $request,
444
        ExtensionEntity $extension,
445
        string $token,
446
        ZikulaHttpKernelInterface $kernel,
447
        BlockRepositoryInterface $blockRepository,
448
        ExtensionHelper $extensionHelper,
449
        ExtensionStateHelper $extensionStateHelper,
450
        ExtensionDependencyHelper $dependencyHelper,
451
        CacheClearer $cacheClearer
452
    ) {
453
        if (!$this->hasPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
454
            throw new AccessDeniedException();
455
        }
456
457
        if (!$this->isCsrfTokenValid('uninstall-extension', $token)) {
458
            throw new AccessDeniedException();
459
        }
460
461
        if (Constant::STATE_MISSING === $extension->getState()) {
462
            throw new RuntimeException($this->trans('Error! The requested extension cannot be uninstalled because its files are missing!'));
463
        }
464
        if (!$kernel->isBundle($extension->getName())) {
465
            $extensionStateHelper->updateState($extension->getId(), Constant::STATE_TRANSITIONAL);
466
            $cacheClearer->clear('symfony');
467
        }
468
        $requiredDependents = $dependencyHelper->getDependentExtensions($extension);
469
        $blocks = $blockRepository->findBy(['module' => $extension]);
470
471
        $form = $this->createForm(DeletionType::class, [], [
472
            'action' => $this->generateUrl('zikulaextensionsmodule_extension_uninstall', [
473
                'id' => $extension->getId(),
474
                'token' => $token
475
            ]),
476
        ]);
477
        $form->handleRequest($request);
478
        if ($form->isSubmitted() && $form->isValid()) {
479
            if ($form->get('delete')->isClicked()) {
480
                // remove dependent extensions
481
                if (!$extensionHelper->uninstallArray($requiredDependents)) {
482
                    $this->addFlash('error', 'Error: Could not uninstall dependent extensions.');
483
484
                    return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
485
                }
486
                // remove blocks
487
                $blockRepository->remove($blocks);
488
489
                // remove the extension
490
                if ($extensionHelper->uninstall($extension)) {
491
                    $this->addFlash('status', 'Done! Uninstalled extension.');
492
                } else {
493
                    $this->addFlash('error', 'Extension removal failed! (note: blocks and dependents may have been removed)');
494
                }
495
            } elseif ($form->get('cancel')->isClicked()) {
496
                $this->addFlash('status', 'Operation cancelled.');
497
            }
498
499
            return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
500
        }
501
502
        return [
503
            'form' => $form->createView(),
504
            'extension' => $extension,
505
            'blocks' => $blocks,
506
            'requiredDependents' => $requiredDependents
507
        ];
508
    }
509
510
    /**
511
     * @Route("/theme-preview/{themeName}")
512
     */
513
    public function previewAction(Engine $engine, string $themeName): Response
514
    {
515
        if (!$this->hasPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
516
            throw new AccessDeniedException();
517
        }
518
519
        $engine->setActiveTheme($themeName);
520
        $this->addFlash('warning', 'Please note that blocks may appear out of place or even missing in a theme preview because position names are not consistent from theme to theme.');
521
522
        return $this->forward('Zikula\Bundle\CoreBundle\Controller\MainController::homeAction');
523
    }
524
}
525