Completed
Pull Request — experimental/3.1 (#2588)
by
unknown
87:26
created

OwnerStoreController::apiInstall()   C

Complexity

Conditions 8
Paths 15

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 23
nc 15
nop 5
dl 0
loc 39
ccs 0
cts 17
cp 0
crap 72
rs 5.3846
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 Eccube\Annotation\Inject;
28
use Eccube\Application;
29
use Eccube\Common\Constant;
30
use Eccube\Controller\AbstractController;
31
use Eccube\Entity\Plugin;
32
use Eccube\Repository\PluginRepository;
33
use Eccube\Service\PluginService;
34
use Eccube\Service\ComposerProcessService;
35
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
38
use Symfony\Component\HttpFoundation\RedirectResponse;
39
use Symfony\Component\HttpFoundation\Request;
40
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
41
42
/**
43
 * @Route(service=OwnerStoreController::class)
44
 */
45
class OwnerStoreController extends AbstractController
46
{
47
    /**
48
     * @Inject("config")
49
     * @var array
50
     */
51
    protected $appConfig;
52
53
    /**
54
     * @Inject(PluginRepository::class)
55
     * @var PluginRepository
56
     */
57
    protected $pluginRepository;
58
59
    /**
60
     * Owner's Store Plugin Installation Screen - Search function
61
     *
62
     * @Route("/{_admin}/store/plugin/search", name="admin_store_plugin_owners_search")
63
     * @Template("Store/plugin_search.twig")
64
     * @param Application $app
65
     * @param Request     $request
66
     * @return array
67
     */
68
    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...
69
    {
70
        // Acquire downloadable plug-in information from owners store
71
        $success = 0;
72
        $items = array();
73
        $promotionItems = array();
74
        $message = '';
75
        // Owner's store communication
76
        $url = $this->appConfig['owners_store_url'].'?method=list';
77
        list($json, $info) = $this->getRequestApi($url, $app);
78
        if ($json === false) {
79
            $message = $this->getResponseErrorMessage($info);
80
        } else {
81
            $data = json_decode($json, true);
82
            if (isset($data['success'])) {
83
                $success = $data['success'];
84
                if ($success == '1') {
85
                    $items = array();
86
                    // Check plugin installed
87
                    $arrPluginInstalled = $this->pluginRepository->findAll();
88
                    // Update_status 1 : not install/purchased 、2 : Installed、 3 : Update、4 : paid purchase
89
                    foreach ($data['item'] as $item) {
90
                        // Not install/purchased
91
                        $item['update_status'] = 1;
92
                        /** @var Plugin $plugin */
93
                        foreach ($arrPluginInstalled as $plugin) {
94
                            if ($plugin->getSource() == $item['product_id']) {
95
                                // Need update
96
                                $item['update_status'] = 3;
97
                                if ($plugin->getVersion() == $item['version']) {
98
                                    // Installed
99
                                    $item['update_status'] = 2;
100
                                }
101
                            }
102
                        }
103
                        $items[] = $item;
104
                    }
105
106
                    // EC-CUBE version check
107
                    $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...
108
                    foreach ($items as &$item) {
109
                        // Not applicable version
110
                        $item['version_check'] = 0;
111
                        if (in_array(Constant::VERSION, $item['eccube_version'])) {
112
                            // Match version
113
                            $item['version_check'] = 1;
114
                        }
115
                        if ($item['price'] != '0' && $item['purchased'] == '0') {
116
                            // Not purchased with paid items
117
                            $item['update_status'] = 4;
118
                        }
119
120
                        // Add plugin dependency
121
                        $item['depend'] = $app['eccube.service.plugin']->getRequirePluginName($items, $item);
122
                    }
123
                    unset($item);
124
125
                    // Promotion item
126
                    $i = 0;
127 View Code Duplication
                    foreach ($items as $item) {
128
                        if ($item['promotion'] == 1) {
129
                            $promotionItems[] = $item;
130
                            unset($items[$i]);
131
                        }
132
                        $i++;
133
                    }
134
                } else {
135
                    $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...
136
                }
137
            } else {
138
                $success = 0;
139
                $message = "EC-CUBEオーナーズストアにエラーが発生しています。";
140
            }
141
        }
142
143
        return [
144
            'success' => $success,
145
            'items' => $items,
146
            'promotionItems' => $promotionItems,
147
            'message' => $message,
148
        ];
149
    }
150
151
    /**
152
     * Do confirm page
153
     *
154
     * @Route("/{_admin}/store/plugin/{id}/confirm", requirements={"id" = "\d+"}, name="admin_store_plugin_install_confirm")
155
     * @Template("Store/plugin_confirm.twig")
156
     * @param Application $app
157
     * @param Request     $request
158
     * @param string      $id
159
     * @return array
160
     */
161
    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...
162
    {
163
        // Owner's store communication
164
        $url = $this->appConfig['owners_store_url'].'?method=list';
165
        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...
166
        $data = json_decode($json, true);
167
        $items = $data['item'];
168
169
        // Find plugin in api
170
        $index = array_search($id, array_column($items, 'product_id'));
171
        if ($index === false) {
172
            throw new NotFoundHttpException();
173
        }
174
175
        $pluginCode = $items[$index]['product_code'];
176
177
        /**
178
         * @var PluginService $pluginService
179
         */
180
        $pluginService =  $app['eccube.service.plugin'];
181
        $plugin = $pluginService->buildInfo($items, $pluginCode);
182
183
        // Prevent infinity loop: A -> B -> A.
184
        $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...
185
        $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 181 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...
186
        // Unset first param
187
        unset($arrDependency[0]);
188
189
        return [
190
            'item' => $plugin,
191
            'arrDependency' => $arrDependency,
192
        ];
193
    }
194
195
    /**
196
     * Api Install plugin by composer connect with package repo
197
     *
198
     * @Route("/{_admin}/store/plugin/api/{pluginCode}/{eccubeVersion}/{version}" , name="admin_store_plugin_api_install")
199
     *
200
     * @param Application $app
201
     * @param Request     $request
202
     * @param string      $pluginCode
203
     * @param string      $eccubeVersion
204
     * @param string      $version
205
     * @return RedirectResponse
206
     */
207
    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...
208
    {
209
        // Check plugin code
210
        $url = $this->appConfig['owners_store_url'].'?eccube_version='.$eccubeVersion.'&plugin_code='.$pluginCode.'&version='.$version;
211
        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...
212
        $existFlg = false;
213
        $data = json_decode($json, true);
214
        if ($data && isset($data['success'])) {
215
            $success = $data['success'];
216
            if ($success == '1') {
217
                foreach ($data['item'] as $item) {
218
                    if ($item['product_code'] == $pluginCode) {
219
                        $existFlg = true;
220
                        break;
221
                    }
222
                }
223
            }
224
        }
225
        if ($existFlg === false) {
226
            $app->log(sprintf('%s plugin not found!', $pluginCode));
227
            $app->addError('admin.plugin.not.found', 'admin');
228
229
            return $app->redirect($app->url('admin_store_plugin_owners_search'));
230
        }
231
232
        /**
233
         * @var ComposerProcessService $composerService
234
         */
235
        $composerService = $app['eccube.service.composer'];
236
        $return = $composerService->execRequire($pluginCode);
237
        if ($return) {
238
            $app->addSuccess('admin.plugin.install.complete', 'admin');
239
240
            return $app->redirect($app->url('admin_store_plugin'));
241
        }
242
        $app->addError('admin.plugin.install.fail', 'admin');
243
244
        return $app->redirect($app->url('admin_store_plugin_owners_search'));
245
    }
246
247
    /**
248
     * New ways to remove plugin: using composer command
249
     *
250
     * @Method("DELETE")
251
     * @Route("/{_admin}/store/plugin/api/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_api_uninstall")
252
     * @param Application $app
253
     * @param Plugin      $Plugin
254
     * @return RedirectResponse
255
     */
256
    public function apiUninstall(Application $app, Plugin $Plugin)
257
    {
258
        $this->isTokenValid($app);
259
260
        if ($Plugin->getEnable() == Constant::ENABLED) {
261
            $app->addError('admin.plugin.uninstall.error.not_disable', 'admin');
262
263
            return $app->redirect($app->url('admin_store_plugin'));
264
        }
265
266
        $pluginCode = $Plugin->getCode();
267
268
        /**
269
         * @var ComposerProcessService $composerService
270
         */
271
        $composerService = $app['eccube.service.composer'];
272
        $return = $composerService->execRemove($pluginCode);
273
        if ($return) {
274
            $app->addSuccess('admin.plugin.uninstall.complete', 'admin');
275
        } else {
276
            $app->addError('admin.plugin.uninstall.error', 'admin');
277
        }
278
279
        return $app->redirect($app->url('admin_store_plugin'));
280
    }
281
282
    /**
283
     * API request processing
284
     *
285
     * @param string  $url
286
     * @param Application $app
287
     * @return array
288
     */
289
    private function getRequestApi($url, $app)
290
    {
291
        $curl = curl_init($url);
292
293
        // Option array
294
        $options = array(
295
            // HEADER
296
            CURLOPT_HTTPGET => true,
297
            CURLOPT_SSL_VERIFYPEER => false,
298
            CURLOPT_RETURNTRANSFER => true,
299
            CURLOPT_FAILONERROR => true,
300
            CURLOPT_CAINFO => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
301
        );
302
303
        // Set option value
304
        curl_setopt_array($curl, $options);
305
        $result = curl_exec($curl);
306
        $info = curl_getinfo($curl);
307
        $message = curl_error($curl);
308
        $info['message'] = $message;
309
        curl_close($curl);
310
311
        $app->log('http get_info', $info);
312
313
        return array($result, $info);
314
    }
315
316
    /**
317
     * Get message
318
     *
319
     * @param $info
320
     * @return string
321
     */
322 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...
323
    {
324
        if (!empty($info)) {
325
            $statusCode = $info['http_code'];
326
            $message = $info['message'];
327
328
            $message = $statusCode.' : '.$message;
329
        } else {
330
            $message = "タイムアウトエラーまたはURLの指定に誤りがあります。";
331
        }
332
333
        return $message;
334
    }
335
}
336