Completed
Push — dev/recommend-plugins ( 237cf5...24efa6 )
by Kiyotaka
07:07
created

PluginApiService::supportedVersion()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Service;
15
16
use Eccube\Common\Constant;
17
use Eccube\Common\EccubeConfig;
18
use Eccube\Entity\BaseInfo;
19
use Eccube\Entity\Plugin;
20
use Eccube\Exception\PluginApiException;
21
use Eccube\Repository\BaseInfoRepository;
22
use Eccube\Repository\PluginRepository;
23
use Symfony\Component\HttpFoundation\RequestStack;
24
25
class PluginApiService
26
{
27
    /**
28
     * Url for Api
29
     *
30
     * @var string
31
     */
32
    private $apiUrl;
33
34
    /**
35
     * @var EccubeConfig
36
     */
37
    private $eccubeConfig;
38
39
    /**
40
     * @var RequestStack
41
     */
42
    private $requestStack;
43
44
    /**
45
     * @var BaseInfo
46
     */
47
    private $BaseInfo;
48
49
    /**
50
     * @var PluginRepository
51
     */
52
    private $pluginRepository;
53
54
    /**
55
     * @var PluginService
56
     */
57
    private $pluginService;
58
59
    /**
60
     * PluginApiService constructor.
61
     *
62
     * @param EccubeConfig $eccubeConfig
63
     * @param RequestStack $requestStack
64
     * @param BaseInfoRepository $baseInfoRepository
65
     * @param PluginRepository $pluginRepository
66
     * @param PluginService $pluginService
67
     *
68
     * @throws \Doctrine\ORM\NoResultException
69
     * @throws \Doctrine\ORM\NonUniqueResultException
70
     */
71 View Code Duplication
    public function __construct(EccubeConfig $eccubeConfig, RequestStack $requestStack, BaseInfoRepository $baseInfoRepository, PluginRepository $pluginRepository, PluginService $pluginService)
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...
72
    {
73
        $this->eccubeConfig = $eccubeConfig;
74
        $this->requestStack = $requestStack;
75
        $this->BaseInfo = $baseInfoRepository->get();
76
        $this->pluginRepository = $pluginRepository;
77
        $this->pluginService = $pluginService;
78
    }
79
80
    /**
81
     * @return mixed
82
     */
83
    public function getApiUrl()
84
    {
85
        if (empty($this->apiUrl)) {
86
            return $this->eccubeConfig->get('eccube_package_api_url');
87
        }
88
89
        return $this->apiUrl;
90
    }
91
92
    /**
93
     * @param mixed $apiUrl
94
     */
95
    public function setApiUrl($apiUrl)
96
    {
97
        $this->apiUrl = $apiUrl;
98
    }
99
100
    /**
101
     * Get master data: category
102
     *
103
     * @return array
104
     */
105
    public function getCategory()
106
    {
107
        try {
108
            $urlCategory = $this->getApiUrl().'/category';
109
110
            return $this->getRequestApi($urlCategory);
111
        } catch (PluginApiException $e) {
112
            return [];
113
        }
114
    }
115
116
    /**
117
     * Get plugins list
118
     *
119
     * @param $data
120
     *
121
     * @return array
122
     *
123
     * @throws PluginApiException
124
     */
125
    public function getPlugins($data)
126
    {
127
        $url = $this->getApiUrl().'/plugins';
128
        $params['category_id'] = $data['category_id'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = 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...
129
        $params['price_type'] = empty($data['price_type']) ? 'all' : $data['price_type'];
130
        $params['keyword'] = $data['keyword'];
131
        $params['sort'] = $data['sort'];
132
        $params['page'] = (isset($data['page_no']) && !empty($data['page_no'])) ? $data['page_no'] : 1;
133
        $params['per_page'] = (isset($data['page_count']) && !empty($data['page_count'])) ? $data['page_count'] : $this->eccubeConfig->get('eccube_default_page_count');
134
135
        $payload = $this->getRequestApi($url, $params);
136
        $data = json_decode($payload, true);
137
138
        if (isset($data['plugins'])) {
139
            $this->buildPlugins($data['plugins']);
140
        }
141
142
        return $data;
143
    }
144
145
    /**
146
     * Get purchased plugins list
147
     *
148
     * @return array
149
     *
150
     * @throws PluginApiException
151
     */
152 View Code Duplication
    public function getPurchased()
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...
153
    {
154
        $url = $this->getApiUrl().'/plugins/purchased';
155
156
        $payload = $this->getRequestApi($url);
157
        $plugins = json_decode($payload, true);
158
159
        return $this->buildPlugins($plugins);
160
    }
161
162
    /**
163
     * Get recommended plugins list
164
     *
165
     * @return array($result, $info)
0 ignored issues
show
Documentation introduced by
The doc-type array($result, could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
166
     *
167
     * @throws PluginApiException
168
     */
169 View Code Duplication
    public function getRecommended()
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...
170
    {
171
        $url = $this->getApiUrl().'/plugins/recommended';
172
173
        $payload = $this->getRequestApi($url);
174
        $plugins = json_decode($payload, true);
175
176
        return $this->buildPlugins($plugins);
177
    }
178
179
    private function buildPlugins(&$plugins)
180
    {
181
        /** @var Plugin[] $pluginInstalled */
182
        $pluginInstalled = $this->pluginRepository->findAll();
183
        // Update_status 1 : not install/purchased 、2 : Installed、 3 : Update、4 : not purchased
184
        foreach ($plugins as &$item) {
185
            // Not install/purchased
186
            $item['update_status'] = 1;
187
            foreach ($pluginInstalled as $plugin) {
188
                if ($plugin->getSource() == $item['id']) {
189
                    // Installed
190
                    $item['update_status'] = 2;
191
                    if ($this->pluginService->isUpdate($plugin->getVersion(), $item['version'])) {
192
                        // Need update
193
                        $item['update_status'] = 3;
194
                    }
195
                }
196
            }
197
            if ($item['purchased'] == false && (isset($item['purchase_required']) && $item['purchase_required'] == true)) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $item['purchase_required'] of type integer to the boolean true. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
198
                // Not purchased with paid items
199
                $item['update_status'] = 4;
200
            }
201
202
            $item = $this->buildInfo($item);
203
            $items[] = $item;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$items was never initialized. Although not strictly required by PHP, it is generally a good practice to add $items = 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...
204
        }
205
206
        return $plugins;
207
    }
208
209
    /**
210
     * Get a plugin
211
     *
212
     * @param int|string $id Id or plugin code
213
     *
214
     * @return array
215
     *
216
     * @throws PluginApiException
217
     */
218 View Code Duplication
    public function getPlugin($id)
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...
219
    {
220
        $url = $this->getApiUrl().'/plugin/'.$id;
221
222
        $payload = $this->getRequestApi($url);
223
        $json = json_decode($payload, true);
224
225
        return $this->buildInfo($json);
226
    }
227
228
    /**
229
     * API request processing
230
     *
231
     * @param string $url
232
     * @param array $data
233
     *
234
     * @return array
235
     *
236
     * @throws PluginApiException
237
     */
238
    public function getRequestApi($url, $data = [])
239
    {
240
        if (count($data) > 0) {
241
            $url .= '?'.http_build_query($data);
242
        }
243
244
        $curl = curl_init($url);
245
246
        $key = $this->BaseInfo->getAuthenticationKey();
247
        $baseUrl = $this->requestStack->getCurrentRequest()->getSchemeAndHttpHost().$this->requestStack->getCurrentRequest()->getBasePath();
248
249
        // Option array
250
        $options = [
251
            // HEADER
252
            CURLOPT_HTTPHEADER => [
253
                'X-ECCUBE-KEY: '.$key,
254
                'X-ECCUBE-URL: '.$baseUrl,
255
                'X-ECCUBE-VERSION: '.Constant::VERSION,
256
            ],
257
            CURLOPT_HTTPGET => true,
258
            CURLOPT_SSL_VERIFYPEER => false,
259
            CURLOPT_RETURNTRANSFER => true,
260
            CURLOPT_FAILONERROR => true,
261
            CURLOPT_CAINFO => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
262
        ];
263
264
        // Set option value
265
        curl_setopt_array($curl, $options);
266
        $result = curl_exec($curl);
267
        $info = curl_getinfo($curl);
268
        $message = curl_error($curl);
269
        $info['message'] = $message;
270
        curl_close($curl);
271
272
        log_info('http get_info', $info);
273
274
        if ($info['http_code'] !== 200) {
275
            throw new PluginApiException($info);
276
        }
277
278
        return $result;
279
    }
280
281
    /**
282
     * Get plugin information
283
     *
284
     * @param array $plugin
285
     *
286
     * @return array|null
287
     */
288
    public function buildInfo(&$plugin)
289
    {
290
        $this->supportedVersion($plugin);
291
292
        return $plugin;
293
    }
294
295
    /**
296
     * Check support version
297
     *
298
     * @param $plugin
299
     */
300
    public function supportedVersion(&$plugin)
301
    {
302
        // Check the eccube version that the plugin supports.
303
        $plugin['version_check'] = false;
304
        if (in_array(Constant::VERSION, $plugin['supported_versions'])) {
305
            // Match version
306
            $plugin['version_check'] = true;
307
        }
308
    }
309
}
310