Failed Conditions
Pull Request — experimental/3.1 (#2636)
by
unknown
79:00 queued 46:49
created

PluginController::install()   B

Complexity

Conditions 8
Paths 32

Size

Total Lines 53
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 36
nc 32
nop 2
dl 0
loc 53
ccs 0
cts 26
cp 0
crap 72
rs 7.1199
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Composer\ComposerApiService;
41
use Eccube\Service\PluginService;
42
use Eccube\Util\Str;
43
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
44
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
45
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
46
use Symfony\Bridge\Monolog\Logger;
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\File\UploadedFile;
53
use Symfony\Component\HttpFoundation\RedirectResponse;
54
use Symfony\Component\HttpFoundation\Request;
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(ComposerApiService::class)
89
     * @var ComposerApiService
90
     */
91
    protected $composerService;
92
93
    /**
94
     * @Inject("config")
95
     * @var array
96
     */
97
    protected $appConfig;
98
99
    /**
100
     * @Inject(BaseInfo::class)
101
     * @var BaseInfo
102
     */
103
    protected $BaseInfo;
104
105
    /**
106
     * @Inject("form.factory")
107
     * @var FormFactory
108
     */
109
    protected $formFactory;
110
111
    /**
112
     * @Inject(PluginRepository::class)
113
     * @var PluginRepository
114
     */
115
    protected $pluginRepository;
116
117
118
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
119
     * インストール済プラグイン画面
120
     *
121
     * @Route("/{_admin}/store/plugin", name="admin_store_plugin")
122
     * @Template("Store/plugin.twig")
123
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
124
    public function index(Application $app, Request $request)
125
    {
126
        $pluginForms = array();
127
        $configPages = array();
128
129
        $Plugins = $this->pluginRepository->findBy(array(), array('code' => 'ASC'));
130
131
        // ファイル設置プラグインの取得.
132
        $unregisterdPlugins = $this->getUnregisteredPlugins($Plugins, $app);
133
        $unregisterdPluginsConfigPages = array();
134
        foreach ($unregisterdPlugins as $unregisterdPlugin) {
135
            try {
136
                $code = $unregisterdPlugin['code'];
137
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
138
                $unregisterdPluginsConfigPages[$code] = $app->url('plugin_'.$code.'_config');
139
            } catch (RouteNotFoundException $e) {
140
                // プラグインで設定画面のルートが定義されていない場合は無視
141
            }
142
        }
143
144
        $officialPlugins = array();
145
        $unofficialPlugins = array();
146
147
        foreach ($Plugins as $Plugin) {
148
            $form = $this->formFactory
149
                ->createNamedBuilder(
150
                    'form'.$Plugin->getId(),
151
                    PluginManagementType::class,
152
                    null,
153
                    array(
154
                        'plugin_id' => $Plugin->getId(),
155
                    )
156
                )
157
                ->getForm();
158
            $pluginForms[$Plugin->getId()] = $form->createView();
159
160
            try {
161
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
162
                $configPages[$Plugin->getCode()] = $app->url('plugin_'.$Plugin->getCode().'_config');
163
            } catch (\Exception $e) {
164
                // プラグインで設定画面のルートが定義されていない場合は無視
165
            }
166
167
            if ($Plugin->getSource() == 0) {
168
                // 商品IDが設定されていない場合、非公式プラグイン
169
                $unofficialPlugins[] = $Plugin;
170
            } else {
171
                $officialPlugins[] = $Plugin;
172
            }
173
        }
174
175
        // Todo: Need new authentication mechanism
176
        // オーナーズストアからダウンロード可能プラグイン情報を取得
177
        $authKey = $this->BaseInfo->getAuthenticationKey();
178
//        if (!is_null($authKey)) {
179
180
        // オーナーズストア通信
181
        $url = $this->appConfig['package_repo_url'].'/search/packages.json';
182
        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...
183
184
        $officialPluginsDetail = [];
185
        if ($json) {
186
            // 接続成功時
187
            $data = json_decode($json, true);
188
            if (isset($data['success'])) {
189
                $success = $data['success'];
190
                if ($success == '1') {
191
                    foreach ($data['item'] as $item) {
192
                        foreach ($officialPlugins as $key => $plugin) {
193
                            if ($plugin->getSource() == $item['product_id']) {
194
                                $officialPluginsDetail[$key] = $item;
195
                                $officialPluginsDetail[$key]['update_status'] = 0;
196
                                if ($plugin->getVersion() != $item['version']) {
197
                                    $officialPluginsDetail[$key]['update_status'] = 1;
198
                                }
199
                            }
200
                        }
201
                    }
202
                }
203
            }
204
        }
205
206
        return [
207
            'plugin_forms' => $pluginForms,
208
            'officialPlugins' => $officialPlugins,
209
            'unofficialPlugins' => $unofficialPlugins,
210
            'configPages' => $configPages,
211
            'unregisterdPlugins' => $unregisterdPlugins,
212
            'unregisterdPluginsConfigPages' => $unregisterdPluginsConfigPages,
213
            'officialPluginsDetail' => $officialPluginsDetail,
214
        ];
215
    }
216
217
    /**
218
     * インストール済プラグインからのアップデート
219
     *
220
     * @Method("POST")
221
     * @Route("/{_admin}/store/plugin/{id}/update", requirements={"id" = "\d+"}, name="admin_store_plugin_update")
222
     * @param Application $app
223
     * @param Request     $request
224
     * @param Plugin      $Plugin
225
     * @return RedirectResponse
226
     */
227
    public function update(Application $app, Request $request, Plugin $Plugin)
228
    {
229
        $form = $this->formFactory
230
            ->createNamedBuilder(
231
                'form'.$Plugin->getId(),
232
                PluginManagementType::class,
233
                null,
234
                array(
235
                    'plugin_id' => null, // placeHolder
236
                )
237
            )
238
            ->getForm();
239
240
        $message = '';
241
        $form->handleRequest($request);
242
        if ($form->isSubmitted() && $form->isValid()) {
243
            $tmpDir = null;
244
            try {
245
                $formFile = $form['plugin_archive']->getData();
246
                $tmpDir = $this->pluginService->createTempDir();
247
                $tmpFile = sha1(Str::random(32)).'.'.$formFile->getClientOriginalExtension();
248
                $formFile->move($tmpDir, $tmpFile);
249
                $this->pluginService->update($Plugin, $tmpDir.'/'.$tmpFile);
250
                $fs = new Filesystem();
251
                $fs->remove($tmpDir);
252
253
                // Check dependent plugin
254
                // Don't install ec-cube library
255
                $pluginCode = $Plugin->getCode();
256
                $dependents = $this->pluginService->getDependentByCode($pluginCode, PluginService::OTHER_PLUGIN_TYPE);
257
                if (!empty($dependents)) {
258
                    $package = $this->pluginService->parseToComposerCommand($dependents);
259
                    $this->composerService->execRequire($package);
260
                }
261
                $app->addSuccess('admin.plugin.update.complete', 'admin');
262
263
                return $app->redirect($app->url('admin_store_plugin'));
264
            } catch (PluginException $e) {
265
                if (!empty($tmpDir) && file_exists($tmpDir)) {
266
                    $fs = new Filesystem();
267
                    $fs->remove($tmpDir);
268
                }
269
                $message = $e->getMessage();
270
            }
271
        } else {
272
            $errors = $form->getErrors(true);
273
            foreach ($errors as $error) {
274
                $message = $error->getMessage();
0 ignored issues
show
Bug introduced by
The method getMessage does only exist in Symfony\Component\Form\FormError, but not in Symfony\Component\Form\FormErrorIterator.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
275
            }
276
        }
277
278
        $app->addError($message, 'admin');
279
280
        return $app->redirect($app->url('admin_store_plugin'));
281
    }
282
283
284
    /**
285
     * 対象のプラグインを有効にします。
286
     *
287
     * @Method("PUT")
288
     * @Route("/{_admin}/store/plugin/{id}/enable", requirements={"id" = "\d+"}, name="admin_store_plugin_enable")
289
     * @param Application $app
290
     * @param Plugin      $Plugin
291
     * @return RedirectResponse
292
     */
293 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...
294
    {
295
        $this->isTokenValid($app);
296
297
        if ($Plugin->isEnable()) {
298
            $app->addError('admin.plugin.already.enable', 'admin');
299
        } else {
300
            $requires = $this->pluginService->findRequirePluginNeedEnable($Plugin->getCode());
301
            if (!empty($requires)) {
302
                $DependPlugin = $this->pluginRepository->findOneBy(['code' => $requires[0]]);
303
                $dependName = $requires[0];
304
                if ($DependPlugin) {
305
                    $dependName = $DependPlugin->getName();
306
                }
307
                $message = $app->trans('admin.plugin.enable.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
308
                $app->addError($message, 'admin');
309
310
                return $app->redirect($app->url('admin_store_plugin'));
311
            }
312
            $this->pluginService->enable($Plugin);
313
            $app->addSuccess('admin.plugin.enable.complete', 'admin');
314
        }
315
316
        return $app->redirect($app->url('admin_store_plugin'));
317
    }
318
319
    /**
320
     * 対象のプラグインを無効にします。
321
     *
322
     * @Method("PUT")
323
     * @Route("/{_admin}/store/plugin/{id}/disable", requirements={"id" = "\d+"}, name="admin_store_plugin_disable")
324
     * @param Application $app
325
     * @param Plugin      $Plugin
326
     * @return RedirectResponse
327
     */
328 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...
329
    {
330
        $this->isTokenValid($app);
331
332
        if ($Plugin->isEnable()) {
333
            $dependents = $this->pluginService->findDependentPluginNeedDisable($Plugin->getCode());
334
            if (!empty($dependents)) {
335
                $dependName = $dependents[0];
336
                $DependPlugin = $this->pluginRepository->findOneBy(['code' => $dependents[0]]);
337
                if ($DependPlugin) {
338
                    $dependName = $DependPlugin->getName();
339
                }
340
                $message = $app->trans('admin.plugin.disable.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
341
                $app->addError($message, 'admin');
342
343
                return $app->redirect($app->url('admin_store_plugin'));
344
            }
345
346
            $this->pluginService->disable($Plugin);
347
            $app->addSuccess('admin.plugin.disable.complete', 'admin');
348
        } else {
349
            $app->addError('admin.plugin.already.disable', 'admin');
350
        }
351
352
        return $app->redirect($app->url('admin_store_plugin'));
353
    }
354
355
    /**
356
     * 対象のプラグインを削除します。
357
     *
358
     * @Method("DELETE")
359
     * @Route("/{_admin}/store/plugin/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_uninstall")
360
     * @param Application $app
361
     * @param Plugin      $Plugin
362
     * @return RedirectResponse
363
     */
364
    public function uninstall(Application $app, Plugin $Plugin)
365
    {
366
        $this->isTokenValid($app);
367
        // Check other plugin depend on it
368
        $pluginCode = $Plugin->getCode();
369
        $otherDepend = $this->pluginService->findDependentPlugin($pluginCode);
370
        if (!empty($otherDepend)) {
371
            $DependPlugin = $this->pluginRepository->findOneBy(['code' => $otherDepend[0]]);
372
            $dependName = $otherDepend[0];
373
            if ($DependPlugin) {
374
                $dependName = $DependPlugin->getName();
375
            }
376
            $message = $app->trans('admin.plugin.uninstall.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
377
            $app->addError($message, 'admin');
378
379
            return $app->redirect($app->url('admin_store_plugin'));
380
        }
381
382
        $this->pluginService->uninstall($Plugin);
383
        $app->addSuccess('admin.plugin.uninstall.complete', 'admin');
384
385
        return $app->redirect($app->url('admin_store_plugin'));
386
    }
387
388
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
389
     * @Route("/{_admin}/store/plugin/handler", name="admin_store_plugin_handler")
390
     * @Template("Store/plugin_handler.twig")
391
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
392
    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...
393
    {
394
        $handlers = $this->pluginEventHandlerRepository->getHandlers();
395
396
        // 一次元配列からイベント毎の二次元配列に変換する
397
        $HandlersPerEvent = array();
398
        foreach ($handlers as $handler) {
399
            $HandlersPerEvent[$handler->getEvent()][$handler->getHandlerType()][] = $handler;
400
        }
401
402
        return [
403
            'handlersPerEvent' => $HandlersPerEvent,
404
        ];
405
    }
406
407
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Handler" missing
Loading history...
408
     * @Route("/{_admin}/store/plugin/handler_up/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_up")
409
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
410 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...
411
    {
412
        $repo = $this->pluginEventHandlerRepository;
413
        $repo->upPriority($repo->find($Handler->getId()));
414
415
        return $app->redirect($app->url('admin_store_plugin_handler'));
416
    }
417
418
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Handler" missing
Loading history...
419
     * @Route("/{_admin}/store/plugin/handler_down/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_down")
420
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
421 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...
422
    {
423
        $repo = $this->pluginEventHandlerRepository;
424
        $repo->upPriority($Handler, false);
425
426
        return $app->redirect($app->url('admin_store_plugin_handler'));
427
    }
428
429
    /**
430
     * プラグインファイルアップロード画面
431
     *
432
     * @Route("/{_admin}/store/plugin/install", name="admin_store_plugin_install")
433
     * @Template("Store/plugin_install.twig")
434
     * @param Application $app
435
     * @param Request     $request
436
     * @return array|RedirectResponse
437
     */
438
    public function install(Application $app, Request $request)
439
    {
440
        $form = $this->formFactory
441
            ->createBuilder(PluginLocalInstallType::class)
442
            ->getForm();
443
        $errors = array();
444
        $form->handleRequest($request);
445
        if ($form->isSubmitted() && $form->isValid()) {
446
            $tmpDir = null;
447
            try {
448
                $service = $this->pluginService;
449
                /** @var UploadedFile $formFile */
450
                $formFile = $form['plugin_archive']->getData();
451
                $tmpDir = $service->createTempDir();
452
                // 拡張子を付けないとpharが動かないので付ける
453
                $tmpFile = sha1(Str::random(32)).'.'.$formFile->getClientOriginalExtension();
454
                $formFile->move($tmpDir, $tmpFile);
455
                $tmpPath = $tmpDir.'/'.$tmpFile;
456
                $pluginCode = $service->install($tmpPath);
457
                // Remove tmp file
458
                $fs = new Filesystem();
459
                $fs->remove($tmpDir);
460
461
                // Check dependent plugin
462
                // Don't install ec-cube library
463
                $dependents = $service->getDependentByCode($pluginCode, PluginService::OTHER_PLUGIN_TYPE);
464
                if (!empty($dependents)) {
465
                    $package = $this->pluginService->parseToComposerCommand($dependents);
466
                    $this->composerService->execRequire($package);
467
                }
468
469
                $app->addSuccess('admin.plugin.install.complete', 'admin');
470
471
                return $app->redirect($app->url('admin_store_plugin'));
472
            } catch (PluginException $e) {
473
                if (!empty($tmpDir) && file_exists($tmpDir)) {
474
                    $fs = new Filesystem();
475
                    $fs->remove($tmpDir);
476
                }
477
                $this->logger->error("plugin install failed.", array('original-message' => $e->getMessage()));
478
                $errors[] = $e->getMessage();
479
            }
480
        } else {
481
            foreach ($form->getErrors(true) as $error) {
482
                $errors[] = $error;
483
            }
484
        }
485
486
        return [
487
            'form' => $form->createView(),
488
            'errors' => $errors,
489
        ];
490
    }
491
492
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
493
     * オーナーズストアプラグインインストール画面
494
     *
495
     * @Route("/{_admin}/store/plugin/owners_install", name="admin_store_plugin_owners_install")
496
     * @Template("Store/plugin_owners_install.twig")
497
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
498
    public function ownersInstall(Application $app, Request $request)
499
    {
500
        // オーナーズストアからダウンロード可能プラグイン情報を取得
501
        $authKey = $this->BaseInfo->getAuthenticationKey();
502
        $authResult = true;
503
        $success = 0;
504
        $items = array();
505
        $promotionItems = array();
506
        $message = '';
507
        if (!is_null($authKey)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
508
509
            // オーナーズストア通信
510
            $url = $this->appConfig['package_repo_url'].'/search/packages.json';
511
            list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
512
513
            if ($json === false) {
514
                // 接続失敗時
515
                $success = 0;
516
517
                $message = $this->getResponseErrorMessage($info);
518
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
519
            } else {
520
                // 接続成功時
521
522
                $data = json_decode($json, true);
523
524
                if (isset($data['success'])) {
525
                    $success = $data['success'];
526
                    if ($success == '1') {
527
                        $items = array();
528
529
                        // 既にインストールされているかどうか確認
530
                        $Plugins = $this->pluginRepository->findAll();
531
                        $status = false;
532
                        // update_status 1 : 未インストール、2 : インストール済、 3 : 更新あり、4 : 有料購入
533
                        foreach ($data['item'] as $item) {
534
                            foreach ($Plugins as $plugin) {
535
                                if ($plugin->getSource() == $item['product_id']) {
536
                                    if ($plugin->getVersion() == $item['version']) {
537
                                        // バージョンが同じ
538
                                        $item['update_status'] = 2;
539
                                    } else {
540
                                        // バージョンが異なる
541
                                        $item['update_status'] = 3;
542
                                    }
543
                                    $items[] = $item;
544
                                    $status = true;
545
                                    break;
546
                                }
547
                            }
548
                            if (!$status) {
549
                                // 未インストール
550
                                $item['update_status'] = 1;
551
                                $items[] = $item;
552
                            }
553
                            $status = false;
554
                        }
555
556
                        // EC-CUBEのバージョンチェック
557
                        // 参照渡しをして値を追加
558
                        foreach ($items as &$item) {
559
                            if (in_array(Constant::VERSION, $item['eccube_version'])) {
560
                                // 対象バージョン
561
                                $item['version_check'] = 1;
562
                            } else {
563
                                // 未対象バージョン
564
                                $item['version_check'] = 0;
565
                            }
566
                            if ($item['price'] != '0' && $item['purchased'] == '0') {
567
                                // 有料商品で未購入
568
                                $item['update_status'] = 4;
569
                            }
570
                        }
571
                        unset($item);
572
573
                        // promotionアイテム
574
                        $i = 0;
575 View Code Duplication
                        foreach ($items as $item) {
576
                            if ($item['promotion'] == 1) {
577
                                $promotionItems[] = $item;
578
                                unset($items[$i]);
579
                            }
580
                            $i++;
581
                        }
582
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
583
                    } else {
584
                        $message = $data['error_code'].' : '.$data['error_message'];
585
                    }
586
                } else {
587
                    $success = 0;
588
                    $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
589
                }
590
            }
591
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
592
        } else {
593
            $authResult = false;
594
        }
595
596
        return [
597
            'authResult' => $authResult,
598
            'success' => $success,
599
            'items' => $items,
600
            'promotionItems' => $promotionItems,
601
            'message' => $message,
602
        ];
603
    }
604
605
    /**
606
     * オーナーズブラグインインストール、アップデート
607
     *
608
     * @Route("/{_admin}/store/plugin/upgrade/{action}/{id}/{version}", requirements={"id" = "\d+"}, name="admin_store_plugin_upgrade")
609
     * @param Application $app
610
     * @param Request     $request
611
     * @param string      $action
612
     * @param int         $id
613
     * @param string      $version
614
     * @return RedirectResponse
615
     */
616
    public function upgrade(Application $app, Request $request, $action, $id, $version)
617
    {
618
        $authKey = $this->BaseInfo->getAuthenticationKey();
619
        $message = '';
620
        if (!is_null($authKey)) {
621
            // オーナーズストア通信
622
            $url = $this->appConfig['package_repo_url'].'/search/packages.json'.'?method=download&product_id='.$id;
623
            list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
624
            if ($json === false) {
625
                // 接続失敗時
626
                $message = $this->getResponseErrorMessage($info);
627
            } else {
628
                // 接続成功時
629
                $data = json_decode($json, true);
630
                if (isset($data['success'])) {
631
                    $success = $data['success'];
632
                    if ($success == '1') {
633
                        $tmpDir = null;
634
                        try {
635
                            $service = $this->pluginService;
636
                            $item = $data['item'];
637
                            $file = base64_decode($item['data']);
638
                            $extension = pathinfo($item['file_name'], PATHINFO_EXTENSION);
639
                            $tmpDir = $service->createTempDir();
640
                            $tmpFile = sha1(Str::random(32)).'.'.$extension;
641
642
                            // ファイル作成
643
                            $fs = new Filesystem();
644
                            $fs->dumpFile($tmpDir.'/'.$tmpFile, $file);
645
646
                            if ($action == 'install') {
647
                                $service->install($tmpDir.'/'.$tmpFile, $id);
648
                                $app->addSuccess('admin.plugin.install.complete', 'admin');
649
                            } else {
650
                                if ($action == 'update') {
651
                                    $Plugin = $this->pluginRepository->findOneBy(array('source' => $id));
652
                                    $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...
653
                                    $app->addSuccess('admin.plugin.update.complete', 'admin');
654
                                }
655
                            }
656
657
                            $fs = new Filesystem();
658
                            $fs->remove($tmpDir);
659
660
                            // ダウンロード完了通知処理(正常終了時)
661
                            $url = $this->appConfig['package_repo_url'].'/search/packages.json'.'?method=commit&product_id='.$id.'&status=1&version='.$version;
662
                            $this->getRequestApi($request, $authKey, $url, $app);
663
664
                            return $app->redirect($app->url('admin_store_plugin'));
665
                        } catch (PluginException $e) {
666
                            if (!empty($tmpDir) && file_exists($tmpDir)) {
667
                                $fs = new Filesystem();
668
                                $fs->remove($tmpDir);
669
                            }
670
                            $message = $e->getMessage();
671
                        }
672
                    } else {
673
                        $message = $data['error_code'].' : '.$data['error_message'];
674
                    }
675
                } else {
676
                    $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
677
                }
678
            }
679
        }
680
681
        // ダウンロード完了通知処理(エラー発生時)
682
        $url = $this->appConfig['package_repo_url']
683
            .'/search/packages.json'
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
684
            .'?method=commit&product_id='.$id
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
685
            .'&status=0&version='.$version
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
686
            .'&message='.urlencode($message);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
687
        $this->getRequestApi($request, $authKey, $url, $app);
688
        $app->addError($message, 'admin');
689
690
        return $app->redirect($app->url('admin_store_plugin_owners_install'));
691
    }
692
693
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
694
     * 認証キー設定画面
695
     *
696
     * @Route("/{_admin}/store/plugin/authentication_setting", name="admin_store_authentication_setting")
697
     * @Template("Store/authentication_setting.twig")
698
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
699
    public function authenticationSetting(Application $app, Request $request)
700
    {
701
        $builder = $this->formFactory
702
            ->createBuilder(FormType::class, $this->BaseInfo);
703
        $builder->add(
704
            'authentication_key',
705
            TextType::class,
706
            [
707
                'label' => '認証キー',
708
                'constraints' => [
709
                    new Assert\Regex(['pattern' => "/^[0-9a-zA-Z]+$/",]),
0 ignored issues
show
introduced by
Add a single space after each comma delimiter
Loading history...
710
                ],
711
            ]
712
        );
713
714
        $form = $builder->getForm();
715
        $form->handleRequest($request);
716
717
        if ($form->isSubmitted() && $form->isValid()) {
718
            // 認証キーの登録
719
            $BaseInfo = $form->getData();
720
            $this->entityManager->flush($BaseInfo);
721
722
            $app->addSuccess('admin.plugin.authentication.setting.complete', 'admin');
723
        }
724
725
        return [
726
            'form' => $form->createView(),
727
        ];
728
    }
729
730
731
    /**
732
     * APIリクエスト処理
733
     *
734
     * @param Request $request
735
     * @param $authKey
736
     * @param string $url
737
     * @param Application $app
738
     * @return array
739
     */
740
    private function getRequestApi(Request $request, $authKey, $url, $app)
741
    {
742
        $curl = curl_init($url);
743
744
        $options = array(           // オプション配列
745
            //HEADER
746
            CURLOPT_HTTPHEADER => array(
747
                'Authorization: '.base64_encode($authKey),
748
                'x-eccube-store-url: '.base64_encode($request->getSchemeAndHttpHost().$request->getBasePath()),
749
                'x-eccube-store-version: '.base64_encode(Constant::VERSION),
750
            ),
751
            CURLOPT_HTTPGET => true,
752
            CURLOPT_SSL_VERIFYPEER => true,
753
            CURLOPT_RETURNTRANSFER => true,
754
            CURLOPT_FAILONERROR => true,
755
            CURLOPT_CAINFO => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
756
        );
757
758
        curl_setopt_array($curl, $options); /// オプション値を設定
759
        $result = curl_exec($curl);
760
        $info = curl_getinfo($curl);
761
762
        $message = curl_error($curl);
763
        $info['message'] = $message;
764
        curl_close($curl);
765
766
        $app->log('http get_info', $info);
767
768
        return array($result, $info);
769
    }
770
771
    /**
772
     * レスポンスのチェック
773
     *
774
     * @param $info
775
     * @return string
776
     */
777 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...
778
    {
779
        if (!empty($info)) {
780
            $statusCode = $info['http_code'];
781
            $message = $info['message'];
782
783
            $message = $statusCode.' : '.$message;
784
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
785
        } else {
786
            $message = "タイムアウトエラーまたはURLの指定に誤りがあります。";
787
        }
788
789
        return $message;
790
    }
791
792
793
    /**
794
     * フォルダ設置のみのプラグインを取得する.
795
     *
796
     * @param array $plugins
797
     * @param Application $app
798
     * @return array
799
     */
800
    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...
801
    {
802
        $finder = new Finder();
803
        $pluginCodes = array();
804
805
        // DB登録済みプラグインコードのみ取得
806
        foreach ($plugins as $key => $plugin) {
807
            $pluginCodes[] = $plugin->getCode();
808
        }
809
        // DB登録済みプラグインコードPluginディレクトリから排他
810
        $dirs = $finder->in($this->appConfig['plugin_realdir'])->depth(0)->directories();
811
812
        // プラグイン基本チェック
813
        $unregisteredPlugins = array();
814
        foreach ($dirs as $dir) {
815
            $pluginCode = $dir->getBasename();
816
            if (in_array($pluginCode, $pluginCodes, true)) {
817
                continue;
818
            }
819
            try {
820
                $this->pluginService->checkPluginArchiveContent($dir->getRealPath());
821
            } catch (\Eccube\Exception\PluginException $e) {
822
                //config.yamlに不備があった際は全てスキップ
823
                $this->logger->warning($e->getMessage());
824
                continue;
825
            }
826
            $config = $this->pluginService->readYml($dir->getRealPath().'/config.yml');
827
            $unregisteredPlugins[$pluginCode]['name'] = isset($config['name']) ? $config['name'] : null;
828
            $unregisteredPlugins[$pluginCode]['event'] = isset($config['event']) ? $config['event'] : null;
829
            $unregisteredPlugins[$pluginCode]['version'] = isset($config['version']) ? $config['version'] : null;
830
            $unregisteredPlugins[$pluginCode]['enable'] = Constant::DISABLED;
831
            $unregisteredPlugins[$pluginCode]['code'] = isset($config['code']) ? $config['code'] : null;
832
        }
833
834
        return $unregisteredPlugins;
835
    }
836
}
837