Failed Conditions
Push — experimental/3.1 ( fc835a...c7d2b5 )
by chihiro
251:51 queued 244:35
created

PluginController::getRequestApi()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 20
nc 1
nop 4
dl 0
loc 30
ccs 0
cts 8
cp 0
crap 2
rs 8.8571
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\Filesystem\Filesystem;
47
use Symfony\Component\Finder\Finder;
48
use Symfony\Component\Form\Extension\Core\Type\FormType;
49
use Symfony\Component\Form\Extension\Core\Type\TextType;
50
use Symfony\Component\Form\FormFactory;
51
use Symfony\Component\HttpFoundation\File\UploadedFile;
52
use Symfony\Component\HttpFoundation\RedirectResponse;
53
use Symfony\Component\HttpFoundation\Request;
54
use Symfony\Component\Routing\Exception\RouteNotFoundException;
55
use Symfony\Component\Validator\Constraints as Assert;
56
57
/**
58
 * @Route(service=PluginController::class)
59
 */
60
class PluginController extends AbstractController
61
{
62
    /**
63
     * @Inject("orm.em")
64
     * @var EntityManager
65
     */
66
    protected $entityManager;
67
68
    /**
69
     * @Inject("monolog")
70
     * @var Logger
71
     */
72
    protected $logger;
73
74
    /**
75
     * @Inject(PluginEventHandlerRepository::class)
76
     * @var PluginEventHandlerRepository
77
     */
78
    protected $pluginEventHandlerRepository;
79
80
    /**
81
     * @Inject(PluginService::class)
82
     * @var PluginService
83
     */
84
    protected $pluginService;
85
86
    /**
87
     * @Inject("config")
88
     * @var array
89
     */
90
    protected $appConfig;
91
92
    /**
93
     * @Inject(BaseInfo::class)
94
     * @var BaseInfo
95
     */
96
    protected $BaseInfo;
97
98
    /**
99
     * @Inject("form.factory")
100
     * @var FormFactory
101
     */
102
    protected $formFactory;
103
104
    /**
105
     * @Inject(PluginRepository::class)
106
     * @var PluginRepository
107
     */
108
    protected $pluginRepository;
109
110
111
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
112
     * インストール済プラグイン画面
113
     *
114
     * @Route("/{_admin}/store/plugin", name="admin_store_plugin")
115
     * @Template("Store/plugin.twig")
116
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
117
    public function index(Application $app, Request $request)
118
    {
119
        $pluginForms = array();
120
        $configPages = array();
121
122
        $Plugins = $this->pluginRepository->findBy(array(), array('code' => 'ASC'));
123
124
        // ファイル設置プラグインの取得.
125
        $unregisterdPlugins = $this->getUnregisteredPlugins($Plugins, $app);
126
        $unregisterdPluginsConfigPages = array();
127
        foreach ($unregisterdPlugins as $unregisterdPlugin) {
128
            try {
129
                $code = $unregisterdPlugin['code'];
130
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
131
                $unregisterdPluginsConfigPages[$code] = $app->url('plugin_'.$code.'_config');
132
            } catch (RouteNotFoundException $e) {
133
                // プラグインで設定画面のルートが定義されていない場合は無視
134
            }
135
        }
136
137
        $officialPlugins = array();
138
        $unofficialPlugins = array();
139
140
        foreach ($Plugins as $Plugin) {
141
            $form = $this->formFactory
142
                ->createNamedBuilder(
143
                    'form'.$Plugin->getId(),
144
                    PluginManagementType::class,
145
                    null,
146
                    array(
147
                        'plugin_id' => $Plugin->getId(),
148
                    )
149
                )
150
                ->getForm();
151
            $pluginForms[$Plugin->getId()] = $form->createView();
152
153
            try {
154
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
155
                $configPages[$Plugin->getCode()] = $app->url('plugin_'.$Plugin->getCode().'_config');
156
            } catch (\Exception $e) {
157
                // プラグインで設定画面のルートが定義されていない場合は無視
158
            }
159
160
            if ($Plugin->getSource() == 0) {
161
                // 商品IDが設定されていない場合、非公式プラグイン
162
                $unofficialPlugins[] = $Plugin;
163
            } else {
164
                $officialPlugins[] = $Plugin;
165
            }
166
        }
167
168
        // Todo: Need new authentication mechanism
169
        // オーナーズストアからダウンロード可能プラグイン情報を取得
170
        $authKey = $this->BaseInfo->getAuthenticationKey();
171
//        if (!is_null($authKey)) {
172
173
        // オーナーズストア通信
174
        $url = $this->appConfig['package_repo_url'].'/search/packages.json';
175
        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...
176
177
        $officialPluginsDetail = [];
178
        if ($json) {
179
            // 接続成功時
180
            $data = json_decode($json, true);
181
            if (isset($data['success'])) {
182
                $success = $data['success'];
183
                if ($success == '1') {
184
                    foreach ($data['item'] as $item) {
185
                        foreach ($officialPlugins as $key => $plugin) {
186
                            if ($plugin->getSource() == $item['product_id']) {
187
                                $officialPluginsDetail[$key] = $item;
188
                                $officialPluginsDetail[$key]['update_status'] = 0;
189
                                if ($plugin->getVersion() != $item['version']) {
190
                                    $officialPluginsDetail[$key]['update_status'] = 1;
191
                                }
192
                            }
193
                        }
194
                    }
195
                }
196
            }
197
        }
198
199
        return [
200
            'plugin_forms' => $pluginForms,
201
            'officialPlugins' => $officialPlugins,
202
            'unofficialPlugins' => $unofficialPlugins,
203
            'configPages' => $configPages,
204
            'unregisterdPlugins' => $unregisterdPlugins,
205
            'unregisterdPluginsConfigPages' => $unregisterdPluginsConfigPages,
206
            'officialPluginsDetail' => $officialPluginsDetail,
207
        ];
208
    }
209
210
    /**
211
     * インストール済プラグインからのアップデート
212
     *
213
     * @Method("POST")
214
     * @Route("/{_admin}/store/plugin/{id}/update", requirements={"id" = "\d+"}, name="admin_store_plugin_update")
215
     * @param Application $app
216
     * @param Request     $request
217
     * @param Plugin      $Plugin
218
     * @return RedirectResponse
219
     */
220
    public function update(Application $app, Request $request, Plugin $Plugin)
221
    {
222
        $form = $this->formFactory
223
            ->createNamedBuilder(
224
                'form'.$Plugin->getId(),
225
                PluginManagementType::class,
226
                null,
227
                array(
228
                    'plugin_id' => null, // placeHolder
229
                )
230
            )
231
            ->getForm();
232
233
        $message = '';
234
        $form->handleRequest($request);
235
        if ($form->isSubmitted() && $form->isValid()) {
236
            $tmpDir = null;
237
            try {
238
                $formFile = $form['plugin_archive']->getData();
239
                $tmpDir = $this->pluginService->createTempDir();
240
                $tmpFile = sha1(Str::random(32)).'.'.$formFile->getClientOriginalExtension();
241
                $formFile->move($tmpDir, $tmpFile);
242
                $this->pluginService->update($Plugin, $tmpDir.'/'.$tmpFile);
243
                $fs = new Filesystem();
244
                $fs->remove($tmpDir);
245
                $app->addSuccess('admin.plugin.update.complete', 'admin');
246
247
                return $app->redirect($app->url('admin_store_plugin'));
248
            } catch (PluginException $e) {
249
                if (!empty($tmpDir) && file_exists($tmpDir)) {
250
                    $fs = new Filesystem();
251
                    $fs->remove($tmpDir);
252
                }
253
                $message = $e->getMessage();
254
            } catch (\Exception $er) {
255
                // Catch composer install error | Other error
256
                if (!empty($tmpDir) && file_exists($tmpDir)) {
257
                    $fs = new Filesystem();
258
                    $fs->remove($tmpDir);
259
                }
260
                $this->logger->error("plugin install failed.", array('original-message' => $er->getMessage()));
261
                $message = 'admin.plugin.install.fail';
262
            }
263
        } else {
264
            $errors = $form->getErrors(true);
265
            foreach ($errors as $error) {
266
                $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...
267
            }
268
        }
269
270
        $app->addError($message, 'admin');
271
272
        return $app->redirect($app->url('admin_store_plugin'));
273
    }
274
275
276
    /**
277
     * 対象のプラグインを有効にします。
278
     *
279
     * @Method("PUT")
280
     * @Route("/{_admin}/store/plugin/{id}/enable", requirements={"id" = "\d+"}, name="admin_store_plugin_enable")
281
     * @param Application $app
282
     * @param Plugin      $Plugin
283
     * @return RedirectResponse
284
     */
285 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...
286
    {
287
        $this->isTokenValid($app);
288
289
        if ($Plugin->isEnable()) {
290
            $app->addError('admin.plugin.already.enable', 'admin');
291
        } else {
292
            $requires = $this->pluginService->findRequirePluginNeedEnable($Plugin->getCode());
293
            if (!empty($requires)) {
294
                $DependPlugin = $this->pluginRepository->findOneBy(['code' => $requires[0]]);
295
                $dependName = $requires[0];
296
                if ($DependPlugin) {
297
                    $dependName = $DependPlugin->getName();
298
                }
299
                $message = $app->trans('admin.plugin.enable.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
300
                $app->addError($message, 'admin');
301
302
                return $app->redirect($app->url('admin_store_plugin'));
303
            }
304
            $this->pluginService->enable($Plugin);
305
            $app->addSuccess('admin.plugin.enable.complete', 'admin');
306
        }
307
308
        return $app->redirect($app->url('admin_store_plugin'));
309
    }
310
311
    /**
312
     * 対象のプラグインを無効にします。
313
     *
314
     * @Method("PUT")
315
     * @Route("/{_admin}/store/plugin/{id}/disable", requirements={"id" = "\d+"}, name="admin_store_plugin_disable")
316
     * @param Application $app
317
     * @param Plugin      $Plugin
318
     * @return RedirectResponse
319
     */
320 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...
321
    {
322
        $this->isTokenValid($app);
323
324
        if ($Plugin->isEnable()) {
325
            $dependents = $this->pluginService->findDependentPluginNeedDisable($Plugin->getCode());
326
            if (!empty($dependents)) {
327
                $dependName = $dependents[0];
328
                $DependPlugin = $this->pluginRepository->findOneBy(['code' => $dependents[0]]);
329
                if ($DependPlugin) {
330
                    $dependName = $DependPlugin->getName();
331
                }
332
                $message = $app->trans('admin.plugin.disable.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
333
                $app->addError($message, 'admin');
334
335
                return $app->redirect($app->url('admin_store_plugin'));
336
            }
337
338
            $this->pluginService->disable($Plugin);
339
            $app->addSuccess('admin.plugin.disable.complete', 'admin');
340
        } else {
341
            $app->addError('admin.plugin.already.disable', 'admin');
342
        }
343
344
        return $app->redirect($app->url('admin_store_plugin'));
345
    }
346
347
    /**
348
     * 対象のプラグインを削除します。
349
     *
350
     * @Method("DELETE")
351
     * @Route("/{_admin}/store/plugin/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_uninstall")
352
     * @param Application $app
353
     * @param Plugin      $Plugin
354
     * @return RedirectResponse
355
     */
356
    public function uninstall(Application $app, Plugin $Plugin)
357
    {
358
        $this->isTokenValid($app);
359
        // Check other plugin depend on it
360
        $pluginCode = $Plugin->getCode();
361
        $otherDepend = $this->pluginService->findDependentPlugin($pluginCode);
362
        if (!empty($otherDepend)) {
363
            $DependPlugin = $this->pluginRepository->findOneBy(['code' => $otherDepend[0]]);
364
            $dependName = $otherDepend[0];
365
            if ($DependPlugin) {
366
                $dependName = $DependPlugin->getName();
367
            }
368
            $message = $app->trans('admin.plugin.uninstall.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
369
            $app->addError($message, 'admin');
370
371
            return $app->redirect($app->url('admin_store_plugin'));
372
        }
373
374
        $this->pluginService->uninstall($Plugin);
375
        $app->addSuccess('admin.plugin.uninstall.complete', 'admin');
376
377
        return $app->redirect($app->url('admin_store_plugin'));
378
    }
379
380
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
381
     * @Route("/{_admin}/store/plugin/handler", name="admin_store_plugin_handler")
382
     * @Template("Store/plugin_handler.twig")
383
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
384
    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...
385
    {
386
        $handlers = $this->pluginEventHandlerRepository->getHandlers();
387
388
        // 一次元配列からイベント毎の二次元配列に変換する
389
        $HandlersPerEvent = array();
390
        foreach ($handlers as $handler) {
391
            $HandlersPerEvent[$handler->getEvent()][$handler->getHandlerType()][] = $handler;
392
        }
393
394
        return [
395
            'handlersPerEvent' => $HandlersPerEvent,
396
        ];
397
    }
398
399
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Handler" missing
Loading history...
400
     * @Route("/{_admin}/store/plugin/handler_up/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_up")
401
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
402 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...
403
    {
404
        $repo = $this->pluginEventHandlerRepository;
405
        $repo->upPriority($repo->find($Handler->getId()));
406
407
        return $app->redirect($app->url('admin_store_plugin_handler'));
408
    }
409
410
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Handler" missing
Loading history...
411
     * @Route("/{_admin}/store/plugin/handler_down/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_down")
412
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
413 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...
414
    {
415
        $repo = $this->pluginEventHandlerRepository;
416
        $repo->upPriority($Handler, false);
417
418
        return $app->redirect($app->url('admin_store_plugin_handler'));
419
    }
420
421
    /**
422
     * プラグインファイルアップロード画面
423
     *
424
     * @Route("/{_admin}/store/plugin/install", name="admin_store_plugin_install")
425
     * @Template("Store/plugin_install.twig")
426
     * @param Application $app
427
     * @param Request     $request
428
     * @return array|RedirectResponse
429
     */
430
    public function install(Application $app, Request $request)
431
    {
432
        $form = $this->formFactory
433
            ->createBuilder(PluginLocalInstallType::class)
434
            ->getForm();
435
        $errors = array();
436
        $form->handleRequest($request);
437
        if ($form->isSubmitted() && $form->isValid()) {
438
            $tmpDir = null;
439
            try {
440
                $service = $this->pluginService;
441
                /** @var UploadedFile $formFile */
442
                $formFile = $form['plugin_archive']->getData();
443
                $tmpDir = $service->createTempDir();
444
                // 拡張子を付けないとpharが動かないので付ける
445
                $tmpFile = sha1(Str::random(32)).'.'.$formFile->getClientOriginalExtension();
446
                $formFile->move($tmpDir, $tmpFile);
447
                $tmpPath = $tmpDir.'/'.$tmpFile;
448
                $service->install($tmpPath);
449
                // Remove tmp file
450
                $fs = new Filesystem();
451
                $fs->remove($tmpDir);
452
                $app->addSuccess('admin.plugin.install.complete', 'admin');
453
454
                return $app->redirect($app->url('admin_store_plugin'));
455
            } catch (PluginException $e) {
456
                if (!empty($tmpDir) && file_exists($tmpDir)) {
457
                    $fs = new Filesystem();
458
                    $fs->remove($tmpDir);
459
                }
460
                $this->logger->error("plugin install failed.", array('original-message' => $e->getMessage()));
461
                $errors[] = $e;
462
            } catch (\Exception $er) {
463
                // Catch composer install error | Other error
464
                if (!empty($tmpDir) && file_exists($tmpDir)) {
465
                    $fs = new Filesystem();
466
                    $fs->remove($tmpDir);
467
                }
468
                $this->logger->error("plugin install failed.", array('original-message' => $er->getMessage()));
469
                $app->addError('admin.plugin.install.fail', 'admin');
470
            }
471
        } else {
472
            foreach ($form->getErrors(true) as $error) {
473
                $errors[] = $error;
474
            }
475
        }
476
477
        return [
478
            'form' => $form->createView(),
479
            'errors' => $errors,
480
        ];
481
    }
482
483
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
484
     * オーナーズストアプラグインインストール画面
485
     *
486
     * @Route("/{_admin}/store/plugin/owners_install", name="admin_store_plugin_owners_install")
487
     * @Template("Store/plugin_owners_install.twig")
488
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
489
    public function ownersInstall(Application $app, Request $request)
490
    {
491
        // オーナーズストアからダウンロード可能プラグイン情報を取得
492
        $authKey = $this->BaseInfo->getAuthenticationKey();
493
        $authResult = true;
494
        $success = 0;
495
        $items = array();
496
        $promotionItems = array();
497
        $message = '';
498
        if (!is_null($authKey)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
499
500
            // オーナーズストア通信
501
            $url = $this->appConfig['package_repo_url'].'/search/packages.json';
502
            list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
503
504
            if ($json === false) {
505
                // 接続失敗時
506
                $success = 0;
507
508
                $message = $this->getResponseErrorMessage($info);
509
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
510
            } else {
511
                // 接続成功時
512
513
                $data = json_decode($json, true);
514
515
                if (isset($data['success'])) {
516
                    $success = $data['success'];
517
                    if ($success == '1') {
518
                        $items = array();
519
520
                        // 既にインストールされているかどうか確認
521
                        $Plugins = $this->pluginRepository->findAll();
522
                        $status = false;
523
                        // update_status 1 : 未インストール、2 : インストール済、 3 : 更新あり、4 : 有料購入
524
                        foreach ($data['item'] as $item) {
525
                            foreach ($Plugins as $plugin) {
526
                                if ($plugin->getSource() == $item['product_id']) {
527
                                    if ($plugin->getVersion() == $item['version']) {
528
                                        // バージョンが同じ
529
                                        $item['update_status'] = 2;
530
                                    } else {
531
                                        // バージョンが異なる
532
                                        $item['update_status'] = 3;
533
                                    }
534
                                    $items[] = $item;
535
                                    $status = true;
536
                                    break;
537
                                }
538
                            }
539
                            if (!$status) {
540
                                // 未インストール
541
                                $item['update_status'] = 1;
542
                                $items[] = $item;
543
                            }
544
                            $status = false;
545
                        }
546
547
                        // EC-CUBEのバージョンチェック
548
                        // 参照渡しをして値を追加
549
                        foreach ($items as &$item) {
550
                            if (in_array(Constant::VERSION, $item['eccube_version'])) {
551
                                // 対象バージョン
552
                                $item['version_check'] = 1;
553
                            } else {
554
                                // 未対象バージョン
555
                                $item['version_check'] = 0;
556
                            }
557
                            if ($item['price'] != '0' && $item['purchased'] == '0') {
558
                                // 有料商品で未購入
559
                                $item['update_status'] = 4;
560
                            }
561
                        }
562
                        unset($item);
563
564
                        // promotionアイテム
565
                        $i = 0;
566 View Code Duplication
                        foreach ($items as $item) {
567
                            if ($item['promotion'] == 1) {
568
                                $promotionItems[] = $item;
569
                                unset($items[$i]);
570
                            }
571
                            $i++;
572
                        }
573
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
574
                    } else {
575
                        $message = $data['error_code'].' : '.$data['error_message'];
576
                    }
577
                } else {
578
                    $success = 0;
579
                    $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
580
                }
581
            }
582
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
583
        } else {
584
            $authResult = false;
585
        }
586
587
        return [
588
            'authResult' => $authResult,
589
            'success' => $success,
590
            'items' => $items,
591
            'promotionItems' => $promotionItems,
592
            'message' => $message,
593
        ];
594
    }
595
596
    /**
597
     * オーナーズブラグインインストール、アップデート
598
     *
599
     * @Route("/{_admin}/store/plugin/upgrade/{action}/{id}/{version}", requirements={"id" = "\d+"}, name="admin_store_plugin_upgrade")
600
     * @param Application $app
601
     * @param Request     $request
602
     * @param string      $action
603
     * @param int         $id
604
     * @param string      $version
605
     * @return RedirectResponse
606
     */
607
    public function upgrade(Application $app, Request $request, $action, $id, $version)
608
    {
609
        $authKey = $this->BaseInfo->getAuthenticationKey();
610
        $message = '';
611
        if (!is_null($authKey)) {
612
            // オーナーズストア通信
613
            $url = $this->appConfig['package_repo_url'].'/search/packages.json'.'?method=download&product_id='.$id;
614
            list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
615
            if ($json === false) {
616
                // 接続失敗時
617
                $message = $this->getResponseErrorMessage($info);
618
            } else {
619
                // 接続成功時
620
                $data = json_decode($json, true);
621
                if (isset($data['success'])) {
622
                    $success = $data['success'];
623
                    if ($success == '1') {
624
                        $tmpDir = null;
625
                        try {
626
                            $service = $this->pluginService;
627
                            $item = $data['item'];
628
                            $file = base64_decode($item['data']);
629
                            $extension = pathinfo($item['file_name'], PATHINFO_EXTENSION);
630
                            $tmpDir = $service->createTempDir();
631
                            $tmpFile = sha1(Str::random(32)).'.'.$extension;
632
633
                            // ファイル作成
634
                            $fs = new Filesystem();
635
                            $fs->dumpFile($tmpDir.'/'.$tmpFile, $file);
636
637
                            if ($action == 'install') {
638
                                $service->install($tmpDir.'/'.$tmpFile, $id);
639
                                $app->addSuccess('admin.plugin.install.complete', 'admin');
640
                            } else {
641
                                if ($action == 'update') {
642
                                    $Plugin = $this->pluginRepository->findOneBy(array('source' => $id));
643
                                    $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...
644
                                    $app->addSuccess('admin.plugin.update.complete', 'admin');
645
                                }
646
                            }
647
648
                            $fs = new Filesystem();
649
                            $fs->remove($tmpDir);
650
651
                            // ダウンロード完了通知処理(正常終了時)
652
                            $url = $this->appConfig['package_repo_url'].'/search/packages.json'.'?method=commit&product_id='.$id.'&status=1&version='.$version;
653
                            $this->getRequestApi($request, $authKey, $url, $app);
654
655
                            return $app->redirect($app->url('admin_store_plugin'));
656
                        } catch (PluginException $e) {
657
                            if (!empty($tmpDir) && file_exists($tmpDir)) {
658
                                $fs = new Filesystem();
659
                                $fs->remove($tmpDir);
660
                            }
661
                            $message = $e->getMessage();
662
                        }
663
                    } else {
664
                        $message = $data['error_code'].' : '.$data['error_message'];
665
                    }
666
                } else {
667
                    $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
668
                }
669
            }
670
        }
671
672
        // ダウンロード完了通知処理(エラー発生時)
673
        $url = $this->appConfig['package_repo_url']
674
            .'/search/packages.json'
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
675
            .'?method=commit&product_id='.$id
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
676
            .'&status=0&version='.$version
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
677
            .'&message='.urlencode($message);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
678
        $this->getRequestApi($request, $authKey, $url, $app);
679
        $app->addError($message, 'admin');
680
681
        return $app->redirect($app->url('admin_store_plugin_owners_install'));
682
    }
683
684
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
685
     * 認証キー設定画面
686
     *
687
     * @Route("/{_admin}/store/plugin/authentication_setting", name="admin_store_authentication_setting")
688
     * @Template("Store/authentication_setting.twig")
689
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
690
    public function authenticationSetting(Application $app, Request $request)
691
    {
692
        $builder = $this->formFactory
693
            ->createBuilder(FormType::class, $this->BaseInfo);
694
        $builder->add(
695
            'authentication_key',
696
            TextType::class,
697
            [
698
                'label' => '認証キー',
699
                'constraints' => [
700
                    new Assert\Regex(['pattern' => "/^[0-9a-zA-Z]+$/",]),
0 ignored issues
show
introduced by
Add a single space after each comma delimiter
Loading history...
701
                ],
702
            ]
703
        );
704
705
        $form = $builder->getForm();
706
        $form->handleRequest($request);
707
708
        if ($form->isSubmitted() && $form->isValid()) {
709
            // 認証キーの登録
710
            $BaseInfo = $form->getData();
711
            $this->entityManager->flush($BaseInfo);
712
713
            $app->addSuccess('admin.plugin.authentication.setting.complete', 'admin');
714
        }
715
716
        return [
717
            'form' => $form->createView(),
718
        ];
719
    }
720
721
722
    /**
723
     * APIリクエスト処理
724
     *
725
     * @param Request $request
726
     * @param $authKey
727
     * @param string $url
728
     * @param Application $app
729
     * @return array
730
     */
731
    private function getRequestApi(Request $request, $authKey, $url, $app)
732
    {
733
        $curl = curl_init($url);
734
735
        $options = array(           // オプション配列
736
            //HEADER
737
            CURLOPT_HTTPHEADER => array(
738
                'Authorization: '.base64_encode($authKey),
739
                'x-eccube-store-url: '.base64_encode($request->getSchemeAndHttpHost().$request->getBasePath()),
740
                'x-eccube-store-version: '.base64_encode(Constant::VERSION),
741
            ),
742
            CURLOPT_HTTPGET => true,
743
            CURLOPT_SSL_VERIFYPEER => true,
744
            CURLOPT_RETURNTRANSFER => true,
745
            CURLOPT_FAILONERROR => true,
746
            CURLOPT_CAINFO => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
747
        );
748
749
        curl_setopt_array($curl, $options); /// オプション値を設定
750
        $result = curl_exec($curl);
751
        $info = curl_getinfo($curl);
752
753
        $message = curl_error($curl);
754
        $info['message'] = $message;
755
        curl_close($curl);
756
757
        $app->log('http get_info', $info);
758
759
        return array($result, $info);
760
    }
761
762
    /**
763
     * レスポンスのチェック
764
     *
765
     * @param $info
766
     * @return string
767
     */
768 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...
769
    {
770
        if (!empty($info)) {
771
            $statusCode = $info['http_code'];
772
            $message = $info['message'];
773
774
            $message = $statusCode.' : '.$message;
775
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
776
        } else {
777
            $message = "タイムアウトエラーまたはURLの指定に誤りがあります。";
778
        }
779
780
        return $message;
781
    }
782
783
784
    /**
785
     * フォルダ設置のみのプラグインを取得する.
786
     *
787
     * @param array $plugins
788
     * @param Application $app
789
     * @return array
790
     */
791
    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...
792
    {
793
        $finder = new Finder();
794
        $pluginCodes = array();
795
796
        // DB登録済みプラグインコードのみ取得
797
        foreach ($plugins as $key => $plugin) {
798
            $pluginCodes[] = $plugin->getCode();
799
        }
800
        // DB登録済みプラグインコードPluginディレクトリから排他
801
        $dirs = $finder->in($this->appConfig['plugin_realdir'])->depth(0)->directories();
802
803
        // プラグイン基本チェック
804
        $unregisteredPlugins = array();
805
        foreach ($dirs as $dir) {
806
            $pluginCode = $dir->getBasename();
807
            if (in_array($pluginCode, $pluginCodes, true)) {
808
                continue;
809
            }
810
            try {
811
                $this->pluginService->checkPluginArchiveContent($dir->getRealPath());
812
            } catch (\Eccube\Exception\PluginException $e) {
813
                //config.yamlに不備があった際は全てスキップ
814
                $this->logger->warning($e->getMessage());
815
                continue;
816
            }
817
            $config = $this->pluginService->readYml($dir->getRealPath().'/config.yml');
818
            $unregisteredPlugins[$pluginCode]['name'] = isset($config['name']) ? $config['name'] : null;
819
            $unregisteredPlugins[$pluginCode]['event'] = isset($config['event']) ? $config['event'] : null;
820
            $unregisteredPlugins[$pluginCode]['version'] = isset($config['version']) ? $config['version'] : null;
821
            $unregisteredPlugins[$pluginCode]['enable'] = Constant::DISABLED;
822
            $unregisteredPlugins[$pluginCode]['code'] = isset($config['code']) ? $config['code'] : null;
823
        }
824
825
        return $unregisteredPlugins;
826
    }
827
}
828