Skip to content

Commit 74f34ea

Browse files
committed
Access tokens are now optimal for clients allowing for getting access token operations
1 parent d4d38ab commit 74f34ea

12 files changed

+163
-51
lines changed

Diff for: examples/streaming-filter-hashtag-async.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
$config = require 'resolve_config.php';
1010

1111
$loop = Factory::create();
12-
$client = new AsyncClient(
12+
$client = (new AsyncClient(
1313
$config['consumer']['key'],
1414
$config['consumer']['secret'],
15-
$config['access_token']['token'],
16-
$config['access_token']['secret'],
1715
$loop
16+
))->withAccessToken(
17+
$config['access_token']['token'],
18+
$config['access_token']['secret']
1819
);
1920

2021
$hashtags = [];

Diff for: examples/streaming-filter-track-async.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
$config = require 'resolve_config.php';
1111

1212
$loop = Factory::create();
13-
$client = new AsyncClient(
13+
$client = (new AsyncClient(
1414
$config['consumer']['key'],
1515
$config['consumer']['secret'],
16-
$config['access_token']['token'],
17-
$config['access_token']['secret'],
1816
$loop
17+
))->withAccessToken(
18+
$config['access_token']['token'],
19+
$config['access_token']['secret']
1920
);
2021

2122
$users = [

Diff for: examples/streaming-filter-users-async.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
$config = require 'resolve_config.php';
1111

1212
$loop = Factory::create();
13-
$client = new AsyncClient(
13+
$client = (new AsyncClient(
1414
$config['consumer']['key'],
1515
$config['consumer']['secret'],
16-
$config['access_token']['token'],
17-
$config['access_token']['secret'],
1816
$loop
17+
))->withAccessToken(
18+
$config['access_token']['token'],
19+
$config['access_token']['secret']
1920
);
2021

2122
$users = [

Diff for: examples/streaming-sample-async.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
$config = require 'resolve_config.php';
99

1010
$loop = Factory::create();
11-
$client = new AsyncClient(
11+
$client = (new AsyncClient(
1212
$config['consumer']['key'],
1313
$config['consumer']['secret'],
14-
$config['access_token']['token'],
15-
$config['access_token']['secret'],
1614
$loop
15+
))->withAccessToken(
16+
$config['access_token']['token'],
17+
$config['access_token']['secret']
1718
);
1819

1920
$client->sampleStream()->subscribeCallback(function ($document) {

Diff for: examples/streaming-sample-counters-async.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
$config = require 'resolve_config.php';
1212

1313
$loop = Factory::create();
14-
$client = new AsyncClient(
14+
$client = (new AsyncClient(
1515
$config['consumer']['key'],
1616
$config['consumer']['secret'],
17-
$config['access_token']['token'],
18-
$config['access_token']['secret'],
1917
$loop
18+
))->withAccessToken(
19+
$config['access_token']['token'],
20+
$config['access_token']['secret']
2021
);
2122

2223
$counters = [

Diff for: examples/user-async.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
$config = require 'resolve_config.php';
1111

1212
$loop = Factory::create();
13-
$client = new AsyncClient(
13+
$client = (new AsyncClient(
1414
$config['consumer']['key'],
1515
$config['consumer']['secret'],
16-
$config['access_token']['token'],
17-
$config['access_token']['secret'],
1816
$loop
17+
))->withAccessToken(
18+
$config['access_token']['token'],
19+
$config['access_token']['secret']
1920
);
2021

2122
$users = [

Diff for: examples/user.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
require dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
77
$config = require 'resolve_config.php';
88

9-
$client = new Client(
9+
$client = (new Client(
1010
$config['consumer']['key'],
11-
$config['consumer']['secret'],
11+
$config['consumer']['secret']
12+
))->withAccessToken(
1213
$config['access_token']['token'],
1314
$config['access_token']['secret']
1415
);

Diff for: src/ApiSettings.php

+12-16
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,20 @@ class ApiSettings
3131
public static function getOptions(
3232
string $consumerKey,
3333
string $consumerSecret,
34-
string $accessToken,
35-
string $accessTokenSecret,
36-
string $suffix
34+
string $suffix,
35+
array $suppliedOptions = []
3736
): array {
38-
$options = self::TRANSPORT_OPTIONS;
37+
// @codingStandardsIgnoreStart
38+
$options = array_replace_recursive(self::TRANSPORT_OPTIONS, $suppliedOptions);
3939
$options[Options::HYDRATOR_OPTIONS][HydratorOptions::NAMESPACE_SUFFIX] = $suffix;
40-
$options[Options::TRANSPORT_OPTIONS][TransportOptions::MIDDLEWARE] = [
41-
Oauth1Middleware::class,
42-
JsonDecodeMiddleware::class,
43-
];
44-
$options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS] = [
45-
Oauth1Middleware::class => [
46-
Oauth1Options::CONSUMER_KEY => new Definition\ConsumerKey($consumerKey),
47-
Oauth1Options::CONSUMER_SECRET => new Definition\ConsumerSecret($consumerSecret),
48-
Oauth1Options::ACCESS_TOKEN => new Definition\AccessToken($accessToken),
49-
Oauth1Options::TOKEN_SECRET => new Definition\TokenSecret($accessTokenSecret),
50-
],
51-
];
40+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::MIDDLEWARE][] = Oauth1Middleware::class;
41+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::MIDDLEWARE][] = JsonDecodeMiddleware::class;
42+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::MIDDLEWARE] = array_unique(
43+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::MIDDLEWARE]
44+
);
45+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::CONSUMER_KEY] = new Definition\ConsumerKey($consumerKey);
46+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::CONSUMER_SECRET] = new Definition\ConsumerSecret($consumerSecret);
47+
// @codingStandardsIgnoreEnd
5248
return $options;
5349
}
5450
}

Diff for: src/AsyncClient.php

+69-11
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,45 @@
22

33
namespace ApiClients\Client\Twitter;
44

5+
use ApiClients\Foundation\Client;
56
use ApiClients\Foundation\Factory;
67
use ApiClients\Foundation\Hydrator\CommandBus\Command\HydrateCommand;
7-
use ApiClients\Foundation\Client;
8+
use ApiClients\Foundation\Oauth1\Middleware\Oauth1Middleware;
9+
use ApiClients\Foundation\Oauth1\Options as Oauth1Options;
10+
use ApiClients\Foundation\Options;
811
use ApiClients\Foundation\Transport\CommandBus\Command\RequestCommand;
912
use ApiClients\Foundation\Transport\CommandBus\Command\StreamingRequestCommand;
13+
use ApiClients\Foundation\Transport\Options as TransportOptions;
14+
use ApiClients\Tools\Psr7\Oauth1\Definition;
1015
use GuzzleHttp\Psr7\Request;
11-
use JacobKiers\OAuth\Consumer\Consumer;
12-
use JacobKiers\OAuth\Token\Token;
1316
use Psr\Http\Message\RequestInterface;
1417
use Psr\Http\Message\ResponseInterface;
1518
use React\EventLoop\LoopInterface;
1619
use React\Promise\PromiseInterface;
17-
use function React\Promise\resolve;
1820
use Rx\Extra\Operator\CutOperator;
1921
use Rx\Observable;
2022
use Rx\React\Promise;
23+
use function React\Promise\resolve;
2124

22-
class AsyncClient
25+
final class AsyncClient
2326
{
2427
const STREAM_DELIMITER = "\r\n";
2528

29+
/**
30+
* @var string
31+
*/
32+
private $consumerKey;
33+
34+
/**
35+
* @var string
36+
*/
37+
private $consumerSecret;
38+
39+
/**
40+
* @var LoopInterface
41+
*/
42+
private $loop;
43+
2644
/**
2745
* @var Client
2846
*/
@@ -31,24 +49,64 @@ class AsyncClient
3149
public function __construct(
3250
string $consumerKey,
3351
string $consumerSecret,
34-
string $accessToken,
35-
string $accessTokenSecret,
3652
LoopInterface $loop,
53+
array $options = [],
3754
Client $client = null
3855
) {
56+
$this->consumerKey = $consumerKey;
57+
$this->consumerSecret = $consumerSecret;
58+
$this->loop = $loop;
59+
3960
if (!($client instanceof Client)) {
4061
$this->options = ApiSettings::getOptions(
4162
$consumerKey,
4263
$consumerSecret,
43-
$accessToken,
44-
$accessTokenSecret,
45-
'Async'
64+
'Async',
65+
$options
4666
);
47-
$client = Factory::create($loop, $this->options);
67+
68+
$client = Factory::create($this->loop, $this->options);
4869
}
70+
4971
$this->client = $client;
5072
}
5173

74+
public function withAccessToken(string $accessToken, string $accessTokenSecret): AsyncClient
75+
{
76+
$options = $this->options;
77+
// @codingStandardsIgnoreStart
78+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::ACCESS_TOKEN] = new Definition\AccessToken($accessToken);
79+
$options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::TOKEN_SECRET] = new Definition\TokenSecret($accessTokenSecret);
80+
// @codingStandardsIgnoreEnd
81+
82+
return new self(
83+
$this->consumerKey,
84+
$this->consumerSecret,
85+
$this->loop,
86+
$options
87+
);
88+
}
89+
90+
public function withOutAccessToken(): AsyncClient
91+
{
92+
$options = $this->options;
93+
// @codingStandardsIgnoreStart
94+
if (isset($options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::ACCESS_TOKEN])) {
95+
unset($options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::ACCESS_TOKEN]);
96+
}
97+
if (isset($options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::TOKEN_SECRET])) {
98+
unset($options[Options::TRANSPORT_OPTIONS][TransportOptions::DEFAULT_REQUEST_OPTIONS][Oauth1Middleware::class][Oauth1Options::TOKEN_SECRET]);
99+
}
100+
// @codingStandardsIgnoreEnd
101+
102+
return new self(
103+
$this->consumerKey,
104+
$this->consumerSecret,
105+
$this->loop,
106+
$options
107+
);
108+
}
109+
52110
public function user(string $user): PromiseInterface
53111
{
54112
return $this->client->handle(new RequestCommand(

Diff for: src/Client.php

+16-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,24 @@ class Client
2222

2323
public function __construct(
2424
string $consumerKey,
25-
string $consumerSecret,
26-
string $accessToken,
27-
string $accessTokenSecret
25+
string $consumerSecret
2826
) {
2927
$this->loop = LoopFactory::create();
30-
$this->client = new AsyncClient($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret, $this->loop);
28+
$this->client = new AsyncClient($consumerKey, $consumerSecret, $this->loop);
29+
}
30+
31+
public function withAccessToken(string $accessToken, string $accessTokenSecret): Client
32+
{
33+
$clone = clone $this;
34+
$clone->client = $this->client->withAccessToken($accessToken, $accessTokenSecret);
35+
return $clone;
36+
}
37+
38+
public function withOutAccessToken(): Client
39+
{
40+
$clone = clone $this;
41+
$clone->client = $this->client->withOutAccessToken();
42+
return $clone;
3143
}
3244

3345
public function tweet(string $tweet): TweetInterface

Diff for: tests/AsyncClientTest.php

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Tests\Client\Twitter;
4+
5+
use ApiClients\Client\Twitter\AsyncClient;
6+
use ApiClients\Tools\TestUtilities\TestCase;
7+
use React\EventLoop\Factory;
8+
9+
class AsyncClientTest extends TestCase
10+
{
11+
public function testImmutability()
12+
{
13+
$client = new AsyncClient('foo', 'bar', Factory::create());
14+
$newClient = $client->withAccessToken('beer', 'baz');
15+
$this->assertNotSame($client, $newClient);
16+
$anotherNewClient = $newClient->withOutAccessToken();
17+
$this->assertNotSame($client, $anotherNewClient);
18+
$this->assertNotSame($newClient, $anotherNewClient);
19+
}
20+
}

Diff for: tests/ClientTest.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Tests\Client\Twitter;
4+
5+
use ApiClients\Client\Twitter\Client;
6+
use ApiClients\Tools\TestUtilities\TestCase;
7+
8+
class ClientTest extends TestCase
9+
{
10+
public function testImmutability()
11+
{
12+
$client = new Client('foo', 'bar');
13+
$newClient = $client->withAccessToken('beer', 'baz');
14+
$this->assertNotSame($client, $newClient);
15+
$anotherNewClient = $newClient->withOutAccessToken();
16+
$this->assertNotSame($client, $anotherNewClient);
17+
$this->assertNotSame($newClient, $anotherNewClient);
18+
}
19+
}

0 commit comments

Comments
 (0)