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