Completed
Pull Request — 4.0 (#4085)
by chihiro
06:46
created

InstallController::step2()   C

Complexity

Conditions 11
Paths 163

Size

Total Lines 61

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
cc 11
nc 163
nop 0
dl 0
loc 61
rs 6.2842
c 0
b 0
f 0
ccs 0
cts 29
cp 0
crap 132

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Controller\Install;
15
16
use Doctrine\Common\Annotations\AnnotationReader;
17
use Doctrine\Common\Annotations\CachedReader;
18
use Doctrine\Common\Cache\ArrayCache;
19
use Doctrine\DBAL\Connection;
20
use Doctrine\DBAL\DriverManager;
21
use Doctrine\DBAL\Migrations\Configuration\Configuration;
22
use Doctrine\DBAL\Migrations\Migration;
23
use Doctrine\DBAL\Migrations\MigrationException;
24
use Doctrine\DBAL\Types\Type;
25
use Doctrine\ORM\EntityManager;
26
use Doctrine\ORM\Tools\SchemaTool;
27
use Doctrine\ORM\Tools\Setup;
28
use Eccube\Common\Constant;
29
use Eccube\Controller\AbstractController;
30
use Eccube\Doctrine\DBAL\Types\UTCDateTimeType;
31
use Eccube\Doctrine\DBAL\Types\UTCDateTimeTzType;
32
use Eccube\Doctrine\ORM\Mapping\Driver\AnnotationDriver;
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\Security\Core\Encoder\PasswordEncoder;
38
use Eccube\Util\CacheUtil;
39
use Eccube\Util\StringUtil;
40
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
41
use Symfony\Component\Finder\Finder;
42
use Symfony\Component\HttpFoundation\Request;
43
use Symfony\Component\HttpFoundation\Session\SessionInterface;
44
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
45
use Symfony\Component\Routing\Annotation\Route;
46
47
class InstallController extends AbstractController
48
{
49
    /**
50
     * default value of auth magic
51
     */
52
    const DEFAULT_AUTH_MAGIC = '<change.me>';
53
54
    protected $requiredModules = [
55
        'pdo',
56
        'phar',
57
        'mbstring',
58
        'zlib',
59
        'ctype',
60
        'session',
61
        'JSON',
62
        'xml',
63
        'libxml',
64
        'OpenSSL',
65
        'zip',
66
        'cURL',
67
        'fileinfo',
68
        'intl',
69
    ];
70
71
    protected $recommendedModules = [
72
        'hash',
73
        'mcrypt',
74
    ];
75
76
    protected $eccubeDirs = [
77
        'app/Plugin',
78
        'app/PluginData',
79
        'app/proxy',
80
        'app/template',
81
        'html',
82
        'var',
83
        'vendor',
84
    ];
85
86
    protected $eccubeFiles = [
87
        'composer.json',
88
        'composer.lock',
89
    ];
90
91
    /**
92
     * @var PasswordEncoder
93
     */
94
    protected $encoder;
95
96
    /**
97
     * @var CacheUtil
98
     */
99
    protected $cacheUtil;
100
101
    public function __construct(PasswordEncoder $encoder, CacheUtil $cacheUtil)
102
    {
103
        $this->encoder = $encoder;
104
        $this->cacheUtil = $cacheUtil;
105
    }
106
107
    /**
108
     * 最初からやり直す場合、SESSION情報をクリア.
109
     *
110
     * @Route("/", name="homepage")
111
     * @Route("/install", name="install")
112
     *
113
     * @Template("index.twig")
114
     *
115
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
116
     */
117
    public function index()
118
    {
119
        if (!$this->isInstallEnv()) {
120
            throw new NotFoundHttpException();
121
        }
122
123
        $this->removeSessionData($this->session);
124
125
        return $this->redirectToRoute('install_step1');
126
    }
127
128
    /**
129
     * ようこそ.
130
     *
131
     * @Route("/install/step1", name="install_step1")
132
     * @Template("step1.twig")
133
     *
134
     * @param Request $request
135
     *
136
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
137
     */
138
    public function step1(Request $request)
139
    {
140
        if (!$this->isInstallEnv()) {
141
            throw new NotFoundHttpException();
142
        }
143
144
        $form = $this->formFactory
145
            ->createBuilder(Step1Type::class)
146
            ->getForm();
147
148
        $form->setData($this->getSessionData($this->session));
149
        $form->handleRequest($request);
150
151 View Code Duplication
        if ($form->isSubmitted() && $form->isValid()) {
152
            $this->setSessionData($this->session, $form->getData());
153
154
            return $this->redirectToRoute('install_step2');
155
        }
156
157
        $this->checkModules();
158
159
        $authmagic = $this->getParameter('eccube_auth_magic');
160
        if ($authmagic === self::DEFAULT_AUTH_MAGIC) {
161
            $authmagic = StringUtil::random(32);
162
        }
163
        $this->setSessionData($this->session, ['authmagic' => $authmagic]);
164
165
        return [
166
            'form' => $form->createView(),
167
        ];
168
    }
169
170
    /**
171
     * ディレクトリとファイルの書き込み権限をチェック.
172
     *
173
     * @Route("/install/step2", name="install_step2")
174
     * @Template("step2.twig")
175
     *
176
     * @return array
177
     */
178
    public function step2()
179
    {
180
        if (!$this->isInstallEnv()) {
181
            throw new NotFoundHttpException();
182
        }
183
184
        $noWritePermissions = [];
185
186
        $projectDir = $this->getParameter('kernel.project_dir');
187
188
        $eccubeDirs = array_map(function ($dir) use ($projectDir) {
189
            return $projectDir.'/'.$dir;
190
        }, $this->eccubeDirs);
191
192
        $eccubeFiles = array_map(function ($file) use ($projectDir) {
193
            return $projectDir.'/'.$file;
194
        }, $this->eccubeFiles);
195
196
        // ルートディレクトリの書き込み権限をチェック
197
        if (!is_writable($projectDir)) {
198
            $noWritePermissions[] = $projectDir;
199
        }
200
201
        // 対象ディレクトリの書き込み権限をチェック
202
        foreach ($eccubeDirs as $dir) {
203
            if (!is_writable($dir)) {
204
                $noWritePermissions[] = $dir;
205
            }
206
        }
207
208
        // 対象ディレクトリ配下のディレクトリの書き込み権限をチェック
209
        $targetDirs = Finder::create()
210
            ->in($eccubeDirs)
211
            ->directories();
212
        foreach ($targetDirs as $targetDir) {
213
            if (!is_writable($targetDir->getRealPath())) {
214
                $noWritePermissions[] = $targetDir;
215
            }
216
        }
217
218
        // 対象ディレクトリ配下のファイルの書き込み権限をチェック
219
        $targetFiles = Finder::create()
220
            ->in($eccubeDirs)
221
            ->files();
222
        foreach ($targetFiles as $targetFile) {
223
            if (!is_writable($targetFile->getRealPath())) {
224
                $noWritePermissions[] = $targetFile;
225
            }
226
        }
227
228
        // composer.json, composer.lockの書き込み権限をチェック
229
        foreach ($eccubeFiles as $file) {
230
            if (!is_writable($file)) {
231
                $noWritePermissions[] = $file;
232
            }
233
        }
234
235
        return [
236
            'noWritePermissions' => $noWritePermissions,
237
        ];
238
    }
239
240
    /**
241
     * サイトの設定.
242
     *
243
     * @Route("/install/step3", name="install_step3")
244
     * @Template("step3.twig")
245
     *
246
     * @param Request $request
247
     *
248
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
249
     *
250
     * @throws \Doctrine\DBAL\DBALException
251
     * @throws \Exception
252
     */
253
    public function step3(Request $request)
254
    {
255
        if (!$this->isInstallEnv()) {
256
            throw new NotFoundHttpException();
257
        }
258
259
        $sessionData = $this->getSessionData($this->session);
260
261
        // 再インストールの場合は環境変数から復旧
262
        if ($this->isInstalled()) {
263
            // ショップ名/メールアドレス
264
            $conn = $this->entityManager->getConnection();
265
            $stmt = $conn->query('SELECT shop_name, email01 FROM dtb_base_info WHERE id = 1;');
266
            $row = $stmt->fetch();
267
            $sessionData['shop_name'] = $row['shop_name'];
268
            $sessionData['email'] = $row['email01'];
269
270
            $databaseUrl = $this->getParameter('eccube_database_url');
271
            $sessionData = array_merge($sessionData, $this->extractDatabaseUrl($databaseUrl));
272
273
            // 管理画面ルーティング
274
            $sessionData['admin_dir'] = $this->getParameter('eccube_admin_route');
275
276
            // 管理画面許可IP
277
            $sessionData['admin_allow_hosts'] = implode($this->getParameter('eccube_admin_allow_hosts'));
278
279
            // 強制SSL
280
            $sessionData['admin_force_ssl'] = $this->getParameter('eccube_force_ssl');
281
282
            // メール
283
            $mailerUrl = $this->getParameter('eccube_mailer_url');
284
            $sessionData = array_merge($sessionData, $this->extractMailerUrl($mailerUrl));
285
        } else {
286
            // 初期値設定
287
            if (!isset($sessionData['admin_allow_hosts'])) {
288
                $sessionData['admin_allow_hosts'] = '';
289
            }
290
            if (!isset($sessionData['smtp_host'])) {
291
                $sessionData = array_merge($sessionData, $this->extractMailerUrl('smtp://localhost:25'));
292
            }
293
        }
294
295
        $form = $this->formFactory
296
            ->createBuilder(Step3Type::class)
297
            ->getForm();
298
299
        $form->setData($sessionData);
300
        $form->handleRequest($request);
301
302 View Code Duplication
        if ($form->isSubmitted() && $form->isValid()) {
303
            $this->setSessionData($this->session, $form->getData());
304
305
            return $this->redirectToRoute('install_step4');
306
        }
307
308
        return [
309
            'form' => $form->createView(),
310
            'request' => $request,
311
        ];
312
    }
313
314
    /**
315
     * データベースの設定.
316
     *
317
     * @Route("/install/step4", name="install_step4")
318
     * @Template("step4.twig")
319
     *
320
     * @param Request $request
321
     *
322
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
323
     *
324
     * @throws \Exception
325
     */
326
    public function step4(Request $request)
327
    {
328
        if (!$this->isInstallEnv()) {
329
            throw new NotFoundHttpException();
330
        }
331
332
        $sessionData = $this->getSessionData($this->session);
333
334
        if (empty($sessionData['database'])) {
335
            // 再インストールの場合は環境変数から復旧.
336
            if ($this->isInstalled()) {
337
                $databaseUrl = $this->getParameter('eccube_database_url');
338
                $sessionData = array_merge($sessionData, $this->extractDatabaseUrl($databaseUrl));
339
            }
340
        }
341
342
        $form = $this->formFactory
343
            ->createBuilder(Step4Type::class)
344
            ->getForm();
345
346
        $form->setData($sessionData);
347
        $form->handleRequest($request);
348
349
        if ($form->isSubmitted() && $form->isValid()) {
350
            $data = $form->getData();
351
            if ($data['database'] === 'pdo_sqlite') {
352
                $data['database_name'] = '/var/eccube.db';
353
            }
354
355
            $this->setSessionData($this->session, $data);
356
357
            return $this->redirectToRoute('install_step5');
358
        }
359
360
        return [
361
            'form' => $form->createView(),
362
        ];
363
    }
364
365
    /**
366
     * データベースの初期化.
367
     *
368
     * @Route("/install/step5", name="install_step5")
369
     * @Template("step5.twig")
370
     *
371
     * @param Request $request
372
     *
373
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
374
     *
375
     * @throws \Exception
376
     */
377
    public function step5(Request $request)
378
    {
379
        if (!$this->isInstallEnv()) {
380
            throw new NotFoundHttpException();
381
        }
382
383
        $form = $this->formFactory
384
            ->createBuilder(Step5Type::class)
385
            ->getForm();
386
387
        $sessionData = $this->getSessionData($this->session);
388
        $form->setData($sessionData);
389
        $form->handleRequest($request);
390
391
        if ($form->isSubmitted() && $form->isValid()) {
392
            $noUpdate = $form['no_update']->getData();
393
394
            $url = $this->createDatabaseUrl($sessionData);
395
396
            try {
397
                $conn = $this->createConnection(['url' => $url]);
398
                $em = $this->createEntityManager($conn);
399
                $migration = $this->createMigration($conn);
400
401
                if ($noUpdate) {
402
                    $this->update($conn, [
403
                        'auth_magic' => $sessionData['authmagic'],
404
                        'login_id' => $sessionData['login_id'],
405
                        'login_pass' => $sessionData['login_pass'],
406
                        'shop_name' => $sessionData['shop_name'],
407
                        'email' => $sessionData['email'],
408
                    ]);
409
                } else {
410
                    $this->dropTables($em);
411
                    $this->createTables($em);
412
                    $this->importCsv($em);
413
                    $this->migrate($migration);
414
                    $this->insert($conn, [
415
                        'auth_magic' => $sessionData['authmagic'],
416
                        'login_id' => $sessionData['login_id'],
417
                        'login_pass' => $sessionData['login_pass'],
418
                        'shop_name' => $sessionData['shop_name'],
419
                        'email' => $sessionData['email'],
420
                    ]);
421
                }
422
            } catch (\Exception $e) {
423
                log_error($e->getMessage());
424
                $this->addError($e->getMessage());
425
426
                return [
427
                    'form' => $form->createView(),
428
                ];
429
            }
430
431
            if (isset($sessionData['agree']) && $sessionData['agree']) {
432
                $host = $request->getSchemeAndHttpHost();
433
                $basePath = $request->getBasePath();
434
                $params = [
435
                    'http_url' => $host.$basePath,
436
                    'shop_name' => $sessionData['shop_name'],
437
                ];
438
                $this->sendAppData($params, $em);
439
            }
440
            $version = $this->getDatabaseVersion($em);
441
            $this->setSessionData($this->session, ['database_version' => $version]);
442
443
            return $this->redirectToRoute('install_complete');
444
        }
445
446
        return [
447
            'form' => $form->createView(),
448
        ];
449
    }
450
451
    /**
452
     * インストール完了
453
     *
454
     * @Route("/install/complete", name="install_complete")
455
     * @Template("complete.twig")
456
     */
457
    public function complete(Request $request)
458
    {
459
        if (!$this->isInstallEnv()) {
460
            throw new NotFoundHttpException();
461
        }
462
463
        $sessionData = $this->getSessionData($this->session);
464
        $databaseUrl = $this->createDatabaseUrl($sessionData);
465
        $mailerUrl = $this->createMailerUrl($sessionData);
466
        $forceSSL = isset($sessionData['admin_force_ssl']) ? (bool) $sessionData['admin_force_ssl'] : false;
467 View Code Duplication
        if ($forceSSL === false) {
468
            $forceSSL = 'false';
469
        } elseif ($forceSSL === true) {
470
            $forceSSL = 'true';
471
        }
472
        $env = file_get_contents(__DIR__.'/../../../../.env.dist');
473
        $replacement = [
474
            'APP_ENV' => 'prod',
475
            'APP_DEBUG' => '0',
476
            'DATABASE_URL' => $databaseUrl,
477
            'MAILER_URL' => $mailerUrl,
478
            'ECCUBE_AUTH_MAGIC' => $sessionData['authmagic'],
479
            'DATABASE_SERVER_VERSION' => isset($sessionData['database_version']) ? $sessionData['database_version'] : '3',
480
            'ECCUBE_ADMIN_ALLOW_HOSTS' => $this->convertAdminAllowHosts($sessionData['admin_allow_hosts']),
481
            'ECCUBE_FORCE_SSL' => $forceSSL,
482
            'ECCUBE_ADMIN_ROUTE' => isset($sessionData['admin_dir']) ? $sessionData['admin_dir'] : 'admin',
483
            'ECCUBE_COOKIE_PATH' => $request->getBasePath() ? $request->getBasePath() : '/',
484
            'ECCUBE_TEMPLATE_CODE' => 'default',
485
            'ECCUBE_LOCALE' => 'ja',
486
        ];
487
488
        $env = StringUtil::replaceOrAddEnv($env, $replacement);
489
490
        if ($this->getParameter('kernel.environment') === 'install') {
491
            file_put_contents(__DIR__.'/../../../../.env', $env);
492
        }
493
        $host = $request->getSchemeAndHttpHost();
494
        $basePath = $request->getBasePath();
495
        $adminUrl = $host.$basePath.'/'.$replacement['ECCUBE_ADMIN_ROUTE'];
496
497
        $this->removeSessionData($this->session);
498
499
        $this->cacheUtil->clearCache('prod');
500
501
        return [
502
            'admin_url' => $adminUrl,
503
        ];
504
    }
505
506
    protected function getSessionData(SessionInterface $session)
507
    {
508
        return $session->get('eccube.session.install', []);
509
    }
510
511
    protected function removeSessionData(SessionInterface $session)
512
    {
513
        $session->clear();
514
    }
515
516
    protected function setSessionData(SessionInterface $session, $data = [])
517
    {
518
        $data = array_replace_recursive($this->getSessionData($session), $data);
519
        $session->set('eccube.session.install', $data);
520
    }
521
522
    protected function checkModules()
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...
523
    {
524
        foreach ($this->requiredModules as $module) {
525
            if (!extension_loaded($module)) {
526
                $this->addDanger(trans('install.required_extension_disabled', ['%module%' => $module]), 'install');
527
            }
528
        }
529
        if (!extension_loaded('pdo_mysql') && !extension_loaded('pdo_pgsql')) {
530
            $this->addDanger(trans('install.required_database_extension_disabled'), 'install');
531
        }
532
        foreach ($this->recommendedModules as $module) {
533
            if (!extension_loaded($module)) {
534
                if ($module == 'mcrypt' && PHP_VERSION_ID >= 70100) {
535
                    //The mcrypt extension has been deprecated in PHP 7.1.x
536
                    //http://php.net/manual/en/migration71.deprecated.php
537
                    continue;
538
                }
539
                $this->addInfo(trans('install.recommend_extension_disabled', ['%module%' => $module]), 'install');
540
            }
541
        }
542
        if ('\\' === DIRECTORY_SEPARATOR) { // for Windows
543
            if (!extension_loaded('wincache')) {
544
                $this->addInfo(trans('install.recommend_extension_disabled', ['%module%' => 'wincache']), 'install');
545
            }
546
        } else {
547
            if (!extension_loaded('apc')) {
548
                $this->addInfo(trans('install.recommend_extension_disabled', ['%module%' => 'apc']), 'install');
549
            }
550
        }
551
        if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
552
            if (!function_exists('apache_get_modules')) {
553
                $this->addWarning(trans('install.mod_rewrite_unknown'), 'install');
554
            } elseif (!in_array('mod_rewrite', apache_get_modules())) {
555
                $this->addDanger(trans('install.mod_rewrite_disabled'), 'install');
556
            }
557
        } elseif (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false) {
558
            // iis
559
        } elseif (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'nginx') !== false) {
560
            // nginx
561
        }
562
    }
563
564
    protected function createConnection(array $params)
565
    {
566
        if (strpos($params['url'], 'mysql') !== false) {
567
            $params['charset'] = 'utf8';
568
            $params['defaultTableOptions'] = [
569
                'collate' => 'utf8_general_ci',
570
            ];
571
        }
572
573
        Type::overrideType('datetime', UTCDateTimeType::class);
574
        Type::overrideType('datetimetz', UTCDateTimeTzType::class);
575
576
        $conn = DriverManager::getConnection($params);
577
        $conn->ping();
578
579
        $platform = $conn->getDatabasePlatform();
580
        $platform->markDoctrineTypeCommented('datetime');
581
        $platform->markDoctrineTypeCommented('datetimetz');
582
583
        return $conn;
584
    }
585
586
    protected function createEntityManager(Connection $conn)
587
    {
588
        $paths = [
589
            $this->getParameter('kernel.project_dir').'/src/Eccube/Entity',
590
            $this->getParameter('kernel.project_dir').'/app/Customize/Entity',
591
        ];
592
        $config = Setup::createConfiguration(true);
593
        $driver = new AnnotationDriver(new CachedReader(new AnnotationReader(), new ArrayCache()), $paths);
594
        $driver->setTraitProxiesDirectory($this->getParameter('kernel.project_dir').'/app/proxy/entity');
595
        $config->setMetadataDriverImpl($driver);
596
597
        $em = EntityManager::create($conn, $config);
598
599
        return $em;
600
    }
601
602
    /**
603
     * @param array $params
604
     *
605
     * @return string
606
     */
607
    public function createDatabaseUrl(array $params)
608
    {
609
        if (!isset($params['database'])) {
610
            return null;
611
        }
612
613
        $url = '';
614
        switch ($params['database']) {
615
            case 'pdo_sqlite':
616
                $url = 'sqlite://'.$params['database_name'];
617
                break;
618
619
            case 'pdo_mysql':
620
            case 'pdo_pgsql':
621
                $url = str_replace('pdo_', '', $params['database']);
622
                $url .= '://';
623
                if (isset($params['database_user'])) {
624
                    $url .= $params['database_user'];
625
                    if (isset($params['database_password'])) {
626
                        $url .= ':'.\rawurlencode($params['database_password']);
627
                    }
628
                    $url .= '@';
629
                }
630 View Code Duplication
                if (isset($params['database_host'])) {
631
                    $url .= $params['database_host'];
632
                    if (isset($params['database_port'])) {
633
                        $url .= ':'.$params['database_port'];
634
                    }
635
                    $url .= '/';
636
                }
637
                $url .= $params['database_name'];
638
                break;
639
        }
640
641
        return $url;
642
    }
643
644
    /**
645
     * @param string $url
646
     *
647
     * @return array
648
     */
649
    public function extractDatabaseUrl($url)
650
    {
651
        if (preg_match('|^sqlite://(.*)$|', $url, $matches)) {
652
            return [
653
                'database' => 'pdo_sqlite',
654
                'database_name' => $matches[1],
655
            ];
656
        }
657
658
        $parsed = parse_url($url);
659
660
        if ($parsed === false) {
661
            throw new \Exception('Malformed parameter "url".');
662
        }
663
664
        return [
665
            'database' => 'pdo_'.$parsed['scheme'],
666
            'database_name' => ltrim($parsed['path'], '/'),
667
            'database_host' => $parsed['host'],
668
            'database_port' => isset($parsed['port']) ? $parsed['port'] : null,
669
            'database_user' => isset($parsed['user']) ? $parsed['user'] : null,
670
            'database_password' => isset($parsed['pass']) ? $parsed['pass'] : null,
671
        ];
672
    }
673
674
    /**
675
     * @param array $params
676
     *
677
     * @return string
678
     *
679
     * @see https://github.com/symfony/swiftmailer-bundle/blob/9728097df87e76e2db71fc41fd7d211c06daea3e/DependencyInjection/SwiftmailerTransportFactory.php#L80-L142
680
     */
681
    public function createMailerUrl(array $params)
682
    {
683
        $url = '';
0 ignored issues
show
Unused Code introduced by
$url 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...
684
        if (isset($params['transport'])) {
685
            $url = $params['transport'].'://';
686
        } else {
687
            $url = 'smtp://';
688
        }
689 View Code Duplication
        if (isset($params['smtp_username'])) {
690
            $url .= $params['smtp_username'];
691
            if (isset($params['smtp_password'])) {
692
                $url .= ':'.$params['smtp_password'];
693
            }
694
            $url .= '@';
695
        }
696
697
        $queryStrings = [];
698
        if (isset($params['encryption'])) {
699
            $queryStrings['encryption'] = $params['encryption'];
700
            if ($params['encryption'] === 'ssl' && !isset($params['smtp_port'])) {
701
                $params['smtp_port'] = 465;
702
            }
703
        }
704
        if (isset($params['auth_mode'])) {
705
            $queryStrings['auth_mode'] = $params['auth_mode'];
706
        } else {
707
            if (isset($params['smtp_username'])) {
708
                $queryStrings['auth_mode'] = 'plain';
709
            }
710
        }
711
        ksort($queryStrings, SORT_STRING);
712
713 View Code Duplication
        if (isset($params['smtp_host'])) {
714
            $url .= $params['smtp_host'];
715
            if (isset($params['smtp_port'])) {
716
                $url .= ':'.$params['smtp_port'];
717
            }
718
        }
719
720
        if (isset($params['smtp_username']) || array_values($queryStrings)) {
721
            $url .= '?';
722
            $i = count($queryStrings);
723
            foreach ($queryStrings as $key => $value) {
724
                $url .= $key.'='.$value;
725
                if ($i > 1) {
726
                    $url .= '&';
727
                }
728
                $i--;
729
            }
730
        }
731
732
        return $url;
733
    }
734
735
    /**
736
     * @param string $url
737
     *
738
     * @return array
739
     */
740
    public function extractMailerUrl($url)
741
    {
742
        $options = [
743
            'transport' => null,
744
            'smtp_username' => null,
745
            'smtp_password' => null,
746
            'smtp_host' => null,
747
            'smtp_port' => null,
748
            'encryption' => null,
749
            'auth_mode' => null,
750
        ];
751
752
        if ($url) {
753
            $parts = parse_url($url);
754
            if (isset($parts['scheme'])) {
755
                $options['transport'] = $parts['scheme'];
756
            }
757
            if (isset($parts['user'])) {
758
                $options['smtp_username'] = $parts['user'];
759
            }
760
            if (isset($parts['pass'])) {
761
                $options['smtp_password'] = $parts['pass'];
762
            }
763
            if (isset($parts['host'])) {
764
                $options['smtp_host'] = $parts['host'];
765
            }
766
            if (isset($parts['port'])) {
767
                $options['smtp_port'] = $parts['port'];
768
            }
769
            if (isset($parts['query'])) {
770
                parse_str($parts['query'], $query);
771
                foreach (array_keys($options) as $key) {
772
                    if (isset($query[$key]) && $query[$key] != '') {
773
                        $options[$key] = $query[$key];
774
                    }
775
                }
776
            }
777
        }
778
        if (!isset($options['transport'])) {
779
            $options['transport'] = 'smtp';
780
        } elseif ('gmail' === $options['transport']) {
781
            $options['encryption'] = 'ssl';
782
            $options['auth_mode'] = 'login';
783
            $options['smtp_host'] = 'smtp.gmail.com';
784
            $options['transport'] = 'smtp';
785
        }
786
        if (!isset($options['smtp_port'])) {
787
            $options['smtp_port'] = 'ssl' === $options['encryption'] ? 465 : 25;
788
        }
789
        if (isset($options['smtp_username']) && !isset($options['auth_mode'])) {
790
            $options['auth_mode'] = 'plain';
791
        }
792
        ksort($options, SORT_STRING);
793
794
        return $options;
795
    }
796
797
    protected function createMigration(Connection $conn)
798
    {
799
        $config = new Configuration($conn);
800
        $config->setMigrationsNamespace('DoctrineMigrations');
801
        $migrationDir = $this->getParameter('kernel.project_dir').'/src/Eccube/Resource/doctrine/migration';
802
        $config->setMigrationsDirectory($migrationDir);
803
        $config->registerMigrationsFromDirectory($migrationDir);
804
805
        $migration = new Migration($config);
806
        $migration->setNoMigrationException(true);
807
808
        return $migration;
809
    }
810
811
    protected function dropTables(EntityManager $em)
812
    {
813
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
814
        $schemaTool = new SchemaTool($em);
815
        $schemaTool->dropSchema($metadatas);
816
        $em->getConnection()->executeQuery('DROP TABLE IF EXISTS doctrine_migration_versions');
817
    }
818
819
    protected function createTables(EntityManager $em)
820
    {
821
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
822
        $schemaTool = new SchemaTool($em);
823
        $schemaTool->createSchema($metadatas);
824
    }
825
826
    protected function importCsv(EntityManager $em)
827
    {
828
        // for full locale code cases
829
        $locale = env('ECCUBE_LOCALE', 'ja_JP');
830
        $locale = str_replace('_', '-', $locale);
831
        $locales = \Locale::parseLocale($locale);
832
        $localeDir = is_null($locales) ? 'ja' : $locales['language'];
833
834
        $loader = new \Eccube\Doctrine\Common\CsvDataFixtures\Loader();
835
        $loader->loadFromDirectory($this->getParameter('kernel.project_dir').'/src/Eccube/Resource/doctrine/import_csv/'.$localeDir);
836
        $executer = new \Eccube\Doctrine\Common\CsvDataFixtures\Executor\DbalExecutor($em);
837
        $fixtures = $loader->getFixtures();
838
        $executer->execute($fixtures);
839
    }
840
841
    protected function insert(Connection $conn, array $data)
842
    {
843
        $conn->beginTransaction();
844
        try {
845
            $salt = StringUtil::random(32);
846
            $this->encoder->setAuthMagic($data['auth_magic']);
847
            $password = $this->encoder->encodePassword($data['login_pass'], $salt);
848
849
            $id = ('postgresql' === $conn->getDatabasePlatform()->getName())
850
                ? $conn->fetchColumn("select nextval('dtb_base_info_id_seq')")
851
                : null;
852
853
            $conn->insert('dtb_base_info', [
854
                'id' => $id,
855
                'shop_name' => $data['shop_name'],
856
                'email01' => $data['email'],
857
                'email02' => $data['email'],
858
                'email03' => $data['email'],
859
                'email04' => $data['email'],
860
                'update_date' => new \DateTime(),
861
                'discriminator_type' => 'baseinfo',
862
            ], [
863
                'update_date' => \Doctrine\DBAL\Types\Type::DATETIME,
864
            ]);
865
866
            $member_id = ('postgresql' === $conn->getDatabasePlatform()->getName())
867
                ? $conn->fetchColumn("select nextval('dtb_member_id_seq')")
868
                : null;
869
870
            $conn->insert('dtb_member', [
871
                'id' => $member_id,
872
                'login_id' => $data['login_id'],
873
                'password' => $password,
874
                'salt' => $salt,
875
                'work_id' => 1,
876
                'authority_id' => 0,
877
                'creator_id' => 1,
878
                'sort_no' => 1,
879
                'update_date' => new \DateTime(),
880
                'create_date' => new \DateTime(),
881
                'name' => trans('install.member_name'),
882
                'department' => $data['shop_name'],
883
                'discriminator_type' => 'member',
884
            ], [
885
                'update_date' => Type::DATETIME,
886
                'create_date' => Type::DATETIME,
887
            ]);
888
            $conn->commit();
889
        } catch (\Exception $e) {
890
            $conn->rollback();
891
            throw $e;
892
        }
893
    }
894
895
    protected function update(Connection $conn, array $data)
896
    {
897
        $conn->beginTransaction();
898
        try {
899
            $salt = StringUtil::random(32);
900
            $stmt = $conn->prepare('SELECT id FROM dtb_member WHERE login_id = :login_id;');
901
            $stmt->execute([':login_id' => $data['login_id']]);
902
            $row = $stmt->fetch();
903
            $this->encoder->setAuthMagic($data['auth_magic']);
904
            $password = $this->encoder->encodePassword($data['login_pass'], $salt);
905
            if ($row) {
906
                // 同一の管理者IDであればパスワードのみ更新
907
                $sth = $conn->prepare('UPDATE dtb_member set password = :password, salt = :salt, update_date = current_timestamp WHERE login_id = :login_id;');
908
                $sth->execute([
909
                    ':password' => $password,
910
                    ':salt' => $salt,
911
                    ':login_id' => $data['login_id'],
912
                ]);
913
            } else {
914
                // 新しい管理者IDが入力されたらinsert
915
                $sth = $conn->prepare("INSERT INTO dtb_member (login_id, password, salt, work_id, authority_id, creator_id, sort_no, update_date, create_date,name,department,discriminator_type) VALUES (:login_id, :password , :salt , '1', '0', '1', '1', current_timestamp, current_timestamp,'管理者','EC-CUBE SHOP', 'member');");
916
                $sth->execute([
917
                    ':login_id' => $data['login_id'],
918
                    ':password' => $password,
919
                    ':salt' => $salt,
920
                ]);
921
            }
922
            $stmt = $conn->prepare('UPDATE dtb_base_info set
923
                shop_name = :shop_name,
924
                email01 = :admin_mail,
925
                email02 = :admin_mail,
926
                email03 = :admin_mail,
927
                email04 = :admin_mail,
928
                update_date = current_timestamp
929
            WHERE id = 1;');
930
            $stmt->execute([
931
                ':shop_name' => $data['shop_name'],
932
                ':admin_mail' => $data['email'],
933
            ]);
934
            $conn->commit();
935
        } catch (\Exception $e) {
936
            $conn->rollback();
937
            throw $e;
938
        }
939
    }
940
941
    public function migrate(Migration $migration)
942
    {
943
        try {
944
            // nullを渡すと最新バージョンまでマイグレートする
945
            $migration->migrate(null, false);
946
        } catch (MigrationException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
947
        }
948
    }
949
950
    /**
951
     * @param array $params
952
     * @param EntityManager $em
953
     *
954
     * @return array
955
     */
956
    public function createAppData($params, EntityManager $em)
957
    {
958
        $platform = $em->getConnection()->getDatabasePlatform()->getName();
959
        $version = $this->getDatabaseVersion($em);
960
        $data = [
961
            'site_url' => $params['http_url'],
962
            'shop_name' => $params['shop_name'],
963
            'cube_ver' => Constant::VERSION,
964
            'php_ver' => phpversion(),
965
            'db_ver' => $platform.' '.$version,
966
            'os_type' => php_uname(),
967
        ];
968
969
        return $data;
970
    }
971
972
    /**
973
     * @param array $params
974
     * @param EntityManager $em
975
     */
976
    protected function sendAppData($params, EntityManager $em)
977
    {
978
        try {
979
            $query = http_build_query($this->createAppData($params, $em));
980
            $header = [
981
                'Content-Type: application/x-www-form-urlencoded',
982
                'Content-Length: '.strlen($query),
983
            ];
984
            $context = stream_context_create(
985
                [
986
                    'http' => [
987
                        'method' => 'POST',
988
                        'header' => $header,
989
                        'content' => $query,
990
                    ],
991
                ]
992
            );
993
            file_get_contents('https://www.ec-cube.net/mall/use_site.php', false, $context);
994
        } catch (\Exception $e) {
995
            // 送信に失敗してもインストールは継続できるようにする
996
            log_error($e->getMessage());
997
        }
998
999
        return $this;
1000
    }
1001
1002
    /**
1003
     * @param EntityManager $em
1004
     *
1005
     * @return string
1006
     */
1007
    public function getDatabaseVersion(EntityManager $em)
1008
    {
1009
        $rsm = new \Doctrine\ORM\Query\ResultSetMapping();
1010
        $rsm->addScalarResult('server_version', 'server_version');
1011
1012
        $platform = $em->getConnection()->getDatabasePlatform()->getName();
1013
        switch ($platform) {
1014
            case 'sqlite':
1015
                $sql = 'SELECT sqlite_version() AS server_version';
1016
                break;
1017
1018
            case 'mysql':
1019
                $sql = 'SELECT version() AS server_version';
1020
                break;
1021
1022
            case 'pgsql':
1023
            default:
1024
                $sql = 'SHOW server_version';
1025
        }
1026
1027
        $version = $em->createNativeQuery($sql, $rsm)
1028
            ->getSingleScalarResult();
1029
1030
        return $version;
1031
    }
1032
1033
    /**
1034
     * @param string
1035
     *
1036
     * @return string
1037
     */
1038
    public function convertAdminAllowHosts($adminAllowHosts)
1039
    {
1040
        if (empty($adminAllowHosts)) {
1041
            return '[]';
1042
        }
1043
1044
        $adminAllowHosts = \json_encode(
1045
            \explode("\n", StringUtil::convertLineFeed($adminAllowHosts))
1046
        );
1047
1048
        return "'$adminAllowHosts'";
1049
    }
1050
1051
    /**
1052
     * @return bool
1053
     */
1054
    protected function isInstalled()
1055
    {
1056
        return self::DEFAULT_AUTH_MAGIC !== $this->getParameter('eccube_auth_magic');
1057
    }
1058
1059
    /**
1060
     * @return bool
1061
     */
1062
    protected function isInstallEnv()
1063
    {
1064
        $env = $this->getParameter('kernel.environment');
1065
1066
        if ($env === 'install' || $env === 'test') {
1067
            return true;
1068
        }
1069
1070
        return false;
1071
    }
1072
}
1073