Completed
Push — 4.0 ( 87d096...bcc1be )
by Kiyotaka
05:44 queued 11s
created

src/Eccube/Service/PluginApiService.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.ec-cube.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
     * PluginApiService constructor.
56
     *
57
     * @param EccubeConfig $eccubeConfig
58
     * @param RequestStack $requestStack
59
     * @param BaseInfoRepository $baseInfoRepository
60
     * @param PluginRepository $pluginRepository
61
     *
62
     * @throws \Doctrine\ORM\NoResultException
63
     * @throws \Doctrine\ORM\NonUniqueResultException
64
     */
65
    public function __construct(EccubeConfig $eccubeConfig, RequestStack $requestStack, BaseInfoRepository $baseInfoRepository, PluginRepository $pluginRepository)
66
    {
67
        $this->eccubeConfig = $eccubeConfig;
68
        $this->requestStack = $requestStack;
69
        $this->BaseInfo = $baseInfoRepository->get();
70
        $this->pluginRepository = $pluginRepository;
71
    }
72
73
    /**
74
     * @return mixed
75
     */
76
    public function getApiUrl()
77
    {
78
        if (empty($this->apiUrl)) {
79
            return $this->eccubeConfig->get('eccube_package_api_url');
80
        }
81
82
        return $this->apiUrl;
83
    }
84
85
    /**
86
     * @param mixed $apiUrl
87
     */
88
    public function setApiUrl($apiUrl)
89
    {
90
        $this->apiUrl = $apiUrl;
91
    }
92
93
    /**
94
     * Get master data: category
95
     *
96
     * @return array
97
     */
98
    public function getCategory()
99
    {
100
        try {
101
            $urlCategory = $this->getApiUrl().'/category';
102
103
            return $this->requestApi($urlCategory);
104
        } catch (PluginApiException $e) {
105
            return [];
106
        }
107
    }
108
109
    /**
110
     * Get plugins list
111
     *
112
     * @param $data
113
     *
114
     * @return array
115
     *
116
     * @throws PluginApiException
117
     */
118
    public function getPlugins($data)
119
    {
120
        $url = $this->getApiUrl().'/plugins';
121
        $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...
122
        $params['price_type'] = empty($data['price_type']) ? 'all' : $data['price_type'];
123
        $params['keyword'] = $data['keyword'];
124
        $params['sort'] = $data['sort'];
125
        $params['page'] = (isset($data['page_no']) && !empty($data['page_no'])) ? $data['page_no'] : 1;
126
        $params['per_page'] = (isset($data['page_count']) && !empty($data['page_count'])) ? $data['page_count'] : $this->eccubeConfig->get('eccube_default_page_count');
127
128
        $payload = $this->requestApi($url, $params);
129
        $data = json_decode($payload, true);
130
131
        if (isset($data['plugins'])) {
132
            $this->buildPlugins($data['plugins']);
133
        }
134
135
        return $data;
136
    }
137
138
    /**
139
     * Get purchased plugins list
140
     *
141
     * @return array
142
     *
143
     * @throws PluginApiException
144
     */
145 View Code Duplication
    public function getPurchased()
146
    {
147
        $url = $this->getApiUrl().'/plugins/purchased';
148
149
        $payload = $this->requestApi($url);
150
        $plugins = json_decode($payload, true);
151
152
        return $this->buildPlugins($plugins);
153
    }
154
155
    /**
156
     * Get recommended plugins list
157
     *
158
     * @return array($result, $info)
159
     *
160
     * @throws PluginApiException
161
     */
162 View Code Duplication
    public function getRecommended()
163
    {
164
        $url = $this->getApiUrl().'/plugins/recommended';
165
166
        $payload = $this->requestApi($url);
167
        $plugins = json_decode($payload, true);
168
169
        return $this->buildPlugins($plugins);
170
    }
171
172
    private function buildPlugins(&$plugins)
173
    {
174
        /** @var Plugin[] $pluginInstalled */
175
        $pluginInstalled = $this->pluginRepository->findAll();
176
        // Update_status 1 : not install/purchased 、2 : Installed、 3 : Update、4 : not purchased
177
        foreach ($plugins as &$item) {
178
            // Not install/purchased
179
            $item['update_status'] = 1;
180
            foreach ($pluginInstalled as $plugin) {
181
                if ($plugin->getSource() == $item['id']) {
182
                    // Installed
183
                    $item['update_status'] = 2;
184
                    if ($this->isUpdate($plugin->getVersion(), $item['version'])) {
185
                        // Need update
186
                        $item['update_status'] = 3;
187
                    }
188
                }
189
            }
190
            if ($item['purchased'] == false && (isset($item['purchase_required']) && $item['purchase_required'] == true)) {
191
                // Not purchased with paid items
192
                $item['update_status'] = 4;
193
            }
194
195
            $this->buildInfo($item);
196
        }
197
198
        return $plugins;
199
    }
200
201
    /**
202
     * Is update
203
     *
204
     * @param string $pluginVersion
205
     * @param string $remoteVersion
206
     *
207
     * @return boolean
208
     */
209
    private function isUpdate($pluginVersion, $remoteVersion)
210
    {
211
        return version_compare($pluginVersion, $remoteVersion, '<');
212
    }
213
214
    /**
215
     * Get a plugin
216
     *
217
     * @param int|string $id Id or plugin code
218
     *
219
     * @return array
220
     *
221
     * @throws PluginApiException
222
     */
223 View Code Duplication
    public function getPlugin($id)
224
    {
225
        $url = $this->getApiUrl().'/plugin/'.$id;
226
227
        $payload = $this->requestApi($url);
228
        $json = json_decode($payload, true);
229
230
        return $this->buildInfo($json);
231
    }
232
233
    public function pluginInstalled(Plugin $Plugin)
234
    {
235
        $this->updatePluginStatus('/status/installed', $Plugin);
236
    }
237
238
    public function pluginEnabled(Plugin $Plugin)
239
    {
240
        $this->updatePluginStatus('/status/enabled', $Plugin);
241
    }
242
243
    public function pluginDisabled(Plugin $Plugin)
244
    {
245
        $this->updatePluginStatus('/status/disabled', $Plugin);
246
    }
247
248
    public function pluginUninstalled(Plugin $Plugin)
249
    {
250
        $this->updatePluginStatus('/status/uninstalled', $Plugin);
251
    }
252
253
    private function updatePluginStatus($url, Plugin $Plugin)
254
    {
255
        if ($Plugin->getSource()) {
256
            try {
257
                $this->requestApi($this->getApiUrl().$url, ['id' => $Plugin->getSource()], true);
258
            } catch (PluginApiException $ignore) {
259
            }
260
        }
261
    }
262
263
    /**
264
     * API request processing
265
     *
266
     * @param string $url
267
     * @param array $data
268
     *
269
     * @return array
270
     *
271
     * @throws PluginApiException
272
     */
273
    public function requestApi($url, $data = [], $post = false)
274
    {
275
        if ($post === false && count($data) > 0) {
276
            $url .= '?'.http_build_query($data);
277
        }
278
279
        $curl = curl_init($url);
280
281
        if ($post) {
282
            curl_setopt($curl, CURLOPT_POST, 1);
283
284
            if (count($data) > 0) {
285
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
286
            }
287
        }
288
289
        $key = $this->BaseInfo->getAuthenticationKey();
290
291
        $baseUrl = null;
292
        if ($this->requestStack->getCurrentRequest()) {
293
            $baseUrl = $this->requestStack->getCurrentRequest()->getSchemeAndHttpHost().$this->requestStack->getCurrentRequest()->getBasePath();
294
        }
295
296
        // Option array
297
        $options = [
298
            // HEADER
299
            CURLOPT_HTTPHEADER => [
300
                'X-ECCUBE-KEY: '.$key,
301
                'X-ECCUBE-URL: '.$baseUrl,
302
                'X-ECCUBE-VERSION: '.Constant::VERSION,
303
            ],
304
            CURLOPT_HTTPGET => $post === false,
305
            CURLOPT_SSL_VERIFYPEER => false,
306
            CURLOPT_RETURNTRANSFER => true,
307
            CURLOPT_FAILONERROR => true,
308
            CURLOPT_CAINFO => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
309
            CURLOPT_TIMEOUT_MS => 5000,
310
        ];
311
312
        // Set option value
313
        curl_setopt_array($curl, $options);
314
        $result = curl_exec($curl);
315
        $info = curl_getinfo($curl);
316
        $message = curl_error($curl);
317
        $info['message'] = $message;
318
        curl_close($curl);
319
320
        log_info('http get_info', $info);
321
322
        if ($info['http_code'] !== 200) {
323
            throw new PluginApiException($info);
324
        }
325
326
        return $result;
327
    }
328
329
    /**
330
     * Get plugin information
331
     *
332
     * @param array $plugin
333
     *
334
     * @return array
335
     */
336
    public function buildInfo(&$plugin)
337
    {
338
        $this->supportedVersion($plugin);
339
340
        return $plugin;
341
    }
342
343
    /**
344
     * Check support version
345
     *
346
     * @param $plugin
347
     */
348
    public function supportedVersion(&$plugin)
349
    {
350
        // Check the eccube version that the plugin supports.
351
        $plugin['version_check'] = false;
352
        if (in_array(Constant::VERSION, $plugin['supported_versions'])) {
353
            // Match version
354
            $plugin['version_check'] = true;
355
        }
356
    }
357
}
358