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\Controller\Admin\Store; |
||
15 | |||
16 | use Eccube\Controller\AbstractController; |
||
17 | use Eccube\Entity\Master\DeviceType; |
||
18 | use Eccube\Form\Type\Admin\TemplateType; |
||
19 | use Eccube\Repository\Master\DeviceTypeRepository; |
||
20 | use Eccube\Repository\TemplateRepository; |
||
21 | use Eccube\Util\CacheUtil; |
||
22 | use Eccube\Util\StringUtil; |
||
23 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; |
||
24 | use Symfony\Component\Filesystem\Filesystem; |
||
25 | use Symfony\Component\Form\Extension\Core\Type\HiddenType; |
||
26 | use Symfony\Component\Form\FormError; |
||
27 | use Symfony\Component\HttpFoundation\BinaryFileResponse; |
||
28 | use Symfony\Component\HttpFoundation\Request; |
||
29 | use Symfony\Component\HttpFoundation\ResponseHeaderBag; |
||
30 | use Symfony\Component\HttpKernel\KernelEvents; |
||
31 | use Symfony\Component\Routing\Annotation\Route; |
||
32 | |||
33 | class TemplateController extends AbstractController |
||
34 | { |
||
35 | /** |
||
36 | * @var TemplateRepository |
||
37 | */ |
||
38 | protected $templateRepository; |
||
39 | |||
40 | /** |
||
41 | * @var DeviceTypeRepository |
||
42 | */ |
||
43 | protected $deviceTypeRepository; |
||
44 | |||
45 | /** |
||
46 | * TemplateController constructor. |
||
47 | * |
||
48 | * @param TemplateRepository $templateRepository |
||
49 | * @param DeviceTypeRepository $deviceTypeRepository |
||
50 | */ |
||
51 | public function __construct( |
||
52 | 4 | TemplateRepository $templateRepository, |
|
53 | DeviceTypeRepository $deviceTypeRepository |
||
54 | ) { |
||
55 | $this->templateRepository = $templateRepository; |
||
56 | 4 | $this->deviceTypeRepository = $deviceTypeRepository; |
|
57 | 4 | } |
|
58 | |||
59 | /** |
||
60 | * テンプレート一覧画面 |
||
61 | * |
||
62 | * @Route("/%eccube_admin_route%/store/template", name="admin_store_template") |
||
63 | * @Template("@admin/Store/template.twig") |
||
64 | * |
||
65 | * @param Request $request |
||
66 | * |
||
67 | * @return array|\Symfony\Component\HttpFoundation\RedirectResponse |
||
68 | */ |
||
69 | public function index(Request $request, CacheUtil $cacheUtil) |
||
70 | 1 | { |
|
71 | $DeviceType = $this->deviceTypeRepository->find(DeviceType::DEVICE_TYPE_PC); |
||
72 | 1 | ||
73 | $Templates = $this->templateRepository->findBy(['DeviceType' => $DeviceType]); |
||
74 | 1 | ||
75 | $form = $this->formFactory->createBuilder() |
||
76 | 1 | ->add('selected', HiddenType::class) |
|
77 | 1 | ->getForm(); |
|
78 | 1 | $form->handleRequest($request); |
|
79 | 1 | ||
80 | if ($form->isSubmitted() && $form->isValid()) { |
||
81 | 1 | $Template = $this->templateRepository->find($form['selected']->getData()); |
|
82 | |||
83 | $envFile = $this->getParameter('kernel.project_dir').'/.env'; |
||
84 | $env = file_exists($envFile) ? file_get_contents($envFile) : ''; |
||
85 | |||
86 | $env = StringUtil::replaceOrAddEnv($env, [ |
||
87 | 'ECCUBE_TEMPLATE_CODE' => $Template->getCode(), |
||
88 | ]); |
||
89 | |||
90 | file_put_contents($envFile, $env); |
||
91 | |||
92 | $this->addSuccess('admin.common.save_complete', 'admin'); |
||
93 | |||
94 | $cacheUtil->clearCache(); |
||
95 | |||
96 | return $this->redirectToRoute('admin_store_template'); |
||
97 | } |
||
98 | |||
99 | return [ |
||
100 | 'form' => $form->createView(), |
||
101 | 1 | 'Templates' => $Templates, |
|
102 | 1 | ]; |
|
103 | } |
||
104 | |||
105 | /** |
||
106 | * テンプレート一覧からのダウンロード |
||
107 | * |
||
108 | * @Route("/%eccube_admin_route%/store/template/{id}/download", name="admin_store_template_download", requirements={"id" = "\d+"}) |
||
109 | * |
||
110 | * @param Request $request |
||
111 | * @param \Eccube\Entity\Template $Template |
||
112 | * |
||
113 | * @return BinaryFileResponse |
||
114 | */ |
||
115 | public function download(Request $request, \Eccube\Entity\Template $Template) |
||
116 | { |
||
117 | // 該当テンプレートのディレクトリ |
||
118 | $templateCode = $Template->getCode(); |
||
119 | $targetRealDir = $this->getParameter('kernel.project_dir').'/app/template/'.$templateCode; |
||
120 | $targetHtmlRealDir = $this->getParameter('kernel.project_dir').'/html/template/'.$templateCode; |
||
121 | |||
122 | // 一時ディレクトリ |
||
123 | $uniqId = sha1(StringUtil::random(32)); |
||
124 | $tmpDir = \sys_get_temp_dir().'/'.$uniqId; |
||
125 | $appDir = $tmpDir.'/app'; |
||
126 | $htmlDir = $tmpDir.'/html'; |
||
127 | |||
128 | // ファイル名 |
||
129 | $tarFile = $tmpDir.'.tar'; |
||
130 | $tarGzFile = $tarFile.'.gz'; |
||
131 | $downloadFileName = $Template->getCode().'.tar.gz'; |
||
132 | |||
133 | // 該当テンプレートを一時ディレクトリへコピーする. |
||
134 | $fs = new Filesystem(); |
||
135 | $fs->mkdir([$appDir, $htmlDir]); |
||
136 | $fs->mirror($targetRealDir, $appDir); |
||
137 | $fs->mirror($targetHtmlRealDir, $htmlDir); |
||
138 | |||
139 | // tar.gzファイルに圧縮する. |
||
140 | $phar = new \PharData($tarFile); |
||
141 | $phar->buildFromDirectory($tmpDir); |
||
142 | // appディレクトリがない場合は, 空ディレクトリを追加 |
||
143 | // @see https://github.com/EC-CUBE/ec-cube/issues/742 |
||
144 | if (empty($phar['app'])) { |
||
145 | $phar->addEmptyDir('app'); |
||
146 | } |
||
147 | $phar->compress(\Phar::GZ); |
||
148 | |||
149 | // ダウンロード完了後にファイルを削除する. |
||
150 | // http://stackoverflow.com/questions/15238897/removing-file-after-delivering-response-with-silex-symfony |
||
151 | $this->eventDispatcher->addListener(KernelEvents::TERMINATE, function () use ( |
||
152 | $tmpDir, |
||
153 | $tarFile, |
||
154 | $tarGzFile |
||
155 | ) { |
||
156 | log_debug('remove temp file: '.$tmpDir); |
||
157 | log_debug('remove temp file: '.$tarFile); |
||
158 | log_debug('remove temp file: '.$tarGzFile); |
||
159 | $fs = new Filesystem(); |
||
160 | $fs->remove($tmpDir); |
||
161 | $fs->remove($tarFile); |
||
162 | $fs->remove($tarGzFile); |
||
163 | }); |
||
164 | |||
165 | $response = new BinaryFileResponse($tarGzFile); |
||
166 | $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $downloadFileName); |
||
167 | |||
168 | return $response; |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * @Route("/%eccube_admin_route%/store/template/{id}/delete", name="admin_store_template_delete", requirements={"id" = "\d+"}, methods={"DELETE"}) |
||
173 | */ |
||
174 | public function delete(Request $request, \Eccube\Entity\Template $Template) |
||
175 | { |
||
176 | 1 | $this->isTokenValid(); |
|
177 | |||
178 | 1 | // デフォルトテンプレート |
|
179 | if ($Template->isDefaultTemplate()) { |
||
180 | $this->addError('admin.store.template.delete_error_default__template', 'admin'); |
||
181 | 1 | ||
182 | return $this->redirectToRoute('admin_store_template'); |
||
183 | } |
||
184 | |||
185 | // 設定中のテンプレート |
||
186 | if ($this->eccubeConfig['eccube.theme'] === $Template->getCode()) { |
||
187 | $this->addError('admin.store.template.delete_error__current_template', 'admin'); |
||
188 | 1 | ||
189 | return $this->redirectToRoute('admin_store_template'); |
||
190 | } |
||
191 | |||
192 | // テンプレートディレクトリの削除 |
||
193 | $templateCode = $Template->getCode(); |
||
194 | $targetRealDir = $this->container->getParameter('kernel.project_dir').'/app/template/'.$templateCode; |
||
195 | 1 | $targetHtmlRealDir = $this->container->getParameter('kernel.project_dir').'/html/template/'.$templateCode; |
|
196 | 1 | ||
197 | 1 | $fs = new Filesystem(); |
|
198 | $fs->remove($targetRealDir); |
||
199 | 1 | $fs->remove($targetHtmlRealDir); |
|
200 | 1 | ||
201 | 1 | // テーブルからも削除 |
|
202 | $this->entityManager->remove($Template); |
||
203 | $this->entityManager->flush(); |
||
204 | 1 | ||
205 | 1 | $this->addSuccess('admin.common.delete_complete', 'admin'); |
|
206 | |||
207 | 1 | return $this->redirectToRoute('admin_store_template'); |
|
208 | } |
||
209 | 1 | ||
210 | /** |
||
211 | * テンプレートの追加画面. |
||
212 | * |
||
213 | * @Route("/%eccube_admin_route%/store/template/install", name="admin_store_template_install") |
||
214 | * @Template("@admin/Store/template_add.twig") |
||
215 | * |
||
216 | * @param Request $request |
||
217 | * |
||
218 | * @return array|\Symfony\Component\HttpFoundation\RedirectResponse |
||
219 | */ |
||
220 | public function install(Request $request) |
||
221 | { |
||
222 | 3 | $form = $this->formFactory |
|
223 | ->createBuilder(TemplateType::class) |
||
224 | 3 | ->getForm(); |
|
225 | 3 | $form->handleRequest($request); |
|
226 | 3 | ||
227 | 3 | if ($form->isSubmitted() && $form->isValid()) { |
|
228 | /** @var $Template \Eccube\Entity\Template */ |
||
229 | 3 | $Template = $form->getData(); |
|
230 | |||
231 | 2 | $TemplateExists = $this->templateRepository->findByCode($Template->getCode()); |
|
232 | |||
233 | 2 | // テンプレートコードの重複チェック. |
|
234 | if ($TemplateExists) { |
||
235 | $form['code']->addError(new FormError(trans('admin.store.template.template_code_already_exists'))); |
||
236 | 2 | ||
237 | return [ |
||
238 | 'form' => $form->createView(), |
||
239 | ]; |
||
240 | } |
||
241 | |||
242 | // 該当テンプレートのディレクトリ |
||
243 | $templateCode = $Template->getCode(); |
||
244 | $targetRealDir = $this->getParameter('kernel.project_dir').'/app/template/'.$templateCode; |
||
245 | 2 | $targetHtmlRealDir = $this->getParameter('kernel.project_dir').'/html/template/'.$templateCode; |
|
246 | 2 | ||
247 | 2 | // 一時ディレクトリ |
|
248 | $uniqId = sha1(StringUtil::random(32)); |
||
249 | $tmpDir = \sys_get_temp_dir().'/'.$uniqId; |
||
250 | 2 | $appDir = $tmpDir.'/app'; |
|
251 | 2 | $htmlDir = $tmpDir.'/html'; |
|
252 | 2 | ||
253 | 2 | $formFile = $form['file']->getData(); |
|
254 | // ファイル名 |
||
255 | 2 | $archive = $templateCode.'.'.$formFile->getClientOriginalExtension(); |
|
256 | |||
257 | 2 | // ファイルを一時ディレクトリへ移動. |
|
258 | $formFile->move($tmpDir, $archive); |
||
259 | |||
260 | 2 | // 一時ディレクトリへ解凍する. |
|
261 | try { |
||
262 | if (strtolower($formFile->getClientOriginalExtension()) === 'zip') { |
||
263 | $zip = new \ZipArchive(); |
||
264 | 2 | $zip->open($tmpDir.'/'.$archive); |
|
265 | 2 | $zip->extractTo($tmpDir); |
|
266 | 2 | $zip->close(); |
|
267 | 2 | } else { |
|
268 | 2 | $phar = new \PharData($tmpDir.'/'.$archive); |
|
269 | $phar->extractTo($tmpDir, null, true); |
||
270 | } |
||
271 | 2 | } catch (\Exception $e) { |
|
272 | $form['file']->addError(new FormError(trans('admin.common.upload_error'))); |
||
273 | |||
274 | return [ |
||
275 | 'form' => $form->createView(), |
||
276 | ]; |
||
277 | } |
||
278 | |||
279 | $fs = new Filesystem(); |
||
280 | |||
281 | 2 | // appディレクトリの存在チェック. |
|
282 | if (!file_exists($appDir)) { |
||
283 | $fs->mkdir($appDir); |
||
284 | 2 | } |
|
285 | |||
286 | // htmlディレクトリの存在チェック. |
||
287 | if (!file_exists($htmlDir)) { |
||
288 | $fs->mkdir($htmlDir); |
||
289 | 2 | } |
|
290 | |||
291 | // 一時ディレクトリから該当テンプレートのディレクトリへコピーする. |
||
292 | $fs->mirror($appDir, $targetRealDir); |
||
293 | $fs->mirror($htmlDir, $targetHtmlRealDir); |
||
294 | 2 | ||
295 | 2 | // 一時ディレクトリを削除. |
|
296 | $fs->remove($tmpDir); |
||
297 | |||
298 | 2 | $DeviceType = $this->deviceTypeRepository->find(DeviceType::DEVICE_TYPE_PC); |
|
299 | |||
300 | 2 | $Template->setDeviceType($DeviceType); |
|
0 ignored issues
–
show
|
|||
301 | |||
302 | 2 | $this->entityManager->persist($Template); |
|
303 | $this->entityManager->flush(); |
||
304 | 2 | ||
305 | 2 | $this->addSuccess('admin.common.upload_complete', 'admin'); |
|
306 | |||
307 | 2 | return $this->redirectToRoute('admin_store_template'); |
|
308 | } |
||
309 | 2 | ||
310 | return [ |
||
311 | 'form' => $form->createView(), |
||
312 | ]; |
||
313 | 1 | } |
|
314 | } |
||
315 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.