Completed
Pull Request — experimental/3.1 (#2594)
by
unknown
133:28 queued 09:38
created

PluginController::handler_down()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 7
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 7
loc 7
ccs 0
cts 4
cp 0
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
crap 2
1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Controller\Admin\Store;
26
27
use Doctrine\ORM\EntityManager;
28
use Eccube\Annotation\Inject;
29
use Eccube\Application;
30
use Eccube\Common\Constant;
31
use Eccube\Controller\AbstractController;
32
use Eccube\Entity\BaseInfo;
33
use Eccube\Entity\Plugin;
34
use Eccube\Entity\PluginEventHandler;
35
use Eccube\Exception\PluginException;
36
use Eccube\Form\Type\Admin\PluginLocalInstallType;
37
use Eccube\Form\Type\Admin\PluginManagementType;
38
use Eccube\Repository\PluginEventHandlerRepository;
39
use Eccube\Repository\PluginRepository;
40
use Eccube\Service\PluginService;
41
use Eccube\Util\Str;
42
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
43
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
44
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
45
use Symfony\Bridge\Monolog\Logger;
46
use Symfony\Component\Config\Definition\Exception\Exception;
47
use Symfony\Component\Filesystem\Filesystem;
48
use Symfony\Component\Finder\Finder;
49
use Symfony\Component\Form\Extension\Core\Type\FormType;
50
use Symfony\Component\Form\Extension\Core\Type\TextType;
51
use Symfony\Component\Form\FormFactory;
52
use Symfony\Component\HttpFoundation\RedirectResponse;
53
use Symfony\Component\HttpFoundation\Request;
54
use Symfony\Component\Process\Process;
55
use Symfony\Component\Routing\Exception\RouteNotFoundException;
56
use Symfony\Component\Validator\Constraints as Assert;
57
58
/**
59
 * @Route(service=PluginController::class)
60
 */
61
class PluginController extends AbstractController
62
{
63
    /**
64
     * @Inject("orm.em")
65
     * @var EntityManager
66
     */
67
    protected $entityManager;
68
69
    /**
70
     * @Inject("monolog")
71
     * @var Logger
72
     */
73
    protected $logger;
74
75
    /**
76
     * @Inject(PluginEventHandlerRepository::class)
77
     * @var PluginEventHandlerRepository
78
     */
79
    protected $pluginEventHandlerRepository;
80
81
    /**
82
     * @Inject(PluginService::class)
83
     * @var PluginService
84
     */
85
    protected $pluginService;
86
87
    /**
88
     * @Inject("config")
89
     * @var array
90
     */
91
    protected $appConfig;
92
93
    /**
94
     * @Inject(BaseInfo::class)
95
     * @var BaseInfo
96
     */
97
    protected $BaseInfo;
98
99
    /**
100
     * @Inject("form.factory")
101
     * @var FormFactory
102
     */
103
    protected $formFactory;
104
105
    /**
106
     * @Inject(PluginRepository::class)
107
     * @var PluginRepository
108
     */
109
    protected $pluginRepository;
110
111
112
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
113
     * インストール済プラグイン画面
114
     *
115
     * @Route("/{_admin}/store/plugin", name="admin_store_plugin")
116
     * @Template("Store/plugin.twig")
117
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
118
    public function index(Application $app, Request $request)
119
    {
120
        $pluginForms = array();
121
        $configPages = array();
122
123
        $Plugins = $this->pluginRepository->findBy(array(), array('code' => 'ASC'));
124
125
        // ファイル設置プラグインの取得.
126
        $unregisterdPlugins = $this->getUnregisteredPlugins($Plugins, $app);
127
        $unregisterdPluginsConfigPages = array();
128
        foreach ($unregisterdPlugins as $unregisterdPlugin) {
129
            try {
130
                $code = $unregisterdPlugin['code'];
131
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
132
                $unregisterdPluginsConfigPages[$code] = $app->url('plugin_'.$code.'_config');
133
            } catch (RouteNotFoundException $e) {
134
                // プラグインで設定画面のルートが定義されていない場合は無視
135
            }
136
        }
137
138
        $officialPlugins = array();
139
        $unofficialPlugins = array();
140
141
        foreach ($Plugins as $Plugin) {
142
            $form = $this->formFactory
143
                ->createNamedBuilder(
144
                    'form'.$Plugin->getId(),
145
                    PluginManagementType::class,
146
                    null,
147
                    array(
148
                        'plugin_id' => $Plugin->getId(),
149
                    )
150
                )
151
                ->getForm();
152
            $pluginForms[$Plugin->getId()] = $form->createView();
153
154
            try {
155
                // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
156
                $configPages[$Plugin->getCode()] = $app->url('plugin_'.$Plugin->getCode().'_config');
157
            } catch (\Exception $e) {
158
                // プラグインで設定画面のルートが定義されていない場合は無視
159
            }
160
161
            if ($Plugin->getSource() == 0) {
162
                // 商品IDが設定されていない場合、非公式プラグイン
163
                $unofficialPlugins[] = $Plugin;
164
            } else {
165
                $officialPlugins[] = $Plugin;
166
            }
167
        }
168
169
        // Todo: Need new authentication mechanism
170
        // オーナーズストアからダウンロード可能プラグイン情報を取得
171
        $authKey = $this->BaseInfo->getAuthenticationKey();
172
//        if (!is_null($authKey)) {
173
174
        // オーナーズストア通信
175
        $url = $this->appConfig['owners_store_url'].'?method=list';
176
        list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app);
0 ignored issues
show
Unused Code introduced by
The assignment to $info is unused. Consider omitting it like so list($first,,$third).

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

Consider the following code example.

<?php

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

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

print $a . " - " . $c;

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

Instead, the list call could have been.

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

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

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

Loading history...
266
                }
267
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
268
            }
269
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
270
        }
271
272
        $app->addError($message, 'admin');
273
274
        return $app->redirect($app->url('admin_store_plugin'));
275
    }
276
277
278
    /**
279
     * 対象のプラグインを有効にします。
280
     * Update new mechanism to check dependency plugin
281
     *
282
     * @Method("PUT")
283
     * @Route("/{_admin}/store/plugin/{id}/enable", requirements={"id" = "\d+"}, name="admin_store_plugin_enable")
284
     * @param Application $app
285
     * @param Plugin      $Plugin
286
     * @return RedirectResponse
287
     */
288
    public function enable(Application $app, Plugin $Plugin)
289
    {
290
        $this->isTokenValid($app);
291
292
        if ($Plugin->getEnable() == Constant::ENABLED) {
293
            $app->addError('admin.plugin.already.enable', 'admin');
294
        } else {
295
            $require = $this->pluginService->findRequirePluginNeedEnable($Plugin->getCode());
296
            if (!empty($require)) {
297
                $DependPlugin = $this->pluginRepository->findOneBy(['code' => $require[0]]);
298
                $dependName = $require[0];
299
                if ($DependPlugin) {
300
                    $dependName = $DependPlugin->getName();
301
                }
302
                $app->addError($Plugin->getName().'を有効化するためには、先に'.$dependName.'を有効化してください。', 'admin');
303
304
                return $app->redirect($app->url('admin_store_plugin'));
305
            }
306
            $this->pluginService->enable($Plugin);
307
            $app->addSuccess('admin.plugin.enable.complete', 'admin');
308
        }
309
310
        return $app->redirect($app->url('admin_store_plugin'));
311
    }
312
313
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$Plugin" missing
Loading history...
314
     * 対象のプラグインを無効にします。
315
     *
316
     * @Method("PUT")
317
     * @Route("/{_admin}/store/plugin/{id}/disable", requirements={"id" = "\d+"}, name="admin_store_plugin_disable")
318
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
319
    public function disable(Application $app, Plugin $Plugin)
320
    {
321
        $this->isTokenValid($app);
322
323
        if ($Plugin->getEnable() == Constant::ENABLED) {
324
            $this->pluginService->disable($Plugin);
325
            $app->addSuccess('admin.plugin.disable.complete', 'admin');
326
        } else {
327
            $app->addError('admin.plugin.already.disable', 'admin');
328
        }
329
330
        return $app->redirect($app->url('admin_store_plugin'));
331
    }
332
333
334
    /**
335
     * 対象のプラグインを削除します。
336
     * Update new ways to remove plugin: using composer command
337
     *
338
     * @Method("DELETE")
339
     * @Route("/{_admin}/store/plugin/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_uninstall")
340
     * @param Application $app
341
     * @param Plugin      $Plugin
342
     * @return RedirectResponse
343
     */
344
    public function uninstall(Application $app, Plugin $Plugin)
345
    {
346
        $this->isTokenValid($app);
347
348
        if ($Plugin->getEnable() == Constant::ENABLED) {
349
            $app->addError('admin.plugin.uninstall.error.not_disable', 'admin');
350
351
            return $app->redirect($app->url('admin_store_plugin'));
352
        }
353
354
        $pluginCode = $Plugin->getCode();
355
        try {
356
            $execute = sprintf('cd %s &&', $this->appConfig['root_dir']);
357
            $execute .= sprintf(' composer remove ec-cube/%s', $pluginCode);
358
359
            // 環境に依存せず動作させるために
360
            // TODO: サーバー環境に応じて、この処理をやるやらないを切り替える必要あり
361
            @ini_set('memory_limit', '1536M');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

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