PageRenderTime 24ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Eccube/Controller/Admin/Store/TemplateController.php

https://bitbucket.org/hkd1123/ecq-docker
PHP | 317 lines | 195 code | 60 blank | 62 comment | 18 complexity | 395a01e2327c2ea63293b2cfc7a64254 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /*
  3. * This file is part of EC-CUBE
  4. *
  5. * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
  6. *
  7. * http://www.lockon.co.jp/
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. */
  23. namespace Eccube\Controller\Admin\Store;
  24. use Eccube\Application;
  25. use Eccube\Controller\AbstractController;
  26. use Eccube\Entity\Master\DeviceType;
  27. use Eccube\Util\Str;
  28. use Symfony\Component\Filesystem\Filesystem;
  29. use Symfony\Component\Finder\Finder;
  30. use Symfony\Component\Form\FormError;
  31. use Symfony\Component\HttpFoundation\Request;
  32. use Symfony\Component\HttpFoundation\Response;
  33. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  34. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  35. use Symfony\Component\Yaml\Yaml;
  36. class TemplateController extends AbstractController
  37. {
  38. /**
  39. * テンプレート一覧画面
  40. *
  41. * @param Application $app
  42. * @param Request $request
  43. */
  44. public function index(Application $app, Request $request)
  45. {
  46. $DeviceType = $app['eccube.repository.master.device_type']
  47. ->find(DeviceType::DEVICE_TYPE_PC);
  48. $Templates = $app['eccube.repository.template']
  49. ->findBy(array('DeviceType' => $DeviceType));
  50. $form = $app->form()
  51. ->add('selected', 'hidden')
  52. ->getForm();
  53. if ('POST' === $request->getMethod()) {
  54. $form->handleRequest($request);
  55. if ($form->isValid()) {
  56. $Template = $app['eccube.repository.template']
  57. ->find($form['selected']->getData());
  58. // path.(yml|php)の再構築
  59. $file = $app['config']['root_dir'].'/app/config/eccube/path';
  60. if (file_exists($file.'.php')) {
  61. $config = require $file.'.php';
  62. } elseif (file_exists($file.'.yml')) {
  63. $config = Yaml::parse(file_get_contents($file.'.yml'));
  64. }
  65. $templateCode = $Template->getCode();
  66. $config['template_code'] = $templateCode;
  67. $config['template_realdir'] = $config['root_dir'].'/app/template/'.$templateCode;
  68. $config['template_html_realdir'] = $config['public_path_realdir'].'/template/'.$templateCode;
  69. $config['front_urlpath'] = $config['root_urlpath'].RELATIVE_PUBLIC_DIR_PATH.'/template/'.$templateCode;
  70. $config['block_realdir'] =$config['template_realdir'].'/Block';
  71. if (file_exists($file.'.php')) {
  72. file_put_contents($file.'.php', sprintf('<?php return %s', var_export($config, true)).';');
  73. }
  74. if (file_exists($file.'.yml')) {
  75. file_put_contents($file.'.yml', Yaml::dump($config));
  76. }
  77. $app->addSuccess('admin.content.template.save.complete', 'admin');
  78. return $app->redirect($app->url('admin_store_template'));
  79. }
  80. }
  81. return $app->render('Store/template.twig', array(
  82. 'form' => $form->createView(),
  83. 'Templates' => $Templates,
  84. ));
  85. }
  86. /**
  87. * テンプレート一覧からのダウンロード
  88. *
  89. * @param Application $app
  90. * @param Request $request
  91. * @param $id
  92. */
  93. public function download(Application $app, Request $request, $id)
  94. {
  95. /** @var $Template \Eccube\Entity\Template */
  96. $Template = $app['eccube.repository.template']->find($id);
  97. if (!$Template) {
  98. throw new NotFoundHttpException();
  99. }
  100. // 該当テンプレートのディレクトリ
  101. $config = $app['config'];
  102. $templateCode = $Template->getCode();
  103. $targetRealDir = $config['root_dir'] . '/app/template/' . $templateCode;
  104. $targetHtmlRealDir = $config['root_dir'] . '/html/template/' . $templateCode;
  105. // 一時ディレクトリ
  106. $uniqId = sha1(Str::random(32));
  107. $tmpDir = $config['template_temp_realdir'] . '/' . $uniqId;
  108. $appDir = $tmpDir . '/app';
  109. $htmlDir = $tmpDir . '/html';
  110. // ファイル名
  111. $tarFile = $config['template_temp_realdir'] . '/' . $uniqId . '.tar';
  112. $tarGzFile = $tarFile . '.gz';
  113. $downloadFileName = $Template->getCode() . '.tar.gz';
  114. // 該当テンプレートを一時ディレクトリへコピーする.
  115. $fs = new Filesystem();
  116. $fs->mkdir(array($appDir, $htmlDir));
  117. $fs->mirror($targetRealDir, $appDir);
  118. $fs->mirror($targetHtmlRealDir, $htmlDir);
  119. // tar.gzファイルに圧縮する.
  120. $phar = new \PharData($tarFile);
  121. $phar->buildFromDirectory($tmpDir);
  122. // appディレクトリがない場合は, 空ディレクトリを追加
  123. // @see https://github.com/EC-CUBE/ec-cube/issues/742
  124. if (empty($phar['app'])) {
  125. $phar->addEmptyDir('app');
  126. }
  127. $phar->compress(\Phar::GZ);
  128. // ダウンロード完了後にファイルを削除する.
  129. // http://stackoverflow.com/questions/15238897/removing-file-after-delivering-response-with-silex-symfony
  130. $app->finish(function (Request $request, Response $response, \Silex\Application $app) use (
  131. $tmpDir,
  132. $tarFile,
  133. $tarGzFile
  134. ) {
  135. $app['monolog']->addDebug('remove temp file: ' . $tmpDir);
  136. $app['monolog']->addDebug('remove temp file: ' . $tarFile);
  137. $app['monolog']->addDebug('remove temp file: ' . $tarGzFile);
  138. $fs = new Filesystem();
  139. $fs->remove($tmpDir);
  140. $fs->remove($tarFile);
  141. $fs->remove($tarGzFile);
  142. });
  143. return $app
  144. ->sendFile($tarGzFile)
  145. ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $downloadFileName);
  146. }
  147. public function delete(Application $app, Request $request, $id)
  148. {
  149. $this->isTokenValid($app);
  150. /** @var $Template \Eccube\Entity\Template */
  151. $Template = $app['eccube.repository.template']->find($id);
  152. if (!$Template) {
  153. $app->deleteMessage();
  154. return $app->redirect($app->url('admin_store_template'));
  155. }
  156. // デフォルトテンプレート
  157. if ($Template->isDefaultTemplate()) {
  158. $app->addError('admin.content.template.delete.default.error', 'admin');
  159. return $app->redirect($app->url('admin_store_template'));
  160. }
  161. // 設定中のテンプレート
  162. if ($app['config']['template_code'] === $Template->getCode()) {
  163. $app->addError('admin.content.template.delete.current.error', 'admin');
  164. return $app->redirect($app->url('admin_store_template'));
  165. }
  166. // テンプレートディレクトリの削除
  167. $config = $app['config'];
  168. $templateCode = $Template->getCode();
  169. $targetRealDir = $config['root_dir'] . '/app/template/' . $templateCode;
  170. $targetHtmlRealDir = $config['root_dir'] . '/html/template/' . $templateCode;
  171. $fs = new Filesystem();
  172. $fs->remove($targetRealDir);
  173. $fs->remove($targetHtmlRealDir);
  174. // テーブルからも削除
  175. $app['orm.em']->remove($Template);
  176. $app['orm.em']->flush();
  177. $app->addSuccess('admin.content.template.delete.complete', 'admin');
  178. return $app->redirect($app->url('admin_store_template'));
  179. }
  180. public function add(Application $app, Request $request)
  181. {
  182. /** @var $Template \Eccube\Entity\Template */
  183. $Template = new \Eccube\Entity\Template();
  184. $form = $app['form.factory']
  185. ->createBuilder('admin_template', $Template)
  186. ->getForm();
  187. if ('POST' === $request->getMethod()) {
  188. $form->handleRequest($request);
  189. if ($form->isValid()) {
  190. /** @var $Template \Eccube\Entity\Template */
  191. $tem = $app['eccube.repository.template']
  192. ->findByCode($form['code']->getData());
  193. // テンプレートコードの重複チェック.
  194. if ($tem) {
  195. $form['code']->addError(new FormError('すでに登録されているテンプレートコードです。'));
  196. return false;
  197. }
  198. // 該当テンプレートのディレクトリ
  199. $config = $app['config'];
  200. $templateCode = $Template->getCode();
  201. $targetRealDir = $config['root_dir'] . '/app/template/' . $templateCode;
  202. $targetHtmlRealDir = $config['root_dir'] . '/html/template/' . $templateCode;
  203. // 一時ディレクトリ
  204. $uniqId = sha1(Str::random(32));
  205. $tmpDir = $config['template_temp_realdir'] . '/' . $uniqId;
  206. $appDir = $tmpDir . '/app';
  207. $htmlDir = $tmpDir . '/html';
  208. $formFile = $form['file']->getData();
  209. // ファイル名
  210. $archive = $templateCode . '.' . $formFile->getClientOriginalExtension();
  211. // ファイルを一時ディレクトリへ移動.
  212. $formFile->move($tmpDir, $archive);
  213. // 一時ディレクトリへ解凍する.
  214. try {
  215. if ($formFile->getClientOriginalExtension() == 'zip') {
  216. $zip = new \ZipArchive();
  217. $zip->open($tmpDir . '/' . $archive);
  218. $zip->extractTo($tmpDir);
  219. $zip->close();
  220. } else {
  221. $phar = new \PharData($tmpDir . '/' . $archive);
  222. $phar->extractTo($tmpDir, null, true);
  223. }
  224. } catch (\Exception $e) {
  225. $form['file']->addError(new FormError('アップロードに失敗しました。圧縮ファイルを確認してください。'));
  226. return $app->render('Store/template_add.twig', array(
  227. 'form' => $form->createView(),
  228. ));
  229. }
  230. $fs = new Filesystem();
  231. // appディレクトリの存在チェック.
  232. if (!file_exists($appDir)) {
  233. $fs->mkdir($appDir);
  234. }
  235. // htmlディレクトリの存在チェック.
  236. if (!file_exists($htmlDir)) {
  237. $fs->mkdir($htmlDir);
  238. }
  239. // 一時ディレクトリから該当テンプレートのディレクトリへコピーする.
  240. $fs->mirror($appDir, $targetRealDir);
  241. $fs->mirror($htmlDir, $targetHtmlRealDir);
  242. // 一時ディレクトリを削除.
  243. $fs->remove($tmpDir);
  244. $DeviceType = $app['eccube.repository.master.device_type']
  245. ->find(DeviceType::DEVICE_TYPE_PC);
  246. $Template->setDeviceType($DeviceType);
  247. $app['orm.em']->persist($Template);
  248. $app['orm.em']->flush();
  249. $app->addSuccess('admin.content.template.add.complete', 'admin');
  250. return $app->redirect($app->url('admin_store_template'));
  251. }
  252. }
  253. return $app->render('Store/template_add.twig', array(
  254. 'form' => $form->createView(),
  255. ));
  256. }
  257. }