Completed
Push — experimental/3.1 ( d4772e...eaf44a )
by Ryo
304:34 queued 304:10
created

PluginController::uninstall()   B

Complexity

Conditions 4
Paths 12

Size

Total Lines 31
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 21
nc 12
nop 2
dl 0
loc 31
ccs 0
cts 10
cp 0
crap 20
rs 8.5806
c 0
b 0
f 0
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
25
namespace Eccube\Controller\Admin\Store;
26
27
use Doctrine\ORM\EntityManager;
28
use Eccube\Annotation\Inject;
29
use Eccube\Application;
30
use Eccube\Common\Constant;
31
use Eccube\Controller\AbstractController;
32
use Eccube\Entity\BaseInfo;
33
use Eccube\Entity\Plugin;
34
use Eccube\Entity\PluginEventHandler;
35
use Eccube\Exception\PluginException;
36
use Eccube\Form\Type\Admin\PluginLocalInstallType;
37
use Eccube\Form\Type\Admin\PluginManagementType;
38
use Eccube\Repository\PluginEventHandlerRepository;
39
use Eccube\Repository\PluginRepository;
40
use Eccube\Service\PluginService;
41
use Eccube\Util\Str;
42
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
43
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
44
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
45
use Symfony\Bridge\Monolog\Logger;
46
use Symfony\Component\Config\Definition\Exception\Exception;
47
use Symfony\Component\Filesystem\Filesystem;
48
use Symfony\Component\Finder\Finder;
49
use Symfony\Component\Form\Extension\Core\Type\FormType;
50
use Symfony\Component\Form\Extension\Core\Type\TextType;
51
use Symfony\Component\Form\FormFactory;
52
use Symfony\Component\HttpFoundation\RedirectResponse;
53
use Symfony\Component\HttpFoundation\Request;
54
use Symfony\Component\Process\Process;
55
use Symfony\Component\Routing\Exception\RouteNotFoundException;
56
use Symfony\Component\Validator\Constraints as Assert;
57
58
/**
59
 * @Route(service=PluginController::class)
60
 */
61
class PluginController extends AbstractController
62
{
63
    /**
64
     * @Inject("orm.em")
65
     * @var EntityManager
66
     */
67
    protected $entityManager;
68
69
    /**
70
     * @Inject("monolog")
71
     * @var Logger
72
     */
73
    protected $logger;
74
75
    /**
76
     * @Inject(PluginEventHandlerRepository::class)
77
     * @var PluginEventHandlerRepository
78
     */
79
    protected $pluginEventHandlerRepository;
80
81
    /**
82
     * @Inject(PluginService::class)
83
     * @var PluginService
84
     */
85
    protected $pluginService;
86
87
    /**
88
     * @Inject("config")
89
     * @var array
90
     */
91
    protected $appConfig;
92
93
    /**
94
     * @Inject(BaseInfo::class)
95
     * @var BaseInfo
96
     */
97
    protected $BaseInfo;
98
99
    /**
100
     * @Inject("form.factory")
101
     * @var FormFactory
102
     */
103
    protected $formFactory;
104
105
    /**
106
     * @Inject(PluginRepository::class)
107
     * @var PluginRepository
108
     */
109
    protected $pluginRepository;
110
111
112
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
113
     * インストール済プラグイン画面
114
     *
115
     * @Route("/{_admin}/store/plugin", name="admin_store_plugin")
116
     * @Template("Store/plugin.twig")
117
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
118
    public function index(Application $app, Request $request)
119
    {
120
        $pluginForms = array();
121
        $configPages = array();
122
123
        $Plugins = $this->pluginRepository->findBy(array(), array('code' => 'ASC'));
124
125
        // ファイル設置プラグインの取得.
126
        $unregisterdPlugins = $this->getUnregisteredPlugins($Plugins, $app);
127
        $unregisterdPluginsConfigPages = array();
128
        foreach ($unregisterdPlugins as $unregisterdPlugin) {
129
            try {
130
                $code = $unregisterdPlugin['code'];
131
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
132
                $unregisterdPluginsConfigPages[$code] = $app->url('plugin_'.$code.'_config');
133
            } catch (RouteNotFoundException $e) {
134
                // プラグインで設定画面のルートが定義されていない場合は無視
135
            }
136
        }
137
138
        $officialPlugins = array();
139
        $unofficialPlugins = array();
140
141
        foreach ($Plugins as $Plugin) {
142
            $form = $this->formFactory
143
                ->createNamedBuilder(
144
                    'form'.$Plugin->getId(),
145
                    PluginManagementType::class,
146
                    null,
147
                    array(
148
                        'plugin_id' => $Plugin->getId(),
149
                    )
150
                )
151
                ->getForm();
152
            $pluginForms[$Plugin->getId()] = $form->createView();
153
154
            try {
155
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
156
                $configPages[$Plugin->getCode()] = $app->url('plugin_'.$Plugin->getCode().'_config');
157
            } catch (\Exception $e) {
158
                // プラグインで設定画面のルートが定義されていない場合は無視
159
            }
160
161
            if ($Plugin->getSource() == 0) {
162
                // 商品IDが設定されていない場合、非公式プラグイン
163
                $unofficialPlugins[] = $Plugin;
164
            } else {
165
                $officialPlugins[] = $Plugin;
166
            }
167
        }
168
169
        // Todo: Need new authentication mechanism
170
        // オーナーズストアからダウンロード可能プラグイン情報を取得
171
        $authKey = $this->BaseInfo->getAuthenticationKey();
172
//        if (!is_null($authKey)) {
173
174
        // オーナーズストア通信
175
        $url = $this->appConfig['owners_store_url'].'?method=list';
176
        list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
0 ignored issues
show
Unused Code introduced by
The assignment to $info is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
177
178
        $officialPluginsDetail = [];
179
        if ($json) {
180
            // 接続成功時
181
            $data = json_decode($json, true);
182
            if (isset($data['success'])) {
183
                $success = $data['success'];
184
                if ($success == '1') {
185
                    foreach ($data['item'] as $item) {
186
                        foreach ($officialPlugins as $key => $plugin) {
187
                            if ($plugin->getSource() == $item['product_id']) {
188
                                $officialPluginsDetail[$key] = $item;
189
                                $officialPluginsDetail[$key]['update_status'] = 0;
190
                                if ($plugin->getVersion() != $item['version']) {
191
                                    $officialPluginsDetail[$key]['update_status'] = 1;
192
                                }
193
                            }
194
                        }
195
                    }
196
                }
197
            }
198
        }
199
200
        return [
201
            'plugin_forms' => $pluginForms,
202
            'officialPlugins' => $officialPlugins,
203
            'unofficialPlugins' => $unofficialPlugins,
204
            'configPages' => $configPages,
205
            'unregisterdPlugins' => $unregisterdPlugins,
206
            'unregisterdPluginsConfigPages' => $unregisterdPluginsConfigPages,
207
            'officialPluginsDetail' => $officialPluginsDetail,
208
        ];
209
    }
210
211
    /**
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 "$Plugin" missing
Loading history...
212
     * インストール済プラグインからのアップデート
213
     *
214
     * @Method("POST")
215
     * @Route("/{_admin}/store/plugin/{id}/update", requirements={"id" = "\d+"}, name="admin_store_plugin_update")
216
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
217
    public function update(Application $app, Request $request, Plugin $Plugin)
218
    {
219
        $form = $this->formFactory
220
            ->createNamedBuilder(
221
                'form'.$Plugin->getId(),
222
                PluginManagementType::class,
223
                null,
224
                array(
225
                    'plugin_id' => null, // placeHolder
226
                )
227
            )
228
            ->getForm();
229
230
        $message = '';
231
232
        if ('POST' === $request->getMethod()) {
233
            $form->handleRequest($request);
234
235
            if ($form->isValid()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
236
237
                $tmpDir = null;
238
                try {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
239
240
                    $formFile = $form['plugin_archive']->getData();
241
242
                    $tmpDir = $this->pluginService->createTempDir();
243
                    $tmpFile = sha1(Str::random(32)).'.'.$formFile->getClientOriginalExtension();
244
245
                    $formFile->move($tmpDir, $tmpFile);
246
                    $this->pluginService->update($Plugin, $tmpDir.'/'.$tmpFile);
247
248
                    $fs = new Filesystem();
249
                    $fs->remove($tmpDir);
250
251
                    $app->addSuccess('admin.plugin.update.complete', 'admin');
252
253
                    return $app->redirect($app->url('admin_store_plugin'));
254
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
255
                } catch (PluginException $e) {
256
                    if (!empty($tmpDir) && file_exists($tmpDir)) {
257
                        $fs = new Filesystem();
258
                        $fs->remove($tmpDir);
259
                    }
260
                    $message = $e->getMessage();
261
                }
262
            } else {
263
                $errors = $form->getErrors(true);
264
                foreach ($errors as $error) {
265
                    $message = $error->getMessage();
0 ignored issues
show
Bug introduced by
The method getMessage() does not seem to exist on object<Symfony\Component\Form\FormErrorIterator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
266
                }
267
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
268
            }
269
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
270
        }
271
272
        $app->addError($message, 'admin');
273
274
        return $app->redirect($app->url('admin_store_plugin'));
275
    }
276
277
278
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Plugin" missing
Loading history...
279
     * 対象のプラグインを有効にします。
280
     *
281
     * @Method("PUT")
282
     * @Route("/{_admin}/store/plugin/{id}/enable", requirements={"id" = "\d+"}, name="admin_store_plugin_enable")
283
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
284 View Code Duplication
    public function enable(Application $app, Plugin $Plugin)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
285
    {
286
        $this->isTokenValid($app);
287
288
        if ($Plugin->getEnable() == Constant::ENABLED) {
289
            $app->addError('admin.plugin.already.enable', 'admin');
290
        } else {
291
            $this->pluginService->enable($Plugin);
292
            $app->addSuccess('admin.plugin.enable.complete', 'admin');
293
        }
294
295
        return $app->redirect($app->url('admin_store_plugin'));
296
    }
297
298
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Plugin" missing
Loading history...
299
     * 対象のプラグインを無効にします。
300
     *
301
     * @Method("PUT")
302
     * @Route("/{_admin}/store/plugin/{id}/disable", requirements={"id" = "\d+"}, name="admin_store_plugin_disable")
303
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
304 View Code Duplication
    public function disable(Application $app, Plugin $Plugin)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
305
    {
306
        $this->isTokenValid($app);
307
308
        if ($Plugin->getEnable() == Constant::ENABLED) {
309
            $this->pluginService->disable($Plugin);
310
            $app->addSuccess('admin.plugin.disable.complete', 'admin');
311
        } else {
312
            $app->addError('admin.plugin.already.disable', 'admin');
313
        }
314
315
        return $app->redirect($app->url('admin_store_plugin'));
316
    }
317
318
319
    /**
320
     * 対象のプラグインを削除します。
321
     * Update new ways to remove plugin: using composer command
322
     *
323
     * @Method("DELETE")
324
     * @Route("/{_admin}/store/plugin/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_uninstall")
325
     * @param Application $app
326
     * @param Plugin      $Plugin
327
     * @return RedirectResponse
328
     */
329
    public function uninstall(Application $app, Plugin $Plugin)
330
    {
331
        $this->isTokenValid($app);
332
333
        if ($Plugin->getEnable() == Constant::ENABLED) {
334
            $app->addError('admin.plugin.uninstall.error.not_disable', 'admin');
335
336
            return $app->redirect($app->url('admin_store_plugin'));
337
        }
338
339
        $pluginCode = $Plugin->getCode();
340
        try {
341
            $execute = sprintf('cd %s &&', $this->appConfig['root_dir']);
342
            $execute .= sprintf(' composer remove ec-cube/%s', $pluginCode);
343
344
            $install = new Process($execute);
345
            $install->setTimeout(null);
346
            $install->run();
347
            if ($install->isSuccessful()) {
348
                $app->addSuccess('admin.plugin.uninstall.complete', 'admin');
349
            } else {
350
                $app->log($install->getErrorOutput());
351
                $app->addError('admin.plugin.uninstall.error', 'admin');
352
            }
353
        } catch (\Exception $exception) {
354
            $app->addError($exception->getMessage(), 'admin');
355
            $app->log($exception->getCode().' : '.$exception->getMessage());
356
        }
357
358
        return $app->redirect($app->url('admin_store_plugin'));
359
    }
360
361
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
362
     * @Route("/{_admin}/store/plugin/handler", name="admin_store_plugin_handler")
363
     * @Template("Store/plugin_handler.twig")
364
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
365
    public function handler(Application $app)
0 ignored issues
show
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...
366
    {
367
        $handlers = $this->pluginEventHandlerRepository->getHandlers();
368
369
        // 一次元配列からイベント毎の二次元配列に変換する
370
        $HandlersPerEvent = array();
371
        foreach ($handlers as $handler) {
372
            $HandlersPerEvent[$handler->getEvent()][$handler->getHandlerType()][] = $handler;
373
        }
374
375
        return [
376
            'handlersPerEvent' => $HandlersPerEvent,
377
        ];
378
    }
379
380
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Handler" missing
Loading history...
381
     * @Route("/{_admin}/store/plugin/handler_up/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_up")
382
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
383 View Code Duplication
    public function handler_up(Application $app, PluginEventHandler $Handler)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
Coding Style introduced by
Method name "PluginController::handler_up" is not in camel caps format
Loading history...
384
    {
385
        $repo = $this->pluginEventHandlerRepository;
386
        $repo->upPriority($repo->find($Handler->getId()));
387
388
        return $app->redirect($app->url('admin_store_plugin_handler'));
389
    }
390
391
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Handler" missing
Loading history...
392
     * @Route("/{_admin}/store/plugin/handler_down/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_down")
393
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
394 View Code Duplication
    public function handler_down(Application $app, PluginEventHandler $Handler)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
Coding Style introduced by
Method name "PluginController::handler_down" is not in camel caps format
Loading history...
395
    {
396
        $repo = $this->pluginEventHandlerRepository;
397
        $repo->upPriority($Handler, false);
398
399
        return $app->redirect($app->url('admin_store_plugin_handler'));
400
    }
401
402
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
403
     * プラグインファイルアップロード画面
404
     *
405
     * @Route("/{_admin}/store/plugin/install", name="admin_store_plugin_install")
406
     * @Template("Store/plugin_install.twig")
407
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
408
    public function install(Application $app, Request $request)
409
    {
410
        $form = $this->formFactory
411
            ->createBuilder(PluginLocalInstallType::class)
412
            ->getForm();
413
414
        $errors = array();
415
416
        if ('POST' === $request->getMethod()) {
417
            $form->handleRequest($request);
418
419
            if ($form->isValid()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
420
421
                $tmpDir = null;
422
                try {
423
                    $service = $this->pluginService;
424
425
                    $formFile = $form['plugin_archive']->getData();
426
427
                    $tmpDir = $service->createTempDir();
428
                    $tmpFile = sha1(Str::random(32))
429
                        .'.'
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
430
                        .$formFile->getClientOriginalExtension(); // 拡張子を付けないとpharが動かないので付ける
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
431
432
                    $formFile->move($tmpDir, $tmpFile);
433
434
                    $service->install($tmpDir.'/'.$tmpFile);
435
436
                    $fs = new Filesystem();
437
                    $fs->remove($tmpDir);
438
439
                    $app->addSuccess('admin.plugin.install.complete', 'admin');
440
441
                    return $app->redirect($app->url('admin_store_plugin'));
442
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
443
                } catch (PluginException $e) {
444
                    if (!empty($tmpDir) && file_exists($tmpDir)) {
445
                        $fs = new Filesystem();
446
                        $fs->remove($tmpDir);
447
                    }
448
                    $this->logger->error(
449
                        "plugin install failed.",
450
                        array(
451
                            'original-message' => $e->getMessage(),
452
                        )
453
                    );
454
                    $errors[] = $e;
455
                }
456
            } else {
457
                foreach ($form->getErrors(true) as $error) {
458
                    $errors[] = $error;
459
                }
460
            }
461
        }
462
463
        return [
464
            'form' => $form->createView(),
465
            'errors' => $errors,
466
        ];
467
    }
468
469
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
470
     * オーナーズストアプラグインインストール画面
471
     *
472
     * @Route("/{_admin}/store/plugin/owners_install", name="admin_store_plugin_owners_install")
473
     * @Template("Store/plugin_owners_install.twig")
474
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
475
    public function ownersInstall(Application $app, Request $request)
476
    {
477
        // オーナーズストアからダウンロード可能プラグイン情報を取得
478
        $authKey = $this->BaseInfo->getAuthenticationKey();
479
        $authResult = true;
480
        $success = 0;
481
        $items = array();
482
        $promotionItems = array();
483
        $message = '';
484
        if (!is_null($authKey)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
485
486
            // オーナーズストア通信
487
            $url = $this->appConfig['owners_store_url'].'?method=list';
488
            list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
489
490
            if ($json === false) {
491
                // 接続失敗時
492
                $success = 0;
493
494
                $message = $this->getResponseErrorMessage($info);
495
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
496
            } else {
497
                // 接続成功時
498
499
                $data = json_decode($json, true);
500
501
                if (isset($data['success'])) {
502
                    $success = $data['success'];
503
                    if ($success == '1') {
504
                        $items = array();
505
506
                        // 既にインストールされているかどうか確認
507
                        $Plugins = $this->pluginRepository->findAll();
508
                        $status = false;
509
                        // update_status 1 : 未インストール、2 : インストール済、 3 : 更新あり、4 : 有料購入
510
                        foreach ($data['item'] as $item) {
511
                            foreach ($Plugins as $plugin) {
512
                                if ($plugin->getSource() == $item['product_id']) {
513
                                    if ($plugin->getVersion() == $item['version']) {
514
                                        // バージョンが同じ
515
                                        $item['update_status'] = 2;
516
                                    } else {
517
                                        // バージョンが異なる
518
                                        $item['update_status'] = 3;
519
                                    }
520
                                    $items[] = $item;
521
                                    $status = true;
522
                                    break;
523
                                }
524
                            }
525
                            if (!$status) {
526
                                // 未インストール
527
                                $item['update_status'] = 1;
528
                                $items[] = $item;
529
                            }
530
                            $status = false;
531
                        }
532
533
                        // EC-CUBEのバージョンチェック
534
                        // 参照渡しをして値を追加
535 View Code Duplication
                        foreach ($items as &$item) {
536
                            if (in_array(Constant::VERSION, $item['eccube_version'])) {
537
                                // 対象バージョン
538
                                $item['version_check'] = 1;
539
                            } else {
540
                                // 未対象バージョン
541
                                $item['version_check'] = 0;
542
                            }
543
                            if ($item['price'] != '0' && $item['purchased'] == '0') {
544
                                // 有料商品で未購入
545
                                $item['update_status'] = 4;
546
                            }
547
                        }
548
                        unset($item);
549
550
                        // promotionアイテム
551
                        $i = 0;
552 View Code Duplication
                        foreach ($items as $item) {
553
                            if ($item['promotion'] == 1) {
554
                                $promotionItems[] = $item;
555
                                unset($items[$i]);
556
                            }
557
                            $i++;
558
                        }
559
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
560
                    } else {
561
                        $message = $data['error_code'].' : '.$data['error_message'];
562
                    }
563
                } else {
564
                    $success = 0;
565
                    $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
566
                }
567
            }
568
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
569
        } else {
570
            $authResult = false;
571
        }
572
573
        return [
574
            'authResult' => $authResult,
575
            'success' => $success,
576
            'items' => $items,
577
            'promotionItems' => $promotionItems,
578
            'message' => $message,
579
        ];
580
    }
581
582
    /**
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 "$action" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
introduced by
Doc comment for parameter "$version" missing
Loading history...
583
     * オーナーズブラグインインストール、アップデート
584
     *
585
     * @Route("/{_admin}/store/plugin/upgrade/{action}/{id}/{version}", requirements={"id" = "\d+"}, name="admin_store_plugin_upgrade")
586
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
587
    public function upgrade(Application $app, Request $request, $action, $id, $version)
588
    {
589
        $authKey = $this->BaseInfo->getAuthenticationKey();
590
        $message = '';
591
592
        if (!is_null($authKey)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
593
594
            // オーナーズストア通信
595
            $url = $this->appConfig['owners_store_url'].'?method=download&product_id='.$id;
596
            list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
597
598
            if ($json === false) {
599
                // 接続失敗時
600
601
                $message = $this->getResponseErrorMessage($info);
602
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
603
            } else {
604
                // 接続成功時
605
606
                $data = json_decode($json, true);
607
608
                if (isset($data['success'])) {
609
                    $success = $data['success'];
610
                    if ($success == '1') {
611
                        $tmpDir = null;
612
                        try {
613
                            $service = $this->pluginService;
614
615
                            $item = $data['item'];
616
                            $file = base64_decode($item['data']);
617
                            $extension = pathinfo($item['file_name'], PATHINFO_EXTENSION);
618
619
                            $tmpDir = $service->createTempDir();
620
                            $tmpFile = sha1(Str::random(32)).'.'.$extension;
621
622
                            // ファイル作成
623
                            $fs = new Filesystem();
624
                            $fs->dumpFile($tmpDir.'/'.$tmpFile, $file);
625
626
                            if ($action == 'install') {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
627
628
                                $service->install($tmpDir.'/'.$tmpFile, $id);
629
                                $app->addSuccess('admin.plugin.install.complete', 'admin');
630
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
631
                            } else {
632
                                if ($action == 'update') {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
633
634
                                    $Plugin = $this->pluginRepository->findOneBy(array('source' => $id));
635
636
                                    $service->update($Plugin, $tmpDir.'/'.$tmpFile);
0 ignored issues
show
Documentation introduced by
$Plugin is of type object|null, but the function expects a object<Eccube\Entity\Plugin>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
637
                                    $app->addSuccess('admin.plugin.update.complete', 'admin');
638
                                }
639
                            }
640
641
                            $fs = new Filesystem();
642
                            $fs->remove($tmpDir);
643
644
                            // ダウンロード完了通知処理(正常終了時)
645
                            $url = $this->appConfig['owners_store_url'].'?method=commit&product_id='.$id.'&status=1&version='.$version;
646
                            $this->getRequestApi($request, $authKey, $url, $app);
647
648
                            return $app->redirect($app->url('admin_store_plugin'));
649
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
650
                        } catch (PluginException $e) {
651
                            if (!empty($tmpDir) && file_exists($tmpDir)) {
652
                                $fs = new Filesystem();
653
                                $fs->remove($tmpDir);
654
                            }
655
                            $message = $e->getMessage();
656
                        }
657
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
658
                    } else {
659
                        $message = $data['error_code'].' : '.$data['error_message'];
660
                    }
661
                } else {
662
                    $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
663
                }
664
            }
665
        }
666
667
        // ダウンロード完了通知処理(エラー発生時)
668
        $url = $this->appConfig['owners_store_url']
669
            .'?method=commit&product_id='.$id
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
670
            .'&status=0&version='.$version
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
671
            .'&message='.urlencode($message);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
672
673
        $this->getRequestApi($request, $authKey, $url, $app);
674
675
        $app->addError($message, 'admin');
676
677
        return $app->redirect($app->url('admin_store_plugin_owners_install'));
678
    }
679
680
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
681
     * 認証キー設定画面
682
     *
683
     * @Route("/{_admin}/store/plugin/authentication_setting", name="admin_store_authentication_setting")
684
     * @Template("Store/authentication_setting.twig")
685
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
686
    public function authenticationSetting(Application $app, Request $request)
687
    {
688
        $builder = $this->formFactory
689
            ->createBuilder(FormType::class, $this->BaseInfo);
690
        $builder->add(
691
            'authentication_key',
692
            TextType::class,
693
            [
694
                'label' => '認証キー',
695
                'constraints' => [
696
                    new Assert\Regex(['pattern' => "/^[0-9a-zA-Z]+$/",]),
0 ignored issues
show
introduced by
Add a single space after each comma delimiter
Loading history...
697
                ],
698
            ]
699
        );
700
701
        $form = $builder->getForm();
702
        $form->handleRequest($request);
703
704
        if ($form->isSubmitted() && $form->isValid()) {
705
            // 認証キーの登録
706
            $BaseInfo = $form->getData();
707
            $this->entityManager->flush($BaseInfo);
708
709
            $app->addSuccess('admin.plugin.authentication.setting.complete', 'admin');
710
        }
711
712
        return [
713
            'form' => $form->createView(),
714
        ];
715
    }
716
717
718
    /**
719
     * APIリクエスト処理
720
     *
721
     * @param Request $request
722
     * @param $authKey
723
     * @param string $url
724
     * @param Application $app
725
     * @return array
726
     */
727
    private function getRequestApi(Request $request, $authKey, $url, $app)
728
    {
729
        $curl = curl_init($url);
730
731
        $options = array(           // オプション配列
732
            //HEADER
733
            CURLOPT_HTTPHEADER => array(
734
                'Authorization: '.base64_encode($authKey),
735
                'x-eccube-store-url: '.base64_encode($request->getSchemeAndHttpHost().$request->getBasePath()),
736
                'x-eccube-store-version: '.base64_encode(Constant::VERSION),
737
            ),
738
            CURLOPT_HTTPGET => true,
739
            CURLOPT_SSL_VERIFYPEER => true,
740
            CURLOPT_RETURNTRANSFER => true,
741
            CURLOPT_FAILONERROR => true,
742
            CURLOPT_CAINFO => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
743
        );
744
745
        curl_setopt_array($curl, $options); /// オプション値を設定
746
        $result = curl_exec($curl);
747
        $info = curl_getinfo($curl);
748
749
        $message = curl_error($curl);
750
        $info['message'] = $message;
751
        curl_close($curl);
752
753
        $app->log('http get_info', $info);
754
755
        return array($result, $info);
756
    }
757
758
    /**
759
     * レスポンスのチェック
760
     *
761
     * @param $info
762
     * @return string
763
     */
764 View Code Duplication
    private function getResponseErrorMessage($info)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
765
    {
766
        if (!empty($info)) {
767
            $statusCode = $info['http_code'];
768
            $message = $info['message'];
769
770
            $message = $statusCode.' : '.$message;
771
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
772
        } else {
773
            $message = "タイムアウトエラーまたはURLの指定に誤りがあります。";
774
        }
775
776
        return $message;
777
    }
778
779
780
    /**
781
     * フォルダ設置のみのプラグインを取得する.
782
     *
783
     * @param array $plugins
784
     * @param Application $app
785
     * @return array
786
     */
787
    protected function getUnregisteredPlugins(array $plugins, \Eccube\Application $app)
0 ignored issues
show
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...
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
788
    {
789
        $finder = new Finder();
790
        $pluginCodes = array();
791
792
        // DB登録済みプラグインコードのみ取得
793
        foreach ($plugins as $key => $plugin) {
794
            $pluginCodes[] = $plugin->getCode();
795
        }
796
        // DB登録済みプラグインコードPluginディレクトリから排他
797
        $dirs = $finder->in($this->appConfig['plugin_realdir'])->depth(0)->directories();
798
799
        // プラグイン基本チェック
800
        $unregisteredPlugins = array();
801
        foreach ($dirs as $dir) {
802
            $pluginCode = $dir->getBasename();
803
            if (in_array($pluginCode, $pluginCodes, true)) {
804
                continue;
805
            }
806
            try {
807
                $this->pluginService->checkPluginArchiveContent($dir->getRealPath());
808
            } catch (\Eccube\Exception\PluginException $e) {
809
                //config.yamlに不備があった際は全てスキップ
810
                $this->logger->warning($e->getMessage());
811
                continue;
812
            }
813
            $config = $this->pluginService->readYml($dir->getRealPath().'/config.yml');
814
            $unregisteredPlugins[$pluginCode]['name'] = isset($config['name']) ? $config['name'] : null;
815
            $unregisteredPlugins[$pluginCode]['event'] = isset($config['event']) ? $config['event'] : null;
816
            $unregisteredPlugins[$pluginCode]['version'] = isset($config['version']) ? $config['version'] : null;
817
            $unregisteredPlugins[$pluginCode]['enable'] = Constant::DISABLED;
818
            $unregisteredPlugins[$pluginCode]['code'] = isset($config['code']) ? $config['code'] : null;
819
        }
820
821
        return $unregisteredPlugins;
822
    }
823
}
824