Completed
Push — master ( e9f67d...a8539b )
by Hector
22s
created

TwitterAds::setAccount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hborras\TwitterAdsSDK;
4
5
use Exception;
6
use Hborras\TwitterAdsSDK\TwitterAds\Account;
7
use Hborras\TwitterAdsSDK\TwitterAds\Cursor;
8
use Hborras\TwitterAdsSDK\TwitterAds\Errors\BadRequest;
9
use Hborras\TwitterAdsSDK\TwitterAds\Errors\Forbidden;
10
use Hborras\TwitterAdsSDK\TwitterAds\Errors\NotAuthorized;
11
use Hborras\TwitterAdsSDK\TwitterAds\Errors\NotFound;
12
use Hborras\TwitterAdsSDK\TwitterAds\Errors\RateLimit;
13
use Hborras\TwitterAdsSDK\TwitterAds\Errors\ServerError;
14
use Hborras\TwitterAdsSDK\TwitterAds\Errors\ServiceUnavailable;
15
use Hborras\TwitterAdsSDK\Util\JsonDecoder;
16
17
/**
18
 * TwitterAds class for interacting with the Twitter API.
19
 *
20
 * @author Hector Borras <[email protected]>
21
 */
22
class TwitterAds extends Config
23
{
24
    const API_VERSION = '3';
25
    const API_REST_VERSION = '1.1';
26
    const API_HOST = 'https://ads-api.twitter.com';
27
    const API_HOST_SANDBOX = 'https://ads-api-sandbox.twitter.com';
28
    const API_HOST_OAUTH = 'https://api.twitter.com';
29
    const UPLOAD_HOST = 'https://upload.twitter.com';
30
    const UPLOAD_PATH = 'media/upload.json';
31
    const UPLOAD_CHUNK = 40960; // 1024 * 40
32
33
    /** @var TwitterAds */
34
    protected static $instance;
35
    /** @var  string Method used for the request */
36
    private $method;
37
    /** @var  string Resource used for the request */
38
    private $resource;
39
    /** @var Response details about the result of the last request */
40
    private $response;
41
    /** @var string|null Application bearer token */
42
    private $bearer;
43
    /** @var Consumer Twitter application details */
44
    private $consumer;
45
    /** @var Token|null User access token details */
46
    private $token;
47
    /** @var HmacSha1 OAuth 1 signature type used by Twitter */
48
    private $signatureMethod;
49
    /** @var  bool Sandbox allows to make requests thought sandbox environment */
50
    private $sandbox;
51
52
    /** @var Account */
53
    private $account;
54
55
    /**
56
     * @return TwitterAds|null
57
     */
58
    public static function instance()
59
    {
60
        return static::$instance;
61
    }
62
63
    /**
64
     * @param TwitterAds $instance
65
     */
66
    public static function setInstance(TwitterAds $instance)
67
    {
68
        static::$instance = $instance;
69
    }
70
71
    /**
72
     * Constructor.
73
     *
74
     * @param string $consumerKey The Application Consumer Key
75
     * @param string $consumerSecret The Application Consumer Secret
76
     * @param string|null $oauthToken The Client Token
77
     * @param string|null $oauthTokenSecret The Client Token Secret
78
     * @param Account $account | null
79
     * @param bool $sandbox The Sandbox environment (optional)
80
     */
81
    public function __construct($consumerKey, $consumerSecret, $oauthToken = '', $oauthTokenSecret = '', $account = null, $sandbox = false)
82
    {
83
        $this->resetLastResponse();
84
        $this->signatureMethod = new HmacSha1();
85
        $this->consumer = new Consumer($consumerKey, $consumerSecret);
86
        if (!empty($oauthToken) && !empty($oauthTokenSecret)) {
87
            $this->token = new Token($oauthToken, $oauthTokenSecret);
88
        }
89
        if (empty($oauthToken) && !empty($oauthTokenSecret)) {
90
            $this->bearer = $oauthTokenSecret;
91
        }
92
        $this->sandbox = $sandbox;
93
        $this->account = $account;
94
    }
95
96
    /**
97
     * @param $consumerKey
98
     * @param $consumerSecret
99
     * @param $oauthToken
100
     * @param $oauthTokenSecret
101
     * @param Account $account | null
102
     * @param bool $sandbox
103
     * @return static
104
     */
105
    public static function init($consumerKey, $consumerSecret, $oauthToken = '', $oauthTokenSecret = '', $account = null, $sandbox = false)
106
    {
107
        $api = new static($consumerKey, $consumerSecret, $oauthToken, $oauthTokenSecret, $account, $sandbox);
108
        static::setInstance($api);
109
110
        return $api;
111
    }
112
113
    /**
114
     * @return Account|Cursor
115
     */
116
    public function getAccounts()
117
    {
118
        return (new Account($this))->all();
119
    }
120
121
    /**
122
     * @param string $oauthToken
123
     * @param string $oauthTokenSecret
124
     */
125
    public function setOauthToken($oauthToken, $oauthTokenSecret)
126
    {
127
        $this->token = new Token($oauthToken, $oauthTokenSecret);
128
    }
129
130
    /**
131
     * @return string|null
132
     */
133
    public function getLastApiPath()
134
    {
135
        return $this->response->getApiPath();
136
    }
137
138
    /**
139
     * @return int
140
     */
141
    public function getLastHttpCode()
142
    {
143
        return $this->response->getHttpCode();
144
    }
145
146
    /**
147
     * @return array
148
     */
149
    public function getLastXHeaders()
150
    {
151
        return $this->response->getXHeaders();
152
    }
153
154
    /**
155
     * @return array|object|null
156
     */
157
    public function getLastBody()
158
    {
159
        return $this->response->getBody();
160
    }
161
162
    /**
163
     * Resets the last response cache.
164
     */
165
    public function resetLastResponse()
166
    {
167
        $this->response = new Response();
168
    }
169
170
    /**
171
     * Make URLs for user browser navigation.
172
     *
173
     * @param string $path
174
     * @param array $parameters
175
     *
176
     * @return string
177
     */
178
    public function url($path, array $parameters)
179
    {
180
        $this->resetLastResponse();
181
        $this->response->setApiPath($path);
182
        $query = http_build_query($parameters);
183
184
        return sprintf('%s/%s?%s', self::API_HOST_OAUTH, $path, $query);
185
    }
186
187
    /**
188
     * Make /oauth/* requests to the API.
189
     *
190
     * @param string $path
191
     * @param array $parameters
192
     * @return array
193
     * @throws Exception
194
     */
195
    public function oauth($path, array $parameters = [])
196
    {
197
        $response = [];
198
        $this->resetLastResponse();
199
        $this->response->setApiPath($path);
200
        $url = sprintf('%s/%s', self::API_HOST_OAUTH, $path);
201
        $result = $this->oAuthRequest($url, 'POST', $parameters);
202
203
        if ($this->getLastHttpCode() != 200) {
204
            throw new TwitterAdsException($result, 500, null, $result);
205
        }
206
207
        parse_str($result, $response);
208
        $this->response->setBody($response);
209
210
        return $response;
211
    }
212
213
    /**
214
     * Make /oauth2/* requests to the API.
215
     *
216
     * @param string $path
217
     * @param array $parameters
218
     *
219
     * @return array|object
220
     */
221
    public function oauth2($path, array $parameters = [])
222
    {
223
        $method = 'POST';
224
        $this->resetLastResponse();
225
        $this->response->setApiPath($path);
226
        $url = sprintf('%s/%s', self::API_HOST_OAUTH, $path);
227
        $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
228
        $authorization = 'Authorization: Basic ' . $this->encodeAppAuthorization($this->consumer);
229
        $result = $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters);
230
        $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
231
        $this->response->setBody($response);
232
233
        return $response;
234
    }
235
236
    public function verifyCredentials($parameters = [])
237
    {
238
        return $this->http('GET', self::API_HOST_OAUTH, 'account/verify_credentials', $parameters);
239
    }
240
241
    /**
242
     * Make GET requests to the API.
243
     *
244
     * @param string $path
245
     * @param array $parameters
246
     *
247
     * @return Response
248
     */
249
    public function get($path, array $parameters = [])
250
    {
251
        return $this->http('GET', !$this->sandbox ? self::API_HOST : self::API_HOST_SANDBOX, $path, $parameters);
252
    }
253
254
    /**
255
     * Make POST requests to the API.
256
     *
257
     * @param string $path
258
     * @param array $parameters
259
     *
260
     * @param array $headers
261
     * @return Response
262
     */
263
    public function post($path, array $parameters = [], array $headers = [])
264
    {
265
        return $this->http('POST', !$this->sandbox ? self::API_HOST : self::API_HOST_SANDBOX, $path, $parameters, $headers);
266
    }
267
268
    /**
269
     * Make DELETE requests to the API.
270
     *
271
     * @param string $path
272
     * @param array $parameters
273
     *
274
     * @return Response
275
     */
276
    public function delete($path, array $parameters = [])
277
    {
278
        return $this->http('DELETE', !$this->sandbox ? self::API_HOST : self::API_HOST_SANDBOX, $path, $parameters);
279
    }
280
281
    /**
282
     * Make PUT requests to the API.
283
     *
284
     * @param string $path
285
     * @param array $parameters
286
     *
287
     * @return Response
288
     */
289
    public function put($path, array $parameters = [], array $headers = [])
290
    {
291
        return $this->http('PUT', !$this->sandbox ? self::API_HOST : self::API_HOST_SANDBOX, $path, $parameters, $headers);
292
    }
293
294
    /**
295
     * Upload media to upload.twitter.com.
296
     *
297
     * @param array $parameters
298
     * @param bool $chunked
299
     *
300
     * @return array|object
301
     */
302
    public function upload(array $parameters = [], $chunked = false)
303
    {
304
        if ($chunked) {
305
            return $this->uploadMediaChunked(self::UPLOAD_PATH, $parameters);
306
        } else {
307
            return $this->uploadMediaNotChunked(self::UPLOAD_PATH, $parameters)->getBody();
308
        }
309
    }
310
311
    /**
312
     * Private method to upload media (not chunked) to upload.twitter.com.
313
     *
314
     * @param string $path
315
     * @param array $parameters
316
     *
317
     * @return array|object
318
     */
319
    private function uploadMediaNotChunked($path, $parameters)
320
    {
321
        $file = file_get_contents($parameters['media']);
322
        $base = base64_encode($file);
323
        $parameters['media'] = $base;
324
325
        return $this->http('POST', self::UPLOAD_HOST, $path, $parameters);
326
    }
327
328
    /**
329
     * Private method to upload media (chunked) to upload.twitter.com.
330
     *
331
     * @param string $path
332
     * @param array $parameters
333
     *
334
     * @return array|object
335
     */
336
    private function uploadMediaChunked($path, $parameters)
337
    {
338
        if ($parameters['media_type'] == 'video/mp4') {
339
            $parameters['media_category'] = "amplify_video";
340
        } elseif ($parameters['media_type'] == 'image/gif') {
341
            $parameters['media_category'] = 'tweet_gif';
342
        } else {
343
            $parameters['media_category'] = 'tweet_image';
344
        }
345
346
        // Init
347
        $initParameters = [
348
            'command' => 'INIT',
349
            'media_type' => $parameters['media_type'],
350
            'media_category' => $parameters['media_category'],
351
            'total_bytes' => filesize($parameters['media'])
352
        ];
353
354
        if (isset($parameters['additional_owners']) && is_array($parameters['additional_owners'])) {
355
            $initParameters['additional_owners'] = implode(',', $parameters['additional_owners']);
356
        }
357
358
        $init = $this->http(
359
            'POST',
360
            self::UPLOAD_HOST,
361
            $path,
362
            $initParameters
363
        )->getBody();
364
365
        // Append
366
        $segment_index = 0;
367
        $media = fopen($parameters['media'], 'rb');
368
        while (!feof($media)) {
369
            $this->http(
0 ignored issues
show
Unused Code introduced by
The call to the method Hborras\TwitterAdsSDK\Response::getBody() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
370
                'POST',
371
                self::UPLOAD_HOST,
372
                $path,
373
                [
374
                    'command' => 'APPEND',
375
                    'media_id' => $init->media_id_string,
376
                    'segment_index' => $segment_index++,
377
                    'media_data' => base64_encode(fread($media, self::UPLOAD_CHUNK)),
378
                ]
379
            )->getBody();
380
        }
381
        fclose($media);
382
        // Finalize
383
        $finalize = $this->http(
384
            'POST',
385
            self::UPLOAD_HOST,
386
            $path,
387
            [
388
                'command' => 'FINALIZE',
389
                'media_id' => $init->media_id_string,
390
            ]
391
        )->getBody();
392
393
        while (isset($finalize->processing_info)) {
394
            if (isset($finalize->processing_info->check_after_secs)) {
395
                sleep($finalize->processing_info->check_after_secs);
396
                $data = array(
397
                    'command' => 'STATUS',
398
                    'media_id' => $finalize->media_id
399
                );
400
                $finalize = $this->http('GET', self::UPLOAD_HOST, $path, $data)->getBody();
401
            } else {
402
                if (isset($finalize->processing_info->state) && $finalize->processing_info->state == 'succeeded') {
403
                    break;
404
                }
405
            }
406
        }
407
408
        return $finalize;
409
    }
410
411
    /**
412
     * @param string $method
413
     * @param string $host
414
     * @param string $path
415
     * @param array $parameters
416
     * @param array $headers
417
     * @return Response
418
     * @throws BadRequest
419
     * @throws Forbidden
420
     * @throws NotAuthorized
421
     * @throws NotFound
422
     * @throws RateLimit
423
     * @throws ServerError
424
     * @throws ServiceUnavailable
425
     */
426
    private function http($method, $host, $path, array $parameters, $headers = [])
427
    {
428
        $this->method = $method;
429
        $this->resource = $path;
430
        $this->resetLastResponse();
431
        if (strpos($path, TONUpload::DEFAULT_DOMAIN) === 0) {
432
            $url = $path;
433
        } else {
434
            if ($host == self::UPLOAD_HOST) {
435
                $url = sprintf('%s/%s/%s', $host, self::API_REST_VERSION, $path);
436
            } else {
437
                $url = sprintf('%s/%s/%s', $host, self::API_VERSION, $path);
438
            }
439
        }
440
441
        $this->response->setApiPath($path);
442
        $result = $this->oAuthRequest($url, $method, $parameters, $headers);
443
        $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
444
        $this->response->setBody($response);
445
        if ($this->getLastHttpCode() > 399) {
446
            $this->manageErrors($response);
447
        }
448
        return $this->response;
449
    }
450
451
    /**
452
     * @param $response
453
     * @throws BadRequest
454
     * @throws Forbidden
455
     * @throws NotAuthorized
456
     * @throws NotFound
457
     * @throws RateLimit
458
     * @throws ServerError
459
     * @throws ServiceUnavailable
460
     */
461
    public function manageErrors($response)
462
    {
463
        switch ($this->getLastHttpCode()) {
464
            case 400:
465
                throw new BadRequest(TwitterAdsException::BAD_REQUEST, 400, null, $response->errors);
466
            case 401:
467
                throw new NotAuthorized(TwitterAdsException::NOT_AUTHORIZED, 401, null, $response->errors);
468
            case 403:
469
                throw new Forbidden(TwitterAdsException::FORBIDDEN, 403, null, $response->errors);
470
            case 404:
471
                throw new NotFound(TwitterAdsException::NOT_FOUND, 404, null, $response->errors);
472
            case 429:
473
                throw new RateLimit(TwitterAdsException::RATE_LIMIT, 429, null, $response->errors, $this->response->getsHeaders());
474
            case 500:
475
                throw new ServerError(TwitterAdsException::SERVER_ERROR, 500, null, $response->errors);
476
            case 503:
477
                throw new ServiceUnavailable(TwitterAdsException::SERVICE_UNAVAILABLE, 503, null, $response->errors, $this->response->getsHeaders());
478
            default:
479
                throw new ServerError(TwitterAdsException::SERVER_ERROR, 500, null, $response->errors);
480
        }
481
    }
482
483
    /**
484
     * Format and sign an OAuth / API request.
485
     *
486
     * @param string $url
487
     * @param string $method
488
     * @param array $parameters
489
     *
490
     * @param array $headers
491
     * @return string
492
     * @throws TwitterAdsException
493
     */
494
    private function oAuthRequest($url, $method, array $parameters, $headers = [])
495
    {
496
        $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters);
497
        if (array_key_exists('oauth_callback', $parameters)) {
498
            // Twitter doesn't like oauth_callback as a parameter.
499
            unset($parameters['oauth_callback']);
500
        }
501
        if ($this->bearer === null) {
502
            $request->signRequest($this->signatureMethod, $this->consumer, $this->token);
503
            $authorization = $request->toHeader();
504
        } else {
505
            $authorization = 'Authorization: Bearer ' . $this->bearer;
506
        }
507
        if (strpos($url, TONUpload::DEFAULT_DOMAIN) === 0) {
508
            return $this->request($url, $method, $authorization, $parameters, $headers);
509
        } else {
510
            return $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters, $headers);
511
        }
512
    }
513
514
    /**
515
     * Make an HTTP request.
516
     *
517
     * @param string $url
518
     * @param string $method
519
     * @param string $authorization
520
     * @param array $postfields
521
     *
522
     * @param array $headers
523
     * @return string
524
     * @throws TwitterAdsException
525
     */
526
    private function request($url, $method, $authorization, $postfields, $headers = [])
527
    {
528
        /* Curl settings */
529
        $options = [
530
            CURLOPT_VERBOSE => false,
531
            CURLOPT_CAINFO => __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem',
532
            CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout,
533
            CURLOPT_HEADER => true,
534
            CURLOPT_HTTPHEADER => array_merge(['Accept: */*', $authorization, 'Expect:'], $headers, ['Connection: close']),
535
            CURLOPT_RETURNTRANSFER => true,
536
            CURLOPT_SSL_VERIFYHOST => 2,
537
            CURLOPT_SSL_VERIFYPEER => true,
538
            CURLOPT_TIMEOUT => $this->timeout,
539
            CURLOPT_URL => $url,
540
            CURLOPT_USERAGENT => $this->userAgent,
541
            CURLOPT_ENCODING => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
542
        ];
543
544
        if (!empty($this->proxy)) {
545
            $options[CURLOPT_PROXY] = $this->proxy['CURLOPT_PROXY'];
546
            $options[CURLOPT_PROXYUSERPWD] = $this->proxy['CURLOPT_PROXYUSERPWD'];
547
            $options[CURLOPT_PROXYPORT] = $this->proxy['CURLOPT_PROXYPORT'];
548
            $options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
549
            $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
550
        }
551
552
        switch ($method) {
553
            case 'GET':
554
                break;
555
            case 'POST':
556
                $options[CURLOPT_POST] = true;
557
                if (isset($postfields['raw'])) {
558
                    $options[CURLOPT_POSTFIELDS] = $postfields['raw'];
559
                } else {
560
                    $options[CURLOPT_POSTFIELDS] = Util::buildHttpQuery($postfields);
561
                }
562
563
                break;
564
            case 'DELETE':
565
                $options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
566
                break;
567
            case 'PUT':
568
                $options[CURLOPT_CUSTOMREQUEST] = 'PUT';
569
                if (isset($postfields['raw'])) {
570
                    $options[CURLOPT_POSTFIELDS] = $postfields['raw'];
571
                }
572
                break;
573
        }
574
575
        if (in_array($method, ['GET', 'PUT', 'DELETE']) && !empty($postfields) && !isset($postfields['raw'])) {
576
            $options[CURLOPT_URL] .= '?' . Util::buildHttpQuery($postfields);
577
        }
578
579
        $curlHandle = curl_init();
580
        curl_setopt_array($curlHandle, $options);
581
        $response = curl_exec($curlHandle);
582
        // Throw exceptions on cURL errors.
583
        if (curl_errno($curlHandle) > 0) {
584
            throw new TwitterAdsException(curl_error($curlHandle), curl_errno($curlHandle), null, null);
585
        }
586
        $this->response->setHttpCode(curl_getinfo($curlHandle, CURLINFO_HTTP_CODE));
587
        $parts = explode("\r\n\r\n", $response);
588
        $responseBody = array_pop($parts);
589
        $responseHeader = array_pop($parts);
590
        $this->response->setHeaders($this->parseHeaders($responseHeader));
591
        curl_close($curlHandle);
592
        return $responseBody;
593
    }
594
595
    /**
596
     * Get the header info to store.
597
     *
598
     * @param string $header
599
     *
600
     * @return array
601
     */
602
    private function parseHeaders($header)
603
    {
604
        $headers = [];
605
        foreach (explode("\r\n", $header) as $line) {
606
            if (strpos($line, ':') !== false) {
607
                list($key, $value) = explode(': ', $line);
608
                $key = str_replace('-', '_', strtolower($key));
609
                $headers[$key] = trim($value);
610
            }
611
        }
612
613
        return $headers;
614
    }
615
616
    /**
617
     * Set API URLS.
618
     */
619
    public function accessTokenURL()
620
    {
621
        return 'https://api.twitter.com/oauth/access_token';
622
    }
623
624
    public function authenticateURL()
625
    {
626
        return 'https://api.twitter.com/oauth/authenticate';
627
    }
628
629
    public function authorizeURL()
630
    {
631
        return 'https://api.twitter.com/oauth/authorize';
632
    }
633
634
    public function requestTokenURL()
635
    {
636
        return 'https://api.twitter.com/oauth/request_token';
637
    }
638
639
    /**
640
     * Encode application authorization header with base64.
641
     *
642
     * @param Consumer $consumer
643
     *
644
     * @return string
645
     */
646
    private function encodeAppAuthorization($consumer)
647
    {
648
        // TODO: key and secret should be rfc 1738 encoded
649
        $key = $consumer->key;
650
        $secret = $consumer->secret;
651
652
        return base64_encode($key . ':' . $secret);
653
    }
654
655
    /**
656
     * Return current response. Allows inheritance.
657
     *
658
     * @return Response
659
     */
660
    public function getResponse()
661
    {
662
        return $this->response;
663
    }
664
665
    /**
666
     * @return string
667
     */
668
    public function getMethod()
669
    {
670
        return $this->method;
671
    }
672
673
    /**
674
     * @return string
675
     */
676
    public function getResource()
677
    {
678
        return $this->resource;
679
    }
680
681
    /**
682
     * @return string
683
     */
684
    public function getAccountId()
685
    {
686
        if(!$this->account instanceof Account){
687
            return '';
688
        }
689
        return $this->account->getId();
690
    }
691
692
    /**
693
     * @return string
694
     */
695
    public function getAccountTimezone()
696
    {
697
        if(!$this->account instanceof Account){
698
            return 'UTC';
699
        }
700
        return $this->account->getTimezone();
701
    }
702
703
    /**
704
     * @param Account $account
705
     */
706
    public function setAccount($account)
707
    {
708
        $this->account = $account;
709
    }
710
711 View Code Duplication
    public function getRequestToken($oauth_callback)
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...
712
    {
713
        $parameters = array();
714
        $parameters['oauth_callback'] = $oauth_callback;
715
        $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
716
        $token = self::parse_parameters($request);
717
718
        return $token;
719
    }
720
721
    /**
722
     * Exchange request token and secret for an access token and
723
     * secret, to sign API calls.
724
     *
725
     * @param $oauth_verifier
726
     * @return array ("oauth_token" => "the-access-token",
727
     *                "oauth_token_secret" => "the-access-secret",
728
     * "user_id" => "9436992",
729
     * "screen_name" => "abraham")
730
     */
731 View Code Duplication
    public function getAccessToken($oauth_verifier)
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...
732
    {
733
        $parameters = array();
734
        $parameters['oauth_verifier'] = $oauth_verifier;
735
        $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
736
        $token = self::parse_parameters($request);
737
738
        return $token;
739
    }
740
741
    // This function takes a input like a=b&a=c&d=e and returns the parsed
742
    // parameters like this
743
    // array('a' => array('b','c'), 'd' => 'e')
744 View Code Duplication
    public static function parse_parameters($input)
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...
745
    {
746
        if (!isset($input) || !$input) {
747
            return array();
748
        }
749
750
        $pairs = explode('&', $input);
751
752
        $parsed_parameters = array();
753
        foreach ($pairs as $pair) {
754
            $split = explode('=', $pair, 2);
755
            $parameter = self::urldecode_rfc3986($split[0]);
756
            $value = isset($split[1]) ? self::urldecode_rfc3986($split[1]) : '';
757
758
            if (isset($parsed_parameters[$parameter])) {
759
                // We have already recieved parameter(s) with this name, so add to the list
760
                // of parameters with this name
761
762
                if (is_scalar($parsed_parameters[$parameter])) {
763
                    // This is the first duplicate, so transform scalar (string) into an array
764
                    // so we can add the duplicates
765
                    $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
766
                }
767
768
                $parsed_parameters[$parameter][] = $value;
769
            } else {
770
                $parsed_parameters[$parameter] = $value;
771
            }
772
        }
773
774
        return $parsed_parameters;
775
    }
776
777
    public static function urlencode_rfc3986($input)
778
    {
779
        if (is_array($input)) {
780
            return array_map(array(__CLASS__, 'urlencode_rfc3986'), $input);
781
        } elseif (is_scalar($input)) {
782
            return str_replace(
783
                '',
784
                ' ',
785
                str_replace('%7E', '~', rawurlencode($input))
786
            );
787
        } else {
788
            return '';
789
        }
790
    }
791
792
    // This decode function isn't taking into consideration the above
793
    // modifications to the encoding process. However, this method doesn't
794
    // seem to be used anywhere so leaving it as is.
795
    public static function urldecode_rfc3986($string)
796
    {
797
        return urldecode($string);
798
    }
799
800
    /**
801
     * Get the authorize URL.
802
     *
803
     * @param $token
804
     * @param bool $sign_in_with_twitter
805
     * @return string
806
     */
807
    public function getAuthorizeURL($token, $sign_in_with_twitter = true)
808
    {
809
        if (is_array($token)) {
810
            $token = $token['oauth_token'];
811
        }
812
        if (empty($sign_in_with_twitter)) {
813
            return $this->authorizeURL() . "?oauth_token={$token}";
814
        } else {
815
            return $this->authenticateURL() . "?oauth_token={$token}";
816
        }
817
    }
818
}
819