Completed
Push — 4.0 ( 87d096...bcc1be )
by Kiyotaka
05:44 queued 11s
created

src/Eccube/DependencyInjection/EccubeExtension.php (2 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) EC-CUBE CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.ec-cube.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\DependencyInjection;
15
16
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Configuration as DoctrineBundleConfiguration;
17
use Doctrine\DBAL\Connection;
18
use Doctrine\DBAL\DriverManager;
19
use Symfony\Component\DependencyInjection\ContainerBuilder;
20
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
21
use Symfony\Component\Finder\Finder;
22
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
23
24
class EccubeExtension extends Extension implements PrependExtensionInterface
25
{
26
    /**
27
     * Loads a specific configuration.
28
     *
29
     * @throws \InvalidArgumentException When provided tag is not defined in this extension
30
     */
31
    public function load(array $configs, ContainerBuilder $container)
32
    {
33
    }
34
35
    /**
36
     * Allow an extension to prepend the extension configurations.
37
     */
38 1
    public function prepend(ContainerBuilder $container)
39
    {
40 1
        // FrameworkBundleの設定を動的に変更する.
41 1
        $this->configureFramework($container);
42
43 1
        // プラグインの有効無効判定および初期化を行う.
44
        $this->configurePlugins($container);
45
    }
46 1
47
    protected function configureFramework(ContainerBuilder $container)
48
    {
49 1
        // SSL強制時は, cookie_secureをtrueにする
50
        $forceSSL = $container->resolveEnvPlaceholders('%env(ECCUBE_FORCE_SSL)%', true);
0 ignored issues
show
true is of type boolean, but the function expects a string|object<Symfony\Co...ncyInjection\true>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
51
        // envから取得した内容が文字列のため, booleanに変換
52 View Code Duplication
        if ('true' === $forceSSL) {
53 1
            $forceSSL = true;
54
        } elseif ('false' === $forceSSL) {
55
            $forceSSL = false;
56 1
        }
57 1
58
        // framework.yamlでは制御できないため, ここで定義する.
59
        $container->prependExtensionConfig('framework', [
60
            'session' => [
61 1
                'cookie_secure' => $forceSSL,
62 1
            ],
63
        ]);
64 1
65
        // SSL強制時は, httpsのみにアクセス制限する
66
        $accessControl = [
67
          ['path' => '^/%eccube_admin_route%/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
68 1
          ['path' => '^/%eccube_admin_route%/', 'roles' => 'ROLE_ADMIN'],
69 1
          ['path' => '^/mypage/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
70
          ['path' => '^/mypage/withdraw_complete', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
71 1
          ['path' => '^/mypage/change', 'roles' => 'IS_AUTHENTICATED_FULLY'],
72 1
          ['path' => '^/mypage/', 'roles' => 'ROLE_USER'],
73
        ];
74
        if ($forceSSL) {
75
            foreach ($accessControl as &$control) {
76
                $control['requires_channel'] = 'https';
77
            }
78 1
        }
79 1
80 1
        // security.ymlでは制御できないため, ここで定義する.
81 1
        $container->prependExtensionConfig('security', [
82
          'access_control' => $accessControl,
83
        ]);
84
    }
85
86 1
    protected function configurePlugins(ContainerBuilder $container)
87 1
    {
88
        $pluginDir = $container->getParameter('kernel.project_dir').'/app/Plugin';
89 1
        $pluginDirs = $this->getPluginDirectories($pluginDir);
90 1
91 1
        $container->setParameter('eccube.plugins.enabled', []);
92
        // ファイル設置のみの場合は, 無効なプラグインとみなす.
93
        // DB接続後, 有効無効の判定を行う.
94
        $container->setParameter('eccube.plugins.disabled', $pluginDirs);
95
96
        // doctrine.yml, または他のprependで差し込まれたdoctrineの設定値を取得する.
97 1
        $configs = $container->getExtensionConfig('doctrine');
98
99 1
        // $configsは, env変数(%env(xxx)%)やパラメータ変数(%xxx.xxx%)がまだ解決されていないため, resolveEnvPlaceholders()で解決する
100
        // @see https://github.com/symfony/symfony/issues/22456
101 1
        $configs = $container->resolveEnvPlaceholders($configs, true);
0 ignored issues
show
true is of type boolean, but the function expects a string|object<Symfony\Co...ncyInjection\true>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
102
103
        // doctrine bundleのconfigurationで設定値を正規化する.
104
        $configuration = new DoctrineBundleConfiguration($container->getParameter('kernel.debug'));
105
        $config = $this->processConfiguration($configuration, $configs);
106
107
        // prependのタイミングではコンテナのインスタンスは利用できない.
108 1
        // 直接dbalのconnectionを生成し, dbアクセスを行う.
109
        $params = $config['dbal']['connections'][$config['dbal']['default_connection']];
110
        // ContainerInterface::resolveEnvPlaceholders() で取得した DATABASE_URL は
111
        // % がエスケープされているため、環境変数から取得し直す
112
        $params['url'] = env('DATABASE_URL');
113
        $conn = DriverManager::getConnection($params);
114
115
        if (!$this->isConnected($conn)) {
116
            return;
117
        }
118 1
119
        $stmt = $conn->query('select * from dtb_plugin');
120 1
        $plugins = $stmt->fetchAll();
121
122 1
        $enabled = [];
123
        foreach ($plugins as $plugin) {
124
            if ($plugin['enabled']) {
125
                $enabled[] = $plugin['code'];
126
            }
127
        }
128
129 1
        $disabled = [];
130
        foreach ($pluginDirs as $dir) {
131
            if (!in_array($dir, $enabled)) {
132
                $disabled[] = $dir;
133
            }
134
        }
135
136
        // 他で使いまわすため, パラメータで保持しておく.
137
        $container->setParameter('eccube.plugins.enabled', $enabled);
138 1
        $container->setParameter('eccube.plugins.disabled', $disabled);
139
140
        $pluginDir = $container->getParameter('kernel.project_dir').'/app/Plugin';
141 1
        $this->configureTwigPaths($container, $enabled, $pluginDir);
142 1
        $this->configureTranslations($container, $enabled, $pluginDir);
143
    }
144
145
    /**
146
     * @param string $pluginDir
147
     */
148 1 View Code Duplication
    protected function configureTwigPaths(ContainerBuilder $container, $enabled, $pluginDir)
149 1
    {
150 1
        $paths = [];
151 1
152 1
        foreach ($enabled as $code) {
153 1
            $dir = $pluginDir.'/'.$code.'/Resource/template';
154
            if (file_exists($dir)) {
155
                $paths[$dir] = $code;
156 1
            }
157
        }
158
159
        if (!empty($paths)) {
160
            $container->prependExtensionConfig('twig', [
161
                'paths' => $paths,
162 1
            ]);
163
        }
164 1
    }
165 1
166 1
    /**
167 1
     * @param string $pluginDir
168 1
     */
169 View Code Duplication
    protected function configureTranslations(ContainerBuilder $container, $enabled, $pluginDir)
170 1
    {
171 1
        $paths = [];
172 1
173
        foreach ($enabled as $code) {
174
            $dir = $pluginDir.'/'.$code.'/Resource/locale';
175 1
            if (file_exists($dir)) {
176
                $paths[] = $dir;
177
            }
178
        }
179
180
        if (!empty($paths)) {
181
            $container->prependExtensionConfig('framework', [
182
                'translator' => [
183
                    'paths' => $paths,
184
                ],
185
            ]);
186
        }
187
    }
188
189
    protected function isConnected(Connection $conn)
190
    {
191
        try {
192
            if (!$conn->ping()) {
193
                return false;
194
            }
195
        } catch (\Exception $e) {
196
            return false;
197
        }
198
199
        $sm = $conn->getSchemaManager();
200
        $tables = array_filter(
201
            $sm->listTables(),
202
            function ($table) {
203
                return $table->getName() === 'dtb_plugin';
204
            }
205
        );
206
207
        return empty($tables) ? false : true;
208
    }
209
210
    /**
211
     * @param string $pluginDir
212
     */
213
    protected function getPluginDirectories($pluginDir)
214
    {
215
        $finder = (new Finder())
216
            ->in($pluginDir)
217
            ->sortByName()
218
            ->depth(0)
219
            ->directories();
220
221
        $dirs = [];
222
        foreach ($finder as $dir) {
223
            $dirs[] = $dir->getBaseName();
224
        }
225
226
        return $dirs;
227
    }
228
}
229