Passed
Push — master ( 745178...3deda8 )
by Alexey
03:44
created

ProxyBonanza::getLocalProxies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the wow-apps/symfony-proxybonanza project
4
 * https://github.com/wow-apps/symfony-proxybonanza
5
 *
6
 * (c) 2016 WoW-Apps
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WowApps\ProxybonanzaBundle\Service;
13
14
use GuzzleHttp\Client as GuzzleClient;
15
use GuzzleHttp\Exception\ClientException;
16
use WowApps\ProxybonanzaBundle\Entity\AuthIps;
17
use WowApps\ProxybonanzaBundle\Entity\Plan;
18
use WowApps\ProxybonanzaBundle\Entity\Proxy;
19
use WowApps\ProxybonanzaBundle\Repository\AuthIpsRepository;
20
use WowApps\ProxybonanzaBundle\Repository\PlanRepository;
21
use WowApps\ProxybonanzaBundle\Repository\ProxiesRepository;
22
use WowApps\ProxybonanzaBundle\Traits\HelperTrait;
23
24
/**
25
 * Class ProxyBonanza
26
 * @author Alexey Samara <[email protected]>
27
 * @package wow-apps/symfony-proxybonanza
28
 */
29
class ProxyBonanza
30
{
31
    use HelperTrait;
32
33
    /** @var array */
34
    private $config;
35
36
    /** @var GuzzleClient */
37
    private $guzzleClient;
38
39
    /** @var PlanRepository */
40
    private $planRepository;
41
42
    /** @var ProxiesRepository */
43
    private $proxiesRepository;
44
45
    /** @var AuthIpsRepository */
46
    private $authIpsRepository;
47
48
    /**
49
     * ProxyBonanza constructor.
50
     * @param array $config
51
     * @param PlanRepository $planRepository
52
     * @param ProxiesRepository $proxiesRepository
53
     * @param AuthIpsRepository $authIpsRepository
54
     */
55
    public function __construct(
56
        array $config,
57
        PlanRepository $planRepository,
58
        ProxiesRepository $proxiesRepository,
59
        AuthIpsRepository $authIpsRepository
60
    ) {
61
        $this->setConfig($config);
62
        $this->planRepository = $planRepository;
63
        $this->proxiesRepository = $proxiesRepository;
64
        $this->authIpsRepository = $authIpsRepository;
65
        $this->guzzleClient = new GuzzleClient(
66
            ['headers' => ['Authorization' => $this->config['api_key']]]
67
        );
68
    }
69
70
    /**
71
     * @return array
72
     */
73
    public function getConfig(): array
74
    {
75
        return $this->config;
76
    }
77
78
    /**
79
     * @param array $config
80
     * @return ProxyBonanza
81
     */
82
    public function setConfig(array $config)
83
    {
84
        $this->config = $config;
85
        return $this;
86
    }
87
88
    /**
89
     * @param string $url
90
     * @return array
91
     * @throws \RuntimeException
92
     */
93
    private function getAPIResponse(string $url): array
94
    {
95
        try {
96
            $request = $this->guzzleClient->get($url);
97
        } catch (ClientException $e) {
98
            throw new \RuntimeException($e->getMessage());
99
        }
100
101
        $response = $request->getBody();
102
103
        $json = json_decode($response, true);
104
        if (!$json) {
105
            throw new \RuntimeException('Can\'t parse json');
106
        }
107
108
        if (!$json['success']) {
109
            throw new \RuntimeException('Error in response');
110
        }
111
112
        return $json;
113
    }
114
115
    /**
116
     * @return \ArrayObject|Plan[]
117
     */
118
    public function getRemotePlans(): \ArrayObject
119
    {
120
        $result = new \ArrayObject();
121
122
        $proxyBonanzaPlans = $this->getAPIResponse($this->config['api_url'] . 'userpackages.json');
123
        if (empty($proxyBonanzaPlans['data'])) {
124
            return $result;
125
        }
126
127
        foreach ($proxyBonanzaPlans['data'] as $plan) {
128
            $proxyBonanzaPlan = new Plan();
129
            $proxyBonanzaPlan
130
                ->setId((int)$plan['id'])
131
                ->setLogin($plan['login'])
132
                ->setPassword($plan['password'])
133
                ->setExpires($this->convertDateTime($plan['expires']))
134
                ->setBandwidth($plan['bandwidth'])
135
                ->setLastIpChange($this->convertDateTime($plan['last_ip_change']))
136
                ->setPackageName($plan['package']['name'])
137
                ->setPackageBandwidth($plan['package']['bandwidth'])
138
                ->setPackagePrice((float) $plan['package']['price'])
139
                ->setPackageHowmanyIps((int) $plan['package']['howmany_ips'])
140
                ->setPackagePricePerGig((float) $plan['package']['price_per_gig'])
0 ignored issues
show
Bug introduced by
(double)$plan['package']['price_per_gig'] of type double is incompatible with the type integer expected by parameter $packagePricePerGig of WowApps\ProxybonanzaBund...setPackagePricePerGig(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

140
                ->setPackagePricePerGig(/** @scrutinizer ignore-type */ (float) $plan['package']['price_per_gig'])
Loading history...
141
                ->setPackageType($plan['package']['package_type'])
142
            ;
143
144
            $result->offsetSet($proxyBonanzaPlan->getId(), $proxyBonanzaPlan);
145
        }
146
147
        return $result;
148
    }
149
150
    /**
151
     * @param \ArrayObject|Plan[] $pbPlans
152
     * @return \ArrayObject|Plan[]
153
     */
154
    public function getRemotePacks(\ArrayObject $pbPlans): \ArrayObject
155
    {
156
        if (!$pbPlans->count()) {
157
            throw new \InvalidArgumentException('Can\'t get ip packs for empty plans');
158
        }
159
160
        /** @var Plan $pbPlan */
161
        foreach ($pbPlans as $pbPlan) {
162
            $pbPackUrl = $this->config['api_url'] . sprintf('userpackages/%s.json', $pbPlan->getId());
163
164
            $pbPack = $this->getAPIResponse($pbPackUrl);
165
            if (empty($pbPack['data']['ippacks'])) {
166
                continue;
167
            }
168
169
            foreach ($pbPack['data']['ippacks'] as $item) {
170
                $proxy = new Proxy();
171
                $proxy
172
                    ->setProxyId((int)$item['id'])
173
                    ->setProxyIp($item['ip'])
174
                    ->setProxyPlan($pbPlan->getId())
175
                    ->setPlan($pbPlan)
176
                    ->setProxyPortHttp((int)$item['port_http'])
177
                    ->setProxyPortSocks((int)$item['port_socks'])
178
                    ->setProxyRegionId((int)$item['proxyserver']['georegion_id'])
179
                    ->setProxyRegionCountryName($item['proxyserver']['georegion']['name'])
180
                ;
181
182
                $pbPlan->appendProxy($proxy);
183
            }
184
185
            if (empty($pbPack['data']['authips'])) {
186
                continue;
187
            }
188
189
            foreach ($pbPack['data']['authips'] as $item) {
190
                $authIp = new AuthIps();
191
                $authIp
192
                    ->setId((int)$item['id'])
193
                    ->setIp($item['id'])
194
                ;
195
                $pbPlan->appendAuthIp($authIp);
196
            }
197
        }
198
199
        return $pbPlans;
200
    }
201
202
    /**
203
     * @param \ArrayObject|Plan[] $pbPlans
204
     */
205
    public function updateLocalDataFromRemote(\ArrayObject $pbPlans = null)
206
    {
207
        if (is_null($pbPlans) || !$pbPlans->count()) {
208
            $pbPlans = $this->getRemotePlans();
209
            $pbPlans = $this->getRemotePacks($pbPlans);
210
        }
211
212
        $this->planRepository->empty();
213
        $this->planRepository->insertPlans($pbPlans);
214
215
        $this->proxiesRepository->empty();
216
        $this->proxiesRepository->insertProxies($pbPlans);
217
218
        $this->authIpsRepository->empty();
219
        $this->authIpsRepository->insertAuthIps($pbPlans);
220
    }
221
222
    /**
223
     * @param int $planId
224
     * @return Plan
225
     * @throws \InvalidArgumentException
226
     */
227
    public function getLocalPlan(int $planId): Plan
228
    {
229
        return $this->planRepository->getLocalPlan($planId);
230
    }
231
232
    /**
233
     * @return \ArrayObject|Plan[]
234
     * @throws \InvalidArgumentException
235
     */
236
    public function getLocalPlans(): \ArrayObject
237
    {
238
        $proxyBonanzaPlans = $this->planRepository->getLocalPlans();
239
240
        if (empty($proxyBonanzaPlans)) {
241
            throw new \InvalidArgumentException('No local plans founded. Run proxybonanza:update to set local plans.');
242
        }
243
244
        return $proxyBonanzaPlans;
245
    }
246
247
    /**
248
     * @param Plan|null $pbPlan
249
     * @return \ArrayObject|Proxy[]
250
     */
251
    public function getLocalProxies(Plan $pbPlan = null): \ArrayObject
252
    {
253
        return $this->proxiesRepository->getLocalProxies($pbPlan);
254
    }
255
256
    /**
257
     * @param \ArrayObject|Plan[] $pbPlans
258
     * @return \ArrayObject|Plan[]
259
     */
260
    public function getLocalPlansProxies(\ArrayObject $pbPlans): \ArrayObject
261
    {
262
        if (empty($pbPlans)) {
263
            return $pbPlans;
264
        }
265
266
        foreach ($pbPlans as $pbPlan) {
267
            $pbPlan->setProxy($this->getLocalProxies($pbPlan));
268
        }
269
270
        return $pbPlans;
271
    }
272
273
    /**
274
     * @param \ArrayObject|Proxy[] $proxies
275
     * @return Proxy
276
     */
277
    public function getRandomProxy(\ArrayObject $proxies): Proxy
278
    {
279
        $keys = $this->getArrayObjectKeys($proxies);
280
        return $proxies->offsetGet(
281
            $keys[array_rand($keys, 1)]
282
        );
283
    }
284
285
    /**
286
     * @param Proxy $proxy
287
     * @return bool
288
     */
289
    public function testProxyConnection(Proxy $proxy): bool
290
    {
291
        $client = new GuzzleClient();
292
293
        $proxyTCP = [
294
            'http' => 'tcp://' . $proxy->getPlan()->getLogin() . ':'
295
                . $proxy->getPlan()->getPassword() . '@'
296
                . $proxy->getProxyIp() . ':'
297
                . $proxy->getProxyPortHttp(),
298
            'https' => 'tcp://' . $proxy->getPlan()->getLogin() . ':'
299
                . $proxy->getPlan()->getPassword() . '@'
300
                . $proxy->getProxyIp() . ':'
301
                . $proxy->getProxyPortHttp(),
302
        ];
303
304
        $response = $client->request('GET', 'http://google.com', ['proxy' => $proxyTCP]);
305
306
        if (!in_array($response->getStatusCode(), [200, 301, 302])) {
307
            return false;
308
        }
309
310
        return true;
311
    }
312
}
313