Completed
Push — 4.0 ( 268f2c...88f012 )
by Hideki
05:48 queued 10s
created

Controller/Admin/Store/TemplateController.php (3 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\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)
0 ignored issues
show
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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)
0 ignored issues
show
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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());
0 ignored issues
show
Documentation Bug introduced by
The method findByCode does not exist on object<Eccube\Repository\TemplateRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
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);
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