Completed
Push — master ( edb9ba...58b9d0 )
by Axel
05:58
created

ParameterHelper::protectFile()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 8
rs 10
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\Bundle\CoreInstallerBundle\Helper;
15
16
use RandomLib\Factory;
17
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\Yaml\Yaml;
20
use Zikula\Bundle\CoreBundle\CacheClearer;
21
use Zikula\Bundle\CoreBundle\Helper\LocalDotEnvHelper;
22
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
23
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaKernel;
24
use Zikula\Bundle\CoreBundle\YamlDumper;
25
use Zikula\ExtensionsModule\Api\ApiInterface\VariableApiInterface;
26
use Zikula\ExtensionsModule\Api\VariableApi;
27
28
class ParameterHelper
29
{
30
    /**
31
     * @var string
32
     */
33
    private $configDir;
34
35
    /**
36
     * @var string
37
     */
38
    private $projectDir;
39
40
    /**
41
     * @var VariableApiInterface
42
     */
43
    private $variableApi;
44
45
    /**
46
     * @var CacheClearer
47
     */
48
    private $cacheClearer;
49
50
    /**
51
     * @var RequestStack
52
     */
53
    private $requestStack;
54
55
    /**
56
     * @var ZikulaHttpKernelInterface
57
     */
58
    private $kernel;
59
60
    /**
61
     * ParameterHelper constructor.
62
     */
63
    public function __construct(
64
        string $projectDir,
65
        VariableApiInterface $variableApi,
66
        CacheClearer $cacheClearer,
67
        RequestStack $requestStack,
68
        ZikulaHttpKernelInterface $kernel
69
    ) {
70
        $this->configDir = $projectDir . '/config';
71
        $this->projectDir = $projectDir;
72
        $this->variableApi = $variableApi;
73
        $this->cacheClearer = $cacheClearer;
74
        $this->requestStack = $requestStack;
75
        $this->kernel = $kernel;
76
    }
77
78
    public function getYamlHelper(bool $initCopy = false): YamlDumper
79
    {
80
        $copyFile = $initCopy ? 'services.yaml' : null;
81
82
        return new YamlDumper($this->configDir, 'services_custom.yaml', $copyFile);
83
    }
84
85
    public function initializeParameters(array $paramsToMerge = []): bool
86
    {
87
        $yamlHelper = $this->getYamlHelper(true);
88
        $params = array_merge($yamlHelper->getParameters(), $paramsToMerge);
89
        $yamlHelper->setParameters($params);
90
        $this->cacheClearer->clear('symfony.config');
91
92
        return true;
93
    }
94
95
    /**
96
     * Load and set new default values from the original services.yaml file into the services_custom.yaml file.
97
     */
98
    public function reInitParameters(): bool
99
    {
100
        $originalParameters = Yaml::parse(file_get_contents($this->kernel->getProjectDir() . '/config/services.yaml'));
101
        $yamlHelper = $this->getYamlHelper();
102
        $yamlHelper->setParameters(array_merge($originalParameters['parameters'], $yamlHelper->getParameters()));
103
        $this->cacheClearer->clear('symfony.config');
104
105
        return true;
106
    }
107
108
    /**
109
     * @throws IOExceptionInterface If .env.local could not be dumped
110
     */
111
    public function finalizeParameters(bool $configureRequestContext = true): bool
112
    {
113
        $yamlHelper = $this->getYamlHelper();
114
        $params = $this->decodeParameters($yamlHelper->getParameters());
115
116
        $this->variableApi->getAll(VariableApi::CONFIG); // forces initialization of API
117
        if (!isset($params['upgrading'])) {
118
            $this->variableApi->set(VariableApi::CONFIG, 'locale', $params['locale']);
119
            // Set the System Identifier as a unique string.
120
            if (!$this->variableApi->get(VariableApi::CONFIG, 'system_identifier')) {
121
                $this->variableApi->set(VariableApi::CONFIG, 'system_identifier', str_replace('.', '', uniqid((string) (random_int(1000000000, 9999999999)), true)));
122
            }
123
            // add admin email as site email
124
            $this->variableApi->set(VariableApi::CONFIG, 'adminmail', $params['email']);
125
        }
126
127
        // add remaining parameters and remove unneeded ones
128
        unset($params['username'], $params['password'], $params['email']);
129
        $params['datadir'] = !empty($params['datadir']) ? $params['datadir'] : 'public/uploads';
130
131
        if ($configureRequestContext) {
132
            // Configure the Request Context
133
            // see http://symfony.com/doc/current/cookbook/console/sending_emails.html#configuring-the-request-context-globally
134
            $request = $this->requestStack->getMasterRequest();
135
            $hostFromRequest = isset($request) ? $request->getHost() : null;
136
            $schemeFromRequest = isset($request) ? $request->getScheme() : 'http';
137
            $basePathFromRequest = isset($request) ? $request->getBasePath() : null;
138
            $params['router.request_context.host'] = $params['router.request_context.host'] ?? $hostFromRequest;
139
            $params['router.request_context.scheme'] = $params['router.request_context.scheme'] ?? $schemeFromRequest;
140
            $params['router.request_context.base_url'] = $params['router.request_context.base_url'] ?? $basePathFromRequest;
141
        }
142
        // store the recent version in a config var for later usage. This enables us to determine the version we are upgrading from
143
        $this->variableApi->set(VariableApi::CONFIG, 'Version_Num', ZikulaKernel::VERSION);
144
145
        if (isset($params['upgrading'])) {
146
            $params['zikula_asset_manager.combine'] = false;
147
148
            // unset start page information to avoid missing module errors
149
            $this->variableApi->set(VariableApi::CONFIG, 'startController_en', '');
150
151
            // on upgrade, if a user doesn't add their custom theme back to the /theme dir, it should be reset to a core theme, if available.
152
            $defaultTheme = (string) $this->variableApi->getSystemVar('Default_Theme');
153
            if (!$this->kernel->isBundle($defaultTheme) && $this->kernel->isBundle('ZikulaBootstrapTheme')) {
154
                $this->variableApi->set(VariableApi::CONFIG, 'Default_Theme', 'ZikulaBootstrapTheme');
155
            }
156
        }
157
158
        // write parameters into config/services_custom.yaml
159
        $yamlHelper->setParameters($params);
160
161
        if (isset($params['upgrading'])) {
162
            unset($params['upgrading']);
163
        } else {
164
            $this->writeEnvVars();
165
        }
166
167
        // clear the cache
168
        $this->cacheClearer->clear('symfony.config');
169
170
        return true;
171
    }
172
173
    private function writeEnvVars()
174
    {
175
        $randomLibFactory = new Factory();
176
        $generator = $randomLibFactory->getMediumStrengthGenerator();
177
        $vars = [
178
            'APP_ENV' => 'prod',
179
            'APP_DEBUG' => 1,
180
            'APP_SECRET' => '\'' . $generator->generateString(50) . '\'',
181
            'ZIKULA_INSTALLED' => '\'' . ZikulaKernel::VERSION . '\''
182
        ];
183
        $helper = new LocalDotEnvHelper($this->projectDir);
184
        $helper->writeLocalEnvVars($vars);
185
    }
186
187
    /**
188
     * Remove base64 encoding for admin parameters.
189
     */
190
    public function decodeParameters(array $params = []): array
191
    {
192
        if (!empty($params['password'])) {
193
            $params['password'] = base64_decode($params['password']);
194
        }
195
        if (!empty($params['username'])) {
196
            $params['username'] = base64_decode($params['username']);
197
        }
198
        if (!empty($params['email'])) {
199
            $params['email'] = base64_decode($params['email']);
200
        }
201
202
        return $params;
203
    }
204
}
205