1<?php
2
3namespace OAuth\OAuth1\Service;
4
5use OAuth\OAuth1\Signature\SignatureInterface;
6use OAuth\OAuth1\Token\StdOAuth1Token;
7use OAuth\Common\Http\Exception\TokenResponseException;
8use OAuth\Common\Http\Uri\Uri;
9use OAuth\Common\Consumer\CredentialsInterface;
10use OAuth\Common\Http\Uri\UriInterface;
11use OAuth\Common\Storage\TokenStorageInterface;
12use OAuth\Common\Http\Client\ClientInterface;
13use OAuth\Common\Exception\Exception;
14
15class Twitter extends AbstractService
16{
17    const ENDPOINT_AUTHENTICATE = "https://api.twitter.com/oauth/authenticate";
18    const ENDPOINT_AUTHORIZE    = "https://api.twitter.com/oauth/authorize";
19
20    protected $authorizationEndpoint   = self::ENDPOINT_AUTHENTICATE;
21
22    public function __construct(
23        CredentialsInterface $credentials,
24        ClientInterface $httpClient,
25        TokenStorageInterface $storage,
26        SignatureInterface $signature,
27        UriInterface $baseApiUri = null
28    ) {
29        parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
30
31        if (null === $baseApiUri) {
32            $this->baseApiUri = new Uri('https://api.twitter.com/1.1/');
33        }
34    }
35
36    /**
37     * {@inheritdoc}
38     */
39    public function getRequestTokenEndpoint()
40    {
41        return new Uri('https://api.twitter.com/oauth/request_token');
42    }
43
44    /**
45     * {@inheritdoc}
46     */
47    public function getAuthorizationEndpoint()
48    {
49        if ($this->authorizationEndpoint != self::ENDPOINT_AUTHENTICATE
50        && $this->authorizationEndpoint != self::ENDPOINT_AUTHORIZE) {
51            $this->authorizationEndpoint = self::ENDPOINT_AUTHENTICATE;
52        }
53        return new Uri($this->authorizationEndpoint);
54    }
55
56    /**
57     * @param string $authorizationEndpoint
58     *
59     * @throws Exception
60     */
61    public function setAuthorizationEndpoint($endpoint)
62    {
63        if ($endpoint != self::ENDPOINT_AUTHENTICATE && $endpoint != self::ENDPOINT_AUTHORIZE) {
64            throw new Exception(
65                sprintf("'%s' is not a correct Twitter authorization endpoint.", $endpoint)
66            );
67        }
68        $this->authorizationEndpoint = $endpoint;
69    }
70
71    /**
72     * {@inheritdoc}
73     */
74    public function getAccessTokenEndpoint()
75    {
76        return new Uri('https://api.twitter.com/oauth/access_token');
77    }
78
79    /**
80     * {@inheritdoc}
81     */
82    protected function parseRequestTokenResponse($responseBody)
83    {
84        parse_str($responseBody, $data);
85
86        if (null === $data || !is_array($data)) {
87            throw new TokenResponseException('Unable to parse response.');
88        } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
89            throw new TokenResponseException('Error in retrieving token.');
90        }
91
92        return $this->parseAccessTokenResponse($responseBody);
93    }
94
95    /**
96     * {@inheritdoc}
97     */
98    protected function parseAccessTokenResponse($responseBody)
99    {
100        parse_str($responseBody, $data);
101
102        if (null === $data || !is_array($data)) {
103            throw new TokenResponseException('Unable to parse response: ' . $responseBody);
104        } elseif (isset($data['error'])) {
105            throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
106        } elseif (!isset($data["oauth_token"]) || !isset($data["oauth_token_secret"])) {
107            throw new TokenResponseException('Invalid response. OAuth Token data not set: ' . $responseBody);
108        }
109
110        $token = new StdOAuth1Token();
111
112        $token->setRequestToken($data['oauth_token']);
113        $token->setRequestTokenSecret($data['oauth_token_secret']);
114        $token->setAccessToken($data['oauth_token']);
115        $token->setAccessTokenSecret($data['oauth_token_secret']);
116
117        $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
118        unset($data['oauth_token'], $data['oauth_token_secret']);
119        $token->setExtraParams($data);
120
121        return $token;
122    }
123}
124