Failed Conditions
Push — experimental/3.1 ( 76ccda...aa3e4c )
by Kiyotaka
20s
created

Eccube/Controller/Install/InstallController.php (37 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Form\Type\Install\Step1Type;
34
use Eccube\Form\Type\Install\Step3Type;
35
use Eccube\Form\Type\Install\Step4Type;
36
use Eccube\Form\Type\Install\Step5Type;
37
use Eccube\InstallApplication;
38
use Eccube\Plugin\ConfigManager as PluginConfigManager;
39
use Eccube\Util\Str;
40
use Symfony\Component\Filesystem\Filesystem;
41
use Symfony\Component\Finder\Finder;
42
use Symfony\Component\Form\Form;
43
use Symfony\Component\HttpFoundation\Request;
44
use Symfony\Component\Yaml\Yaml;
45
46
class InstallController
47
{
48
49
    const MCRYPT = 'mcrypt';
50
51
    private $app;
52
    private $PDO;
53
    private $config_path;
54
    private $dist_path;
55
    private $cache_path;
56
    private $session_data;
57
    private $required_modules = array('pdo', 'phar', 'mbstring', 'zlib', 'ctype', 'session', 'JSON', 'xml', 'libxml', 'OpenSSL', 'zip', 'cURL', 'fileinfo');
58
    private $recommended_module = array('hash', self::MCRYPT);
59
60
    const SESSION_KEY = 'eccube.session.install';
61
62 7
    public function __construct()
63
    {
64 7
        $this->config_path = __DIR__ . '/../../../../app/config/eccube';
65 7
        $this->dist_path = __DIR__ . '/../../Resource/config';
66 7
        $this->cache_path = __DIR__ . '/../../../../app/cache';
67
    }
68
69 4
    private function isValid(Request $request, Form $form)
70
    {
71 4
        $session = $request->getSession();
72 4
        if ('POST' === $request->getMethod()) {
73
            $form->handleRequest($request);
74
            if ($form->isValid()) {
75
                $sessionData = $session->get(self::SESSION_KEY) ?: array();
76
                $formData = array_replace_recursive($sessionData, $form->getData());
77
                $session->set(self::SESSION_KEY, $formData);
78
79
                return true;
80
            }
81
        }
82
83 4
        return false;
84
    }
85
86 5
    private function getSessionData(Request $request)
87
    {
88 5
        return $this->session_data = $request->getSession()->get(self::SESSION_KEY);
89
    }
90
91
    // 最初からやり直す場合、SESSION情報をクリア
92 1
    public function index(InstallApplication $app, Request $request)
93
    {
94 1
        $request->getSession()->remove(self::SESSION_KEY);
95
96 1
        return $app->redirect($app->path('install_step1'));
97
    }
98
99
    // ようこそ
100 1
    public function step1(InstallApplication $app, Request $request)
101
    {
102 1
        $form = $app['form.factory']
103 1
            ->createBuilder(Step1Type::class)
104 1
            ->getForm();
105 1
        $sessionData = $this->getSessionData($request);
106 1
        $form->setData($sessionData);
107
108 1
        if ($this->isValid($request, $form)) {
109
            return $app->redirect($app->path('install_step2'));
110
        }
111
112 1
        $this->checkModules($app);
113
114 1
        return $app['twig']->render('step1.twig', array(
115 1
                'form' => $form->createView(),
116 1
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
117
        ));
118
    }
119
120
    // 権限チェック
121 1
    public function step2(InstallApplication $app, Request $request)
122
    {
123 1
        $this->getSessionData($request);
124
125 1
        $protectedDirs = $this->getProtectedDirs();
126
127
        // 権限がある場合, キャッシュディレクトリをクリア
128 1
        if (empty($protectedDirs)) {
129 1
            $finder = Finder::create()
130 1
                ->in($this->cache_path)
131 1
                ->notName('.gitkeep')
132 1
                ->files();
133 1
            $fs = new Filesystem();
134 1
            $fs->remove($finder);
135
        }
136
137 1
        return $app['twig']->render('step2.twig', array(
138 1
                'protectedDirs' => $protectedDirs,
139 1
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
140
        ));
141
    }
142
143
    //    サイトの設定
144 1
    public function step3(InstallApplication $app, Request $request)
145
    {
146 1
        $form = $app['form.factory']
147 1
            ->createBuilder(Step3Type::class)
148 1
            ->getForm();
149 1
        $sessionData = $this->getSessionData($request);
150
151 1
        if (empty($sessionData['shop_name'])) {
152
153 1
            $config_file = $this->config_path . '/config.yml';
154 1
            $fs = new Filesystem();
155
156 1
            if ($fs->exists($config_file)) {
157
                // すでに登録されていた場合、登録データを表示
158 1
                $this->setPDO();
159 1
                $stmt = $this->PDO->query("SELECT shop_name, email01 FROM dtb_base_info WHERE id = 1;");
160
161 1
                foreach ($stmt as $row) {
162 1
                    $sessionData['shop_name'] = $row['shop_name'];
163 1
                    $sessionData['email'] = $row['email01'];
164
                }
165
166
                // セキュリティの設定
167 1
                $config_file = $this->config_path . '/path.yml';
168 1
                $config = Yaml::parse(file_get_contents($config_file));
169 1
                $sessionData['admin_dir'] = $config['admin_route'];
170
171 1
                $config_file = $this->config_path . '/config.yml';
172 1
                $config = Yaml::parse(file_get_contents($config_file));
173
174 1
                $allowHost = $config['admin_allow_host'];
175 1 View Code Duplication
                if (count($allowHost) > 0) {
176
                    $sessionData['admin_allow_hosts'] = Str::convertLineFeed(implode("\n", $allowHost));
177
                }
178 1
                $sessionData['admin_force_ssl'] = (bool) $config['force_ssl'];
179
180
                // ロードバランサー、プロキシサーバ設定
181 1
                if (isset($config['trusted_proxies_connection_only'])) {
182 1
                    $sessionData['trusted_proxies_connection_only'] = (bool)$config['trusted_proxies_connection_only'];
183 1
                }
184 1
                if (isset($config['trusted_proxies'])) {
185 1
                    $trustedProxies = $config['trusted_proxies'];
186 1 View Code Duplication
                    if (count($trustedProxies) > 0) {
187 1
                        $sessionData['trusted_proxies'] = Str::convertLineFeed(implode("\n", $trustedProxies));
188 1
                    }
189
                }
190
                // メール設定
191
                $config_file = $this->config_path . '/mail.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
192
                $config = Yaml::parse(file_get_contents($config_file));
193
                $mail = $config['mail'];
194
                $sessionData['mail_backend'] = $mail['transport'];
195 1
                $sessionData['smtp_host'] = $mail['host'];
196 1
                $sessionData['smtp_port'] = $mail['port'];
197
                $sessionData['smtp_username'] = $mail['username'];
198
                $sessionData['smtp_password'] = $mail['password'];
199
            } else {
200
                // 初期値にmailを設定
201
                $sessionData['mail_backend'] = 'mail';
202 1
            }
203 1
        }
204 1
205
        $form->setData($sessionData);
206
        if ($this->isValid($request, $form)) {
207
            $data = $form->getData();
208
209 1
            return $app->redirect($app->path('install_step4'));
210
        }
211 1
212 1
        return $app['twig']->render('step3.twig', array(
213 1
                'form' => $form->createView(),
214
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
215 1
        ));
216
    }
217 1
218
    //    データベースの設定
219 1
    public function step4(InstallApplication $app, Request $request)
220 1
    {
221
        $form = $app['form.factory']
222 1
            ->createBuilder(Step4Type::class)
223
            ->getForm();
224
225 1
        $sessionData = $this->getSessionData($request);
226 1
227 1
        if (empty($sessionData['database'])) {
228 1
229 1
            $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
230 1
            $fs = new Filesystem();
231 1
232 1
            if ($fs->exists($config_file)) {
233 1
                // すでに登録されていた場合、登録データを表示
234
                // データベース設定
235
                $config = Yaml::parse(file_get_contents($config_file));
236
                $database = $config['database'];
237
                $sessionData['database'] = $database['driver'];
238 1
                if ($database['driver'] != 'pdo_sqlite') {
239
                    $sessionData['database_host'] = $database['host'];
240 1
                    $sessionData['database_port'] = $database['port'];
241
                    $sessionData['database_name'] = $database['dbname'];
242
                    $sessionData['database_user'] = $database['user'];
243
                    $sessionData['database_password'] = $database['password'];
244
                }
245 1
            }
246 1
        }
247 1
248
        $form->setData($sessionData);
249
250
        if ($this->isValid($request, $form)) {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
251
252 1
            return $app->redirect($app->path('install_step5'));
253
        }
254 1
255 1
        return $app['twig']->render('step4.twig', array(
256 1
                'form' => $form->createView(),
257 1
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
258 1
        ));
259 1
    }
260 1
261
    //    データベースの初期化
262 1
    public function step5(InstallApplication $app, Request $request)
263
    {
264
        set_time_limit(0);
265
        $this->app = $app;
266
        $form = $app['form.factory']
267
            ->createBuilder(Step5Type::class)
268
            ->getForm();
269
        $sessionData = $this->getSessionData($request);
270
        $form->setData($sessionData);
271
272
        if ($this->isValid($request, $form)) {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
273
274
            $this
275
                ->createDatabaseYamlFile($sessionData)
276
                ->createMailYamlFile($sessionData)
277
                ->createPathYamlFile($sessionData, $request);
278
279
            if (!$form['no_update']->getData()) {
280
                set_time_limit(0);
281
                $this->createConfigYamlFile($sessionData);
282
283
                $this
284
                    ->setPDO()
285
                    ->dropTables()
286
                    ->createTables()
287
                    ->importCsv()
288
                    ->doMigrate()
289
                    ->insert();
290
            } else {
291
                // データベースを初期化しない場合、auth_magicは初期化しない
292
                $this->createConfigYamlFile($sessionData, false);
293
294
                $this
295
                    ->setPDO()
296
                    ->update();
297
            }
298
299
300
            if (isset($sessionData['agree']) && $sessionData['agree'] == '1') {
301
                $host = $request->getSchemeAndHttpHost();
302
                $basePath = $request->getBasePath();
303
                $params = array(
304
                    'http_url' => $host . $basePath,
305
                    'shop_name' => $sessionData['shop_name'],
306 1
                );
307 1
308 1
                $this->sendAppData($params);
309
            }
310
            $this->addInstallStatus();
311
312
            $request->getSession()->remove(self::SESSION_KEY);
313 1
314
            return $app->redirect($app->path('install_complete'));
315 1
        }
316 1
317
        return $app['twig']->render('step5.twig', array(
318 1
                'form' => $form->createView(),
319 1
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
320
        ));
321 1
    }
322
323 1
    //    インストール完了
324 1
    public function complete(InstallApplication $app, Request $request)
325 1
    {
326
        $config_yml = $this->config_path . '/config.yml';
327
        $config = Yaml::parse(file_get_contents($config_yml));
328
        $config_path = $this->config_path . '/path.yml';
329
        $path_yml = Yaml::parse(file_get_contents($config_path));
330
331
        $config = array_replace_recursive($path_yml, $config);
332
333
334
        if (isset($config['trusted_proxies_connection_only']) && !empty($config['trusted_proxies_connection_only'])) {
335
            Request::setTrustedProxies(array_merge(array($request->server->get('REMOTE_ADDR')), $config['trusted_proxies']));
336 View Code Duplication
        } elseif (isset($config['trusted_proxies']) && !empty($config['trusted_proxies'])) {
337 1
            Request::setTrustedProxies($config['trusted_proxies']);
338
        }
339 1
340 1
        $host = $request->getSchemeAndHttpHost();
341 1
        $basePath = $request->getBasePath();
342
343
        $adminUrl = $host . $basePath . '/' . $config['admin_dir'];
344
345 1
        return $app['twig']->render('complete.twig', array(
346
                'admin_url' => $adminUrl,
347
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
348
        ));
349 1
    }
350 1
351
    private function resetNatTimer()
352
    {
353
        // NATの無通信タイマ対策(仮)
354
        echo str_repeat(' ', 4 * 1024);
355
        ob_flush();
356 1
        flush();
357
    }
358
359
    private function checkModules($app)
360 1
    {
361
        foreach ($this->required_modules as $module) {
362
            if (!extension_loaded($module)) {
363
                $app->addDanger('[必須] ' . $module . ' 拡張モジュールが有効になっていません。', 'install');
364
            }
365 1
        }
366 1
367
        if (!extension_loaded('pdo_mysql') && !extension_loaded('pdo_pgsql')) {
368
            $app->addDanger('[必須] ' . 'pdo_pgsql又はpdo_mysql 拡張モジュールを有効にしてください。', 'install');
369
        }
370 1
371
        foreach ($this->recommended_module as $module) {
372
            if (!extension_loaded($module)) {
373
                if ($module == self::MCRYPT && PHP_VERSION_ID >= 70100) {
374
                    //The mcrypt extension has been deprecated in PHP 7.1.x 
375
                    //http://php.net/manual/en/migration71.deprecated.php
376 1
                    continue;
377
                }
378 1
                $app->addInfo('[推奨] '.$module.' 拡張モジュールが有効になっていません。', 'install');
379
            }
380
        }
381
382
        if ('\\' === DIRECTORY_SEPARATOR) { // for Windows
383 1
            if (!extension_loaded('wincache')) {
384
                $app->addInfo('[推奨] WinCache 拡張モジュールが有効になっていません。', 'install');
385 1
            }
386 1
        } else {
387
            if (!extension_loaded('apc')) {
388
                $app->addInfo('[推奨] APC 拡張モジュールが有効になっていません。', 'install');
389 1
            }
390 1
        }
391
392
        if (isset($_SERVER['SERVER_SOFTWARE']) && strpos('Apache', $_SERVER['SERVER_SOFTWARE']) !== false) {
393
            if (!function_exists('apache_get_modules')) {
394
                $app->addWarning('mod_rewrite が有効になっているか不明です。', 'install');
395
            } elseif (!in_array('mod_rewrite', apache_get_modules())) {
396 1
                $app->addDanger('[必須] ' . 'mod_rewriteを有効にしてください。', 'install');
397
            }
398
        } elseif (isset($_SERVER['SERVER_SOFTWARE']) && strpos('Microsoft-IIS', $_SERVER['SERVER_SOFTWARE']) !== false) {
399
            // iis
400
        } elseif (isset($_SERVER['SERVER_SOFTWARE']) && strpos('nginx', $_SERVER['SERVER_SOFTWARE']) !== false) {
401
            // nginx
402
        }
403
    }
404
405
    private function setPDO()
406
    {
407
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
408
        $config = Yaml::parse(file_get_contents($config_file));
409
410
        try {
411
            $this->PDO = \Doctrine\DBAL\DriverManager::getConnection($config['database'], new \Doctrine\DBAL\Configuration());
412
            $this->PDO->connect();
413
        } catch (\Exception $e) {
414
            $this->PDO->close();
415
            throw $e;
416
        }
417
418
        return $this;
419
    }
420
421 View Code Duplication
    private function dropTables()
422
    {
423
        $this->resetNatTimer();
424
425
        $em = $this->getEntityManager();
426
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
427
        $schemaTool = new SchemaTool($em);
428
429
        $schemaTool->dropSchema($metadatas);
430
431
        $em->getConnection()->executeQuery('DROP TABLE IF EXISTS doctrine_migration_versions');
432
433
        return $this;
434
    }
435
436
    /**
437
     * @return EntityManager
438
     */
439
    private function getEntityManager()
440
    {
441
        if (!isset($this->app['orm.em'])) {
442
            $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
443
            $database = Yaml::parse(file_get_contents($config_file));
444
445
            $this->app->register(new \Silex\Provider\DoctrineServiceProvider(), array(
446
                'db.options' => $database['database']
447
            ));
448
449
            $ormMappings = array(
450
                array(
451
                    'type' => 'yml',
452
                    'namespace' => 'Eccube\Entity',
453
                    'path' => array(
454
                        __DIR__ . '/../../Resource/doctrine',
455
                        __DIR__ . '/../../Resource/doctrine/master',
456
                    ),
457
                ),
458
                array(  // TODO 暫定
459
                    'type' => 'annotation',
460
                    'namespace' => 'Acme\Entity',
461
                    'path' => array(
462
                        __DIR__.'/../../../../app/Acme/Entity',
463
                    ),
464
                    'use_simple_annotation_reader' => false,
465
                )
466
            );
467
468
            // XXX 同梱したプラグインがエラーになるため暫定
469
            $pluginConfigs = PluginConfigManager::getPluginConfigAll();
470
            foreach ($pluginConfigs as $code) {
471
                $config = $code['config'];
472
                // Doctrine Extend
473
                if (isset($config['orm.path']) && is_array($config['orm.path'])) {
474
                    $paths = array();
475 View Code Duplication
                    foreach ($config['orm.path'] as $path) {
476
                        $paths[] = __DIR__.'/../../../../app/Plugin/'.$config['code'].$path;
477
                    }
478
                    $ormMappings[] = array(
479
                        'type' => 'annotation',
480
                        'namespace' => 'Plugin\\'.$config['code'].'\\Entity',
481
                        'path' => $paths,
482
                        'use_simple_annotation_reader' => false,
483
                    );
484
                }
485
            }
486
            $this->app->register(new \Dflydev\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(
487
                'orm.proxies_dir' => __DIR__ . '/../../app/cache/doctrine',
488
                'orm.em.options' => array(
489
                    'mappings' => $ormMappings
490
                )
491
            ));
492
0 ignored issues
show
Blank line found at end of control structure
Loading history...
493
        }
494
495
        return $em = $this->app['orm.em'];
496
    }
497
498 View Code Duplication
    private function createTables()
499
    {
500
        $this->resetNatTimer();
501
502
        $em = $this->getEntityManager();
503
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
504
        $schemaTool = new SchemaTool($em);
505
506
        $schemaTool->createSchema($metadatas);
507
508
        return $this;
509
    }
510
511
    private function importCsv() {
512
513
        $em = $this->getEntityManager();
514
        $loader = new \Eccube\Doctrine\Common\CsvDataFixtures\Loader();
515
        $loader->loadFromDirectory(__DIR__.'/../../Resource/doctrine/import_csv');
516
        $Executor = new \Eccube\Doctrine\Common\CsvDataFixtures\Executor\DbalExecutor($em);
517
        $fixtures = $loader->getFixtures();
518
        $Executor->execute($fixtures);
519
520
        return $this;
521
    }
522
523
    private function insert()
524
    {
525
        $this->resetNatTimer();
526
527
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
528
        $database = Yaml::parse(file_get_contents($config_file));
529
        $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...
530
531
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
532
        $baseConfig = Yaml::parse(file_get_contents($config_file));
533
        $config['config'] = $baseConfig;
534
535
        $this->PDO->beginTransaction();
536
537
        try {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
538
539
            $config = array(
540
                'auth_type' => '',
541
                'auth_magic' => $config['config']['auth_magic'],
542
                'password_hash_algos' => 'sha256',
543
            );
544
            $passwordEncoder = new \Eccube\Security\Core\Encoder\PasswordEncoder($config);
545
            $salt = \Eccube\Util\Str::random(32);
546
547
            $encodedPassword = $passwordEncoder->encodePassword($this->session_data['login_pass'], $salt);
548
            $sth = $this->PDO->prepare("INSERT INTO dtb_base_info (
549
                id,
550
                shop_name,
551
                email01,
552
                email02,
553
                email03,
554
                email04,
555
                update_date,
556
                option_product_tax_rule,
557
                discriminator_type
558
            ) VALUES (
559
                1,
560
                :shop_name,
561
                :admin_mail,
562
                :admin_mail,
563
                :admin_mail,
564
                :admin_mail,
565
                current_timestamp,
566
                0,
567
                'baseinfo');");
568
            $sth->execute(array(
0 ignored issues
show
Add a comma after each item in a multi-line array
Loading history...
569
                ':shop_name' => $this->session_data['shop_name'],
570
                ':admin_mail' => $this->session_data['email']
571
            ));
572
573
            $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, discriminator_type) VALUES (2, :login_id, :admin_pass , :salt , '1', '0', '0', '1', '1', current_timestamp, current_timestamp,'管理者','EC-CUBE SHOP', 'member');");
574
            $sth->execute(array(':login_id' => $this->session_data['login_id'], ':admin_pass' => $encodedPassword, ':salt' => $salt));
575
576
            $this->PDO->commit();
577
        } catch (\Exception $e) {
578
            $this->PDO->rollback();
579
            throw $e;
580
        }
581
582
        return $this;
583
    }
584
585
    private function update()
586
    {
587
        $this->resetNatTimer();
588
589
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
590
        $database = Yaml::parse(file_get_contents($config_file));
591
        $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...
592
593
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
594
        $baseConfig = Yaml::parse(file_get_contents($config_file));
595
        $config['config'] = $baseConfig;
596
597
        $this->PDO->beginTransaction();
598
599
        try {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
600
601
            $config = array(
602
                'auth_type' => '',
603
                'auth_magic' => $config['config']['auth_magic'],
604
                'password_hash_algos' => 'sha256',
605
            );
606
            $passwordEncoder = new \Eccube\Security\Core\Encoder\PasswordEncoder($config);
607
            $salt = \Eccube\Util\Str::random(32);
608
609
            $stmt = $this->PDO->prepare("SELECT member_id FROM dtb_member WHERE login_id = :login_id;");
610
            $stmt->execute(array(':login_id' => $this->session_data['login_id']));
611
            $rs = $stmt->fetch();
612
613
            $encodedPassword = $passwordEncoder->encodePassword($this->session_data['login_pass'], $salt);
614
615
            if ($rs) {
616
                // 同一の管理者IDであればパスワードのみ更新
617
                $sth = $this->PDO->prepare("UPDATE dtb_member set password = :admin_pass, salt = :salt, update_date = current_timestamp WHERE login_id = :login_id;");
618
                $sth->execute(array(':admin_pass' => $encodedPassword, ':salt' => $salt, ':login_id' => $this->session_data['login_id']));
619
            } else {
620
                // 新しい管理者IDが入力されたらinsert
621
                $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,discriminator_type) VALUES (:login_id, :admin_pass , :salt , '1', '0', '0', '1', '1', current_timestamp, current_timestamp,'管理者','EC-CUBE SHOP', 'member');");
622
                $sth->execute(array(':login_id' => $this->session_data['login_id'], ':admin_pass' => $encodedPassword, ':salt' => $salt));
623
            }
624
625
            $sth = $this->PDO->prepare('UPDATE dtb_base_info set
626
                shop_name = :shop_name,
627
                email01 = :admin_mail,
628
                email02 = :admin_mail,
629
                email03 = :admin_mail,
630
                email04 = :admin_mail,
631
                update_date = current_timestamp
632
            WHERE id = 1;');
633
            $sth->execute(array(
0 ignored issues
show
Add a comma after each item in a multi-line array
Loading history...
634
                ':shop_name' => $this->session_data['shop_name'],
635
                ':admin_mail' => $this->session_data['email']
636
            ));
637
638
            $this->PDO->commit();
639
        } catch (\Exception $e) {
640
            $this->PDO->rollback();
641
            throw $e;
642
        }
643
644
        return $this;
645
    }
646
647
    private function getMigration()
648
    {
649
        $app = \Eccube\Application::getInstance();
650
        $app->initialize();
651 1
        $app->boot();
652
653 1
        $config = new Configuration($app['db']);
654 1
        $config->setMigrationsNamespace('DoctrineMigrations');
655
656 1
        $migrationDir = __DIR__ . '/../../Resource/doctrine/migration';
657
        $config->setMigrationsDirectory($migrationDir);
658
        $config->registerMigrationsFromDirectory($migrationDir);
659
660
        $migration = new Migration($config);
661
        $migration->setNoMigrationException(true);
662
663
        return $migration;
664
    }
665
666 1
    private function doMigrate()
667 1
    {
668 1
        try {
669
            $migration = $this->getMigration();
670
671
            // DBとのコネクションを維持するためpingさせる
672 1
            if (is_null($this->PDO)) {
673
                $this->setPDO();
674
            }
675
            $this->PDO->ping();
676
677
            // nullを渡すと最新バージョンまでマイグレートする
678
            $migration->migrate(null, false);
679
        } catch (MigrationException $e) {
680
            
681
        }
682
683
        return $this;
684
    }
685
686
    private function getProtectedDirs()
687
    {
688
        $protectedDirs = array();
689
        $base = __DIR__ . '/../../../..';
690
        $dirs = array(
691
            '/html',
692
            '/app',
693
            '/app/template',
694
            '/app/cache',
695
            '/app/config',
696
            '/app/config/eccube',
697
            '/app/log',
698
            '/app/Plugin',
699
        );
700
701
        foreach ($dirs as $dir) {
702
            if (!is_writable($base . $dir)) {
703
                $protectedDirs[] = $dir;
704
            }
705
        }
706
707
        return $protectedDirs;
708
    }
709
710
    private function createConfigYamlFile($data, $auth = true)
711
    {
712
        $fs = new Filesystem();
713
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
714
715
        if ($fs->exists($config_file)) {
716
            $config = Yaml::parse(file_get_contents($config_file));
717
            $fs->remove($config_file);
718
        }
719
720
        if ($auth) {
721
            $auth_magic = Str::random(32);
722
        } else {
723
            if (isset($config['auth_magic'])) {
724
                $auth_magic = $config['auth_magic'];
725
            } else {
726
                $auth_magic = Str::random(32);
727
            }
728
        }
729
730
        $allowHost = Str::convertLineFeed($data['admin_allow_hosts']);
731
        if (empty($allowHost)) {
732
            $adminAllowHosts = array();
733
        } else {
734
            $adminAllowHosts = explode("\n", $allowHost);
735
        }
736
        $trustedProxies = Str::convertLineFeed($data['trusted_proxies']);
737
        if (empty($trustedProxies)) {
738
            $adminTrustedProxies = array();
739
        } else {
740
            $adminTrustedProxies = explode("\n", $trustedProxies);
741
            // ループバックアドレスを含める
742
            $adminTrustedProxies = array_merge($adminTrustedProxies, array('127.0.0.1/8', '::1'));
743
        }
744
        if ($data['trusted_proxies_connection_only']) {
745
            // ループバックアドレスを含める
746
            $adminTrustedProxies = array('127.0.0.1/8', '::1');
747
        }
748
749
        $target = array('${AUTH_MAGIC}', '${SHOP_NAME}', '${ECCUBE_INSTALL}', '${FORCE_SSL}');
750
        $replace = array($auth_magic, $data['shop_name'], '0', $data['admin_force_ssl']);
751
752
        $fs = new Filesystem();
753
        $content = str_replace(
754
            $target, $replace, file_get_contents($this->dist_path . '/config.yml.dist')
755
        );
756
        $fs->dumpFile($config_file, $content);
757
758
        $config = Yaml::parse(file_get_contents($config_file));
759
        $config['admin_allow_host'] = $adminAllowHosts;
760
        $config['trusted_proxies_connection_only'] = $data['trusted_proxies_connection_only'];
761
        $config['trusted_proxies'] = $adminTrustedProxies;
762
        $yml = Yaml::dump($config);
763
        file_put_contents($config_file, $yml);
764
765
        return $this;
766
    }
767
768
    private function addInstallStatus()
769
    {
770
        $config_file = $this->config_path . '/config.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
771
        $config = Yaml::parse(file_get_contents($config_file));
772
        $config['eccube_install'] = 1;
773
        $yml = Yaml::dump($config);
774
        file_put_contents($config_file, $yml);
775
776
        return $this;
777
    }
778
779
    private function createDatabaseYamlFile($data)
780
    {
781
        $fs = new Filesystem();
782
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
783
        if ($fs->exists($config_file)) {
784
            $fs->remove($config_file);
785
        }
786
787
        if ($data['database'] != 'pdo_sqlite') {
788
            switch ($data['database'])
789
            {
790
                case 'pdo_pgsql':
791
                    if (empty($data['db_port'])) {
792
                        $data['db_port'] = '5432';
793
                    }
794
                    $data['db_driver'] = 'pdo_pgsql';
795
                    break;
796
                case 'pdo_mysql':
797
                    if (empty($data['db_port'])) {
798
                        $data['db_port'] = '3306';
799
                    }
800
                    $data['db_driver'] = 'pdo_mysql';
801
                    break;
802
            }
803
            $target = array('${DBDRIVER}', '${DBSERVER}', '${DBNAME}', '${DBPORT}', '${DBUSER}', '${DBPASS}');
804
            $replace = array(
0 ignored issues
show
Add a comma after each item in a multi-line array
Loading history...
805
                $data['db_driver'],
806
                $data['database_host'],
807
                $data['database_name'],
808
                $data['database_port'],
809
                $data['database_user'],
810
                $data['database_password']
811
            );
812
813
            $fs = new Filesystem();
814
            $content = str_replace(
815
                $target, $replace, file_get_contents($this->dist_path . '/database.yml.dist')
816
            );
817
        } else {
818
            $content = Yaml::dump(
819
                    array(
0 ignored issues
show
Add a comma after each item in a multi-line array
Loading history...
820
                        'database' => array(
821
                            'driver' => 'pdo_sqlite',
822
                            'path' => realpath($this->config_path . '/eccube.db')
823
                        )
824
                    )
825
            );
826
        }
827
        $fs->dumpFile($config_file, $content);
828
829
        return $this;
830
    }
831
832
    private function createMailYamlFile($data)
833
    {
834
        $fs = new Filesystem();
835
        $config_file = $this->config_path . '/mail.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
836
        if ($fs->exists($config_file)) {
837
            $fs->remove($config_file);
838
        }
839
        $target = array('${MAIL_BACKEND}', '${MAIL_HOST}', '${MAIL_PORT}', '${MAIL_USER}', '${MAIL_PASS}');
840
        $replace = array(
0 ignored issues
show
Add a comma after each item in a multi-line array
Loading history...
841
            $data['mail_backend'],
842
            $data['smtp_host'],
843
            $data['smtp_port'],
844
            $data['smtp_username'],
845
            $data['smtp_password']
846
        );
847
848
        $fs = new Filesystem();
849
        $content = str_replace(
850
            $target, $replace, file_get_contents($this->dist_path . '/mail.yml.dist')
851
        );
852
        $fs->dumpFile($config_file, $content);
853
854
        return $this;
855
    }
856
857
    private function createPathYamlFile($data, Request $request)
858
    {
859
        $fs = new Filesystem();
860
        $config_file = $this->config_path . '/path.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
861
        if ($fs->exists($config_file)) {
862
            $fs->remove($config_file);
863
        }
864
865
        $ADMIN_ROUTE = $data['admin_dir'];
866
        $TEMPLATE_CODE = 'default';
867
        $USER_DATA_ROUTE = 'user_data';
868
        $ROOT_DIR = realpath(__DIR__ . '/../../../../');
869
        $ROOT_URLPATH = $request->getBasePath();
870
        $ROOT_PUBLIC_URLPATH = $ROOT_URLPATH . RELATIVE_PUBLIC_DIR_PATH;
871
872
        $target = array('${ADMIN_ROUTE}', '${TEMPLATE_CODE}', '${USER_DATA_ROUTE}', '${ROOT_DIR}', '${ROOT_URLPATH}', '${ROOT_PUBLIC_URLPATH}');
873
        $replace = array($ADMIN_ROUTE, $TEMPLATE_CODE, $USER_DATA_ROUTE, $ROOT_DIR, $ROOT_URLPATH, $ROOT_PUBLIC_URLPATH);
874
875
        $fs = new Filesystem();
876
        $content = str_replace(
877
            $target, $replace, file_get_contents($this->dist_path . '/path.yml.dist')
878
        );
879
        $fs->dumpFile($config_file, $content);
880
881
        return $this;
882
    }
883
884
    private function sendAppData($params)
885
    {
886
        $config_file = $this->config_path . '/database.yml';
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
887
        $db_config = Yaml::parse(file_get_contents($config_file));
888
889
        $this->setPDO();
890
        $stmt = $this->PDO->query('select version() as v');
891
892
        $version = '';
893
        foreach ($stmt as $row) {
894
            $version = $row['v'];
895
        }
896
897
        if ($db_config['database']['driver'] === 'pdo_mysql') {
898
            $db_ver = 'MySQL:' . $version;
899
        } else {
900
            $db_ver = $version;
901
        }
902
903
        $data = http_build_query(
904
            array(
905
                'site_url' => $params['http_url'],
906
                'shop_name' => $params['shop_name'],
907
                'cube_ver' => Constant::VERSION,
908
                'php_ver' => phpversion(),
909
                'db_ver' => $db_ver,
910
                'os_type' => php_uname(),
911
            )
912
        );
913
914
        $header = array(
915
            'Content-Type: application/x-www-form-urlencoded',
916
            'Content-Length: ' . strlen($data),
917
        );
918
        $context = stream_context_create(
919
            array(
0 ignored issues
show
Add a comma after each item in a multi-line array
Loading history...
920
                'http' => array(
921
                    'method' => 'POST',
922
                    'header' => $header,
923
                    'content' => $data,
924
                )
925
            )
926
        );
927
        file_get_contents('http://www.ec-cube.net/mall/use_site.php', false, $context);
928
929
        return $this;
930
    }
931
932
    /**
933
     * マイグレーション画面を表示する.
934
     *
935
     * @param InstallApplication $app
936
     * @param Request $request
0 ignored issues
show
Expected 12 spaces after parameter type; 1 found
Loading history...
937
     *
938
     * @return \Symfony\Component\HttpFoundation\Response
939
     */
940
    public function migration(InstallApplication $app, Request $request)
941
    {
942
        return $app['twig']->render('migration.twig', array(
943
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
944
        ));
945
    }
946
947
    /**
948
     * インストール済プラグインの一覧を表示する.
949
     * プラグインがインストールされていない場合は, マイグレーション実行画面へリダイレクトする.
950
     *
951
     * @param InstallApplication $app
952
     * @param Request $request
0 ignored issues
show
Expected 12 spaces after parameter type; 1 found
Loading history...
953
     *
954
     * @return \Symfony\Component\HttpFoundation\Response
955
     */
956
    public function migration_plugin(InstallApplication $app, Request $request)
957
    {
958
        $eccube = \Eccube\Application::getInstance();
959
        $eccube->initialize();
960
        $eccube->boot();
961
962
        $pluginRepository = $eccube['orm.em']->getRepository('Eccube\Entity\Plugin');
963
        $Plugins = $pluginRepository->findBy(array('del_flg' => Constant::DISABLED));
964
965
        if (empty($Plugins)) {
966
            // インストール済プラグインがない場合はマイグレーション実行画面へリダイレクト.
967
            return $app->redirect($app->path('migration_end'));
968
        } else {
969
            return $app['twig']->render('migration_plugin.twig', array(
970
                    'Plugins' => $Plugins,
971
                    'version' => Constant::VERSION,
972
                    'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
973
            ));
974
        }
975
    }
976
977
    /**
978
     * マイグレーションを実行し, 完了画面を表示させる
979
     *
980
     * @param InstallApplication $app
981
     * @param Request $request
0 ignored issues
show
Expected 12 spaces after parameter type; 1 found
Loading history...
982
     *
983
     * @return \Symfony\Component\HttpFoundation\Response
984
     */
985
    public function migration_end(InstallApplication $app, Request $request)
986
    {
987
        $this->doMigrate();
988
989
        $config_app = new \Eccube\Application(); // install用のappだとconfigが取れないので
990
        $config_app->initialize();
991
        $config_app->boot();
992
        \Eccube\Util\Cache::clear($config_app, true);
993
994
        return $app['twig']->render('migration_end.twig', array(
995
                'publicPath' => '..' . RELATIVE_PUBLIC_DIR_PATH . '/',
0 ignored issues
show
Concat operator must not be surrounded by spaces
Loading history...
996
        ));
997
    }
998
}
999