InstallController::checkModules()   F
last analyzed

Complexity

Conditions 20
Paths 576

Size

Total Lines 45
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 420

Importance

Changes 0
Metric Value
cc 20
eloc 24
nc 576
nop 1
dl 0
loc 45
rs 2.7939
c 0
b 0
f 0
ccs 0
cts 0
cp 0
crap 420

How to fix   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
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU General Public License
12
 * as published by the Free Software Foundation; either version 2
13
 * of the License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23
 */
24
25
namespace Eccube\Controller\Install;
26
27
use Doctrine\DBAL\Migrations\Configuration\Configuration;
28
use Doctrine\DBAL\Migrations\Migration;
29
use Doctrine\DBAL\Migrations\MigrationException;
30
use Doctrine\ORM\EntityManager;
31
use Doctrine\ORM\Tools\SchemaTool;
32
use Eccube\Common\Constant;
33
use Eccube\InstallApplication;
34
use Eccube\Util\Str;
35
use Symfony\Component\Filesystem\Filesystem;
36
use Symfony\Component\Finder\Finder;
37
use Symfony\Component\Form\Form;
38
use Symfony\Component\HttpFoundation\Request;
39
use Symfony\Component\Yaml\Yaml;
40
41
class InstallController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
42
{
43
44
    const MCRYPT = 'mcrypt';
45
46
    private $app;
47
    private $PDO;
48
    private $config_path;
49
    private $dist_path;
50
    private $cache_path;
51
    private $session_data;
52
    private $required_modules = array('pdo', 'phar', 'mbstring', 'zlib', 'ctype', 'session', 'JSON', 'xml', 'libxml', 'OpenSSL', 'zip', 'cURL', 'fileinfo');
53
    private $recommended_module = array('hash', self::MCRYPT);
54
55
    const SESSION_KEY = 'eccube.session.install';
56
57
    public function __construct()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
58
    {
59
        $this->config_path = __DIR__ . '/../../../../app/config/eccube';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
60
        $this->dist_path = __DIR__ . '/../../Resource/config';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
61 6
        $this->cache_path = __DIR__ . '/../../../../app/cache';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
62
    }
63 6
64 6
    private function isValid(Request $request, Form $form)
65 6
    {
66 6
        $session = $request->getSession();
67
        if ('POST' === $request->getMethod()) {
68 4
            $form->handleRequest($request);
69
            if ($form->isValid()) {
70
                $sessionData = $session->get(self::SESSION_KEY) ?: array();
71
                $formData = array_replace_recursive($sessionData, $form->getData());
72
                $session->set(self::SESSION_KEY, $formData);
73
74
                return true;
75
            }
76
        }
77
78
        return false;
79
    }
80
81
    private function getSessionData(Request $request)
82 4
    {
83 4
        return $this->session_data = $request->getSession()->get(self::SESSION_KEY);
84
    }
85 5
86
    // 最初からやり直す場合、SESSION情報をクリア
87
    public function index(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
introduced by
You must use "/**" style comments for a function comment
Loading history...
88 5
    {
89
        $request->getSession()->remove(self::SESSION_KEY);
90
91 1
        return $app->redirect($app->path('install_step1'));
92
    }
93
94
    // ようこそ
95
    public function step1(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
96 1
    {
97
        $form = $app['form.factory']
98
            ->createBuilder('install_step1')
99 1
            ->getForm();
100
        $sessionData = $this->getSessionData($request);
101
        $form->setData($sessionData);
102
103
        if ($this->isValid($request, $form)) {
104
            return $app->redirect($app->path('install_step2'));
105
        }
106
107
        $this->checkModules($app);
108
109
        return $app['twig']->render('step1.twig', array(
110
                'form' => $form->createView(),
111
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
112
        ));
113 1
    }
114 1
115
    // 権限チェック
116 1
    public function step2(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
117
    {
118
        $this->getSessionData($request);
119 1
120
        $protectedDirs = $this->getProtectedDirs();
121
122
        // 権限がある場合, キャッシュディレクトリをクリア
123
        if (empty($protectedDirs)) {
124
            $finder = Finder::create()
125
                ->in($this->cache_path)
126 1
                ->directories()
127 1
                ->depth(0);
128 1
            $fs = new Filesystem();
129 1
            $fs->remove($finder);
130
        }
131
132
        return $app['twig']->render('step2.twig', array(
133
                'protectedDirs' => $protectedDirs,
134
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
135 1
        ));
136
    }
137
138 1
    //    サイトの設定
139
    public function step3(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
140
    {
141 1
        $form = $app['form.factory']
142
            ->createBuilder('install_step3')
143
            ->getForm();
144
        $sessionData = $this->getSessionData($request);
145
146
        if (empty($sessionData['shop_name'])) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
147
148
            $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
149
            $fs = new Filesystem();
150
151
            if ($fs->exists($config_file)) {
152
                // すでに登録されていた場合、登録データを表示
153
                $this->setPDO();
154
                $stmt = $this->PDO->query("SELECT shop_name, email01 FROM dtb_base_info WHERE id = 1;");
155
156
                foreach ($stmt as $row) {
157
                    $sessionData['shop_name'] = $row['shop_name'];
158 1
                    $sessionData['email'] = $row['email01'];
159 1
                }
160
161 1
                // セキュリティの設定
162
                $config_file = $this->config_path . '/path.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
163
                $config = Yaml::parse(file_get_contents($config_file));
164 1
                $sessionData['admin_dir'] = $config['admin_route'];
165
166
                $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
167
                $config = Yaml::parse(file_get_contents($config_file));
168
169
                $allowHost = $config['admin_allow_host'];
170 View Code Duplication
                if (count($allowHost) > 0) {
171
                    $sessionData['admin_allow_hosts'] = Str::convertLineFeed(implode("\n", $allowHost));
172
                }
173
                $sessionData['admin_force_ssl'] = (bool) $config['force_ssl'];
174
175
                // ロードバランサー、プロキシサーバ設定
176
                $sessionData['trusted_proxies_connection_only'] = (bool)$config['trusted_proxies_connection_only'];
0 ignored issues
show
Coding Style introduced by
As per coding-style, a cast statement should be followed by a single space.
Loading history...
177
                $trustedProxies = $config['trusted_proxies'];
178 View Code Duplication
                if (count($trustedProxies) > 0) {
179 1
                    $sessionData['trusted_proxies'] = Str::convertLineFeed(implode("\n", $trustedProxies));
180 1
                }
181
182 1
                // メール設定
183
                $config_file = $this->config_path . '/mail.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
184
                $config = Yaml::parse(file_get_contents($config_file));
185 1
                $mail = $config['mail'];
186
                $sessionData['mail_backend'] = $mail['transport'];
187
                $sessionData['smtp_host'] = $mail['host'];
188 1
                $sessionData['smtp_port'] = $mail['port'];
189
                $sessionData['smtp_username'] = $mail['username'];
190
                $sessionData['smtp_password'] = $mail['password'];
191
            } else {
192
                // 初期値にmailを設定
193
                $sessionData['mail_backend'] = 'mail';
194
            }
195
        }
196
197
        $form->setData($sessionData);
198
        if ($this->isValid($request, $form)) {
199
            $data = $form->getData();
0 ignored issues
show
Unused Code introduced by
$data is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
200
201
            return $app->redirect($app->path('install_step4'));
202
        }
203
204
        return $app['twig']->render('step3.twig', array(
205
                'form' => $form->createView(),
206
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
207
        ));
208
    }
209
210
    //    データベースの設定
211
    public function step4(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
212
    {
213
        $form = $app['form.factory']
214
            ->createBuilder('install_step4')
215
            ->getForm();
216
217
        $sessionData = $this->getSessionData($request);
218
219
        if (empty($sessionData['database'])) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
220
221
            $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
222
            $fs = new Filesystem();
223 1
224 1
            if ($fs->exists($config_file)) {
225
                // すでに登録されていた場合、登録データを表示
226 1
                // データベース設定
227
                $config = Yaml::parse(file_get_contents($config_file));
228
                $database = $config['database'];
229
                $sessionData['database'] = $database['driver'];
230
                if ($database['driver'] != 'pdo_sqlite') {
231
                    $sessionData['database_host'] = $database['host'];
232
                    $sessionData['database_port'] = $database['port'];
233
                    $sessionData['database_name'] = $database['dbname'];
234
                    $sessionData['database_user'] = $database['user'];
235
                    $sessionData['database_password'] = $database['password'];
236
                }
237
            }
238
        }
239
240
        $form->setData($sessionData);
241
242
        if ($this->isValid($request, $form)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
243
244
            return $app->redirect($app->path('install_step5'));
245
        }
246
247
        return $app['twig']->render('step4.twig', array(
248
                'form' => $form->createView(),
249
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
250
        ));
251
    }
252
253 1
    //    データベースの初期化
254
    public function step5(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
255 1
    {
256
        set_time_limit(0);
257
        $this->app = $app;
258
        $form = $app['form.factory']
259
            ->createBuilder('install_step5')
260
            ->getForm();
261
        $sessionData = $this->getSessionData($request);
262
        $form->setData($sessionData);
263
264
        if ($this->isValid($request, $form)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
265 1
266
            $this
267
                ->createDatabaseYamlFile($sessionData)
268
                ->createMailYamlFile($sessionData)
269
                ->createPathYamlFile($sessionData, $request);
270
271 1
            if (!$form['no_update']->getData()) {
272
                set_time_limit(0);
273
                $this->createConfigYamlFile($sessionData);
274
275
                $this
276
                    ->setPDO()
277
                    ->dropTables()
278
                    ->createTables()
279
                    ->doMigrate()
280
                    ->insert();
281 1
            } else {
282
                // データベースを初期化しない場合、auth_magicは初期化しない
283
                $this->createConfigYamlFile($sessionData, false);
284
285
                $this
286
                    ->setPDO()
287 1
                    ->update();
288
            }
289 1
290
291
            if (isset($sessionData['agree']) && $sessionData['agree'] == '1') {
292 1
                $host = $request->getSchemeAndHttpHost();
293
                $basePath = $request->getBasePath();
294
                $params = array(
295
                    'http_url' => $host . $basePath,
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
296
                    'shop_name' => $sessionData['shop_name'],
297
                );
298
299
                $this->sendAppData($params);
300
            }
301
            $this->addInstallStatus();
302
303
            $request->getSession()->remove(self::SESSION_KEY);
304
305
            return $app->redirect($app->path('install_complete'));
306
        }
307
308
        return $app['twig']->render('step5.twig', array(
309
                'form' => $form->createView(),
310
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
311
        ));
312
    }
313
314
    //    インストール完了
315
    public function complete(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
316
    {
317
        $config_yml = $this->config_path . '/config.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
318
        $config = Yaml::parse(file_get_contents($config_yml));
319
        $config_path = $this->config_path . '/path.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
320
        $path_yml = Yaml::parse(file_get_contents($config_path));
321
322
        $config = array_replace_recursive($path_yml, $config);
323
324
325
        if (isset($config['trusted_proxies_connection_only']) && !empty($config['trusted_proxies_connection_only'])) {
326
            Request::setTrustedProxies(array_merge(array($request->server->get('REMOTE_ADDR')), $config['trusted_proxies']));
327 View Code Duplication
        } elseif (isset($config['trusted_proxies']) && !empty($config['trusted_proxies'])) {
328
            Request::setTrustedProxies($config['trusted_proxies']);
329
        }
330
331
        $host = $request->getSchemeAndHttpHost();
332
        $basePath = $request->getBasePath();
333
334
        $adminUrl = $host . $basePath . '/' . $config['admin_dir'];
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
335
336
        return $app['twig']->render('complete.twig', array(
337
                'admin_url' => $adminUrl,
338
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
339
        ));
340
    }
341
342
    private function resetNatTimer()
343
    {
344
        // NATの無通信タイマ対策(仮)
345
        echo str_repeat(' ', 4 * 1024);
346
        ob_flush();
347
        flush();
348
    }
349
350
    private function checkModules($app)
351
    {
352
        foreach ($this->required_modules as $module) {
353
            if (!extension_loaded($module)) {
354
                $app->addDanger('[必須] ' . $module . ' 拡張モジュールが有効になっていません。', 'install');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
355
            }
356
        }
357
358
        if (!extension_loaded('pdo_mysql') && !extension_loaded('pdo_pgsql')) {
359
            $app->addDanger('[必須] ' . 'pdo_pgsql又はpdo_mysql 拡張モジュールを有効にしてください。', 'install');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
360
        }
361
362
        foreach ($this->recommended_module as $module) {
363
            if (!extension_loaded($module)) {
364
                if ($module == self::MCRYPT && PHP_VERSION_ID >= 70100) {
365
                    //The mcrypt extension has been deprecated in PHP 7.1.x 
366
                    //http://php.net/manual/en/migration71.deprecated.php
367
                    continue;
368
                }
369
                $app->addInfo('[推奨] '.$module.' 拡張モジュールが有効になっていません。', 'install');
370
            }
371
        }
372
373
        if ('\\' === DIRECTORY_SEPARATOR) { // for Windows
374
            if (!extension_loaded('wincache')) {
375
                $app->addInfo('[推奨] WinCache 拡張モジュールが有効になっていません。', 'install');
376
            }
377
        } else {
378
            if (!extension_loaded('apc')) {
379
                $app->addInfo('[推奨] APC 拡張モジュールが有効になっていません。', 'install');
380
            }
381
        }
382
383
        if (isset($_SERVER['SERVER_SOFTWARE']) && strpos('Apache', $_SERVER['SERVER_SOFTWARE']) !== false) {
384
            if (!function_exists('apache_get_modules')) {
385
                $app->addWarning('mod_rewrite が有効になっているか不明です。', 'install');
386
            } elseif (!in_array('mod_rewrite', apache_get_modules())) {
387
                $app->addDanger('[必須] ' . 'mod_rewriteを有効にしてください。', 'install');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
388
            }
389
        } elseif (isset($_SERVER['SERVER_SOFTWARE']) && strpos('Microsoft-IIS', $_SERVER['SERVER_SOFTWARE']) !== false) {
0 ignored issues
show
Unused Code introduced by
This elseif statement is empty, and could be removed.

This check looks for the bodies of elseif statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These elseif bodies can be removed. If you have an empty elseif but statements in the else branch, consider inverting the condition.

Loading history...
390
            // iis
391
        } elseif (isset($_SERVER['SERVER_SOFTWARE']) && strpos('nginx', $_SERVER['SERVER_SOFTWARE']) !== false) {
0 ignored issues
show
Unused Code introduced by
This elseif statement is empty, and could be removed.

This check looks for the bodies of elseif statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These elseif bodies can be removed. If you have an empty elseif but statements in the else branch, consider inverting the condition.

Loading history...
392
            // nginx
393
        }
394
    }
395
396
    private function setPDO()
397
    {
398
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
399
        $config = Yaml::parse(file_get_contents($config_file));
400
401
        try {
402
            $this->PDO = \Doctrine\DBAL\DriverManager::getConnection($config['database'], new \Doctrine\DBAL\Configuration());
403
            $this->PDO->connect();
404
        } catch (\Exception $e) {
405
            $this->PDO->close();
406
            throw $e;
407
        }
408
409
        return $this;
410
    }
411
412 View Code Duplication
    private function dropTables()
413
    {
414
        $this->resetNatTimer();
415
416
        $em = $this->getEntityManager();
417
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
418
        $schemaTool = new SchemaTool($em);
419
420
        $schemaTool->dropSchema($metadatas);
421
422
        $em->getConnection()->executeQuery('DROP TABLE IF EXISTS doctrine_migration_versions');
423
424
        return $this;
425
    }
426
427
    /**
428
     * @return EntityManager
429
     */
430
    private function getEntityManager()
431
    {
432
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
433
        $database = Yaml::parse(file_get_contents($config_file));
434
435
        $this->app->register(new \Silex\Provider\DoctrineServiceProvider(), array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
436
            'db.options' => $database['database']
437
        ));
438
439
        $this->app->register(new \Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
440
            'orm.proxies_dir' => __DIR__ . '/../../app/cache/doctrine',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
441
            'orm.em.options' => array(
442
                'mappings' => array(
443
                    array(
444
                        'type' => 'yml',
445
                        'namespace' => 'Eccube\Entity',
446
                        'path' => array(
447
                            __DIR__ . '/../../Resource/doctrine',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
448
                            __DIR__ . '/../../Resource/doctrine/master',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
449
                        ),
450
                    ),
451
                ),
452
            )
453
        ));
454
455
        return $em = $this->app['orm.em'];
0 ignored issues
show
Unused Code introduced by
$em is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
456
    }
457
458 View Code Duplication
    private function createTables()
459 1
    {
460
        $this->resetNatTimer();
461 1
462 1
        $em = $this->getEntityManager();
463
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
464
        $schemaTool = new SchemaTool($em);
465
466
        $schemaTool->createSchema($metadatas);
467
468
        return $this;
469
    }
470
471
    private function insert()
472 1
    {
473
        $this->resetNatTimer();
474
475
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
476
        $database = Yaml::parse(file_get_contents($config_file));
477
        $config['database'] = $database['database'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$config was never initialized. Although not strictly required by PHP, it is generally a good practice to add $config = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
478
479
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
480 1
        $baseConfig = Yaml::parse(file_get_contents($config_file));
481
        $config['config'] = $baseConfig;
482
483
        $this->PDO->beginTransaction();
484
485
        try {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
486
487
            $config = array(
488
                'auth_type' => '',
489
                'auth_magic' => $config['config']['auth_magic'],
490
                'password_hash_algos' => 'sha256',
491
            );
492
            $passwordEncoder = new \Eccube\Security\Core\Encoder\PasswordEncoder($config);
493
            $salt = \Eccube\Util\Str::random(32);
494
495
            $encodedPassword = $passwordEncoder->encodePassword($this->session_data['login_pass'], $salt);
496
            $sth = $this->PDO->prepare('INSERT INTO dtb_base_info (
497
                id,
498
                shop_name,
499
                email01,
500
                email02,
501
                email03,
502
                email04,
503
                update_date,
504
                option_product_tax_rule
505
            ) VALUES (
506
                1,
507
                :shop_name,
508
                :admin_mail,
509
                :admin_mail,
510
                :admin_mail,
511
                :admin_mail,
512
                current_timestamp,
513
                0);');
514
            $sth->execute(array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
515
                ':shop_name' => $this->session_data['shop_name'],
516
                ':admin_mail' => $this->session_data['email']
517
            ));
518
519
            $sth = $this->PDO->prepare("INSERT INTO dtb_member (member_id, login_id, password, salt, work, del_flg, authority, creator_id, rank, update_date, create_date,name,department) VALUES (2, :login_id, :admin_pass , :salt , '1', '0', '0', '1', '1', current_timestamp, current_timestamp,'管理者','EC-CUBE SHOP');");
520
            $sth->execute(array(':login_id' => $this->session_data['login_id'], ':admin_pass' => $encodedPassword, ':salt' => $salt));
521
522
            $this->PDO->commit();
523
        } catch (\Exception $e) {
524
            $this->PDO->rollback();
525
            throw $e;
526
        }
527
528
        return $this;
529
    }
530
531
    private function update()
532
    {
533
        $this->resetNatTimer();
534
535
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
536
        $database = Yaml::parse(file_get_contents($config_file));
537
        $config['database'] = $database['database'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$config was never initialized. Although not strictly required by PHP, it is generally a good practice to add $config = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
538
539
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
540
        $baseConfig = Yaml::parse(file_get_contents($config_file));
541
        $config['config'] = $baseConfig;
542
543
        $this->PDO->beginTransaction();
544
545
        try {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
546
547
            $config = array(
548
                'auth_type' => '',
549
                'auth_magic' => $config['config']['auth_magic'],
550
                'password_hash_algos' => 'sha256',
551
            );
552
            $passwordEncoder = new \Eccube\Security\Core\Encoder\PasswordEncoder($config);
553
            $salt = \Eccube\Util\Str::random(32);
554
555
            $stmt = $this->PDO->prepare("SELECT member_id FROM dtb_member WHERE login_id = :login_id;");
556
            $stmt->execute(array(':login_id' => $this->session_data['login_id']));
557
            $rs = $stmt->fetch();
558
559
            $encodedPassword = $passwordEncoder->encodePassword($this->session_data['login_pass'], $salt);
560
561
            if ($rs) {
562
                // 同一の管理者IDであればパスワードのみ更新
563
                $sth = $this->PDO->prepare("UPDATE dtb_member set password = :admin_pass, salt = :salt, update_date = current_timestamp WHERE login_id = :login_id;");
564
                $sth->execute(array(':admin_pass' => $encodedPassword, ':salt' => $salt, ':login_id' => $this->session_data['login_id']));
565
            } else {
566
                // 新しい管理者IDが入力されたらinsert
567
                $sth = $this->PDO->prepare("INSERT INTO dtb_member (login_id, password, salt, work, del_flg, authority, creator_id, rank, update_date, create_date,name,department) VALUES (:login_id, :admin_pass , :salt , '1', '0', '0', '1', '1', current_timestamp, current_timestamp,'管理者','EC-CUBE SHOP');");
568
                $sth->execute(array(':login_id' => $this->session_data['login_id'], ':admin_pass' => $encodedPassword, ':salt' => $salt));
569
            }
570
571
            $sth = $this->PDO->prepare('UPDATE dtb_base_info set
572
                shop_name = :shop_name,
573
                email01 = :admin_mail,
574
                email02 = :admin_mail,
575
                email03 = :admin_mail,
576
                email04 = :admin_mail,
577
                update_date = current_timestamp
578
            WHERE id = 1;');
579
            $sth->execute(array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
580
                ':shop_name' => $this->session_data['shop_name'],
581
                ':admin_mail' => $this->session_data['email']
582
            ));
583
584
            $this->PDO->commit();
585
        } catch (\Exception $e) {
586
            $this->PDO->rollback();
587
            throw $e;
588
        }
589
590
        return $this;
591
    }
592
593
    private function getMigration()
594
    {
595
        $app = \Eccube\Application::getInstance();
596
        $app->initialize();
597
        $app->boot();
598
599
        $config = new Configuration($app['db']);
600
        $config->setMigrationsNamespace('DoctrineMigrations');
601
602
        $migrationDir = __DIR__ . '/../../Resource/doctrine/migration';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
603
        $config->setMigrationsDirectory($migrationDir);
604
        $config->registerMigrationsFromDirectory($migrationDir);
605
606
        $migration = new Migration($config);
607
608
        return $migration;
609
    }
610
611
    private function doMigrate()
612
    {
613
        try {
614
            $migration = $this->getMigration();
615
616
            // DBとのコネクションを維持するためpingさせる
617
            if (is_null($this->PDO)) {
618
                $this->setPDO();
619
            }
620
            $this->PDO->ping();
621
622
            // nullを渡すと最新バージョンまでマイグレートする
623
            $migration->migrate(null, false);
624
        } catch (MigrationException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Coding Style introduced by
Blank line found at start of control structure
Loading history...
625
            
0 ignored issues
show
introduced by
Please trim any trailing whitespace
Loading history...
626
        }
627
628
        return $this;
629
    }
630
631
    private function getProtectedDirs()
632
    {
633
        $protectedDirs = array();
634
        $base = __DIR__ . '/../../../..';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
635
        $dirs = array(
636
            '/html',
637
            '/app',
638
            '/app/template',
639
            '/app/cache',
640
            '/app/config',
641
            '/app/config/eccube',
642
            '/app/log',
643
            '/app/Plugin',
644
        );
645
646
        foreach ($dirs as $dir) {
647
            if (!is_writable($base . $dir)) {
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
648
                $protectedDirs[] = $dir;
649
            }
650
        }
651
652
        return $protectedDirs;
653
    }
654
655
    private function createConfigYamlFile($data, $auth = true)
656
    {
657
        $fs = new Filesystem();
658
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
659
660
        if ($fs->exists($config_file)) {
661
            $config = Yaml::parse(file_get_contents($config_file));
662
            $fs->remove($config_file);
663
        }
664
665
        if ($auth) {
666
            $auth_magic = Str::random(32);
667
        } else {
668
            if (isset($config['auth_magic'])) {
669
                $auth_magic = $config['auth_magic'];
670
            } else {
671
                $auth_magic = Str::random(32);
672
            }
673
        }
674
675
        $allowHost = Str::convertLineFeed($data['admin_allow_hosts']);
676
        if (empty($allowHost)) {
677
            $adminAllowHosts = array();
678
        } else {
679
            $adminAllowHosts = explode("\n", $allowHost);
680
        }
681
        $trustedProxies = Str::convertLineFeed($data['trusted_proxies']);
682
        if (empty($trustedProxies)) {
683
            $adminTrustedProxies = array();
684
        } else {
685
            $adminTrustedProxies = explode("\n", $trustedProxies);
686
            // ループバックアドレスを含める
687
            $adminTrustedProxies = array_merge($adminTrustedProxies, array('127.0.0.1/8', '::1'));
688
        }
689
        if ($data['trusted_proxies_connection_only']) {
690
            // ループバックアドレスを含める
691
            $adminTrustedProxies = array('127.0.0.1/8', '::1');
692
        }
693
694
        $target = array('${AUTH_MAGIC}', '${SHOP_NAME}', '${ECCUBE_INSTALL}', '${FORCE_SSL}');
695
        $replace = array($auth_magic, $data['shop_name'], '0', $data['admin_force_ssl']);
696
697
        $fs = new Filesystem();
698
        $content = str_replace(
699
            $target, $replace, file_get_contents($this->dist_path . '/config.yml.dist')
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
700
        );
701
        $fs->dumpFile($config_file, $content);
702
703
        $config = Yaml::parse(file_get_contents($config_file));
704
        $config['admin_allow_host'] = $adminAllowHosts;
705
        $config['trusted_proxies_connection_only'] = $data['trusted_proxies_connection_only'];
706
        $config['trusted_proxies'] = $adminTrustedProxies;
707
        $yml = Yaml::dump($config);
708
        file_put_contents($config_file, $yml);
709
710
        return $this;
711
    }
712
713
    private function addInstallStatus()
714
    {
715
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
716
        $config = Yaml::parse(file_get_contents($config_file));
717
        $config['eccube_install'] = 1;
718
        $yml = Yaml::dump($config);
719
        file_put_contents($config_file, $yml);
720
721
        return $this;
722
    }
723
724
    private function createDatabaseYamlFile($data)
725
    {
726
        $fs = new Filesystem();
727
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
728
        if ($fs->exists($config_file)) {
729
            $fs->remove($config_file);
730
        }
731
732
        if ($data['database'] != 'pdo_sqlite') {
733
            switch ($data['database'])
734
            {
735
                case 'pdo_pgsql':
736
                    if (empty($data['db_port'])) {
737
                        $data['db_port'] = '5432';
738
                    }
739
                    $data['db_driver'] = 'pdo_pgsql';
740
                    break;
741
                case 'pdo_mysql':
742
                    if (empty($data['db_port'])) {
743
                        $data['db_port'] = '3306';
744
                    }
745
                    $data['db_driver'] = 'pdo_mysql';
746
                    break;
747
            }
748
            $target = array('${DBDRIVER}', '${DBSERVER}', '${DBNAME}', '${DBPORT}', '${DBUSER}', '${DBPASS}');
749
            $replace = array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
750
                $data['db_driver'],
751
                $data['database_host'],
752
                $data['database_name'],
753
                $data['database_port'],
754
                $data['database_user'],
755
                $data['database_password']
756
            );
757
758
            $fs = new Filesystem();
759
            $content = str_replace(
760
                $target, $replace, file_get_contents($this->dist_path . '/database.yml.dist')
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
761
            );
762
        } else {
763
            $content = Yaml::dump(
764
                    array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
765
                        'database' => array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
766
                            'driver' => 'pdo_sqlite',
767
                            'path' => realpath($this->config_path . '/eccube.db')
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
768
                        )
769
                    )
770
            );
771
        }
772
        $fs->dumpFile($config_file, $content);
773
774
        return $this;
775
    }
776
777
    private function createMailYamlFile($data)
778
    {
779
        $fs = new Filesystem();
780
        $config_file = $this->config_path . '/mail.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
781
        if ($fs->exists($config_file)) {
782
            $fs->remove($config_file);
783
        }
784
        $target = array('${MAIL_BACKEND}', '${MAIL_HOST}', '${MAIL_PORT}', '${MAIL_USER}', '${MAIL_PASS}');
785
        $replace = array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
786
            $data['mail_backend'],
787
            $data['smtp_host'],
788
            $data['smtp_port'],
789
            $data['smtp_username'],
790
            $data['smtp_password']
791
        );
792
793
        $fs = new Filesystem();
794
        $content = str_replace(
795
            $target, $replace, file_get_contents($this->dist_path . '/mail.yml.dist')
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
796
        );
797
        $fs->dumpFile($config_file, $content);
798
799
        return $this;
800
    }
801
802
    private function createPathYamlFile($data, Request $request)
803
    {
804
        $fs = new Filesystem();
805
        $config_file = $this->config_path . '/path.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
806
        if ($fs->exists($config_file)) {
807
            $fs->remove($config_file);
808
        }
809
810
        $ADMIN_ROUTE = $data['admin_dir'];
811
        $TEMPLATE_CODE = 'default';
812
        $USER_DATA_ROUTE = 'user_data';
813
        $ROOT_DIR = realpath(__DIR__ . '/../../../../');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
814
        $ROOT_URLPATH = $request->getBasePath();
815
        $ROOT_PUBLIC_URLPATH = $ROOT_URLPATH . RELATIVE_PUBLIC_DIR_PATH;
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
816
817
        $target = array('${ADMIN_ROUTE}', '${TEMPLATE_CODE}', '${USER_DATA_ROUTE}', '${ROOT_DIR}', '${ROOT_URLPATH}', '${ROOT_PUBLIC_URLPATH}');
818
        $replace = array($ADMIN_ROUTE, $TEMPLATE_CODE, $USER_DATA_ROUTE, $ROOT_DIR, $ROOT_URLPATH, $ROOT_PUBLIC_URLPATH);
819
820
        $fs = new Filesystem();
821
        $content = str_replace(
822
            $target, $replace, file_get_contents($this->dist_path . '/path.yml.dist')
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
823
        );
824
        $fs->dumpFile($config_file, $content);
825
826
        return $this;
827
    }
828
829
    private function sendAppData($params)
830
    {
831
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
832
        $db_config = Yaml::parse(file_get_contents($config_file));
833
834
        $this->setPDO();
835
        $stmt = $this->PDO->query('select version() as v');
836
837
        $version = '';
838
        foreach ($stmt as $row) {
839
            $version = $row['v'];
840
        }
841
842
        if ($db_config['database']['driver'] === 'pdo_mysql') {
843
            $db_ver = 'MySQL:' . $version;
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
844
        } else {
845
            $db_ver = $version;
846
        }
847
848
        $data = http_build_query(
849
            array(
850
                'site_url' => $params['http_url'],
851
                'shop_name' => $params['shop_name'],
852
                'cube_ver' => Constant::VERSION,
853
                'php_ver' => phpversion(),
854
                'db_ver' => $db_ver,
855
                'os_type' => php_uname(),
856
            )
857
        );
858
859
        $header = array(
860
            'Content-Type: application/x-www-form-urlencoded',
861
            'Content-Length: ' . strlen($data),
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
862
        );
863
        $context = stream_context_create(
864
            array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
865
                'http' => array(
866
                    'method' => 'POST',
867
                    'header' => $header,
868
                    'content' => $data,
869
                )
870
            )
871
        );
872
        file_get_contents('http://www.ec-cube.net/mall/use_site.php', false, $context);
873
874
        return $this;
875
    }
876
877
    /**
878
     * マイグレーション画面を表示する.
879
     *
880
     * @param InstallApplication $app
881
     * @param Request $request
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
882
     *
883
     * @return \Symfony\Component\HttpFoundation\Response
884
     */
885
    public function migration(InstallApplication $app, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
886
    {
887
        return $app['twig']->render('migration.twig', array(
888
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
889
        ));
890
    }
891
892
    /**
893
     * インストール済プラグインの一覧を表示する.
894
     * プラグインがインストールされていない場合は, マイグレーション実行画面へリダイレクトする.
895
     *
896
     * @param InstallApplication $app
897
     * @param Request $request
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
898
     *
899
     * @return \Symfony\Component\HttpFoundation\Response
900
     */
901
    public function migration_plugin(InstallApplication $app, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
Method name "InstallController::migration_plugin" is not in camel caps format
Loading history...
902
    {
903
        $eccube = \Eccube\Application::getInstance();
904
        $eccube->initialize();
905
        $eccube->boot();
906
907
        $pluginRepository = $eccube['orm.em']->getRepository('Eccube\Entity\Plugin');
908
        $Plugins = $pluginRepository->findBy(array('del_flg' => Constant::DISABLED));
909
910
        if (empty($Plugins)) {
911
            // インストール済プラグインがない場合はマイグレーション実行画面へリダイレクト.
912
            return $app->redirect($app->path('migration_end'));
913
        } else {
914
            return $app['twig']->render('migration_plugin.twig', array(
915
                    'Plugins' => $Plugins,
916
                    'version' => Constant::VERSION,
917
                    'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
918
            ));
919
        }
920
    }
921
922
    /**
923
     * マイグレーションを実行し, 完了画面を表示させる
924
     *
925
     * @param InstallApplication $app
926
     * @param Request $request
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
927
     *
928
     * @return \Symfony\Component\HttpFoundation\Response
929
     */
930
    public function migration_end(InstallApplication $app, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
Method name "InstallController::migration_end" is not in camel caps format
Loading history...
931
    {
932
        $this->doMigrate();
933
934
        $config_app = new \Eccube\Application(); // install用のappだとconfigが取れないので
935
        $config_app->initialize();
936
        $config_app->boot();
937
        \Eccube\Util\Cache::clear($config_app, true);
938
939
        return $app['twig']->render('migration_end.twig', array(
940
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
941
        ));
942
    }
943
}
944