Failed Conditions
Pull Request — 4.0 (#3593)
by chihiro
08:59
created

InstallController   F

Complexity

Total Complexity 139

Size/Duplication

Total Lines 940
Duplicated Lines 4.47 %

Coupling/Cohesion

Components 1
Dependencies 26

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 42
loc 940
rs 1.66
c 0
b 0
f 0
ccs 0
cts 431
cp 0
wmc 139
lcom 1
cbo 26

31 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A index() 0 10 2
A step1() 5 31 5
A step2() 0 22 5
B step3() 5 60 7
B step4() 0 38 7
B step5() 0 66 7
B complete() 5 45 8
A getSessionData() 0 4 1
A removeSessionData() 0 4 1
A setSessionData() 0 5 1
F checkModules() 0 43 20
A createConnection() 0 7 1
A createEntityManager() 0 11 1
B createDatabaseUrl() 14 36 9
B extractDatabaseUrl() 0 24 6
F createMailerUrl() 13 53 15
F extractMailerUrl() 0 56 17
A createMigration() 0 13 1
A dropTables() 0 7 1
A createTables() 0 6 1
A importCsv() 0 8 1
A insert() 0 53 4
A update() 0 45 3
A migrate() 0 8 2
A createAppData() 0 15 1
A sendAppData() 0 20 1
A getDatabaseVersion() 0 25 4
A convertAdminAllowHosts() 0 12 2
A isInstalled() 0 4 1
A isInstallEnv() 0 10 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like InstallController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use InstallController, and based on these observations, apply Extract Interface, too.

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\DBAL\Connection;
17
use Doctrine\DBAL\DriverManager;
18
use Doctrine\DBAL\Migrations\Configuration\Configuration;
19
use Doctrine\DBAL\Migrations\Migration;
20
use Doctrine\DBAL\Migrations\MigrationException;
21
use Doctrine\DBAL\Types\Type;
22
use Doctrine\ORM\EntityManager;
23
use Doctrine\ORM\Tools\SchemaTool;
24
use Doctrine\ORM\Tools\Setup;
25
use Eccube\Common\Constant;
26
use Eccube\Controller\AbstractController;
27
use Eccube\Form\Type\Install\Step1Type;
28
use Eccube\Form\Type\Install\Step3Type;
29
use Eccube\Form\Type\Install\Step4Type;
30
use Eccube\Form\Type\Install\Step5Type;
31
use Eccube\Security\Core\Encoder\PasswordEncoder;
32
use Eccube\Util\CacheUtil;
33
use Eccube\Util\StringUtil;
34
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
35
use Symfony\Component\Finder\Finder;
36
use Symfony\Component\HttpFoundation\Request;
37
use Symfony\Component\HttpFoundation\Session\SessionInterface;
38
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
39
use Symfony\Component\Routing\Annotation\Route;
40
41
class InstallController extends AbstractController
42
{
43
    /**
44
     * default value of auth magic
45
     */
46
    const DEFAULT_AUTH_MAGIC = '<change.me>';
47
48
    protected $requiredModules = [
49
        'pdo',
50
        'phar',
51
        'mbstring',
52
        'zlib',
53
        'ctype',
54
        'session',
55
        'JSON',
56
        'xml',
57
        'libxml',
58
        'OpenSSL',
59
        'zip',
60
        'cURL',
61
        'fileinfo',
62
        'intl',
63
    ];
64
65
    protected $recommendedModules = [
66
        'hash',
67
        'mcrypt',
68
    ];
69
70
    protected $writableDirs = [
71
        'app',
72
        'html',
73
        'var',
74
    ];
75
76
    /**
77
     * @var PasswordEncoder
78
     */
79
    protected $encoder;
80
81
    /**
82
     * @var CacheUtil
83
     */
84
    protected $cacheUtil;
85
86
    public function __construct(PasswordEncoder $encoder, CacheUtil $cacheUtil)
87
    {
88
        $this->encoder = $encoder;
89
        $this->cacheUtil = $cacheUtil;
90
    }
91
92
    /**
93
     * 最初からやり直す場合、SESSION情報をクリア.
94
     *
95
     * @Route("/install", name="install")
96
     *
97
     * @Template("index.twig")
98
     *
99
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
100
     */
101
    public function index()
102
    {
103
        if (!$this->isInstallEnv()) {
104
            throw new NotFoundHttpException();
105
        }
106
107
        $this->removeSessionData($this->session);
108
109
        return $this->redirectToRoute('install_step1');
110
    }
111
112
    /**
113
     * ようこそ.
114
     *
115
     * @Route("/install/step1", name="install_step1")
116
     * @Template("step1.twig")
117
     *
118
     * @param Request $request
119
     *
120
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
121
     */
122
    public function step1(Request $request)
123
    {
124
        if (!$this->isInstallEnv()) {
125
            throw new NotFoundHttpException();
126
        }
127
128
        $form = $this->formFactory
129
            ->createBuilder(Step1Type::class)
130
            ->getForm();
131
132
        $form->setData($this->getSessionData($this->session));
133
        $form->handleRequest($request);
134
135 View Code Duplication
        if ($form->isSubmitted() && $form->isValid()) {
136
            $this->setSessionData($this->session, $form->getData());
137
138
            return $this->redirectToRoute('install_step2');
139
        }
140
141
        $this->checkModules();
142
143
        $authmagic = $this->getParameter('eccube_auth_magic');
144
        if ($authmagic === self::DEFAULT_AUTH_MAGIC) {
145
            $authmagic = StringUtil::random(32);
146
        }
147
        $this->setSessionData($this->session, ['authmagic' => $authmagic]);
148
149
        return [
150
            'form' => $form->createView(),
151
        ];
152
    }
153
154
    /**
155
     * ディレクトリの書き込み権限をチェック.
156
     *
157
     * @Route("/install/step2", name="install_step2")
158
     * @Template("step2.twig")
159
     *
160
     * @return array
161
     */
162
    public function step2()
163
    {
164
        if (!$this->isInstallEnv()) {
165
            throw new NotFoundHttpException();
166
        }
167
168
        $protectedDirs = [];
169
        foreach ($this->writableDirs as $writableDir) {
170
            $targetDirs = Finder::create()
171
                ->in($this->getParameter('kernel.project_dir').'/'.$writableDir)
172
                ->directories();
173
            foreach ($targetDirs as $targetDir) {
174
                if (!is_writable($targetDir->getRealPath())) {
175
                    $protectedDirs[] = $targetDir;
176
                }
177
            }
178
        }
179
180
        return [
181
            'protectedDirs' => $protectedDirs,
182
        ];
183
    }
184
185
    /**
186
     * サイトの設定.
187
     *
188
     * @Route("/install/step3", name="install_step3")
189
     * @Template("step3.twig")
190
     *
191
     * @param Request $request
192
     *
193
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
194
     *
195
     * @throws \Doctrine\DBAL\DBALException
196
     * @throws \Exception
197
     */
198
    public function step3(Request $request)
199
    {
200
        if (!$this->isInstallEnv()) {
201
            throw new NotFoundHttpException();
202
        }
203
204
        $sessionData = $this->getSessionData($this->session);
205
206
        // 再インストールの場合は環境変数から復旧
207
        if ($this->isInstalled()) {
208
            // ショップ名/メールアドレス
209
            $conn = $this->entityManager->getConnection();
210
            $stmt = $conn->query('SELECT shop_name, email01 FROM dtb_base_info WHERE id = 1;');
211
            $row = $stmt->fetch();
212
            $sessionData['shop_name'] = $row['shop_name'];
213
            $sessionData['email'] = $row['email01'];
214
215
            $databaseUrl = $this->getParameter('eccube_database_url');
216
            $sessionData = array_merge($sessionData, $this->extractDatabaseUrl($databaseUrl));
217
218
            // 管理画面ルーティング
219
            $sessionData['admin_dir'] = $this->getParameter('eccube_admin_route');
220
221
            // 管理画面許可IP
222
            $sessionData['admin_allow_hosts'] = implode($this->getParameter('eccube_admin_allow_hosts'));
223
224
            // 強制SSL
225
            $sessionData['admin_force_ssl'] = $this->getParameter('eccube_force_ssl');
226
227
            // メール
228
            $mailerUrl = $this->getParameter('eccube_mailer_url');
229
            $sessionData = array_merge($sessionData, $this->extractMailerUrl($mailerUrl));
230
        } else {
231
            // 初期値設定
232
            if (!isset($sessionData['admin_allow_hosts'])) {
233
                $sessionData['admin_allow_hosts'] = '';
234
            }
235
            if (!isset($sessionData['smtp_host'])) {
236
                $sessionData = array_merge($sessionData, $this->extractMailerUrl('smtp://localhost:25'));
237
            }
238
        }
239
240
        $form = $this->formFactory
241
            ->createBuilder(Step3Type::class)
242
            ->getForm();
243
244
        $form->setData($sessionData);
245
        $form->handleRequest($request);
246
247 View Code Duplication
        if ($form->isSubmitted() && $form->isValid()) {
248
            $this->setSessionData($this->session, $form->getData());
249
250
            return $this->redirectToRoute('install_step4');
251
        }
252
253
        return [
254
            'form' => $form->createView(),
255
            'request' => $request,
256
        ];
257
    }
258
259
    /**
260
     * データベースの設定.
261
     *
262
     * @Route("/install/step4", name="install_step4")
263
     * @Template("step4.twig")
264
     *
265
     * @param Request $request
266
     *
267
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
268
     *
269
     * @throws \Exception
270
     */
271
    public function step4(Request $request)
272
    {
273
        if (!$this->isInstallEnv()) {
274
            throw new NotFoundHttpException();
275
        }
276
277
        $sessionData = $this->getSessionData($this->session);
278
279
        if (empty($sessionData['database'])) {
280
            // 再インストールの場合は環境変数から復旧.
281
            if ($this->isInstalled()) {
282
                $databaseUrl = $this->getParameter('eccube_database_url');
283
                $sessionData = array_merge($sessionData, $this->extractDatabaseUrl($databaseUrl));
284
            }
285
        }
286
287
        $form = $this->formFactory
288
            ->createBuilder(Step4Type::class)
289
            ->getForm();
290
291
        $form->setData($sessionData);
292
        $form->handleRequest($request);
293
294
        if ($form->isSubmitted() && $form->isValid()) {
295
            $data = $form->getData();
296
            if ($data['database'] === 'pdo_sqlite') {
297
                $data['database_name'] = '/%kernel.project_dir%/var/eccube.db';
298
            }
299
300
            $this->setSessionData($this->session, $data);
301
302
            return $this->redirectToRoute('install_step5');
303
        }
304
305
        return [
306
            'form' => $form->createView(),
307
        ];
308
    }
309
310
    /**
311
     * データベースの初期化.
312
     *
313
     * @Route("/install/step5", name="install_step5")
314
     * @Template("step5.twig")
315
     *
316
     * @param Request $request
317
     *
318
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
319
     *
320
     * @throws \Exception
321
     */
322
    public function step5(Request $request)
323
    {
324
        if (!$this->isInstallEnv()) {
325
            throw new NotFoundHttpException();
326
        }
327
328
        $form = $this->formFactory
329
            ->createBuilder(Step5Type::class)
330
            ->getForm();
331
332
        $sessionData = $this->getSessionData($this->session);
333
        $form->setData($sessionData);
334
        $form->handleRequest($request);
335
336
        if ($form->isSubmitted() && $form->isValid()) {
337
            $noUpdate = $form['no_update']->getData();
338
339
            $url = $this->createDatabaseUrl($sessionData);
340
            // for sqlite, resolve %kernel.project_dir% paramter.
341
            $url = $this->container->getParameterBag()->resolveValue($url);
0 ignored issues
show
Bug introduced by
The method getParameterBag() does not exist on Symfony\Component\Depend...tion\ContainerInterface. Did you maybe mean getParameter()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
342
343
            $conn = $this->createConnection(['url' => $url]);
344
            $em = $this->createEntityManager($conn);
345
            $migration = $this->createMigration($conn);
346
347
            if ($noUpdate) {
348
                $this->update($conn, [
349
                    'auth_magic' => $sessionData['authmagic'],
350
                    'login_id' => $sessionData['login_id'],
351
                    'login_pass' => $sessionData['login_pass'],
352
                    'shop_name' => $sessionData['shop_name'],
353
                    'email' => $sessionData['email'],
354
                ]);
355
            } else {
356
                $this->dropTables($em);
357
                $this->createTables($em);
358
                $this->importCsv($em);
359
                $this->migrate($migration);
360
                $this->insert($conn, [
361
                    'auth_magic' => $sessionData['authmagic'],
362
                    'login_id' => $sessionData['login_id'],
363
                    'login_pass' => $sessionData['login_pass'],
364
                    'shop_name' => $sessionData['shop_name'],
365
                    'email' => $sessionData['email'],
366
                ]);
367
            }
368
369
            if (isset($sessionData['agree']) && $sessionData['agree']) {
370
                $host = $request->getSchemeAndHttpHost();
371
                $basePath = $request->getBasePath();
372
                $params = [
373
                    'http_url' => $host.$basePath,
374
                    'shop_name' => $sessionData['shop_name'],
375
                ];
376
                $this->sendAppData($params, $em);
377
            }
378
            $version = $this->getDatabaseVersion($em);
379
            $this->setSessionData($this->session, ['database_version' => $version]);
380
381
            return $this->redirectToRoute('install_complete');
382
        }
383
384
        return [
385
            'form' => $form->createView(),
386
        ];
387
    }
388
389
    /**
390
     * インストール完了
391
     *
392
     * @Route("/install/complete", name="install_complete")
393
     * @Template("complete.twig")
394
     */
395
    public function complete(Request $request)
396
    {
397
        if (!$this->isInstallEnv()) {
398
            throw new NotFoundHttpException();
399
        }
400
401
        $sessionData = $this->getSessionData($this->session);
402
        $databaseUrl = $this->createDatabaseUrl($sessionData);
403
        $mailerUrl = $this->createMailerUrl($sessionData);
404
        $forceSSL = isset($sessionData['admin_force_ssl']) ? (bool) $sessionData['admin_force_ssl'] : false;
405 View Code Duplication
        if ($forceSSL === false) {
406
            $forceSSL = 'false';
407
        } elseif ($forceSSL === true) {
408
            $forceSSL = 'true';
409
        }
410
        $env = file_get_contents(__DIR__.'/../../../../.env.dist');
411
        $replacement = [
412
            'APP_ENV' => 'prod',
413
            'APP_DEBUG' => '0',
414
            'DATABASE_URL' => $databaseUrl,
415
            'MAILER_URL' => $mailerUrl,
416
            'ECCUBE_AUTH_MAGIC' => $sessionData['authmagic'],
417
            'DATABASE_SERVER_VERSION' => isset($sessionData['database_version']) ? $sessionData['database_version'] : '3',
418
            'ECCUBE_ADMIN_ALLOW_HOSTS' => $this->convertAdminAllowHosts($sessionData['admin_allow_hosts']),
419
            'ECCUBE_FORCE_SSL' => $forceSSL,
420
            'ECCUBE_ADMIN_ROUTE' => isset($sessionData['admin_dir']) ? $sessionData['admin_dir'] : 'admin',
421
        ];
422
423
        $env = StringUtil::replaceOrAddEnv($env, $replacement);
424
425
        if ($this->getParameter('kernel.environment') === 'install') {
426
            file_put_contents(__DIR__.'/../../../../.env', $env);
427
        }
428
        $host = $request->getSchemeAndHttpHost();
429
        $basePath = $request->getBasePath();
430
        $adminUrl = $host.$basePath.'/'.$replacement['ECCUBE_ADMIN_ROUTE'];
431
432
        $this->removeSessionData($this->session);
433
434
        $this->cacheUtil->clearCache('prod');
435
436
        return [
437
            'admin_url' => $adminUrl,
438
        ];
439
    }
440
441
    protected function getSessionData(SessionInterface $session)
442
    {
443
        return $session->get('eccube.session.install', []);
444
    }
445
446
    protected function removeSessionData(SessionInterface $session)
447
    {
448
        $session->remove('eccube.session.install');
449
    }
450
451
    protected function setSessionData(SessionInterface $session, $data = [])
452
    {
453
        $data = array_replace_recursive($this->getSessionData($session), $data);
454
        $session->set('eccube.session.install', $data);
455
    }
456
457
    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...
458
    {
459
        foreach ($this->requiredModules as $module) {
460
            if (!extension_loaded($module)) {
461
                $this->addDanger(trans('install.required_extension_disabled', ['%module%' => $module]), 'install');
462
            }
463
        }
464
        if (!extension_loaded('pdo_mysql') && !extension_loaded('pdo_pgsql')) {
465
            $this->addDanger(trans('install.required_database_extension_disabled'), 'install');
466
        }
467
        foreach ($this->recommendedModules as $module) {
468
            if (!extension_loaded($module)) {
469
                if ($module == 'mcrypt' && PHP_VERSION_ID >= 70100) {
470
                    //The mcrypt extension has been deprecated in PHP 7.1.x
471
                    //http://php.net/manual/en/migration71.deprecated.php
472
                    continue;
473
                }
474
                $this->addInfo(trans('install.recommend_extension_disabled', ['%module%' => $module]), 'install');
475
            }
476
        }
477
        if ('\\' === DIRECTORY_SEPARATOR) { // for Windows
478
            if (!extension_loaded('wincache')) {
479
                $this->addInfo(trans('install.recommend_extension_disabled', ['%module%' => 'wincache']), 'install');
480
            }
481
        } else {
482
            if (!extension_loaded('apc')) {
483
                $this->addInfo(trans('install.recommend_extension_disabled', ['%module%' => 'apc']), 'install');
484
            }
485
        }
486
        if (isset($_SERVER['SERVER_SOFTWARE']) && strpos('Apache', $_SERVER['SERVER_SOFTWARE']) !== false) {
487
            if (!function_exists('apache_get_modules')) {
488
                $this->addWarning(trans('install.mod_rewrite_unknown'), 'install');
489
            } elseif (!in_array('mod_rewrite', apache_get_modules())) {
490
                $this->addDanger(trans('install.mod_rewrite_disabled'), 'install');
491
            }
492
        } elseif (isset($_SERVER['SERVER_SOFTWARE']) && strpos('Microsoft-IIS',
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...
493
                $_SERVER['SERVER_SOFTWARE']) !== false
494
        ) {
495
            // iis
496
        } 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...
497
            // nginx
498
        }
499
    }
500
501
    protected function createConnection(array $params)
502
    {
503
        $conn = DriverManager::getConnection($params);
504
        $conn->ping();
505
506
        return $conn;
507
    }
508
509
    protected function createEntityManager(Connection $conn)
510
    {
511
        $paths = [
512
            $this->getParameter('kernel.project_dir').'/src/Eccube/Entity',
513
            $this->getParameter('kernel.project_dir').'/app/Customize/Entity',
514
        ];
515
        $config = Setup::createAnnotationMetadataConfiguration($paths, true, null, null, false);
516
        $em = EntityManager::create($conn, $config);
517
518
        return $em;
519
    }
520
521
    /**
522
     * @param array $params
523
     *
524
     * @return string
525
     */
526
    public function createDatabaseUrl(array $params)
527
    {
528
        if (!isset($params['database'])) {
529
            return null;
530
        }
531
532
        $url = '';
533
        switch ($params['database']) {
534
            case 'pdo_sqlite':
535
                $url = 'sqlite://'.$params['database_name'];
536
                break;
537
538
            case 'pdo_mysql':
539
            case 'pdo_pgsql':
540
                $url = str_replace('pdo_', '', $params['database']);
541
                $url .= '://';
542 View Code Duplication
                if (isset($params['database_user'])) {
543
                    $url .= $params['database_user'];
544
                    if (isset($params['database_password'])) {
545
                        $url .= ':'.$params['database_password'];
546
                    }
547
                    $url .= '@';
548
                }
549 View Code Duplication
                if (isset($params['database_host'])) {
550
                    $url .= $params['database_host'];
551
                    if (isset($params['database_port'])) {
552
                        $url .= ':'.$params['database_port'];
553
                    }
554
                    $url .= '/';
555
                }
556
                $url .= $params['database_name'];
557
                break;
558
        }
559
560
        return $url;
561
    }
562
563
    /**
564
     * @param string $url
565
     *
566
     * @return array
567
     */
568
    public function extractDatabaseUrl($url)
569
    {
570
        if (preg_match('|^sqlite://(.*)$|', $url, $matches)) {
571
            return [
572
                'database' => 'pdo_sqlite',
573
                'database_name' => $matches[1],
574
            ];
575
        }
576
577
        $parsed = parse_url($url);
578
579
        if ($parsed === false) {
580
            throw new \Exception('Malformed parameter "url".');
581
        }
582
583
        return [
584
            'database' => 'pdo_'.$parsed['scheme'],
585
            'database_name' => ltrim($parsed['path'], '/'),
586
            'database_host' => $parsed['host'],
587
            'database_port' => isset($parsed['port']) ? $parsed['port'] : null,
588
            'database_user' => isset($parsed['user']) ? $parsed['user'] : null,
589
            'database_password' => isset($parsed['pass']) ? $parsed['pass'] : null,
590
        ];
591
    }
592
593
    /**
594
     * @param array $params
595
     *
596
     * @return string
597
     *
598
     * @see https://github.com/symfony/swiftmailer-bundle/blob/9728097df87e76e2db71fc41fd7d211c06daea3e/DependencyInjection/SwiftmailerTransportFactory.php#L80-L142
599
     */
600
    public function createMailerUrl(array $params)
601
    {
602
        $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...
603
        if (isset($params['transport'])) {
604
            $url = $params['transport'].'://';
605
        } else {
606
            $url = 'smtp://';
607
        }
608 View Code Duplication
        if (isset($params['smtp_username'])) {
609
            $url .= $params['smtp_username'];
610
            if (isset($params['smtp_password'])) {
611
                $url .= ':'.$params['smtp_password'];
612
            }
613
            $url .= '@';
614
        }
615
616
        $queryStrings = [];
617
        if (isset($params['encryption'])) {
618
            $queryStrings['encryption'] = $params['encryption'];
619
            if ($params['encryption'] === 'ssl' && !isset($params['smtp_port'])) {
620
                $params['smtp_port'] = 465;
621
            }
622
        }
623
        if (isset($params['auth_mode'])) {
624
            $queryStrings['auth_mode'] = $params['auth_mode'];
625
        } else {
626
            if (isset($params['smtp_username'])) {
627
                $queryStrings['auth_mode'] = 'plain';
628
            }
629
        }
630
        ksort($queryStrings, SORT_STRING);
631
632 View Code Duplication
        if (isset($params['smtp_host'])) {
633
            $url .= $params['smtp_host'];
634
            if (isset($params['smtp_port'])) {
635
                $url .= ':'.$params['smtp_port'];
636
            }
637
        }
638
639
        if (isset($params['smtp_username']) || array_values($queryStrings)) {
640
            $url .= '?';
641
            $i = count($queryStrings);
642
            foreach ($queryStrings as $key => $value) {
643
                $url .= $key.'='.$value;
644
                if ($i > 1) {
645
                    $url .= '&';
646
                }
647
                $i--;
648
            }
649
        }
650
651
        return $url;
652
    }
653
654
    /**
655
     * @param string $url
656
     *
657
     * @return array
658
     */
659
    public function extractMailerUrl($url)
660
    {
661
        $options = [
662
            'transport' => null,
663
            'smtp_username' => null,
664
            'smtp_password' => null,
665
            'smtp_host' => null,
666
            'smtp_port' => null,
667
            'encryption' => null,
668
            'auth_mode' => null,
669
        ];
670
671
        if ($url) {
672
            $parts = parse_url($url);
673
            if (isset($parts['scheme'])) {
674
                $options['transport'] = $parts['scheme'];
675
            }
676
            if (isset($parts['user'])) {
677
                $options['smtp_username'] = $parts['user'];
678
            }
679
            if (isset($parts['pass'])) {
680
                $options['smtp_password'] = $parts['pass'];
681
            }
682
            if (isset($parts['host'])) {
683
                $options['smtp_host'] = $parts['host'];
684
            }
685
            if (isset($parts['port'])) {
686
                $options['smtp_port'] = $parts['port'];
687
            }
688
            if (isset($parts['query'])) {
689
                parse_str($parts['query'], $query);
690
                foreach (array_keys($options) as $key) {
691
                    if (isset($query[$key]) && $query[$key] != '') {
692
                        $options[$key] = $query[$key];
693
                    }
694
                }
695
            }
696
        }
697
        if (!isset($options['transport'])) {
698
            $options['transport'] = 'smtp';
699
        } elseif ('gmail' === $options['transport']) {
700
            $options['encryption'] = 'ssl';
701
            $options['auth_mode'] = 'login';
702
            $options['smtp_host'] = 'smtp.gmail.com';
703
            $options['transport'] = 'smtp';
704
        }
705
        if (!isset($options['smtp_port'])) {
706
            $options['smtp_port'] = 'ssl' === $options['encryption'] ? 465 : 25;
707
        }
708
        if (isset($options['smtp_username']) && !isset($options['auth_mode'])) {
709
            $options['auth_mode'] = 'plain';
710
        }
711
        ksort($options, SORT_STRING);
712
713
        return $options;
714
    }
715
716
    protected function createMigration(Connection $conn)
717
    {
718
        $config = new Configuration($conn);
719
        $config->setMigrationsNamespace('DoctrineMigrations');
720
        $migrationDir = $this->getParameter('kernel.project_dir').'/src/Eccube/Resource/doctrine/migration';
721
        $config->setMigrationsDirectory($migrationDir);
722
        $config->registerMigrationsFromDirectory($migrationDir);
723
724
        $migration = new Migration($config);
725
        $migration->setNoMigrationException(true);
726
727
        return $migration;
728
    }
729
730
    protected function dropTables(EntityManager $em)
731
    {
732
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
733
        $schemaTool = new SchemaTool($em);
734
        $schemaTool->dropSchema($metadatas);
735
        $em->getConnection()->executeQuery('DROP TABLE IF EXISTS doctrine_migration_versions');
736
    }
737
738
    protected function createTables(EntityManager $em)
739
    {
740
        $metadatas = $em->getMetadataFactory()->getAllMetadata();
741
        $schemaTool = new SchemaTool($em);
742
        $schemaTool->createSchema($metadatas);
743
    }
744
745
    protected function importCsv(EntityManager $em)
746
    {
747
        $loader = new \Eccube\Doctrine\Common\CsvDataFixtures\Loader();
748
        $loader->loadFromDirectory($this->getParameter('kernel.project_dir').'/src/Eccube/Resource/doctrine/import_csv');
749
        $executer = new \Eccube\Doctrine\Common\CsvDataFixtures\Executor\DbalExecutor($em);
750
        $fixtures = $loader->getFixtures();
751
        $executer->execute($fixtures);
752
    }
753
754
    protected function insert(Connection $conn, array $data)
755
    {
756
        $conn->beginTransaction();
757
        try {
758
            $salt = StringUtil::random(32);
759
            $this->encoder->setAuthMagic($data['auth_magic']);
760
            $password = $this->encoder->encodePassword($data['login_pass'], $salt);
761
762
            $id = ('postgresql' === $conn->getDatabasePlatform()->getName())
763
                ? $conn->fetchColumn("select nextval('dtb_base_info_id_seq')")
764
                : null;
765
766
            $conn->insert('dtb_base_info', [
767
                'id' => $id,
768
                'shop_name' => $data['shop_name'],
769
                'email01' => $data['email'],
770
                'email02' => $data['email'],
771
                'email03' => $data['email'],
772
                'email04' => $data['email'],
773
                'update_date' => new \DateTime(),
774
                'discriminator_type' => 'baseinfo',
775
            ], [
776
                'update_date' => \Doctrine\DBAL\Types\Type::DATETIME,
777
            ]);
778
779
            $member_id = ('postgresql' === $conn->getDatabasePlatform()->getName())
780
                ? $conn->fetchColumn("select nextval('dtb_member_id_seq')")
781
                : null;
782
783
            $conn->insert('dtb_member', [
784
                'id' => $member_id,
785
                'login_id' => $data['login_id'],
786
                'password' => $password,
787
                'salt' => $salt,
788
                'work_id' => 1,
789
                'authority_id' => 0,
790
                'creator_id' => 1,
791
                'sort_no' => 1,
792
                'update_date' => new \DateTime(),
793
                'create_date' => new \DateTime(),
794
                'name' => trans('install.member_name'),
795
                'department' => $data['shop_name'],
796
                'discriminator_type' => 'member',
797
            ], [
798
                'update_date' => Type::DATETIME,
799
                'create_date' => Type::DATETIME,
800
            ]);
801
            $conn->commit();
802
        } catch (\Exception $e) {
803
            $conn->rollback();
804
            throw $e;
805
        }
806
    }
807
808
    protected function update(Connection $conn, array $data)
809
    {
810
        $conn->beginTransaction();
811
        try {
812
            $salt = StringUtil::random(32);
813
            $stmt = $conn->prepare('SELECT id FROM dtb_member WHERE login_id = :login_id;');
814
            $stmt->execute([':login_id' => $data['login_id']]);
815
            $row = $stmt->fetch();
816
            $this->encoder->setAuthMagic($data['auth_magic']);
817
            $password = $this->encoder->encodePassword($data['login_pass'], $salt);
818
            if ($row) {
819
                // 同一の管理者IDであればパスワードのみ更新
820
                $sth = $conn->prepare('UPDATE dtb_member set password = :password, salt = :salt, update_date = current_timestamp WHERE login_id = :login_id;');
821
                $sth->execute([
822
                    ':password' => $password,
823
                    ':salt' => $salt,
824
                    ':login_id' => $data['login_id'],
825
                ]);
826
            } else {
827
                // 新しい管理者IDが入力されたらinsert
828
                $sth = $conn->prepare("INSERT INTO dtb_member (login_id, password, salt, work, del_flg, authority, creator_id, sort_no, update_date, create_date,name,department,discriminator_type) VALUES (:login_id, :password , :salt , '1', '0', '0', '1', '1', current_timestamp, current_timestamp,'管理者','EC-CUBE SHOP', 'member');");
829
                $sth->execute([
830
                    ':login_id' => $data['login_id'],
831
                    ':password' => $password,
832
                    ':salt' => $salt,
833
                ]);
834
            }
835
            $stmt = $conn->prepare('UPDATE dtb_base_info set
836
                shop_name = :shop_name,
837
                email01 = :admin_mail,
838
                email02 = :admin_mail,
839
                email03 = :admin_mail,
840
                email04 = :admin_mail,
841
                update_date = current_timestamp
842
            WHERE id = 1;');
843
            $stmt->execute([
844
                ':shop_name' => $data['shop_name'],
845
                ':admin_mail' => $data['email'],
846
            ]);
847
            $conn->commit();
848
        } catch (\Exception $e) {
849
            $conn->rollback();
850
            throw $e;
851
        }
852
    }
853
854
    public function migrate(Migration $migration)
855
    {
856
        try {
857
            // nullを渡すと最新バージョンまでマイグレートする
858
            $migration->migrate(null, false);
859
        } catch (MigrationException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
860
        }
861
    }
862
863
    /**
864
     * @param array $params
865
     * @param EntityManager $em
866
     *
867
     * @return array
868
     */
869
    public function createAppData($params, EntityManager $em)
870
    {
871
        $platform = $em->getConnection()->getDatabasePlatform()->getName();
872
        $version = $this->getDatabaseVersion($em);
873
        $data = [
874
            'site_url' => $params['http_url'],
875
            'shop_name' => $params['shop_name'],
876
            'cube_ver' => Constant::VERSION,
877
            'php_ver' => phpversion(),
878
            'db_ver' => $platform.' '.$version,
879
            'os_type' => php_uname(),
880
        ];
881
882
        return $data;
883
    }
884
885
    /**
886
     * @param array $params
887
     * @param EntityManager $em
888
     */
889
    protected function sendAppData($params, EntityManager $em)
890
    {
891
        $query = http_build_query($this->createAppData($params, $em));
892
        $header = [
893
            'Content-Type: application/x-www-form-urlencoded',
894
            'Content-Length: '.strlen($query),
895
        ];
896
        $context = stream_context_create(
897
            [
898
                'http' => [
899
                    'method' => 'POST',
900
                    'header' => $header,
901
                    'content' => $query,
902
                ],
903
            ]
904
        );
905
        file_get_contents('http://www.ec-cube.net/mall/use_site.php', false, $context);
906
907
        return $this;
908
    }
909
910
    /**
911
     * @param EntityManager $em
912
     *
913
     * @return string
914
     */
915
    public function getDatabaseVersion(EntityManager $em)
916
    {
917
        $rsm = new \Doctrine\ORM\Query\ResultSetMapping();
918
        $rsm->addScalarResult('server_version', 'server_version');
919
920
        $platform = $em->getConnection()->getDatabasePlatform()->getName();
921
        switch ($platform) {
922
            case 'sqlite':
923
                $sql = 'SELECT sqlite_version() AS server_version';
924
                break;
925
926
            case 'mysql':
927
                $sql = 'SELECT version() AS server_version';
928
                break;
929
930
            case 'pgsql':
931
            default:
932
                $sql = 'SHOW server_version';
933
        }
934
935
        $version = $em->createNativeQuery($sql, $rsm)
936
            ->getSingleScalarResult();
937
938
        return $version;
939
    }
940
941
    /**
942
     * @param string
943
     *
944
     * @return string
945
     */
946
    public function convertAdminAllowHosts($adminAllowHosts)
947
    {
948
        if (empty($adminAllowHosts)) {
949
            return '[]';
950
        }
951
952
        $adminAllowHosts = \json_encode(
953
            \explode("\n", StringUtil::convertLineFeed($adminAllowHosts))
954
        );
955
956
        return "'$adminAllowHosts'";
957
    }
958
959
    /**
960
     * @return bool
961
     */
962
    protected function isInstalled()
963
    {
964
        return self::DEFAULT_AUTH_MAGIC !== $this->getParameter('eccube_auth_magic');
965
    }
966
967
    /**
968
     * @return bool
969
     */
970
    protected function isInstallEnv()
971
    {
972
        $env = $this->getParameter('kernel.environment');
973
974
        if ($env === 'install' || $env === 'test') {
975
            return true;
976
        }
977
978
        return false;
979
    }
980
}
981