Completed
Pull Request — master (#4264)
by Craig
10:39
created

ExtensionInstallerController::installAction()   B

Complexity

Conditions 11
Paths 7

Size

Total Lines 62
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 37
c 1
b 0
f 0
nc 7
nop 5
dl 0
loc 62
rs 7.3166

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\ExtensionsModule\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\Routing\Annotation\Route;
20
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
21
use Symfony\Contracts\Translation\TranslatorInterface;
22
use Zikula\Bundle\CoreBundle\Composer\MetaData;
23
use Zikula\Bundle\CoreBundle\Controller\AbstractController;
24
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
25
use Zikula\ExtensionsModule\AbstractExtension;
26
use Zikula\ExtensionsModule\Api\ApiInterface\VariableApiInterface;
27
use Zikula\ExtensionsModule\Collector\InstallerCollector;
28
use Zikula\ExtensionsModule\Constant;
29
use Zikula\ExtensionsModule\Entity\ExtensionEntity;
30
use Zikula\ExtensionsModule\Entity\RepositoryInterface\ExtensionRepositoryInterface;
31
use Zikula\ExtensionsModule\Event\ExtensionPostCacheRebuildEvent;
32
use Zikula\ExtensionsModule\Form\Type\ExtensionInstallType;
33
use Zikula\ExtensionsModule\Helper\ExtensionDependencyHelper;
34
use Zikula\ExtensionsModule\Helper\ExtensionHelper;
35
use Zikula\ExtensionsModule\Helper\ExtensionStateHelper;
36
use Zikula\PermissionsModule\Annotation\PermissionCheck;
37
use Zikula\PermissionsModule\Api\ApiInterface\PermissionApiInterface;
38
use Zikula\ThemeModule\Engine\Annotation\Theme;
39
40
/**
41
 * @Route("")
42
 */
43
class ExtensionInstallerController extends AbstractController
44
{
45
    /**
46
     * @var ExtensionStateHelper
47
     */
48
    private $extensionStateHelper;
49
50
    /**
51
     * @var ExtensionRepositoryInterface
52
     */
53
    private $extensionRepository;
54
55
    /**
56
     * @var ExtensionDependencyHelper
57
     */
58
    private $dependencyHelper;
59
60
    public function __construct(
61
        AbstractExtension $extension,
62
        PermissionApiInterface $permissionApi,
63
        VariableApiInterface $variableApi,
64
        TranslatorInterface $translator,
65
        ExtensionStateHelper $extensionStateHelper,
66
        ExtensionRepositoryInterface $extensionRepository,
67
        ExtensionDependencyHelper $dependencyHelper
68
    )
69
    {
70
        parent::__construct($extension, $permissionApi, $variableApi, $translator);
71
        $this->extensionStateHelper = $extensionStateHelper;
72
        $this->extensionRepository = $extensionRepository;
73
        $this->dependencyHelper = $dependencyHelper;
74
    }
75
76
    /**
77
     * @Route("/preinstall/{id}", requirements={"id" = "^[1-9]\d*$"})
78
     * @PermissionCheck("admin")
79
     * @Theme("admin")
80
     * @Template("@ZikulaExtensionsModule/Extension/preinstall.html.twig")
81
     */
82
    public function preInstallAction(ExtensionEntity $extension) {
83
        if (Constant::STATE_TRANSITIONAL !== $extension->getState()) {
84
            $this->extensionStateHelper->updateState($extension->getId(), Constant::STATE_TRANSITIONAL);
85
86
            return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
87
        }
88
        $unsatisfiedDependencies = $this->dependencyHelper->getUnsatisfiedExtensionDependencies($extension);
89
        $form = $this->createForm(ExtensionInstallType::class, [
90
            'dependencies' => $this->formatDependencyCheckboxArray($unsatisfiedDependencies)
91
        ], [
92
            'action' => $this->generateUrl('zikulaextensionsmodule_extensioninstaller_install', ['id' => $extension->getId()])
93
        ]);
94
95
        return [
96
            'dependencies' => $unsatisfiedDependencies,
97
            'extension' => $extension,
98
            'form' => $form->createView()
99
        ];
100
    }
101
102
    /**
103
     * @Route("/install/{id}", requirements={"id" = "^[1-9]\d*$"})
104
     * @PermissionCheck("admin")
105
     * @Theme("admin")
106
     *
107
     * Install and initialise an extension.
108
     *
109
     * @return RedirectResponse
110
     */
111
    public function installAction(
112
        Request $request,
113
        ExtensionEntity $extension,
114
        ZikulaHttpKernelInterface $kernel,
115
        InstallerCollector $installerCollector,
116
        ExtensionHelper $extensionHelper
117
    ) {
118
        $id = $extension->getId();
119
120
        $state = $extension->getState();
0 ignored issues
show
Unused Code introduced by
The assignment to $state is dead and can be removed.
Loading history...
121
        $isBundle = $kernel->isBundle($extension->getName());
0 ignored issues
show
Unused Code introduced by
The assignment to $isBundle is dead and can be removed.
Loading history...
122
        $extensionBundle = $kernel->getBundle($extension->getName());
123
        $className = $extensionBundle->getInstallerClass();
0 ignored issues
show
Bug introduced by
The method getInstallerClass() does not exist on Symfony\Component\HttpKe...\Bundle\BundleInterface. It seems like you code against a sub-type of Symfony\Component\HttpKe...\Bundle\BundleInterface such as Zikula\ExtensionsModule\AbstractExtension. ( Ignorable by Annotation )

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

123
        /** @scrutinizer ignore-call */ 
124
        $className = $extensionBundle->getInstallerClass();
Loading history...
124
        $hasInstaller = $installerCollector->has($className);
0 ignored issues
show
Unused Code introduced by
The assignment to $hasInstaller is dead and can be removed.
Loading history...
125
        $installer = $installerCollector->get($className);
0 ignored issues
show
Unused Code introduced by
The assignment to $installer is dead and can be removed.
Loading history...
126
127
        $unsatisfiedDependencies = $this->dependencyHelper->getUnsatisfiedExtensionDependencies($extension);
128
        $form = $this->createForm(ExtensionInstallType::class, [
129
            'dependencies' => $this->formatDependencyCheckboxArray($unsatisfiedDependencies)
130
        ]);
131
132
        $form->handleRequest($request);
133
        if ($form->isSubmitted() && $form->isValid()) {
134
            if ($form->get('install')->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

134
            if ($form->get('install')->/** @scrutinizer ignore-call */ isClicked()) {
Loading history...
135
                $extensionsInstalled = [];
136
                $data = $form->getData();
137
138
                // Install extension dependencies
139
                foreach ($data['dependencies'] as $dependencyId => $installSelected) {
140
                    if (!$installSelected && MetaData::DEPENDENCY_REQUIRED !== $unsatisfiedDependencies[$dependencyId]->getStatus()) {
141
                        continue;
142
                    }
143
                    $dependencyExtensionEntity = $this->extensionRepository->get($unsatisfiedDependencies[$dependencyId]->getModname());
144
                    if (isset($dependencyExtensionEntity)) {
145
                        if (!$extensionHelper->install($dependencyExtensionEntity)) {
146
                            $this->addFlash('error', $this->trans('Failed to install dependency "%name%"!', ['%name%' => $dependencyExtensionEntity->getName()]));
147
148
                            return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
149
                        }
150
                        $extensionsInstalled[] = $dependencyExtensionEntity->getId();
151
                        $this->addFlash('status', $this->trans('Installed dependency "%name%".', ['%name%' => $dependencyExtensionEntity->getName()]));
152
                    } else {
153
                        $this->addFlash('warning', $this->trans('Warning: could not install selected dependency "%name%".', ['%name%' => $unsatisfiedDependencies[$dependencyId]->getModname()]));
154
                    }
155
                }
156
157
                if ($extensionHelper->install($extension)) {
158
                    $this->addFlash('status', $this->trans('Done! Installed "%name%".', ['%name%' => $extension->getName()]));
159
                    $extensionsInstalled[] = $id;
160
161
                    return $this->redirectToRoute('zikulaextensionsmodule_extensioninstaller_postinstall', ['extensions' => json_encode($extensionsInstalled)]);
162
                }
163
                $this->extensionStateHelper->updateState($id, Constant::STATE_UNINITIALISED);
164
                $this->addFlash('error', $this->trans('Initialization of "%name%" failed!', ['%name%' => $extension->getName()]));
165
            }
166
            if ($form->get('cancel')->isClicked()) {
167
                $this->extensionStateHelper->updateState($id, Constant::STATE_UNINITIALISED);
168
                $this->addFlash('status', 'Operation cancelled.');
169
            }
170
        }
171
172
        return $this->redirectToRoute('zikulaextensionsmodule_extension_list');
173
    }
174
175
    /**
176
     * Post-installation action to trigger the MODULE_POSTINSTALL event.
177
     * The additional Action is required because this event must occur AFTER the rebuild of the cache which occurs on Request.
178
     *
179
     * @Route("/postinstall/{extensions}", methods = {"GET"})
180
     */
181
    public function postInstallAction(
182
        ZikulaHttpKernelInterface $kernel,
183
        EventDispatcherInterface $eventDispatcher,
184
        string $extensions = null
185
    ): RedirectResponse {
186
        if (!empty($extensions)) {
187
            $extensions = json_decode($extensions);
188
            foreach ($extensions as $extensionId) {
189
                /** @var ExtensionEntity $extensionEntity */
190
                $extensionEntity = $this->extensionRepository->find($extensionId);
191
                if (null === $this->extensionRepository) {
192
                    continue;
193
                }
194
                /** @var AbstractExtension $extensionBundle */
195
                $extensionBundle = $kernel->getBundle($extensionEntity->getName());
196
                $eventDispatcher->dispatch(new ExtensionPostCacheRebuildEvent($extensionBundle, $extensionEntity));
197
            }
198
        }
199
200
        return $this->redirectToRoute('zikulaextensionsmodule_extension_list', ['justinstalled' => json_encode($extensions)]);
201
    }
202
203
    /**
204
     * Create array suitable for checkbox FormType [[ID => bool][ID => bool]].
205
     */
206
    private function formatDependencyCheckboxArray(array $dependencies): array
207
    {
208
        $return = [];
209
        foreach ($dependencies as $dependency) {
210
            /** @var ExtensionEntity $dependencyExtension */
211
            $dependencyExtension = $this->extensionRepository->get($dependency->getModname());
212
            $return[$dependency->getId()] = null !== $dependencyExtension;
213
        }
214
215
        return $return;
216
    }
217
}
218