Failed Conditions
Pull Request — experimental/3.1 (#2494)
by chihiro
49:51 queued 21:25
created

TemplateController::index()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 40
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4.2654

Importance

Changes 0
Metric Value
cc 3
eloc 26
nc 2
nop 2
dl 0
loc 40
rs 8.8571
c 0
b 0
f 0
ccs 12
cts 25
cp 0.48
crap 4.2654
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
24
namespace Eccube\Controller\Admin\Store;
25
26
use Doctrine\ORM\EntityManager;
27
use Eccube\Annotation\Component;
28
use Eccube\Annotation\Inject;
29
use Eccube\Application;
30
use Eccube\Controller\AbstractController;
31
use Eccube\Entity\Master\DeviceType;
32
use Eccube\Form\Type\Admin\TemplateType;
33
use Eccube\Repository\Master\DeviceTypeRepository;
34
use Eccube\Repository\TemplateRepository;
35
use Eccube\Util\Str;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
38
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
39
use Symfony\Bridge\Monolog\Logger;
40
use Symfony\Component\Filesystem\Filesystem;
41
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
42
use Symfony\Component\Form\FormError;
43
use Symfony\Component\Form\FormFactory;
44
use Symfony\Component\HttpFoundation\Request;
45
use Symfony\Component\HttpFoundation\Response;
46
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
47
48
/**
49
 * @Component
50
 * @Route(service=TemplateController::class)
51
 */
52
class TemplateController extends AbstractController
53
{
54
    /**
55
     * @Inject("form.factory")
56
     * @var FormFactory
57
     */
58
    protected $formFactory;
59
60
    /**
61
     * @Inject("orm.em")
62
     * @var EntityManager
63
     */
64
    protected $entityManager;
65
66
    /**
67
     * @Inject("monolog")
68
     * @var Logger
69
     */
70
    protected $logger;
71
72
    /**
73
     * @Inject("config")
74
     * @var array
75
     */
76
    protected $appConfig;
77
78
    /**
79
     * @Inject(TemplateRepository::class)
80
     * @var TemplateRepository
81
     */
82
    protected $templateRepository;
83
84
    /**
85
     * @Inject(DeviceTypeRepository::class)
86
     * @var DeviceTypeRepository
87
     */
88
    protected $deviceTypeRepository;
89
90
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
91
     * テンプレート一覧画面
92
     *
93
     * @Route("/{_admin}/store/template", name="admin_store_template")
94
     * @Template("Store/template.twig")
95
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
96 1
    public function index(Application $app, Request $request)
97
    {
98 1
        $DeviceType = $this->deviceTypeRepository
99 1
            ->find(DeviceType::DEVICE_TYPE_PC);
100
101 1
        $Templates = $this->templateRepository
102 1
            ->findBy(array('DeviceType' => $DeviceType));
103
104 1
        $form = $this->formFactory->createBuilder()
105 1
            ->add('selected', HiddenType::class)
106 1
            ->getForm();
107 1
        $form->handleRequest($request);
108
109 1
        if ($form->isSubmitted() && $form->isValid()) {
110
            $Template = $this->templateRepository
111
                ->find($form['selected']->getData());
112
113
            // path.(yml|php)の再構築
114
            $file = $this->appConfig['root_dir'].'/app/config/eccube/path.php';
115
            $config = require $file;
116
117
            $templateCode = $Template->getCode();
118
            $config['template_code'] = $templateCode;
119
            $config['template_realdir'] = $config['root_dir'].'/app/template/'.$templateCode;
120
            $config['template_html_realdir'] = $config['public_path_realdir'].'/template/'.$templateCode;
121
            $config['front_urlpath'] = $config['root_urlpath'].RELATIVE_PUBLIC_DIR_PATH.'/template/'.$templateCode;
122
            $config['block_realdir'] = $config['template_realdir'].'/Block';
123
124
            file_put_contents($file, sprintf('<?php return %s', var_export($config, true)).';');
125
126
            $app->addSuccess('admin.content.template.save.complete', 'admin');
127
128
            return $app->redirect($app->url('admin_store_template'));
129
        }
130
131
        return [
132 1
            'form' => $form->createView(),
133 1
            'Templates' => $Templates,
134
        ];
135
    }
136
137
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$Template" missing
Loading history...
138
     * テンプレート一覧からのダウンロード
139
     *
140
     * @Route("/{_admin}/store/template/{id}/download", name="admin_store_template_download", requirements={"id" = "\d+"})
141
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
142
    public function download(Application $app, Request $request, \Eccube\Entity\Template $Template)
0 ignored issues
show
Unused Code introduced by
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...
143
    {
144
        // 該当テンプレートのディレクトリ
145
        $config = $this->appConfig;
146
        $templateCode = $Template->getCode();
147
        $targetRealDir = $config['root_dir'].'/app/template/'.$templateCode;
148
        $targetHtmlRealDir = $config['root_dir'].'/html/template/'.$templateCode;
149
150
        // 一時ディレクトリ
151
        $uniqId = sha1(Str::random(32));
152
        $tmpDir = $config['template_temp_realdir'].'/'.$uniqId;
153
        $appDir = $tmpDir.'/app';
154
        $htmlDir = $tmpDir.'/html';
155
156
        // ファイル名
157
        $tarFile = $config['template_temp_realdir'].'/'.$uniqId.'.tar';
158
        $tarGzFile = $tarFile.'.gz';
159
        $downloadFileName = $Template->getCode().'.tar.gz';
160
161
        // 該当テンプレートを一時ディレクトリへコピーする.
162
        $fs = new Filesystem();
163
        $fs->mkdir(array($appDir, $htmlDir));
164
        $fs->mirror($targetRealDir, $appDir);
165
        $fs->mirror($targetHtmlRealDir, $htmlDir);
166
167
        // tar.gzファイルに圧縮する.
168
        $phar = new \PharData($tarFile);
169
        $phar->buildFromDirectory($tmpDir);
170
        // appディレクトリがない場合は, 空ディレクトリを追加
171
        // @see https://github.com/EC-CUBE/ec-cube/issues/742
172
        if (empty($phar['app'])) {
173
            $phar->addEmptyDir('app');
174
        }
175
        $phar->compress(\Phar::GZ);
176
177
        // ダウンロード完了後にファイルを削除する.
178
        // http://stackoverflow.com/questions/15238897/removing-file-after-delivering-response-with-silex-symfony
179
        $app->finish(
180
            function (Request $request, Response $response, \Silex\Application $app) use (
0 ignored issues
show
Unused Code introduced by
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...
Unused Code introduced by
The parameter $response 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...
Unused Code introduced by
The parameter $app 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...
Coding Style introduced by
Multi-line function declarations must define one parameter per line
Loading history...
181
                $tmpDir,
182
                $tarFile,
183
                $tarGzFile
184
            ) {
185
                $this->logger->addDebug('remove temp file: '.$tmpDir);
186
                $this->logger->addDebug('remove temp file: '.$tarFile);
187
                $this->logger->addDebug('remove temp file: '.$tarGzFile);
188
                $fs = new Filesystem();
189
                $fs->remove($tmpDir);
190
                $fs->remove($tarFile);
191
                $fs->remove($tarGzFile);
192
            }
193
        );
194
195
        return $app
196
            ->sendFile($tarGzFile)
197
            ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $downloadFileName);
198
    }
199
200
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$Template" missing
Loading history...
201
     * @Route("/{_admin}/store/template/{id}/delete", name="admin_store_template_delete", requirements={"id" = "\d+"})
202
     * @Method("DELETE")
203
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
204
    public function delete(Application $app, Request $request, \Eccube\Entity\Template $Template)
0 ignored issues
show
Unused Code introduced by
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...
205
    {
206
        $this->isTokenValid($app);
207
208
        // デフォルトテンプレート
209
        if ($Template->isDefaultTemplate()) {
210
            $app->addError('admin.content.template.delete.default.error', 'admin');
211
212
            return $app->redirect($app->url('admin_store_template'));
213
        }
214
215
        // 設定中のテンプレート
216
        if ($this->appConfig['template_code'] === $Template->getCode()) {
217
            $app->addError('admin.content.template.delete.current.error', 'admin');
218
219
            return $app->redirect($app->url('admin_store_template'));
220
        }
221
222
        // テンプレートディレクトリの削除
223
        $config = $this->appConfig;
224
        $templateCode = $Template->getCode();
225
        $targetRealDir = $config['root_dir'].'/app/template/'.$templateCode;
226
        $targetHtmlRealDir = $config['root_dir'].'/html/template/'.$templateCode;
227
228
        $fs = new Filesystem();
229
        $fs->remove($targetRealDir);
230
        $fs->remove($targetHtmlRealDir);
231
232
        // テーブルからも削除
233
        $this->entityManager->remove($Template);
234
        $this->entityManager->flush();
235
236
        $app->addSuccess('admin.content.template.delete.complete', 'admin');
237
238
        return $app->redirect($app->url('admin_store_template'));
239
    }
240
241
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
242
     * テンプレートの追加画面.
243
     *
244
     * @Route("/{_admin}/store/template/install", name="admin_store_template_install")
245
     * @Template("Store/template_add.twig")
246
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
247 1
    public function install(Application $app, Request $request)
248
    {
249 1
        $form = $this->formFactory
250 1
            ->createBuilder(TemplateType::class)
251 1
            ->getForm();
252 1
        $form->handleRequest($request);
253
254 1
        if ($form->isSubmitted() && $form->isValid()) {
255
            /** @var $Template \Eccube\Entity\Template */
256
            $Template = $form->getData();
257
258
            $TemplateExists = $this->templateRepository
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...
259
                ->findByCode($Template->getCode());
260
261
            // テンプレートコードの重複チェック.
262
            if ($TemplateExists) {
263
                $form['code']->addError(new FormError('すでに登録されているテンプレートコードです。'));
264
265
                return [
266
                    'form' => $form->createView(),
267
                ];
268
            }
269
270
            // 該当テンプレートのディレクトリ
271
            $config = $this->appConfig;
272
            $templateCode = $Template->getCode();
273
            $targetRealDir = $config['root_dir'].'/app/template/'.$templateCode;
274
            $targetHtmlRealDir = $config['root_dir'].'/html/template/'.$templateCode;
275
276
            // 一時ディレクトリ
277
            $uniqId = sha1(Str::random(32));
278
            $tmpDir = $config['template_temp_realdir'].'/'.$uniqId;
279
            $appDir = $tmpDir.'/app';
280
            $htmlDir = $tmpDir.'/html';
281
282
            $formFile = $form['file']->getData();
283
            // ファイル名
284
            $archive = $templateCode.'.'.$formFile->getClientOriginalExtension();
285
286
            // ファイルを一時ディレクトリへ移動.
287
            $formFile->move($tmpDir, $archive);
288
289
            // 一時ディレクトリへ解凍する.
290
            try {
291
                if ($formFile->getClientOriginalExtension() === 'zip') {
292
                    $zip = new \ZipArchive();
293
                    $zip->open($tmpDir.'/'.$archive);
294
                    $zip->extractTo($tmpDir);
295
                    $zip->close();
296
                } else {
297
                    $phar = new \PharData($tmpDir.'/'.$archive);
298
                    $phar->extractTo($tmpDir, null, true);
299
                }
300
            } catch (\Exception $e) {
301
                $form['file']->addError(new FormError('アップロードに失敗しました。圧縮ファイルを確認してください。'));
302
303
                return [
304
                    'form' => $form->createView(),
305
                ];
306
            }
307
308
            $fs = new Filesystem();
309
310
            // appディレクトリの存在チェック.
311
            if (!file_exists($appDir)) {
312
                $fs->mkdir($appDir);
313
            }
314
315
            // htmlディレクトリの存在チェック.
316
            if (!file_exists($htmlDir)) {
317
                $fs->mkdir($htmlDir);
318
            }
319
320
            // 一時ディレクトリから該当テンプレートのディレクトリへコピーする.
321
            $fs->mirror($appDir, $targetRealDir);
322
            $fs->mirror($htmlDir, $targetHtmlRealDir);
323
324
            // 一時ディレクトリを削除.
325
            $fs->remove($tmpDir);
326
327
            $DeviceType = $this->deviceTypeRepository
328
                ->find(DeviceType::DEVICE_TYPE_PC);
329
330
            $Template->setDeviceType($DeviceType);
331
332
            $this->entityManager->persist($Template);
333
            $this->entityManager->flush();
334
335
            $app->addSuccess('admin.content.template.add.complete', 'admin');
336
337
            return $app->redirect($app->url('admin_store_template'));
338
        }
339
340
        return [
341 1
            'form' => $form->createView(),
342
        ];
343
    }
344
}
345