Failed Conditions
Pull Request — experimental/3.1 (#2636)
by
unknown
82:48
created

PluginController::handler()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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