Passed
Push — master ( 8a455a...42a228 )
by Craig
07:01
created

ModuleHelper::executeCoreMetaUpgrade()   F

Complexity

Conditions 16
Paths 630

Size

Total Lines 71
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 45
nc 630
nop 1
dl 0
loc 71
rs 1.9138
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 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\Bundle\CoreInstallerBundle\Helper;
15
16
use ReflectionClass;
17
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
18
use Symfony\Component\DependencyInjection\ContainerInterface;
19
use Zikula\BlocksModule\Entity\BlockEntity;
20
use Zikula\Bundle\CoreBundle\Bundle\AbstractCoreModule;
21
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaKernel;
22
use Zikula\Bundle\CoreBundle\YamlDumper;
23
use Zikula\Common\Translator\Translator;
24
use Zikula\Common\Translator\TranslatorInterface;
25
use Zikula\ExtensionsModule\Api\VariableApi;
26
use Zikula\ExtensionsModule\Constant;
27
use Zikula\ExtensionsModule\Entity\ExtensionEntity;
28
use Zikula\ExtensionsModule\Helper\BundleSyncHelper;
29
use Zikula\ExtensionsModule\Helper\ExtensionHelper;
30
31
class ModuleHelper
32
{
33
    /**
34
     * @var ContainerInterface
35
     */
36
    private $container;
37
38
    /**
39
     * @var TranslatorInterface
40
     */
41
    private $translator;
42
43
    /**
44
     * @var YamlDumper
45
     */
46
    private $yamlHelper;
47
48
    public function __construct(
49
        ContainerInterface $container
50
    ) {
51
        $this->container = $container;
52
        $this->translator = $container->get(Translator::class);
53
        $this->yamlHelper = $container->get(ParameterHelper::class)->getYamlHelper();
54
    }
55
56
    public function installModule(string $moduleName): bool
57
    {
58
        $module = $this->container->get('kernel')->getModule($moduleName);
59
        /** @var AbstractCoreModule $module */
60
        $className = $module->getInstallerClass();
61
        $reflectionInstaller = new ReflectionClass($className);
62
        $installer = $reflectionInstaller->newInstance();
63
        $installer->setBundle($module);
64
        if ($installer instanceof ContainerAwareInterface) {
65
            $installer->setContainer($this->container);
66
        }
67
68
        if ($installer->install()) {
69
            return true;
70
        }
71
72
        return false;
73
    }
74
75
    /**
76
     * Set an admin category for a module or set to default.
77
     */
78
    private function setModuleCategory(string $moduleName, string $translatedCategoryName): bool
79
    {
80
        $doctrine = $this->container->get('doctrine');
81
        $categoryRepository = $doctrine->getRepository('ZikulaAdminModule:AdminCategoryEntity');
82
        $modulesCategories = $categoryRepository->getIndexedCollection('name');
83
        $moduleEntity = $doctrine->getRepository('ZikulaExtensionsModule:ExtensionEntity')
84
            ->findOneBy(['name' => $moduleName]);
85
86
        $moduleRepository = $doctrine->getRepository('ZikulaAdminModule:AdminModuleEntity');
87
        if (isset($modulesCategories[$translatedCategoryName])) {
88
            $moduleRepository->setModuleCategory($moduleEntity, $modulesCategories[$translatedCategoryName]);
89
        } else {
90
            $defaultCategoryId = $this->container->get(VariableApi::class)->get('ZikulaAdminModule', 'defaultcategory', 5);
91
            $defaultCategory = $categoryRepository->find($defaultCategoryId);
92
            $moduleRepository->setModuleCategory($moduleEntity, $defaultCategory);
93
        }
94
95
        return true;
96
    }
97
98
    public function categorizeModules(): bool
99
    {
100
        reset(ZikulaKernel::$coreModules);
101
        $systemModulesCategories = [
102
            'ZikulaExtensionsModule' => $this->translator->__('System'),
103
            'ZikulaPermissionsModule' => $this->translator->__('Users'),
104
            'ZikulaGroupsModule' => $this->translator->__('Users'),
105
            'ZikulaBlocksModule' => $this->translator->__('Layout'),
106
            'ZikulaUsersModule' => $this->translator->__('Users'),
107
            'ZikulaZAuthModule' => $this->translator->__('Users'),
108
            'ZikulaThemeModule' => $this->translator->__('Layout'),
109
            'ZikulaSecurityCenterModule' => $this->translator->__('Security'),
110
            'ZikulaCategoriesModule' => $this->translator->__('Content'),
111
            'ZikulaMailerModule' => $this->translator->__('System'),
112
            'ZikulaSearchModule' => $this->translator->__('Content'),
113
            'ZikulaAdminModule' => $this->translator->__('System'),
114
            'ZikulaSettingsModule' => $this->translator->__('System'),
115
            'ZikulaRoutesModule' => $this->translator->__('System'),
116
            'ZikulaMenuModule' => $this->translator->__('Content'),
117
        ];
118
119
        foreach (ZikulaKernel::$coreModules as $systemModule => $bundleClass) {
120
            $this->setModuleCategory($systemModule, $systemModulesCategories[$systemModule]);
121
        }
122
123
        return true;
124
    }
125
126
    /**
127
     * Scan the filesystem and sync the modules table. Set all core modules to active state.
128
     */
129
    public function reSyncAndActivateModules(): bool
130
    {
131
        $bundleSyncHelper = $this->container->get(BundleSyncHelper::class);
132
        $extensionsInFileSystem = $bundleSyncHelper->scanForBundles();
133
        $bundleSyncHelper->syncExtensions($extensionsInFileSystem);
134
135
        $doctrine = $this->container->get('doctrine');
136
137
        /** @var ExtensionEntity[] $extensions */
138
        $extensions = $doctrine->getRepository('ZikulaExtensionsModule:ExtensionEntity')
139
            ->findBy(['name' => array_keys(ZikulaKernel::$coreModules)]);
140
        foreach ($extensions as $extension) {
141
            $extension->setState(Constant::STATE_ACTIVE);
142
        }
143
        $doctrine->getManager()->flush();
144
145
        return true;
146
    }
147
148
    /**
149
     * Attempt to upgrade ALL the core modules. Some will need it, some will not.
150
     * Modules that do not need upgrading return TRUE as a result of the upgrade anyway.
151
     */
152
    public function upgradeModules(): bool
153
    {
154
        $coreModulesInPriorityUpgradeOrder = [
155
            'ZikulaExtensionsModule',
156
            'ZikulaUsersModule',
157
            'ZikulaZAuthModule',
158
            'ZikulaGroupsModule',
159
            'ZikulaPermissionsModule',
160
            'ZikulaAdminModule',
161
            'ZikulaBlocksModule',
162
            'ZikulaThemeModule',
163
            'ZikulaSettingsModule',
164
            'ZikulaCategoriesModule',
165
            'ZikulaSecurityCenterModule',
166
            'ZikulaRoutesModule',
167
            'ZikulaMailerModule',
168
            'ZikulaSearchModule',
169
            'ZikulaMenuModule',
170
        ];
171
        $result = true;
172
        foreach ($coreModulesInPriorityUpgradeOrder as $moduleName) {
173
            $extensionEntity = $this->container->get('doctrine')->getRepository('ZikulaExtensionsModule:ExtensionEntity')->get($moduleName);
174
            if (isset($extensionEntity)) {
175
                $result = $result && $this->container->get(ExtensionHelper::class)->upgrade($extensionEntity);
176
            }
177
        }
178
179
        return $result;
180
    }
181
182
    public function executeCoreMetaUpgrade($currentCoreVersion): bool
183
    {
184
        $doctrine = $this->container->get('doctrine');
185
        /**
186
         * NOTE: There are *intentionally* no `break` statements within each case here so that the process continues
187
         * through each case until the end.
188
         */
189
        switch ($currentCoreVersion) {
190
            case '1.4.3':
191
                $this->installModule('ZikulaMenuModule');
192
                $this->reSyncAndActivateModules();
193
                $this->setModuleCategory('ZikulaMenuModule', $this->translator->__('Content'));
194
            case '1.4.4':
195
                // nothing
196
            case '1.4.5':
197
                // Menu module was introduced in 1.4.4 but not installed on upgrade
198
                $schemaManager = $doctrine->getConnection()->getSchemaManager();
199
                if (!$schemaManager->tablesExist(['menu_items'])) {
200
                    $this->installModule('ZikulaMenuModule');
201
                    $this->reSyncAndActivateModules();
202
                    $this->setModuleCategory('ZikulaMenuModule', $this->translator->__('Content'));
203
                }
204
            case '1.4.6':
205
                // nothing needed
206
            case '1.4.7':
207
                // nothing needed
208
            case '1.5.0':
209
                // nothing needed
210
            case '1.9.99':
211
                // upgrades required for 2.0.0
212
                foreach (['objectdata_attributes', 'objectdata_log', 'objectdata_meta', 'workflows'] as $table) {
213
                    $sql = "DROP TABLE ${table};";
214
                    /** @var \Doctrine\DBAL\Driver\PDOConnection $connection */
215
                    $connection = $doctrine->getConnection();
216
                    $stmt = $connection->prepare($sql);
217
                    $stmt->execute();
218
                    $stmt->closeCursor();
219
                }
220
                $variableApi = $this->container->get(VariableApi::class);
221
                $variableApi->del(VariableApi::CONFIG, 'metakeywords');
222
                $variableApi->del(VariableApi::CONFIG, 'startpage');
223
                $variableApi->del(VariableApi::CONFIG, 'startfunc');
224
                $variableApi->del(VariableApi::CONFIG, 'starttype');
225
                if ('userdata' === $this->container->getParameter('datadir')) {
226
                    $this->yamlHelper->setParameter('datadir', 'web/uploads');
227
                    $fs = $this->container->get('filesystem');
228
                    $src = dirname(__DIR__, 5) . '/';
229
                    try {
230
                        if ($fs->exists($src . '/userdata')) {
231
                            $fs->mirror($src . '/userdata', $src . '/web/uploads');
232
                        }
233
                    } catch (\Exception $exception) {
234
                        $this->container->get('session')->getFlashBag()->add('info', $this->translator->__('Attempt to copy files from `userdata` to `web/uploads` failed. You must manually copy the contents.'));
235
                    }
236
                }
237
                // remove legacy blocks
238
                $blocksToRemove = $doctrine->getRepository(BlockEntity::class)->findBy(['blocktype' => ['Extmenu', 'Menutree', 'Menu']]);
239
                foreach ($blocksToRemove as $block) {
240
                    $doctrine->getManager()->remove($block);
241
                }
242
                $doctrine->getManager()->flush();
243
            case '2.0.0':
244
                // nothing needed
245
            case '3.0.0':
246
                // current version - cannot perform anything yet
247
        }
248
249
        // always do this
250
        $this->reSyncAndActivateModules();
251
252
        return true;
253
    }
254
}
255