Completed
Push — master ( ad0611...abd676 )
by Tom
09:08 queued 04:30
created

InstallMagento::_getDefaultSessionFolder()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 3
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace N98\Magento\Command\Installer\SubCommand;
4
5
use N98\Magento\Command\SubCommand\AbstractSubCommand;
6
use N98\Util\OperatingSystem;
7
8
class InstallMagento extends AbstractSubCommand
9
{
10
    /**
11
     * @var int
12
     */
13
    const EXEC_STATUS_OK = 0;
14
15
    /**
16
     * @var \Closure
17
     */
18
    protected $notEmptyCallback;
19
20
    /**
21
     * @return void
22
     * @throws \Exception
23
     */
24
    public function execute()
25
    {
26
        $this->notEmptyCallback = function ($input) {
27
            if (empty($input)) {
28
                throw new \InvalidArgumentException('Please enter a value');
29
            }
30
            return $input;
31
        };
32
33
        $this->getCommand()->getApplication()->setAutoExit(false);
34
35
        $dialog = $this->getCommand()->getHelper('dialog');
36
37
        $defaults = $this->commandConfig['installation']['defaults'];
38
39
        $useDefaultConfigParams = $this->getCommand()->parseBoolOption(
40
            $this->input->getOption('useDefaultConfigParams')
41
        );
42
43
        $sessionSave = $useDefaultConfigParams ? $defaults['session-save'] : $dialog->ask(
44
            $this->output,
45
            '<question>Please enter the session save:</question> <comment>[' .
46
            $defaults['session-save'] . ']</comment>: ',
47
            $defaults['session-save']
48
        );
49
50
        $adminFrontname = $useDefaultConfigParams ? $defaults['backend-frontname'] : $dialog->askAndValidate(
51
            $this->output,
52
            '<question>Please enter the admin/backend frontname:</question> <comment>[' .
53
            $defaults['backend-frontname'] . ']</comment> ',
54
            $this->notEmptyCallback,
55
            false,
56
            $defaults['backend-frontname']
57
        );
58
59
        $currency = $useDefaultConfigParams ? $defaults['currency'] : $dialog->askAndValidate(
60
            $this->output,
61
            '<question>Please enter the default currency code:</question> <comment>[' .
62
            $defaults['currency'] . ']</comment>: ',
63
            $this->notEmptyCallback,
64
            false,
65
            $defaults['currency']
66
        );
67
68
        $locale = $useDefaultConfigParams ? $defaults['locale'] : $dialog->askAndValidate(
69
            $this->output,
70
            '<question>Please enter the locale code:</question> <comment>[' . $defaults['locale'] . ']</comment>: ',
71
            $this->notEmptyCallback,
72
            false,
73
            $defaults['locale']
74
        );
75
76
        $timezone = $useDefaultConfigParams ? $defaults['timezone'] : $dialog->askAndValidate(
77
            $this->output,
78
            '<question>Please enter the timezone:</question> <comment>[' . $defaults['timezone'] . ']</comment>: ',
79
            $this->notEmptyCallback,
80
            false,
81
            $defaults['timezone']
82
        );
83
84
        $adminUsername = $useDefaultConfigParams ? $defaults['admin-user'] : $dialog->askAndValidate(
85
            $this->output,
86
            '<question>Please enter the admin username:</question> <comment>[' .
87
            $defaults['admin-user'] . ']</comment>: ',
88
            $this->notEmptyCallback,
89
            false,
90
            $defaults['admin-user']
91
        );
92
93
        $adminPassword = $useDefaultConfigParams ? $defaults['admin-password'] : $dialog->askAndValidate(
94
            $this->output,
95
            '<question>Please enter the admin password:</question> <comment>[' .
96
            $defaults['admin-password'] . ']</comment>: ',
97
            $this->notEmptyCallback,
98
            false,
99
            $defaults['admin-password']
100
        );
101
102
        $adminFirstname = $useDefaultConfigParams ? $defaults['admin-firstname'] : $dialog->askAndValidate(
103
            $this->output,
104
            '<question>Please enter the admin\'s firstname:</question> <comment>[' .
105
            $defaults['admin-firstname'] . ']</comment>: ',
106
            $this->notEmptyCallback,
107
            false,
108
            $defaults['admin-firstname']
109
        );
110
111
        $adminLastname = $useDefaultConfigParams ? $defaults['admin-lastname'] : $dialog->askAndValidate(
112
            $this->output,
113
            '<question>Please enter the admin\'s lastname:</question> <comment>[' .
114
            $defaults['admin-lastname'] . ']</comment>: ',
115
            $this->notEmptyCallback,
116
            false,
117
            $defaults['admin-lastname']
118
        );
119
120
        $adminEmail = $useDefaultConfigParams ? $defaults['admin-email'] : $dialog->askAndValidate(
121
            $this->output,
122
            '<question>Please enter the admin\'s email:</question> <comment>[' .
123
            $defaults['admin-email'] . ']</comment>: ',
124
            $this->notEmptyCallback,
125
            false,
126
            $defaults['admin-email']
127
        );
128
129
        $validateBaseUrl = function ($url) {
130
            if (!preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url)) {
131
                throw new \InvalidArgumentException('Please enter a valid URL');
132
            }
133
            if (parse_url($url, \PHP_URL_HOST) == 'localhost') {
134
                throw new \InvalidArgumentException(
135
                    'localhost cause problems! Please use 127.0.0.1 or another hostname'
136
                );
137
            }
138
139
            return $url;
140
        };
141
142
        $baseUrl = ($this->input->getOption('baseUrl') !== null)
143
            ? $this->input->getOption('baseUrl')
144
            : $dialog->askAndValidate(
145
                $this->output,
146
                '<question>Please enter the base url:</question> ',
147
                $validateBaseUrl,
148
                false
149
            );
150
        $baseUrl = rtrim($baseUrl, '/') . '/'; // normalize baseUrl
151
152
        /**
153
         * Correct session save (common mistake)
154
         */
155
        if ($sessionSave == 'file') {
156
            $sessionSave = 'files';
157
        }
158
        $this->_getDefaultSessionFolder($sessionSave);
159
160
        $argv = array(
161
            'language' => $locale,
162
            'timezone' => $timezone,
163
            'db-host' => $this->_prepareDbHost(),
164
            'db-name' => $this->config->getString('db_name'),
165
            'db-user' => $this->config->getString('db_user'),
166
            'base-url' => $baseUrl,
167
            'use-rewrites' => 1,
168
            'use-secure' => 0,
169
            'use-secure-admin' => 1,
170
            'admin-user' => $adminUsername,
171
            'admin-lastname' => $adminLastname,
172
            'admin-firstname' => $adminFirstname,
173
            'admin-email' => $adminEmail,
174
            'admin-password' => $adminPassword,
175
            'session-save' => $sessionSave,
176
            'backend-frontname' => $adminFrontname,
177
            'currency' => $currency,
178
        );
179
180
        $dbPass = $this->config->getString('db_pass');
181
        if (!empty($dbPass)) {
182
            $argv['db-password'] = $dbPass;
183
        }
184
185
        if ($useDefaultConfigParams) {
186
            if (isset($defaults['encryption-key']) && strlen($defaults['encryption-key']) > 0) {
187
                $argv['encryption-key'] = $defaults['encryption-key'];
188
            }
189
            if (strlen($defaults['use-secure']) > 0) {
190
                $argv['use-secure'] = $defaults['use-secure'];
191
                $argv['base-url-secure'] = str_replace('http://', 'https://', $baseUrl);
192
            }
193
            if (strlen($defaults['use-rewrites']) > 0) {
194
                $argv['use-rewrites'] = $defaults['use-rewrites'];
195
            }
196
        }
197
198
        $this->config->setArray('installation_args', $argv);
199
200
        $installArgs = '';
201
        foreach ($argv as $argName => $argValue) {
202
            if (is_null($argValue)) {
203
                $installArgs .= '--' . $argName . ' ';
204
            } elseif (is_bool($argValue)) {
205
                if ($argValue) {
206
                    $argValue = '1';
207
                } else {
208
                    $argValue = '0';
209
                }
210
                $installArgs .= '--' . $argName . '=' . $argValue . ' ';
211
            } else {
212
                $installArgs .= '--' . $argName . '=' . escapeshellarg($argValue) . ' ';
213
            }
214
        }
215
216
        $this->output->writeln('<info>Start installation process.</info>');
217
        $this->_runInstaller($installArgs);
0 ignored issues
show
Documentation introduced by
$installArgs is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
218
    }
219
220
    /**
221
     * @return string
222
     * @throws \Exception
223
     */
224
    protected function getInstallScriptPath()
225
    {
226
        $installerScript = $this->config->getString('installationFolder') . '/bin/magento';
227
        if (!file_exists($installerScript)) {
228
            throw new \RuntimeException('Installation script was not found.', 1);
229
        }
230
231
        return $installerScript;
232
    }
233
234
    /**
235
     * @param $sessionSave
236
     */
237
    protected function _getDefaultSessionFolder($sessionSave)
238
    {
239
        /**
240
         * Try to create session folder
241
         */
242
        $defaultSessionFolder = $this->config->getString('installationFolder') . '/var/session';
243
        if ($sessionSave == 'files' && !is_dir($defaultSessionFolder)) {
244
            @mkdir($defaultSessionFolder);
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...
245
        }
246
    }
247
248
    /**
249
     * @return string
250
     */
251
    protected function _prepareDbHost()
252
    {
253
        $dbHost = $this->config->getString('db_host');
254
255
        if ($this->config->getInt('db_port') != 3306) {
256
            $dbHost .= ':' . strval($this->config->getInt('db_port'));
257
258
            return $dbHost;
259
        }
260
261
        return $dbHost;
262
    }
263
264
    /**
265
     * @param array $installArgs
266
     *
267
     * @throws \Exception
268
     */
269
    protected function _runInstaller($installArgs)
270
    {
271
        $installationOutput = null;
272
        $returnStatus = null;
273
274
        if (OperatingSystem::isWindows()) {
275
            $installCommand = 'php ' . $this->getInstallScriptPath() . ' setup:install ' . $installArgs;
276
        } else {
277
            $installCommand = '/usr/bin/env php ' . $this->getInstallScriptPath() . ' setup:install ' . $installArgs;
278
        }
279
280
        $this->output->writeln('<comment>' . $installCommand . '</comment>');
281
        exec($installCommand, $installationOutput, $returnStatus);
282
        $installationOutput = implode(PHP_EOL, $installationOutput);
283
        if ($returnStatus !== self::EXEC_STATUS_OK) {
284
            throw new \RuntimeException('Installation failed.' . $installationOutput, 1);
285
        } else {
286
            $this->output->writeln('<info>Successfully installed Magento</info>');
287
            $encryptionKey = trim(substr($installationOutput, strpos($installationOutput, ':') + 1));
288
            $this->output->writeln('<comment>Encryption Key:</comment> <info>' . $encryptionKey . '</info>');
289
        }
290
    }
291
}
292