Failed Conditions
Push — master ( df997f...0f3867 )
by Kentaro
16:49
created

InstallController::update()   A

Complexity

Conditions 3
Paths 19

Size

Total Lines 62
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 62
ccs 0
cts 0
cp 0
rs 9.4745
cc 3
eloc 35
nc 19
nop 0
crap 12

How to fix   Long Method   

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
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
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
    private $app;
44
45
    private $PDO;
46
47
    private $config_path;
48
49
    private $dist_path;
50
51
    private $cache_path;
52
53
    private $session_data;
54
55
    private $required_modules = array('pdo', 'phar', 'mbstring', 'zlib', 'ctype', 'session', 'JSON', 'xml', 'libxml', 'OpenSSL', 'zip', 'cURL', 'fileinfo');
56
57
    private $recommended_module = array('hash', 'mcrypt');
58
59
    const SESSION_KEY = 'eccube.session.install';
60
61 7
    public function __construct()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
62
    {
63 7
        $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...
64 7
        $this->dist_path = __DIR__ . '/../../Resource/config';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
65 7
        $this->cache_path = __DIR__ . '/../../../../app/cache';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
66 7
    }
67
68 4
    private function isValid(Request $request, Form $form)
69
    {
70
        $session = $request->getSession();
71
        if ('POST' === $request->getMethod()) {
72
            $form->handleRequest($request);
73
            if ($form->isValid()) {
74
                $sessionData = $session->get(self::SESSION_KEY) ?: array();
75
                $formData = array_replace_recursive($sessionData, $form->getData());
76
                $session->set(self::SESSION_KEY, $formData);
77
78
                return true;
79
            }
80
        }
81
82 4
        return false;
83 4
    }
84
85 5
    private function getSessionData(Request $request)
86
    {
87
        return $this->session_data = $request->getSession()->get(self::SESSION_KEY);
88 5
    }
89
90
    // 最初からやり直す場合、SESSION情報をクリア
91 1
    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...
92
    {
93
        $request->getSession()->remove(self::SESSION_KEY);
94
95
        return $app->redirect($app->url('install_step1'));
96 1
    }
97
98
    // ようこそ
99 1
    public function step1(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
100
    {
101
        $form = $app['form.factory']
102
            ->createBuilder('install_step1')
103
            ->getForm();
104
        $sessionData = $this->getSessionData($request);
105
        $form->setData($sessionData);
106
107
        if ($this->isValid($request, $form)) {
108
            return $app->redirect($app->url('install_step2'));
109
        }
110
111
        $this->checkModules($app);
112
113 1
        return $app['twig']->render('step1.twig', array(
114 1
            'form' => $form->createView(),
115
        ));
116 1
    }
117
118
    // 権限チェック
119 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...
120
    {
121
        $this->getSessionData($request);
122
123
        $protectedDirs = $this->getProtectedDirs();
124
125
        // 権限がある場合, キャッシュディレクトリをクリア
126 1
        if (empty($protectedDirs)) {
127 1
            $finder = Finder::create()
128 1
                ->in($this->cache_path)
129 1
                ->directories()
130
                ->depth(0);
131
            $fs = new Filesystem();
132
            $fs->remove($finder);
133
        }
134
135 1
        return $app['twig']->render('step2.twig', array(
136
            'protectedDirs' => $protectedDirs,
137
        ));
138 1
    }
139
140
    //    サイトの設定
141 1
    public function step3(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
142
    {
143
        $form = $app['form.factory']
144
            ->createBuilder('install_step3')
145
            ->getForm();
146
        $sessionData = $this->getSessionData($request);
147
148 1
        if (empty($sessionData['shop_name'])) {
149
150 1
            $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...
151
            $fs = new Filesystem();
152
153
            if ($fs->exists($config_file)) {
154
                // すでに登録されていた場合、登録データを表示
155
                $this->setPDO();
156
                $stmt = $this->PDO->query("SELECT shop_name, email01 FROM dtb_base_info WHERE id = 1;");
157
158
                foreach ($stmt as $row) {
159 1
                    $sessionData['shop_name'] = $row['shop_name'];
160 1
                    $sessionData['email'] = $row['email01'];
161
                }
162
163
                // セキュリティの設定
164 1
                $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...
165
                $config = Yaml::parse(file_get_contents($config_file));
166 1
                $sessionData['admin_dir'] = $config['admin_route'];
167
168 1
                $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...
169
                $config = Yaml::parse(file_get_contents($config_file));
170
171 1
                $allowHost = $config['admin_allow_host'];
172
                if (count($allowHost) > 0) {
173
                    $sessionData['admin_allow_hosts'] = Str::convertLineFeed(implode("\n", $allowHost));
174
                }
175 1
                $sessionData['admin_force_ssl'] = (bool)$config['force_ssl'];
0 ignored issues
show
Coding Style introduced by
As per coding-style, a cast statement should be followed by a single space.
Loading history...
176
177
                // メール設定
178 1
                $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...
179
                $config = Yaml::parse(file_get_contents($config_file));
180 1
                $mail = $config['mail'];
181 1
                $sessionData['mail_backend'] = $mail['transport'];
182 1
                $sessionData['smtp_host'] = $mail['host'];
183 1
                $sessionData['smtp_port'] = $mail['port'];
184 1
                $sessionData['smtp_username'] = $mail['username'];
185 1
                $sessionData['smtp_password'] = $mail['password'];
186
            } else {
187
                // 初期値にmailを設定
188
                $sessionData['mail_backend'] = 'mail';
189 1
            }
190
        }
191
192
        $form->setData($sessionData);
193
        if ($this->isValid($request, $form)) {
194
            $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...
195
196
            return $app->redirect($app->url('install_step4'));
197
        }
198
199 1
        return $app['twig']->render('step3.twig', array(
200 1
            'form' => $form->createView(),
201
        ));
202 1
    }
203
204
    //    データベースの設定
205 1
    public function step4(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
206
    {
207
        $form = $app['form.factory']
208
            ->createBuilder('install_step4')
209
            ->getForm();
210
211
        $sessionData = $this->getSessionData($request);
212
213 1
        if (empty($sessionData['database'])) {
214
215 1
            $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...
216
            $fs = new Filesystem();
217
218
            if ($fs->exists($config_file)) {
219
                // すでに登録されていた場合、登録データを表示
220
221
                // データベース設定
222
                $config = Yaml::parse(file_get_contents($config_file));
223 1
                $database = $config['database'];
224 1
                $sessionData['database'] = $database['driver'];
225 1
                $sessionData['database_host'] = $database['host'];
226 1
                $sessionData['database_port'] = $database['port'];
227 1
                $sessionData['database_name'] = $database['dbname'];
228 1
                $sessionData['database_user'] = $database['user'];
229 1
                $sessionData['database_password'] = $database['password'];
230
            }
231
        }
232
233
        $form->setData($sessionData);
234
235
        if ($this->isValid($request, $form)) {
236
237
            return $app->redirect($app->url('install_step5'));
238
        }
239
240 1
        return $app['twig']->render('step4.twig', array(
241 1
            'form' => $form->createView(),
242
        ));
243 1
    }
244
245
    //    データベースの初期化
246 1
    public function step5(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
247
    {
248
        set_time_limit(0);
249 1
        $this->app = $app;
250
        $form = $app['form.factory']
251
            ->createBuilder('install_step5')
252
            ->getForm();
253
        $sessionData = $this->getSessionData($request);
254
        $form->setData($sessionData);
255
256
        if ($this->isValid($request, $form)) {
257
            if (!$form['no_update']->getData()) {
258
                set_time_limit(0);
259
260
                $this
261
                    ->setPDO()
262
                    ->dropTables()
263
                    ->createTables()
264
                    ->doMigrate()
265
                    ->insert();
266
267
                $this->createConfigYamlFile($sessionData);
268
269
            } else {
270
                // データベースを初期化しない場合、auth_magicは初期化しない
271
                $this->createConfigYamlFile($sessionData, false);
272
273
                $this
274
                    ->setPDO()
275
                    ->update();
276
277
            }
278
279
            $this
280
                ->createDatabaseYamlFile($sessionData)
281
                ->createMailYamlFile($sessionData)
282
                ->createPathYamlFile($sessionData, $request);
283
284
            if (isset($sessionData['agree']) && $sessionData['agree'] == '1') {
285
                $host = $request->getSchemeAndHttpHost();
286
                $basePath = $request->getBasePath();
287
                $params = array(
288
                    'http_url' => $host . $basePath,
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
289
                    'shop_name' => $sessionData['shop_name'],
290
                );
291
292
                $this->sendAppData($params);
293
            }
294
            $this->addInstallStatus();
295
296
            $request->getSession()->remove(self::SESSION_KEY);
297
298
            return $app->redirect($app->url('install_complete'));
299
        }
300
301 1
        return $app['twig']->render('step5.twig', array(
302 1
            'form' => $form->createView(),
303
        ));
304 1
    }
305
306
    //    インストール完了
307 1
    public function complete(InstallApplication $app, Request $request)
0 ignored issues
show
introduced by
You must use "/**" style comments for a function comment
Loading history...
308
    {
309 1
        $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...
310
        $config = Yaml::parse(file_get_contents($config_file));
311
312
        $host = $request->getSchemeAndHttpHost();
313
        $basePath = $request->getBasePath();
314
315 1
        $adminUrl = $host . $basePath . '/' . $config['admin_dir'];
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
316
317 1
        return $app['twig']->render('complete.twig', array(
318
            'admin_url' => $adminUrl,
319
        ));
320 1
    }
321
322
    private function resetNatTimer()
323
    {
324
        // NATの無通信タイマ対策(仮)
325
        echo str_repeat(' ', 4 * 1024);
326
        ob_flush();
327
        flush();
328
    }
329
330
331 1
    private function checkModules($app)
0 ignored issues
show
Coding Style introduced by
checkModules uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
332
    {
333 1
        foreach ($this->required_modules as $module) {
334
            if (!extension_loaded($module)) {
335
                $app->addDanger('[必須] ' . $module . ' 拡張モジュールが有効になっていません。', 'install');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
336
            }
337
        }
338
339
        if (!extension_loaded('pdo_mysql') && !extension_loaded('pdo_pgsql')) {
340
            $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...
341
        }
342
343 1
        foreach ($this->recommended_module as $module) {
344
            if (!extension_loaded($module)) {
345
                $app->addWarning('[推奨] ' . $module . ' 拡張モジュールが有効になっていません。', 'install');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
346
            }
347
        }
348
349 1
        if ('\\' === DIRECTORY_SEPARATOR) { // for Windows
350
            if (!extension_loaded('wincache')) {
351
                $app->addWarning('[推奨] WinCache 拡張モジュールが有効になっていません。', 'install');
352
            }
353
        } else {
354
            if (!extension_loaded('apc')) {
355
                $app->addWarning('[推奨] APC 拡張モジュールが有効になっていません。', 'install');
356
            }
357
        }
358
359 1
        if (isset($_SERVER['SERVER_SOFTWARE']) && strpos('Apache', $_SERVER['SERVER_SOFTWARE']) !== false) {
360
            if (!function_exists('apache_get_modules')) {
361
                $app->addWarning('mod_rewrite が有効になっているか不明です。', 'install');
362
            } elseif (!in_array('mod_rewrite', apache_get_modules())) {
363
                $app->addDanger('[必須] ' . 'mod_rewriteを有効にしてください。', 'install');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
364
            }
365 1
        } 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...
366
            // iis
367 1
        } 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...
368
            // nginx
369
        }
370 1
    }
371
372 1
    private function setPDO()
373
    {
374 1
        $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...
375
        $config = Yaml::parse(file_get_contents($config_file));
376
377
        try {
378
            $this->PDO = \Doctrine\DBAL\DriverManager::getConnection($config['database'], new \Doctrine\DBAL\Configuration());
379
            $this->PDO->connect();
380
381
        } catch (\Exception $e) {
382
            $this->PDO->close();
383
            throw $e;
384 1
        }
385
386 1
        return $this;
387
    }
388
389 View Code Duplication
    private function dropTables()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
390
    {
391
        $this->resetNatTimer();
392
393
        $em = $this->getEntityManager();
394
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
395
        $schemaTool = new SchemaTool($em);
396
397
        $schemaTool->dropSchema($metadatas);
398
399
        $em->getConnection()->executeQuery('DROP TABLE IF EXISTS doctrine_migration_versions');
400
401
        return $this;
402
    }
403
404
    /**
405
     * @return EntityManager
406
     */
407
    private function getEntityManager()
408
    {
409
        $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...
410
        $database = Yaml::parse(file_get_contents($config_file));
411
412
        $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...
413
            'db.options' => $database['database']
414
        ));
415
416
        $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...
417
            '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...
418
            'orm.em.options' => array(
419
                'mappings' => array(
420
                    array(
421
                        'type' => 'yml',
422
                        'namespace' => 'Eccube\Entity',
423
                        'path' => array(
424
                            __DIR__ . '/../../Resource/doctrine',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
425
                            __DIR__ . '/../../Resource/doctrine/master',
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
426
                        ),
427
                    ),
428
429
                ),
430
            )
431
        ));
432
433
        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...
434
    }
435
436 View Code Duplication
    private function createTables()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
437
    {
438
        $this->resetNatTimer();
439
440
        $em = $this->getEntityManager();
441
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
442
        $schemaTool = new SchemaTool($em);
443
444
        $schemaTool->createSchema($metadatas);
445
446
        return $this;
447
    }
448
449
    private function insert()
450
    {
451
        $this->resetNatTimer();
452
453
        $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...
454
        $database = Yaml::parse(file_get_contents($config_file));
455
        $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...
456
457
        $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...
458
        $baseConfig = Yaml::parse(file_get_contents($config_file));
459
        $config['config'] = $baseConfig;
460
461
        $this->PDO->beginTransaction();
462
463
        try {
464
465
            $config = array(
466
                'auth_type' => '',
467
                'auth_magic' => $config['config']['auth_magic'],
468
                'password_hash_algos' => 'sha256',
469
            );
470
            $passwordEncoder = new \Eccube\Security\Core\Encoder\PasswordEncoder($config);
471
            $salt = \Eccube\Util\Str::random(32);
472
473
            $encodedPassword = $passwordEncoder->encodePassword($this->session_data['login_pass'], $salt);
474
            $sth = $this->PDO->prepare('INSERT INTO dtb_base_info (
475
                id,
476
                shop_name,
477
                email01,
478
                email02,
479
                email03,
480
                email04,
481
                update_date,
482
                option_product_tax_rule
483
            ) VALUES (
484
                1,
485
                :shop_name,
486
                :admin_mail,
487
                :admin_mail,
488
                :admin_mail,
489
                :admin_mail,
490
                current_timestamp,
491
                0);');
492
            $sth->execute(array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
493
                ':shop_name' => $this->session_data['shop_name'],
494
                ':admin_mail' => $this->session_data['email']
495
            ));
496
497
            $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');");
498
            $sth->execute(array(':login_id' => $this->session_data['login_id'], ':admin_pass' => $encodedPassword, ':salt' => $salt));
499
500
            $this->PDO->commit();
501
        } catch (\Exception $e) {
502
            $this->PDO->rollback();
503
            throw $e;
504
        }
505
506
        return $this;
507
    }
508
509
    private function update()
510
    {
511
        $this->resetNatTimer();
512
513
        $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...
514
        $database = Yaml::parse(file_get_contents($config_file));
515
        $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...
516
517
        $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...
518
        $baseConfig = Yaml::parse(file_get_contents($config_file));
519
        $config['config'] = $baseConfig;
520
521
        $this->PDO->beginTransaction();
522
523
        try {
524
525
            $config = array(
526
                'auth_type' => '',
527
                'auth_magic' => $config['config']['auth_magic'],
528
                'password_hash_algos' => 'sha256',
529
            );
530
            $passwordEncoder = new \Eccube\Security\Core\Encoder\PasswordEncoder($config);
531
            $salt = \Eccube\Util\Str::random(32);
532
533
            $stmt = $this->PDO->prepare("SELECT member_id FROM dtb_member WHERE login_id = :login_id;");
534
            $stmt->execute(array(':login_id' => $this->session_data['login_id']));
535
            $rs = $stmt->fetch();
536
537
            $encodedPassword = $passwordEncoder->encodePassword($this->session_data['login_pass'], $salt);
538
539
            if ($rs) {
540
                // 同一の管理者IDであればパスワードのみ更新
541
                $sth = $this->PDO->prepare("UPDATE dtb_member set password = :admin_pass, salt = :salt, update_date = current_timestamp WHERE login_id = :login_id;");
542
                $sth->execute(array(':admin_pass' => $encodedPassword, ':salt' => $salt, ':login_id' => $this->session_data['login_id']));
543
544
            } else {
545
                // 新しい管理者IDが入力されたらinsert
546
                $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');");
547
                $sth->execute(array(':login_id' => $this->session_data['login_id'], ':admin_pass' => $encodedPassword, ':salt' => $salt));
548
            }
549
550
            $sth = $this->PDO->prepare('UPDATE dtb_base_info set
551
                shop_name = :shop_name,
552
                email01 = :admin_mail,
553
                email02 = :admin_mail,
554
                email03 = :admin_mail,
555
                email04 = :admin_mail,
556
                update_date = current_timestamp
557
            WHERE id = 1;');
558
            $sth->execute(array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
559
                ':shop_name' => $this->session_data['shop_name'],
560
                ':admin_mail' => $this->session_data['email']
561
            ));
562
563
            $this->PDO->commit();
564
        } catch (\Exception $e) {
565
            $this->PDO->rollback();
566
            throw $e;
567
        }
568
569
        return $this;
570
    }
571
572
573
    private function getMigration()
574
    {
575
        $app = new \Eccube\Application();
576
        $app->initDoctrine();
577
        $config = new Configuration($app['db']);
578
        $config->setMigrationsNamespace('DoctrineMigrations');
579
580
        $migrationDir = __DIR__ . '/../../Resource/doctrine/migration';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
581
        $config->setMigrationsDirectory($migrationDir);
582
        $config->registerMigrationsFromDirectory($migrationDir);
583
584
        $migration = new Migration($config);
585
586
        return $migration;
587
    }
588
589
    private function doMigrate()
590
    {
591
        try {
592
            $migration = $this->getMigration();
593
594
            // DBとのコネクションを維持するためpingさせる
595
            $this->PDO->ping();
596
597
            // nullを渡すと最新バージョンまでマイグレートする
598
            $migration->migrate(null, false);
599
        } catch (MigrationException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
600
        }
601
602
        return $this;
603
    }
604
605 1
    private function getProtectedDirs()
606
    {
607 1
        $protectedDirs = array();
608 1
        $base = __DIR__ . '/../../../..';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
609
        $dirs = array(
610
            '/html',
611
            '/app',
612
            '/app/template',
613
            '/app/cache',
614
            '/app/config',
615
            '/app/config/eccube',
616
            '/app/log',
617
            '/app/Plugin',
618 1
        );
619
620
        foreach ($dirs as $dir) {
621
            if (!is_writable($base . $dir)) {
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
622
                $protectedDirs[] = $dir;
623
            }
624
        }
625
626 1
        return $protectedDirs;
627
    }
628
629
    private function createConfigYamlFile($data, $auth = true)
630
    {
631
        $fs = new Filesystem();
632
        $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...
633
634
        if ($fs->exists($config_file)) {
635
            $config = Yaml::parse(file_get_contents($config_file));
636
            $fs->remove($config_file);
637
        }
638
639
        if ($auth) {
640
            $auth_magic = Str::random(32);
641
        } else {
642
            if (isset($config['auth_magic'])) {
643
                $auth_magic = $config['auth_magic'];
644
            } else {
645
                $auth_magic = Str::random(32);
646
            }
647
        }
648
649
        $allowHost = Str::convertLineFeed($data['admin_allow_hosts']);
650
        if (empty($allowHost)) {
651
            $adminAllowHosts = array();
652
        } else {
653
            $adminAllowHosts = explode("\n", $allowHost);
654
        }
655
656
        $target = array('${AUTH_MAGIC}', '${SHOP_NAME}', '${ECCUBE_INSTALL}', '${FORCE_SSL}');
657
        $replace = array($auth_magic, $data['shop_name'], '0', $data['admin_force_ssl']);
658
659
        $fs = new Filesystem();
660
        $content = str_replace(
661
            $target,
662
            $replace,
663
            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...
664
        );
665
        $fs->dumpFile($config_file, $content);
666
667
        $config = Yaml::Parse($config_file);
668
        $config['admin_allow_host'] = $adminAllowHosts;
669
        $yml = Yaml::dump($config);
0 ignored issues
show
Bug introduced by
It seems like $config defined by \Symfony\Component\Yaml\Yaml::Parse($config_file) on line 667 can also be of type string; however, Symfony\Component\Yaml\Yaml::dump() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
670
        file_put_contents($config_file, $yml);
671
672
        return $this;
673
    }
674
675
    private function addInstallStatus()
676
    {
677
        $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...
678
        $config = Yaml::parse(file_get_contents($config_file));
679
        $config['eccube_install'] = 1;
680
        $yml = Yaml::dump($config);
0 ignored issues
show
Bug introduced by
It seems like $config defined by \Symfony\Component\Yaml\...contents($config_file)) on line 678 can also be of type string; however, Symfony\Component\Yaml\Yaml::dump() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
681
        file_put_contents($config_file, $yml);
682
683
        return $this;
684
    }
685
686
    private function createDatabaseYamlFile($data)
687
    {
688
        $fs = new Filesystem();
689
        $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...
690
        if ($fs->exists($config_file)) {
691
            $fs->remove($config_file);
692
        }
693
694
        switch ($data['database']) {
695
            case 'pdo_pgsql':
696
                if (empty($data['db_port'])) {
697
                    $data['db_port'] = '5432';
698
                }
699
                $data['db_driver'] = 'pdo_pgsql';
700
                break;
701
            case 'pdo_mysql':
702
                if (empty($data['db_port'])) {
703
                    $data['db_port'] = '3306';
704
                }
705
                $data['db_driver'] = 'pdo_mysql';
706
                break;
707
        }
708
        $target = array('${DBDRIVER}', '${DBSERVER}', '${DBNAME}', '${DBPORT}', '${DBUSER}', '${DBPASS}');
709
        $replace = array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
710
            $data['db_driver'],
711
            $data['database_host'],
712
            $data['database_name'],
713
            $data['database_port'],
714
            $data['database_user'],
715
            $data['database_password']
716
        );
717
718
        $fs = new Filesystem();
719
        $content = str_replace(
720
            $target,
721
            $replace,
722
            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...
723
        );
724
725
        $fs->dumpFile($config_file, $content);
726
727
        return $this;
728
    }
729
730
    private function createMailYamlFile($data)
731
    {
732
        $fs = new Filesystem();
733
        $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...
734
        if ($fs->exists($config_file)) {
735
            $fs->remove($config_file);
736
        }
737
        $target = array('${MAIL_BACKEND}', '${MAIL_HOST}', '${MAIL_PORT}', '${MAIL_USER}', '${MAIL_PASS}');
738
        $replace = array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
739
            $data['mail_backend'],
740
            $data['smtp_host'],
741
            $data['smtp_port'],
742
            $data['smtp_username'],
743
            $data['smtp_password']
744
        );
745
746
        $fs = new Filesystem();
747
        $content = str_replace(
748
            $target,
749
            $replace,
750
            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...
751
        );
752
        $fs->dumpFile($config_file, $content);
753
754
        return $this;
755
    }
756
757
    private function createPathYamlFile($data, Request $request)
758
    {
759
        $fs = new Filesystem();
760
        $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...
761
        if ($fs->exists($config_file)) {
762
            $fs->remove($config_file);
763
        }
764
765
        $ADMIN_ROUTE = $data['admin_dir'];
766
        $TEMPLATE_CODE = 'default';
767
        $USER_DATA_ROUTE = 'user_data';
768
        $ROOT_DIR = realpath(__DIR__ . '/../../../../');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
769
        $ROOT_URLPATH = $request->getBasePath();
770
771
        $target = array('${ADMIN_ROUTE}', '${TEMPLATE_CODE}', '${USER_DATA_ROUTE}', '${ROOT_DIR}', '${ROOT_URLPATH}');
772
        $replace = array($ADMIN_ROUTE, $TEMPLATE_CODE, $USER_DATA_ROUTE, $ROOT_DIR, $ROOT_URLPATH);
773
774
        $fs = new Filesystem();
775
        $content = str_replace(
776
            $target,
777
            $replace,
778
            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...
779
        );
780
        $fs->dumpFile($config_file, $content);
781
782
        return $this;
783
    }
784
785
    private function sendAppData($params)
786
    {
787
        $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...
788
        $db_config = Yaml::parse(file_get_contents($config_file));
789
790
        $this->setPDO();
791
        $stmt = $this->PDO->query('select version() as v');
792
793
        $version = '';
794
        foreach ($stmt as $row) {
795
            $version = $row['v'];
796
        }
797
798
        if ($db_config['database']['driver'] === 'pdo_mysql') {
799
            $db_ver = 'MySQL:' . $version;
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
800
        } else {
801
            $db_ver = $version;
802
        }
803
804
        $data = http_build_query(
805
            array(
806
                'site_url' => $params['http_url'],
807
                'shop_name' => $params['shop_name'],
808
                'cube_ver' => Constant::VERSION,
809
                'php_ver' => phpversion(),
810
                'db_ver' => $db_ver,
811
                'os_type' => php_uname(),
812
            )
813
        );
814
815
        $header = array(
816
            'Content-Type: application/x-www-form-urlencoded',
817
            'Content-Length: ' . strlen($data),
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
818
        );
819
        $context = stream_context_create(
820
            array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
821
                'http' => array(
822
                    'method' => 'POST',
823
                    'header' => $header,
824
                    'content' => $data,
825
                )
826
            )
827
        );
828
        file_get_contents('http://www.ec-cube.net/mall/use_site.php', false, $context);
829
830
        return $this;
831
    }
832
833
834
    /**
835
     * マイグレーション画面を表示する.
836
     *
837
     * @param InstallApplication $app
838
     * @param Request $request
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
839
     *
840
     * @return \Symfony\Component\HttpFoundation\Response
841
     */
842
    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...
843
    {
844
        return $app['twig']->render('migration.twig');
845
    }
846
847
    /**
848
     * インストール済プラグインの一覧を表示する.
849
     * プラグインがインストールされていない場合は, マイグレーション実行画面へリダイレクトする.
850
     *
851
     * @param InstallApplication $app
852
     * @param Request $request
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
853
     *
854
     * @return \Symfony\Component\HttpFoundation\Response
855
     */
856
    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...
857
    {
858
        $eccube = new \Eccube\Application();
859
        $eccube->initDoctrine();
860
861
        $pluginRepository = $eccube['orm.em']->getRepository('Eccube\Entity\Plugin');
862
        $Plugins = $pluginRepository->findBy(array('del_flg' => Constant::DISABLED));
863
864
        if (empty($Plugins)) {
865
            // インストール済プラグインがない場合はマイグレーション実行画面へリダイレクト.
866
            return $app->redirect($app->url('migration_end'));
867
        } else {
868
            return $app['twig']->render('migration_plugin.twig', array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
869
                'Plugins' => $Plugins,
870
                'version' => Constant::VERSION));
871
        }
872
    }
873
874
    /**
875
     * マイグレーションを実行し, 完了画面を表示させる
876
     *
877
     * @param InstallApplication $app
878
     * @param Request $request
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
879
     *
880
     * @return \Symfony\Component\HttpFoundation\Response
881
     */
882
    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...
883
    {
884
        $this->doMigrate();
885
886
        $config_app = new \Eccube\Application(); // install用のappだとconfigが取れないので
887
        $config_app->initialize();
888
        $config_app->boot();
889
        \Eccube\Util\Cache::clear($config_app, true);
0 ignored issues
show
Documentation introduced by
$config_app is of type object<Eccube\Application>, but the function expects a object<Eccube\Util\Application>.

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...
890
891
        return $app['twig']->render('migration_end.twig');
892
    }
893
}
894