Skip to content
This repository was archived by the owner on Jan 13, 2022. It is now read-only.

Commit fb4de4f

Browse files
splitted complex constructor into different factories
1 parent bd55939 commit fb4de4f

File tree

4 files changed

+286
-66
lines changed

4 files changed

+286
-66
lines changed

src/Facebook/Facebook.php

Lines changed: 30 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,11 @@
3030
use Facebook\GraphNodes\GraphEdge;
3131
use Facebook\Url\UrlDetectionInterface;
3232
use Facebook\Url\FacebookUrlDetectionHandler;
33+
use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory;
3334
use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface;
34-
use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator;
35-
use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator;
36-
use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator;
37-
use Facebook\HttpClients\FacebookHttpClientInterface;
38-
use Facebook\HttpClients\FacebookCurlHttpClient;
39-
use Facebook\HttpClients\FacebookStreamHttpClient;
40-
use Facebook\HttpClients\FacebookGuzzleHttpClient;
35+
use Facebook\HttpClients\HttpClientsFactory;
36+
use Facebook\PersistentData\PersistentDataFactory;
4137
use Facebook\PersistentData\PersistentDataInterface;
42-
use Facebook\PersistentData\FacebookSessionPersistentDataHandler;
43-
use Facebook\PersistentData\FacebookMemoryPersistentDataHandler;
4438
use Facebook\Helpers\FacebookCanvasHelper;
4539
use Facebook\Helpers\FacebookJavaScriptHelper;
4640
use Facebook\Helpers\FacebookPageTabHelper;
@@ -128,73 +122,43 @@ class Facebook
128122
*/
129123
public function __construct(array $config = [])
130124
{
131-
$appId = isset($config['app_id']) ? $config['app_id'] : getenv(static::APP_ID_ENV_NAME);
132-
if (!$appId) {
125+
$config = array_merge([
126+
'app_id' => getenv(static::APP_ID_ENV_NAME),
127+
'app_secret' => getenv(static::APP_SECRET_ENV_NAME),
128+
'default_graph_version' => static::DEFAULT_GRAPH_VERSION,
129+
'enable_beta_mode' => false,
130+
'http_client_handler' => null,
131+
'persistent_data_handler' => null,
132+
'pseudo_random_string_generator' => null,
133+
'url_detection_handler' => null,
134+
], $config);
135+
136+
if (!$config['app_id']) {
133137
throw new FacebookSDKException('Required "app_id" key not supplied in config and could not find fallback environment variable "' . static::APP_ID_ENV_NAME . '"');
134138
}
135-
136-
$appSecret = isset($config['app_secret']) ? $config['app_secret'] : getenv(static::APP_SECRET_ENV_NAME);
137-
if (!$appSecret) {
139+
if (!$config['app_secret']) {
138140
throw new FacebookSDKException('Required "app_secret" key not supplied in config and could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME . '"');
139141
}
140142

141-
$this->app = new FacebookApp($appId, $appSecret);
142-
143-
$httpClientHandler = null;
144-
if (isset($config['http_client_handler'])) {
145-
if ($config['http_client_handler'] instanceof FacebookHttpClientInterface) {
146-
$httpClientHandler = $config['http_client_handler'];
147-
} elseif ($config['http_client_handler'] === 'curl') {
148-
$httpClientHandler = new FacebookCurlHttpClient();
149-
} elseif ($config['http_client_handler'] === 'stream') {
150-
$httpClientHandler = new FacebookStreamHttpClient();
151-
} elseif ($config['http_client_handler'] === 'guzzle') {
152-
$httpClientHandler = new FacebookGuzzleHttpClient();
153-
} else {
154-
throw new \InvalidArgumentException('The http_client_handler must be set to "curl", "stream", "guzzle", or be an instance of Facebook\HttpClients\FacebookHttpClientInterface');
155-
}
156-
}
157-
158-
$enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true;
159-
$this->client = new FacebookClient($httpClientHandler, $enableBeta);
160-
161-
if (isset($config['pseudo_random_string_generator'])) {
162-
if ($config['pseudo_random_string_generator'] instanceof PseudoRandomStringGeneratorInterface) {
163-
$this->pseudoRandomStringGenerator = $config['pseudo_random_string_generator'];
164-
} elseif ($config['pseudo_random_string_generator'] === 'mcrypt') {
165-
$this->pseudoRandomStringGenerator = new McryptPseudoRandomStringGenerator();
166-
} elseif ($config['pseudo_random_string_generator'] === 'openssl') {
167-
$this->pseudoRandomStringGenerator = new OpenSslPseudoRandomStringGenerator();
168-
} elseif ($config['pseudo_random_string_generator'] === 'urandom') {
169-
$this->pseudoRandomStringGenerator = new UrandomPseudoRandomStringGenerator();
170-
} else {
171-
throw new \InvalidArgumentException('The pseudo_random_string_generator must be set to "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface');
172-
}
173-
}
174-
175-
if (isset($config['persistent_data_handler'])) {
176-
if ($config['persistent_data_handler'] instanceof PersistentDataInterface) {
177-
$this->persistentDataHandler = $config['persistent_data_handler'];
178-
} elseif ($config['persistent_data_handler'] === 'session') {
179-
$this->persistentDataHandler = new FacebookSessionPersistentDataHandler();
180-
} elseif ($config['persistent_data_handler'] === 'memory') {
181-
$this->persistentDataHandler = new FacebookMemoryPersistentDataHandler();
182-
} else {
183-
throw new \InvalidArgumentException('The persistent_data_handler must be set to "session", "memory", or be an instance of Facebook\PersistentData\PersistentDataInterface');
184-
}
185-
}
143+
$this->app = new FacebookApp($config['app_id'], $config['app_secret']);
144+
$this->client = new FacebookClient(
145+
HttpClientsFactory::createHttpClient($config['http_client_handler']),
146+
$config['enable_beta_mode']
147+
);
148+
$this->pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator(
149+
$config['pseudo_random_string_generator']
150+
);
186151
$this->setUrlDetectionHandler($config['url_detection_handler'] ?: new FacebookUrlDetectionHandler());
152+
$this->persistentDataHandler = PersistentDataFactory::createPersistentDataHandler(
153+
$config['persistent_data_handler']
154+
);
187155

188156
if (isset($config['default_access_token'])) {
189157
$this->setDefaultAccessToken($config['default_access_token']);
190158
}
191159

192-
if (isset($config['default_graph_version'])) {
193-
$this->defaultGraphVersion = $config['default_graph_version'];
194-
} else {
195-
// @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set
196-
$this->defaultGraphVersion = static::DEFAULT_GRAPH_VERSION;
197-
}
160+
// @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set
161+
$this->defaultGraphVersion = $config['default_graph_version'];
198162
}
199163

200164
/**
@@ -255,7 +219,7 @@ public function getUrlDetectionHandler()
255219

256220
/**
257221
* Changes the URL detection handler.
258-
*
222+
*
259223
* @param UrlDetectionInterface $urlDetectionHandler
260224
*/
261225
private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
/**
3+
* Copyright 2014 Facebook, Inc.
4+
*
5+
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
6+
* use, copy, modify, and distribute this software in source code or binary
7+
* form for use in connection with the web services and APIs provided by
8+
* Facebook.
9+
*
10+
* As with any software that integrates with the Facebook platform, your use
11+
* of this software is subject to the Facebook Developer Principles and
12+
* Policies [http://developers.facebook.com/policy/]. This copyright notice
13+
* shall be included in all copies or substantial portions of the software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
*/
24+
namespace Facebook\HttpClients;
25+
26+
use GuzzleHttp\Client;
27+
use InvalidArgumentException;
28+
29+
class HttpClientsFactory
30+
{
31+
private function __construct()
32+
{
33+
// a factory constructor should never be invoked
34+
}
35+
36+
/**
37+
* HTTP client generation.
38+
*
39+
* @param FacebookHttpClientInterface|Client|string|null $handler
40+
*
41+
* @throws Exception If the cURL extension or the Guzzle client aren't available (if required).
42+
* @throws InvalidArgumentException If the http client handler isn't "curl", "stream", "guzzle", or an instance of Facebook\HttpClients\FacebookHttpClientInterface.
43+
*
44+
* @return FacebookHttpClientInterface
45+
*/
46+
public static function createHttpClient($handler)
47+
{
48+
if (!$handler) {
49+
return self::detectDefaultClient();
50+
}
51+
52+
if ($handler instanceof FacebookHttpClientInterface) {
53+
return $handler;
54+
}
55+
56+
if ('stream' === $handler) {
57+
return new FacebookStreamHttpClient();
58+
}
59+
if ('curl' === $handler) {
60+
if (!extension_loaded('curl')) {
61+
throw new Exception('The cURL extension must be loaded in order to use the "curl" handler.');
62+
}
63+
64+
return new FacebookCurlHttpClient();
65+
}
66+
67+
if ('guzzle' === $handler && !class_exists('GuzzleHttp\Client')) {
68+
throw new Exception('The Guzzle HTTP client must be included in order to use the "guzzle" handler.');
69+
}
70+
71+
if ($handler instanceof Client) {
72+
return new FacebookGuzzleHttpClient($handler);
73+
}
74+
if ('guzzle' === $handler) {
75+
return new FacebookGuzzleHttpClient();
76+
}
77+
78+
throw new InvalidArgumentException('The http client handler must be set to "curl", "stream", "guzzle", be an instance of GuzzleHttp\Client or an instance of Facebook\HttpClients\FacebookHttpClientInterface');
79+
}
80+
81+
/**
82+
* Detect default HTTP client.
83+
*
84+
* @return FacebookHttpClientInterface
85+
*/
86+
private static function detectDefaultClient()
87+
{
88+
if (extension_loaded('curl')) {
89+
return new FacebookCurlHttpClient();
90+
}
91+
92+
if (class_exists('GuzzleHttp\Client')) {
93+
return new FacebookGuzzleHttpClient();
94+
}
95+
96+
return new FacebookStreamHttpClient();
97+
}
98+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
/**
3+
* Copyright 2014 Facebook, Inc.
4+
*
5+
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
6+
* use, copy, modify, and distribute this software in source code or binary
7+
* form for use in connection with the web services and APIs provided by
8+
* Facebook.
9+
*
10+
* As with any software that integrates with the Facebook platform, your use
11+
* of this software is subject to the Facebook Developer Principles and
12+
* Policies [http://developers.facebook.com/policy/]. This copyright notice
13+
* shall be included in all copies or substantial portions of the software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
*/
24+
namespace Facebook\PersistentData;
25+
26+
use InvalidArgumentException;
27+
28+
class PersistentDataFactory
29+
{
30+
private function __construct()
31+
{
32+
// a factory constructor should never be invoked
33+
}
34+
35+
/**
36+
* PersistentData generation.
37+
*
38+
* @param PersistentDataInterface|string|null $handler
39+
*
40+
* @throws InvalidArgumentException If the persistent data handler isn't "session", "memory", or an instance of Facebook\PersistentData\PersistentDataInterface.
41+
*
42+
* @return PersistentDataInterface
43+
*/
44+
public static function createPersistentDataHandler($handler)
45+
{
46+
if (!$handler) {
47+
return session_status() === PHP_SESSION_ACTIVE
48+
? new FacebookSessionPersistentDataHandler()
49+
: new FacebookMemoryPersistentDataHandler();
50+
}
51+
52+
if ($handler instanceof PersistentDataInterface) {
53+
return $handler;
54+
}
55+
56+
if ('session' === $handler) {
57+
new FacebookSessionPersistentDataHandler();
58+
}
59+
if ('memory' === $handler) {
60+
return new FacebookMemoryPersistentDataHandler();
61+
}
62+
63+
throw new InvalidArgumentException('The persistent data handler must be set to "session", "memory", or be an instance of Facebook\PersistentData\PersistentDataInterface');
64+
}
65+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
/**
3+
* Copyright 2014 Facebook, Inc.
4+
*
5+
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
6+
* use, copy, modify, and distribute this software in source code or binary
7+
* form for use in connection with the web services and APIs provided by
8+
* Facebook.
9+
*
10+
* As with any software that integrates with the Facebook platform, your use
11+
* of this software is subject to the Facebook Developer Principles and
12+
* Policies [http://developers.facebook.com/policy/]. This copyright notice
13+
* shall be included in all copies or substantial portions of the software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
*/
24+
namespace Facebook\PseudoRandomString;
25+
26+
use Facebook\Exceptions\FacebookSDKException;
27+
use InvalidArgumentException;
28+
29+
class PseudoRandomStringGeneratorFactory
30+
{
31+
private function __construct()
32+
{
33+
// a factory constructor should never be invoked
34+
}
35+
36+
/**
37+
* Pseudo random string generator creation.
38+
*
39+
* @param PseudoRandomStringGeneratorInterface|string|null $generator
40+
*
41+
* @throws InvalidArgumentException If the pseudo random string generator must be set to "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface.
42+
*
43+
* @return PseudoRandomStringGeneratorInterface
44+
*/
45+
public static function createPseudoRandomStringGenerator($generator)
46+
{
47+
if (!$generator) {
48+
return self::detectDefaultPseudoRandomStringGenerator();
49+
}
50+
51+
if ($generator instanceof PseudoRandomStringGeneratorInterface) {
52+
return $generator;
53+
}
54+
55+
if ('mcrypt' === $generator) {
56+
return new McryptPseudoRandomStringGenerator();
57+
}
58+
if ('openssl' === $generator) {
59+
return new OpenSslPseudoRandomStringGenerator();
60+
}
61+
if ('urandom' === $generator) {
62+
return new UrandomPseudoRandomStringGenerator();
63+
}
64+
65+
throw new InvalidArgumentException('The pseudo random string generator must be set to "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface');
66+
}
67+
68+
/**
69+
* Detects which pseudo-random string generator to use.
70+
*
71+
* @throws FacebookSDKException If unable to detect a cryptographically secure pseudo-random string generator.
72+
*
73+
* @return PseudoRandomStringGeneratorInterface
74+
*/
75+
private static function detectDefaultPseudoRandomStringGenerator()
76+
{
77+
// Since openssl_random_pseudo_bytes() can sometimes return non-cryptographically
78+
// secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() first.
79+
if (function_exists('mcrypt_create_iv')) {
80+
return new McryptPseudoRandomStringGenerator();
81+
}
82+
83+
if (function_exists('openssl_random_pseudo_bytes')) {
84+
return new OpenSslPseudoRandomStringGenerator();
85+
}
86+
87+
if (!ini_get('open_basedir') && is_readable('/dev/urandom')) {
88+
return new UrandomPseudoRandomStringGenerator();
89+
}
90+
91+
throw new FacebookSDKException('Unable to detect a cryptographically secure pseudo-random string generator.');
92+
}
93+
}

0 commit comments

Comments
 (0)