Completed
Pull Request — experimental/3.1 (#2588)
by
unknown
48:59 queued 06:16
created

OwnerStoreController::search()   D

Complexity

Conditions 14
Paths 4

Size

Total Lines 82
Code Lines 49

Duplication

Lines 7
Ratio 8.54 %

Code Coverage

Tests 0
CRAP Score 210

Importance

Changes 0
Metric Value
cc 14
eloc 49
nc 4
nop 2
dl 7
loc 82
ccs 0
cts 38
cp 0
crap 210
rs 4.955
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Controller\Admin\Store;
26
27
use Doctrine\ORM\EntityManagerInterface;
28
use Eccube\Annotation\Inject;
29
use Eccube\Application;
30
use Eccube\Common\Constant;
31
use Eccube\Controller\AbstractController;
32
use Eccube\Entity\Plugin;
33
use Eccube\Repository\PluginRepository;
34
use Eccube\Service\PluginService;
35
use Eccube\Service\ComposerProcessService;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
38
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
39
use Symfony\Component\HttpFoundation\RedirectResponse;
40
use Symfony\Component\HttpFoundation\Request;
41
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
42
43
/**
44
 * @Route(service=OwnerStoreController::class)
45
 */
46
class OwnerStoreController extends AbstractController
47
{
48
    /**
49
     * @Inject("config")
50
     * @var array
51
     */
52
    protected $appConfig;
53
54
    /**
55
     * @Inject(PluginRepository::class)
56
     * @var PluginRepository
57
     */
58
    protected $pluginRepository;
59
60
    /**
61
     * @Inject(ComposerProcessService::class)
62
     * @var ComposerProcessService
63
     */
64
    protected $composerService;
65
66
    /**
67
     * Owner's Store Plugin Installation Screen - Search function
68
     *
69
     * @Route("/{_admin}/store/plugin/search", name="admin_store_plugin_owners_search")
70
     * @Template("Store/plugin_search.twig")
71
     * @param Application $app
72
     * @param Request     $request
73
     * @return array
74
     */
75
    public function search(Application $app, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
76
    {
77
        // Acquire downloadable plug-in information from owners store
78
        $success = 0;
79
        $items = array();
80
        $promotionItems = array();
81
        $message = '';
82
        // Owner's store communication
83
        $url = $this->appConfig['owners_store_url'].'?method=list';
84
        list($json, $info) = $this->getRequestApi($url, $app);
85
        if ($json === false) {
86
            $message = $this->getResponseErrorMessage($info);
87
        } else {
88
            $data = json_decode($json, true);
89
            if (isset($data['success'])) {
90
                $success = $data['success'];
91
                if ($success == '1') {
92
                    $items = array();
93
                    // Check plugin installed
94
                    $arrPluginInstalled = $this->pluginRepository->findAll();
95
                    // Update_status 1 : not install/purchased 、2 : Installed、 3 : Update、4 : paid purchase
96
                    foreach ($data['item'] as $item) {
97
                        // Not install/purchased
98
                        $item['update_status'] = 1;
99
                        /** @var Plugin $plugin */
100
                        foreach ($arrPluginInstalled as $plugin) {
101
                            if ($plugin->getSource() == $item['product_id']) {
102
                                // Need update
103
                                $item['update_status'] = 3;
104
                                if ($plugin->getVersion() == $item['version']) {
105
                                    // Installed
106
                                    $item['update_status'] = 2;
107
                                }
108
                            }
109
                        }
110
                        $items[] = $item;
111
                    }
112
113
                    // EC-CUBE version check
114
                    $arrDependency = [];
0 ignored issues
show
Unused Code introduced by
$arrDependency is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
115
                    foreach ($items as &$item) {
116
                        // Not applicable version
117
                        $item['version_check'] = 0;
118
                        if (in_array(Constant::VERSION, $item['eccube_version'])) {
119
                            // Match version
120
                            $item['version_check'] = 1;
121
                        }
122
                        if ($item['price'] != '0' && $item['purchased'] == '0') {
123
                            // Not purchased with paid items
124
                            $item['update_status'] = 4;
125
                        }
126
127
                        // Add plugin dependency
128
                        $item['depend'] = $app['eccube.service.plugin']->getRequirePluginName($items, $item);
129
                    }
130
                    unset($item);
131
132
                    // Promotion item
133
                    $i = 0;
134 View Code Duplication
                    foreach ($items as $item) {
135
                        if ($item['promotion'] == 1) {
136
                            $promotionItems[] = $item;
137
                            unset($items[$i]);
138
                        }
139
                        $i++;
140
                    }
141
                } else {
142
                    $message = $data['error_code'] . ' : ' . $data['error_message'];
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
143
                }
144
            } else {
145
                $success = 0;
146
                $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
147
            }
148
        }
149
150
        return [
151
            'success' => $success,
152
            'items' => $items,
153
            'promotionItems' => $promotionItems,
154
            'message' => $message,
155
        ];
156
    }
157
158
    /**
159
     * Do confirm page
160
     *
161
     * @Route("/{_admin}/store/plugin/{id}/confirm", requirements={"id" = "\d+"}, name="admin_store_plugin_install_confirm")
162
     * @Template("Store/plugin_confirm.twig")
163
     * @param Application $app
164
     * @param Request     $request
165
     * @param string      $id
166
     * @return array
167
     */
168
    public function doConfirm(Application $app, Request $request, $id)
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
169
    {
170
        // Owner's store communication
171
        $url = $this->appConfig['owners_store_url'].'?method=list';
172
        list($json, $info) = $this->getRequestApi($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...
173
        $data = json_decode($json, true);
174
        $items = $data['item'];
175
176
        // Find plugin in api
177
        $index = array_search($id, array_column($items, 'product_id'));
178
        if ($index === false) {
179
            throw new NotFoundHttpException();
180
        }
181
182
        $pluginCode = $items[$index]['product_code'];
183
184
        /**
185
         * @var PluginService $pluginService
186
         */
187
        $pluginService =  $app['eccube.service.plugin'];
188
        $plugin = $pluginService->buildInfo($items, $pluginCode);
189
190
        // Prevent infinity loop: A -> B -> A.
191
        $arrDependency[] = $plugin;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arrDependency was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arrDependency = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
192
        $arrDependency = $pluginService->getDependency($items, $plugin, $arrDependency);
0 ignored issues
show
Bug introduced by
It seems like $plugin defined by $pluginService->buildInfo($items, $pluginCode) on line 188 can also be of type null; however, Eccube\Service\PluginService::getDependency() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
193
        // Unset first param
194
        unset($arrDependency[0]);
195
196
        return [
197
            'item' => $plugin,
198
            'arrDependency' => $arrDependency,
199
        ];
200
    }
201
202
    /**
203
     * Api Install plugin by composer connect with package repo
204
     *
205
     * @Route("/{_admin}/store/plugin/api/{pluginCode}/{eccubeVersion}/{version}" , name="admin_store_plugin_api_install")
206
     *
207
     * @param Application $app
208
     * @param Request     $request
209
     * @param string      $pluginCode
210
     * @param string      $eccubeVersion
211
     * @param string      $version
212
     * @return RedirectResponse
213
     */
214
    public function apiInstall(Application $app, Request $request, $pluginCode, $eccubeVersion, $version)
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
215
    {
216
        // Check plugin code
217
        $url = $this->appConfig['owners_store_url'].'?eccube_version='.$eccubeVersion.'&plugin_code='.$pluginCode.'&version='.$version;
218
        list($json, $info) = $this->getRequestApi($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...
219
        $existFlg = false;
220
        $data = json_decode($json, true);
221
        if ($data && isset($data['success'])) {
222
            $success = $data['success'];
223
            if ($success == '1') {
224
                foreach ($data['item'] as $item) {
225
                    if ($item['product_code'] == $pluginCode) {
226
                        $existFlg = true;
227
                        break;
228
                    }
229
                }
230
            }
231
        }
232
        if ($existFlg === false) {
233
            $app->log(sprintf('%s plugin not found!', $pluginCode));
234
            $app->addError('admin.plugin.not.found', 'admin');
235
236
            return $app->redirect($app->url('admin_store_plugin_owners_search'));
237
        }
238
239
        /**
240
         * Mysql lock in transaction
241
         * @link https://dev.mysql.com/doc/refman/5.7/en/lock-tables.html
242
         * @var EntityManagerInterface $em
243
         */
244
        $em = $app['orm.em'];
245
        if ($em->getConnection()->isTransactionActive()) {
246
            $em->getConnection()->commit();
247
            $em->getConnection()->beginTransaction();
248
        }
249
250
        $return = $this->composerService->execRequire($pluginCode);
251
        if ($return) {
252
            $app->addSuccess('admin.plugin.install.complete', 'admin');
253
254
            return $app->redirect($app->url('admin_store_plugin'));
255
        }
256
        $app->addError('admin.plugin.install.fail', 'admin');
257
258
        return $app->redirect($app->url('admin_store_plugin_owners_search'));
259
    }
260
261
    /**
262
     * New ways to remove plugin: using composer command
263
     *
264
     * @Method("DELETE")
265
     * @Route("/{_admin}/store/plugin/api/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_api_uninstall")
266
     * @param Application $app
267
     * @param Plugin      $Plugin
268
     * @return RedirectResponse
269
     */
270
    public function apiUninstall(Application $app, Plugin $Plugin)
271
    {
272
        $this->isTokenValid($app);
273
274
        if ($Plugin->getEnable() == Constant::ENABLED) {
275
            $app->addError('admin.plugin.uninstall.error.not_disable', 'admin');
276
277
            return $app->redirect($app->url('admin_store_plugin'));
278
        }
279
280
        $pluginCode = $Plugin->getCode();
281
282
283
        /**
284
         * Mysql lock in transaction
285
         * @link https://dev.mysql.com/doc/refman/5.7/en/lock-tables.html
286
         * @var EntityManagerInterface $em
287
         */
288
        $em = $app['orm.em'];
289
        if ($em->getConnection()->isTransactionActive()) {
290
            $em->getConnection()->commit();
291
            $em->getConnection()->beginTransaction();
292
        }
293
294
        $return = $this->composerService->execRemove($pluginCode);
295
        if ($return) {
296
            $app->addSuccess('admin.plugin.uninstall.complete', 'admin');
297
        } else {
298
            $app->addError('admin.plugin.uninstall.error', 'admin');
299
        }
300
301
        return $app->redirect($app->url('admin_store_plugin'));
302
    }
303
304
    /**
305
     * API request processing
306
     *
307
     * @param string  $url
308
     * @param Application $app
309
     * @return array
310
     */
311
    private function getRequestApi($url, $app)
312
    {
313
        $curl = curl_init($url);
314
315
        // Option array
316
        $options = array(
317
            // HEADER
318
            CURLOPT_HTTPGET => true,
319
            CURLOPT_SSL_VERIFYPEER => false,
320
            CURLOPT_RETURNTRANSFER => true,
321
            CURLOPT_FAILONERROR => true,
322
            CURLOPT_CAINFO => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
323
        );
324
325
        // Set option value
326
        curl_setopt_array($curl, $options);
327
        $result = curl_exec($curl);
328
        $info = curl_getinfo($curl);
329
        $message = curl_error($curl);
330
        $info['message'] = $message;
331
        curl_close($curl);
332
333
        $app->log('http get_info', $info);
334
335
        return array($result, $info);
336
    }
337
338
    /**
339
     * Get message
340
     *
341
     * @param $info
342
     * @return string
343
     */
344 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...
345
    {
346
        if (!empty($info)) {
347
            $statusCode = $info['http_code'];
348
            $message = $info['message'];
349
350
            $message = $statusCode.' : '.$message;
351
        } else {
352
            $message = "タイムアウトエラーまたはURLの指定に誤りがあります。";
353
        }
354
355
        return $message;
356
    }
357
}
358