Completed
Pull Request — master (#484)
by
unknown
04:41
created

ServiceFactory::buildV2Service()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 17
rs 9.4285
c 1
b 0
f 1
cc 1
eloc 14
nc 1
nop 6
1
<?php
2
3
/**
4
 * OAuth service factory.
5
 *
6
 * PHP version 5.4
7
 *
8
 * @category   OAuth
9
 * @author     David Desberg <[email protected]>
10
 * @author     Pieter Hordijk <[email protected]>
11
 * @copyright  Copyright (c) 2013 The authors
12
 * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
13
 */
14
15
namespace OAuth;
16
17
use OAuth\Common\Service\ServiceInterface;
18
use OAuth\Common\Consumer\CredentialsInterface;
19
use OAuth\Common\Storage\TokenStorageInterface;
20
use OAuth\Common\Http\Client\ClientInterface;
21
use OAuth\Common\Http\Client\StreamClient;
22
use OAuth\Common\Http\Uri\UriInterface;
23
use OAuth\Common\Exception\Exception;
24
use OAuth\OAuth1\Signature\Signature;
25
26
class ServiceFactory
27
{
28
    /**
29
     *@var ClientInterface
30
     */
31
    protected $httpClient;
32
33
    /**
34
     * @var array
35
     */
36
    protected $serviceClassMap = array(
37
        'OAuth1' => array(),
38
        'OAuth2' => array()
39
    );
40
41
    /**
42
     * @var array
43
     */
44
    protected $serviceBuilders = array(
45
        'OAuth2' => 'buildV2Service',
46
        'OAuth1' => 'buildV1Service',
47
    );
48
49
    /**
50
     * @param ClientInterface $httpClient
51
     *
52
     * @return ServiceFactory
53
     */
54
    public function setHttpClient(ClientInterface $httpClient)
55
    {
56
        $this->httpClient = $httpClient;
57
58
        return $this;
59
    }
60
61
    /**
62
     * Register a custom service to classname mapping.
63
     *
64
     * @param string $serviceName Name of the service
65
     * @param string $className   Class to instantiate
66
     *
67
     * @return ServiceFactory
68
     *
69
     * @throws Exception If the class is nonexistent or does not implement a valid ServiceInterface
70
     */
71
    public function registerService($serviceName, $className)
72
    {
73
        if (!class_exists($className)) {
74
            throw new Exception(sprintf('Service class %s does not exist.', $className));
75
        }
76
77
        $reflClass = new \ReflectionClass($className);
78
79
        foreach (array('OAuth2', 'OAuth1') as $version) {
80
            if ($reflClass->implementsInterface('OAuth\\' . $version . '\\Service\\ServiceInterface')) {
81
                $this->serviceClassMap[$version][ucfirst($serviceName)] = $className;
82
83
                return $this;
84
            }
85
        }
86
87
        throw new Exception(sprintf('Service class %s must implement ServiceInterface.', $className));
88
    }
89
90
    /**
91
     * Builds and returns oauth services
92
     *
93
     * It will first try to build an OAuth2 service and if none found it will try to build an OAuth1 service
94
     *
95
     * @param string                $serviceName Name of service to create
96
     * @param CredentialsInterface  $credentials
97
     * @param TokenStorageInterface $storage
98
     * @param array|null            $scopes      If creating an oauth2 service, array of scopes
99
     * @param UriInterface|null     $baseApiUri
100
     * @param string                $apiVersion version of the api call
101
     *
102
     * @return ServiceInterface
103
     */
104
    public function createService(
105
        $serviceName,
106
        CredentialsInterface $credentials,
107
        TokenStorageInterface $storage,
108
        $scopes = array(),
109
        UriInterface $baseApiUri = null,
110
        $apiVersion = ""
111
    ) {
112
        if (!$this->httpClient) {
113
            // for backwards compatibility.
114
            $this->httpClient = new StreamClient();
115
        }
116
117
        foreach ($this->serviceBuilders as $version => $buildMethod) {
118
            $fullyQualifiedServiceName = $this->getFullyQualifiedServiceName($serviceName, $version);
119
120
            if (class_exists($fullyQualifiedServiceName)) {
121
                return $this->$buildMethod(
122
                    $fullyQualifiedServiceName,
123
                    $credentials,
124
                    $storage,
125
                    $scopes,
126
                    $baseApiUri,
127
                    $apiVersion
128
                );
129
            }
130
        }
131
132
        return null;
133
    }
134
135
    /**
136
     * Gets the fully qualified name of the service
137
     *
138
     * @param string $serviceName The name of the service of which to get the fully qualified name
139
     * @param string $type        The type of the service to get (either OAuth1 or OAuth2)
140
     *
141
     * @return string The fully qualified name of the service
142
     */
143
    private function getFullyQualifiedServiceName($serviceName, $type)
144
    {
145
        $serviceName = ucfirst($serviceName);
146
147
        if (isset($this->serviceClassMap[$type][$serviceName])) {
148
            return $this->serviceClassMap[$type][$serviceName];
149
        }
150
151
        return '\\OAuth\\' . $type . '\\Service\\' . $serviceName;
152
    }
153
154
    /**
155
     * Builds v2 services
156
     *
157
     * @param string                $serviceName The fully qualified service name
158
     * @param CredentialsInterface  $credentials
159
     * @param TokenStorageInterface $storage
160
     * @param array|null            $scopes      Array of scopes for the service
161
     * @param UriInterface|null     $baseApiUri
162
     *
163
     * @return ServiceInterface
164
     *
165
     * @throws Exception
166
     */
167
    private function buildV2Service(
168
        $serviceName,
169
        CredentialsInterface $credentials,
170
        TokenStorageInterface $storage,
171
        array $scopes,
172
        UriInterface $baseApiUri = null,
173
        $apiVersion = ""
174
    ) {
175
        return new $serviceName(
176
            $credentials,
177
            $this->httpClient,
178
            $storage,
179
            $this->resolveScopes($serviceName, $scopes),
180
            $baseApiUri,
181
            $apiVersion
182
        );
183
    }
184
185
    /**
186
     * Resolves scopes for v2 services
187
     *
188
     * @param string  $serviceName The fully qualified service name
189
     * @param array   $scopes      List of scopes for the service
190
     *
191
     * @return array List of resolved scopes
192
     */
193
    private function resolveScopes($serviceName, array $scopes)
194
    {
195
        $reflClass = new \ReflectionClass($serviceName);
196
        $constants = $reflClass->getConstants();
197
198
        $resolvedScopes = array();
199
        foreach ($scopes as $scope) {
200
            $key = strtoupper('SCOPE_' . $scope);
201
202
            if (array_key_exists($key, $constants)) {
203
                $resolvedScopes[] = $constants[$key];
204
            } else {
205
                $resolvedScopes[] = $scope;
206
            }
207
        }
208
209
        return $resolvedScopes;
210
    }
211
212
    /**
213
     * Builds v1 services
214
     *
215
     * @param string                $serviceName The fully qualified service name
216
     * @param CredentialsInterface  $credentials
217
     * @param TokenStorageInterface $storage
218
     * @param array                 $scopes
219
     * @param UriInterface          $baseApiUri
220
     *
221
     * @return ServiceInterface
222
     *
223
     * @throws Exception
224
     */
225
    private function buildV1Service(
226
        $serviceName,
227
        CredentialsInterface $credentials,
228
        TokenStorageInterface $storage,
229
        $scopes,
230
        UriInterface $baseApiUri = null
231
    ) {
232
        if (!empty($scopes)) {
233
            throw new Exception(
234
                'Scopes passed to ServiceFactory::createService but an OAuth1 service was requested.'
235
            );
236
        }
237
238
        return new $serviceName($credentials, $this->httpClient, $storage, new Signature($credentials), $baseApiUri);
239
    }
240
}
241