Completed
Push — master ( e25986...ffddd1 )
by Craig
07:06
created

AjaxInstallController::protectFiles()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 15
nc 4
nop 0
dl 0
loc 27
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Zikula package.
5
 *
6
 * Copyright Zikula Foundation - http://zikula.org/
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zikula\Bundle\CoreInstallerBundle\Controller;
13
14
use RandomLib\Factory;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
use Zikula\BlocksModule\Entity\BlockEntity;
19
use Zikula\BlocksModule\Entity\BlockPlacementEntity;
20
use Zikula\Bundle\CoreBundle\Bundle\Bootstrap as CoreBundleBootstrap;
21
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaKernel;
22
use Zikula\Bundle\CoreBundle\YamlDumper;
23
use Zikula\Core\CoreEvents;
24
use Zikula\Core\Event\GenericEvent;
25
use Zikula\ExtensionsModule\Api\VariableApi;
26
use Zikula\ZAuthModule\Entity\AuthenticationMappingEntity;
27
use Zikula\ZAuthModule\ZAuthConstant;
28
29
/**
30
 * Class AjaxInstallController
31
 */
32
class AjaxInstallController extends AbstractController
33
{
34
    /**
35
     * @var YamlDumper
36
     */
37
    private $yamlManager;
38
39
    public function __construct(ContainerInterface $container)
40
    {
41
        parent::__construct($container);
42
        $this->yamlManager = new YamlDumper($this->container->get('kernel')->getRootDir() .'/config', 'custom_parameters.yml');
43
    }
44
45
    public function ajaxAction(Request $request)
46
    {
47
        $stage = $request->request->get('stage');
48
        $status = $this->executeStage($stage);
49
50
        return new JsonResponse(['status' => $status]);
51
    }
52
53
    public function commandLineAction($stage)
54
    {
55
        return $this->executeStage($stage);
56
    }
57
58
    private function executeStage($stageName)
59
    {
60
        switch ($stageName) {
61
            case "bundles":
62
                return $this->createBundles();
63
            case "install_event":
64
                return $this->fireEvent(CoreEvents::CORE_INSTALL_PRE_MODULE);
65
            case "extensions":
66
                return $this->installModule('ZikulaExtensionsModule');
67
            case "settings":
68
                return $this->installModule('ZikulaSettingsModule');
69
            case "theme":
70
                return $this->installModule('ZikulaThemeModule');
71
            case "admin":
72
                return $this->installModule('ZikulaAdminModule');
73
            case "permissions":
74
                return $this->installModule('ZikulaPermissionsModule');
75
            case "groups":
76
                return $this->installModule('ZikulaGroupsModule');
77
            case "blocks":
78
                return $this->installModule('ZikulaBlocksModule');
79
            case "users":
80
                return $this->installModule('ZikulaUsersModule');
81
            case "zauth":
82
                return $this->installModule('ZikulaZAuthModule');
83
            case "security":
84
                return $this->installModule('ZikulaSecurityCenterModule');
85
            case "categories":
86
                return $this->installModule('ZikulaCategoriesModule');
87
            case "mailer":
88
                return $this->installModule('ZikulaMailerModule');
89
            case "search":
90
                return $this->installModule('ZikulaSearchModule');
91
            case "routes":
92
                return $this->installModule('ZikulaRoutesModule');
93
            case "menu":
94
                return $this->installModule('ZikulaMenuModule');
95
            case "updateadmin":
96
                return $this->updateAdmin();
97
            case "loginadmin":
98
                $params = $this->decodeParameters($this->yamlManager->getParameters());
99
100
                return $this->loginAdmin($params);
101
            case "activatemodules":
102
                return $this->reSyncAndActivateModules();
103
            case "categorize":
104
                return $this->categorizeModules();
105
            case "createblocks":
106
                return $this->createBlocks();
107
            case "finalizeparameters":
108
                return $this->finalizeParameters();
109
            case "installassets":
110
                return $this->installAssets();
111
            case "protect":
112
                return $this->protectFiles();
113
        }
114
115
        return true;
116
    }
117
118
    private function createBundles()
119
    {
120
        $kernel = $this->container->get('kernel');
121
        $boot = new CoreBundleBootstrap();
122
        $helper = $this->container->get('zikula_core.internal.bootstrap_helper');
123
        $helper->createSchema();
124
        $helper->load();
125
        $bundles = [];
126
        // this neatly autoloads
127
        $boot->getPersistedBundles($kernel, $bundles);
128
129
        return true;
130
    }
131
132
    private function categorizeModules()
133
    {
134
        reset(ZikulaKernel::$coreModules);
135
        $systemModulesCategories = [
136
            'ZikulaExtensionsModule' => $this->translator->__('System'),
137
            'ZikulaPermissionsModule' => $this->translator->__('Users'),
138
            'ZikulaGroupsModule' => $this->translator->__('Users'),
139
            'ZikulaBlocksModule' => $this->translator->__('Layout'),
140
            'ZikulaUsersModule' => $this->translator->__('Users'),
141
            'ZikulaZAuthModule' => $this->translator->__('Users'),
142
            'ZikulaThemeModule' => $this->translator->__('Layout'),
143
            'ZikulaSecurityCenterModule' => $this->translator->__('Security'),
144
            'ZikulaCategoriesModule' => $this->translator->__('Content'),
145
            'ZikulaMailerModule' => $this->translator->__('System'),
146
            'ZikulaSearchModule' => $this->translator->__('Content'),
147
            'ZikulaAdminModule' => $this->translator->__('System'),
148
            'ZikulaSettingsModule' => $this->translator->__('System'),
149
            'ZikulaRoutesModule' => $this->translator->__('System'),
150
            'ZikulaMenuModule' => $this->translator->__('Content'),
151
        ];
152
153
        foreach (ZikulaKernel::$coreModules as $systemModule => $bundleClass) {
154
            $this->setModuleCategory($systemModule, $systemModulesCategories[$systemModule]);
155
        }
156
157
        return true;
158
    }
159
160
    private function createBlocks()
161
    {
162
        $installer = new \Zikula\BlocksModule\BlocksModuleInstaller();
163
        $installer->setBundle($this->container->get('kernel')->getModule('ZikulaBlocksModule'));
164
        $installer->setContainer($this->container);
165
        // create the default blocks.
166
        $installer->defaultdata();
167
        $this->createMainMenuBlock();
168
169
        return true;
170
    }
171
172
    /**
173
     * This function inserts the admin's user data
174
     */
175
    private function updateAdmin()
176
    {
177
        $entityManager = $this->container->get('doctrine')->getManager();
178
        $params = $this->decodeParameters($this->yamlManager->getParameters());
179
180
        $nowUTC = new \DateTime(null, new \DateTimeZone('UTC'));
181
182
        /** @var \Zikula\UsersModule\Entity\UserEntity $userEntity */
183
        $userEntity = $entityManager->find('ZikulaUsersModule:UserEntity', 2);
184
        $userEntity->setUname($params['username']);
185
        $userEntity->setEmail($params['email']);
186
        $userEntity->setActivated(1);
187
        $userEntity->setUser_Regdate($nowUTC);
188
        $userEntity->setLastlogin($nowUTC);
189
        $entityManager->persist($userEntity);
190
191
        $mapping = new AuthenticationMappingEntity();
192
        $mapping->setUid($userEntity->getUid());
193
        $mapping->setUname($userEntity->getUname());
194
        $mapping->setEmail($userEntity->getEmail());
195
        $mapping->setVerifiedEmail(true);
196
        $mapping->setPass($this->container->get('zikula_zauth_module.api.password')->getHashedPassword($params['password']));
197
        $mapping->setMethod(ZAuthConstant::AUTHENTICATION_METHOD_UNAME);
198
        $entityManager->persist($mapping);
199
200
        $entityManager->flush();
201
202
        return true;
203
    }
204
205
    private function finalizeParameters()
206
    {
207
        $params = $this->decodeParameters($this->yamlManager->getParameters());
208
        $variableApi = $this->container->get('zikula_extensions_module.api.variable');
209
        $variableApi->getAll(VariableApi::CONFIG); // forces initialization of API
210
        $variableApi->set(VariableApi::CONFIG, 'language_i18n', $params['locale']);
211
        // Set the System Identifier as a unique string.
212
        $variableApi->set(VariableApi::CONFIG, 'system_identifier', str_replace('.', '', uniqid(rand(1000000000, 9999999999), true)));
213
        // add admin email as site email
214
        $variableApi->set(VariableApi::CONFIG, 'adminmail', $params['email']);
215
        // regenerate the theme list
216
        $this->container->get('zikula_theme_module.helper.bundle_sync_helper')->regenerate();
217
218
        // add remaining parameters and remove unneeded ones
219
        unset($params['username'], $params['password'], $params['email'], $params['dbtabletype']);
220
        $params['datadir'] = !empty($params['datadir']) ? $params['datadir'] : 'userdir';
221
        $RandomLibFactory = new Factory();
222
        $generator = $RandomLibFactory->getMediumStrengthGenerator();
223
        $params['secret'] = $generator->generateString(50);
224
        $params['url_secret'] = $generator->generateString(10);
225
        // Configure the Request Context
226
        // see http://symfony.com/doc/current/cookbook/console/sending_emails.html#configuring-the-request-context-globally
227
        $request = $this->container->get('request_stack')->getMasterRequest();
228
        $hostFromRequest = isset($request) ? $request->getHost() : null;
229
        $basePathFromRequest = isset($request) ? $request->getBasePath() : null;
230
        $params['router.request_context.host'] = isset($params['router.request_context.host']) ? $params['router.request_context.host'] : $hostFromRequest;
231
        $params['router.request_context.scheme'] = isset($params['router.request_context.scheme']) ? $params['router.request_context.scheme'] : 'http';
232
        $params['router.request_context.base_url'] = isset($params['router.request_context.base_url']) ? $params['router.request_context.base_url'] : $basePathFromRequest;
233
        $params['umask'] = isset($params['umask']) ? $params['umask'] : null;
234
        $this->yamlManager->setParameters($params);
235
236
        // clear the cache
237
        $this->container->get('zikula.cache_clearer')->clear('symfony.config');
238
239
        return true;
240
    }
241
242
    private function installAssets()
243
    {
244
        $this->container->get('zikula_extensions_module.extension_helper')->installAssets();
245
246
        return true;
247
    }
248
249
    private function protectFiles()
250
    {
251
        // protect config.php and parameters.yml files
252
        foreach ([
253
            realpath($this->container->get('kernel')->getRootDir() . '/../app/config/parameters.yml')
254
        ] as $file) {
255
            @chmod($file, 0400);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
256
            if (!is_readable($file)) {
257
                @chmod($file, 0440);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
258
                if (!is_readable($file)) {
259
                    @chmod($file, 0444);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
260
                }
261
            }
262
        }
263
264
        // set installed = true
265
        $params = $this->yamlManager->getParameters();
266
        $params['installed'] = true;
267
        // set currently installed version into parameters
268
        $params[ZikulaKernel::CORE_INSTALLED_VERSION_PARAM] = ZikulaKernel::VERSION;
269
270
        $this->yamlManager->setParameters($params);
271
        // clear the cache
272
        $this->container->get('zikula.cache_clearer')->clear('symfony.config');
273
274
        return true;
275
    }
276
277
    private function createMainMenuBlock()
278
    {
279
        // Create the Main Menu Block
280
        $_em = $this->container->get('doctrine')->getManager();
281
        $menuModuleEntity = $_em->getRepository('ZikulaExtensionsModule:ExtensionEntity')->findOneBy(['name' => 'ZikulaMenuModule']);
282
        $blockEntity = new BlockEntity();
283
        $mainMenuString = $this->translator->__('Main menu');
284
        $blockEntity->setTitle($mainMenuString);
285
        $blockEntity->setBkey('ZikulaMenuModule:\Zikula\MenuModule\Block\MenuBlock');
286
        $blockEntity->setBlocktype('Menu');
287
        $blockEntity->setDescription($mainMenuString);
288
        $blockEntity->setModule($menuModuleEntity);
289
        $blockEntity->setProperties([
290
            'name' => 'mainMenu',
291
            'options' => '{"template": "ZikulaMenuModule:Override:bootstrap_fontawesome.html.twig"}'
292
        ]);
293
        $_em->persist($blockEntity);
294
295
        $topNavPosition = $_em->getRepository('ZikulaBlocksModule:BlockPositionEntity')->findOneBy(['name' => 'topnav']);
296
        $placement = new BlockPlacementEntity();
297
        $placement->setBlock($blockEntity);
298
        $placement->setPosition($topNavPosition);
299
        $placement->setSortorder(0);
300
        $_em->persist($placement);
301
302
        $_em->flush();
303
    }
304
305
    private function fireEvent($eventName)
306
    {
307
        $event = new GenericEvent();
308
        $this->container->get('event_dispatcher')->dispatch($eventName, $event);
309
        if ($event->isPropagationStopped()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !$event->isPropagationStopped();.
Loading history...
310
            return false;
311
        }
312
313
        return true;
314
    }
315
}
316