Completed
Pull Request — master (#63)
by
unknown
03:38
created

SocialiteManager::getRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the overtrue/socialite.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Overtrue\Socialite;
13
14
use Closure;
15
use InvalidArgumentException;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Overtrue\Socialite\InvalidArgumentException.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpFoundation\Session\Session;
18
19
/**
20
 * Class SocialiteManager.
21
 */
22
class SocialiteManager implements FactoryInterface
23
{
24
    /**
25
     * The configuration.
26
     *
27
     * @var \Overtrue\Socialite\Config
28
     */
29
    protected $config;
30
31
    /**
32
     * The request instance.
33
     *
34
     * @var \Symfony\Component\HttpFoundation\Request
35
     */
36
    protected $request;
37
38
    /**
39
     * The registered custom driver creators.
40
     *
41
     * @var array
42
     */
43
    protected $customCreators = [];
44
45
    /**
46
     * The initial drivers.
47
     *
48
     * @var array
49
     */
50
    protected $initialDrivers = [
51
            'facebook' => 'Facebook',
52
            'github' => 'GitHub',
53
            'google' => 'Google',
54
            'linkedin' => 'Linkedin',
55
            'weibo' => 'Weibo',
56
            'qq' => 'QQ',
57
            'wechat' => 'WeChat',
58
            'wechat_open' => 'WeChatOpenPlatform',
59
            'douban' => 'Douban',
60
    ];
61
62
    /**
63
     * The array of created "drivers".
64
     *
65
     * @var array
66
     */
67
    protected $drivers = [];
68
69
    /**
70
     * SocialiteManager constructor.
71
     *
72
     * @param array                                          $config
73
     * @param \Symfony\Component\HttpFoundation\Request|null $request
74
     */
75
    public function __construct(array $config, Request $request = null)
76
    {
77
        $this->config = new Config($config);
78
        $this->request = $request ?: $this->createDefaultRequest();
79
    }
80
81
    /**
82
     * Set config instance.
83
     *
84
     * @param \Overtrue\Socialite\Config $config
85
     *
86
     * @return $this
87
     */
88
    public function config(Config $config)
89
    {
90
        $this->config = $config;
91
92
        return $this;
93
    }
94
95
    /**
96
     * Get the default driver name.
97
     *
98
     * @return string
99
     */
100
    public function getDefaultDriver()
101
    {
102
        throw new InvalidArgumentException('No Socialite driver was specified.');
103
    }
104
105
    /**
106
     * Get a driver instance.
107
     *
108
     * @param string $driver
109
     *
110
     * @return \Overtrue\Socialite\Providers\AbstractProvider
111
     */
112
    public function driver($driver = null)
113
    {
114
        $driver = $driver ?: $this->getDefaultDriver();
115
116
        if (!isset($this->drivers[$driver])) {
117
            $this->drivers[$driver] = $this->createDriver($driver);
118
        }
119
120
        return $this->drivers[$driver];
121
    }
122
123
    /**
124
     * Create a new driver instance.
125
     *
126
     * @param string $driver
127
     *
128
     * @throws \InvalidArgumentException
129
     *
130
     * @return \Overtrue\Socialite\Providers\AbstractProvider
131
     */
132
    protected function createDriver($driver)
133
    {
134
        if (isset($this->initialDrivers[$driver])) {
135
            $provider = $this->initialDrivers[$driver];
136
            $provider = __NAMESPACE__.'\\Providers\\'.$provider.'Provider';
137
138
            return $this->buildProvider($provider, $this->formatConfig($this->config->get($driver)));
139
        }
140
141
        if (isset($this->customCreators[$driver])) {
142
            return $this->callCustomCreator($driver);
143
        }
144
145
        throw new InvalidArgumentException("Driver [$driver] not supported.");
146
    }
147
148
    /**
149
     * Call a custom driver creator.
150
     *
151
     * @param string $driver
152
     *
153
     * @return \Overtrue\Socialite\Providers\AbstractProvider
154
     */
155
    protected function callCustomCreator($driver)
156
    {
157
        return $this->customCreators[$driver]($this->config);
158
    }
159
160
    /**
161
     * Create default request instance.
162
     *
163
     * @return \Symfony\Component\HttpFoundation\Request
164
     */
165
    protected function createDefaultRequest()
166
    {
167
        $request = Request::createFromGlobals();
168
        $session = new Session();
169
170
        $request->setSession($session);
171
172
        return $request;
173
    }
174
175
    /**
176
     * Register a custom driver creator Closure.
177
     *
178
     * @param string   $driver
179
     * @param \Closure $callback
180
     *
181
     * @return $this
182
     */
183
    public function extend($driver, Closure $callback)
184
    {
185
        $this->customCreators[$driver] = $callback;
186
187
        return $this;
188
    }
189
190
    /**
191
     * Get all of the created "drivers".
192
     *
193
     * @return array
194
     */
195
    public function getDrivers()
196
    {
197
        return $this->drivers;
198
    }
199
200
    /**
201
     * Get a driver instance.
202
     *
203
     * @param string $driver
204
     *
205
     * @return mixed
206
     */
207
    public function with($driver)
208
    {
209
        return $this->driver($driver);
210
    }
211
212
    /**
213
     * Build an OAuth 2 provider instance.
214
     *
215
     * @param string $provider
216
     * @param array  $config
217
     *
218
     * @return \Overtrue\Socialite\Providers\AbstractProvider
219
     */
220
    public function buildProvider($provider, $config)
221
    {
222
        return new $provider(
223
            $this->request, $config['client_id'],
224
            $config['client_secret'], $config['redirect']
225
        );
226
    }
227
228
    /**
229
     * Format the server configuration.
230
     *
231
     * @param array $config
232
     *
233
     * @return array
234
     */
235
    public function formatConfig(array $config)
236
    {
237
        return array_merge([
238
            'identifier' => $config['client_id'],
239
            'secret' => $config['client_secret'],
240
            'callback_uri' => $config['redirect'],
241
        ], $config);
242
    }
243
244
    /**
245
     * Dynamically call the default driver instance.
246
     *
247
     * @param string $method
248
     * @param array  $parameters
249
     *
250
     * @return mixed
251
     */
252
    public function __call($method, $parameters)
253
    {
254
        return call_user_func_array([$this->driver(), $method], $parameters);
255
    }
256
257
    /**
258
     * Get a request
259
     *
260
     * @return \Symfony\Component\HttpFoundation\Request
261
     */
262
    public function getRequest()
263
    {
264
        return $this->request;
265
    }
266
267
    /**
268
     * Set a request
269
     *
270
     * @param \Symfony\Component\HttpFoundation\Request $request
271
     *
272
     * @return $this
273
     */
274
    public function setRequest(Request $request)
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
275
    {
276
        $this->request = $request;
277
278
        return $this;
279
    }
280
}
281