Skip to content

Commit 27cfdec

Browse files
authored
Merge pull request #69 from jolicode/collection-client-decorator
Introduce client decorator to handle collection
2 parents dfb44ac + e0c6553 commit 27cfdec

File tree

6 files changed

+137
-17
lines changed

6 files changed

+137
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
* Add a new Client to ease iteration over Slack paginated endpoints thanks to `iterateXxxx` methods (where `xxxx` is the endpoint name to iterate over)
6+
57
## 4.1.1 (2021-03-16)
68

79
* Upgrade Jane to from 6.3.3 to v6.3.5, fix an error with very long string / payload

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"symfony/http-client": "^4.3.3 || ^5.1",
3939
"nyholm/psr7": "^1.2",
4040
"friendsofphp/php-cs-fixer": "^2.17",
41-
"symfony/phpunit-bridge": "^4.3",
41+
"symfony/phpunit-bridge": "^5.2",
4242
"opis/json-schema": "^1.0",
4343
"symfony/console": "^5.1",
4444
"symfony/contracts": "^2.1",

doc/examples/retrieve-users.php

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,9 @@
88

99
$client = ClientFactory::create('Your token');
1010

11-
/** @var ObjsUser[] $users */
12-
$users = [];
13-
$cursor = '';
14-
1511
try {
16-
do {
17-
// This method requires your token to have the scope "users:read"
18-
$response = $client->usersList([
19-
'limit' => 200,
20-
'cursor' => $cursor,
21-
]);
22-
23-
$users = array_merge($users, $response->getMembers());
24-
$cursor = $response->getResponseMetadata() ? $response->getResponseMetadata()->getNextCursor() : '';
25-
} while (!empty($cursor));
12+
/** @var ObjsUser[] $users */
13+
$users = iterator_to_array($client->iterateUsersList());
2614

2715
echo sprintf('Here is the names of the members of your workspace: %s', implode(', ', array_map(function(ObjsUser $user) {
2816
return $user->getName();

src/Client.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of JoliCode's Slack PHP API project.
7+
*
8+
* (c) JoliCode <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace JoliCode\Slack;
15+
16+
use JoliCode\Slack\Api\Client as ApiClient;
17+
18+
class Client extends ApiClient
19+
{
20+
const CURSOR_PAGINATION = [
21+
'channelsList' => 'channels',
22+
'conversationsHistory' => 'messages',
23+
'conversationsList' => 'channels',
24+
'conversationsMembers' => 'members',
25+
'conversationsReplies' => 'messages',
26+
'filesInfo' => 'comments',
27+
'groupsList' => 'groups',
28+
'imList' => 'ims',
29+
'mpimList' => 'groups',
30+
'reactionsList' => 'items',
31+
'starsList' => 'items',
32+
'usersList' => 'members',
33+
];
34+
35+
public function __call(string $name, $arguments)
36+
{
37+
$method = lcfirst(str_replace('iterate', '', $name));
38+
39+
if (isset(self::CURSOR_PAGINATION[$method])) {
40+
return $this->iterate($method, $arguments);
41+
}
42+
43+
throw new \BadMethodCallException(sprintf('Unknown method %s::%s()', self::class, $name));
44+
}
45+
46+
public function iterate(string $method, array $arguments): iterable
47+
{
48+
$getter = 'get'.self::CURSOR_PAGINATION[$method];
49+
50+
$arguments[0] = $arguments[0] ?? [];
51+
$arguments[0]['limit'] = $arguments[0]['limit'] ?? 1000;
52+
53+
$cursor = '';
54+
55+
do {
56+
$arguments[0]['cursor'] = $cursor;
57+
58+
$response = $this->{$method}(...$arguments);
59+
60+
foreach ($response->{$getter}() as $item) {
61+
yield $item;
62+
}
63+
64+
$cursor = $response->getResponseMetadata() ? $response->getResponseMetadata()->getNextCursor() : '';
65+
} while (!empty($cursor));
66+
}
67+
}

src/ClientFactory.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Http\Client\Common\PluginClient;
1919
use Http\Discovery\Psr17FactoryDiscovery;
2020
use Http\Discovery\Psr18ClientDiscovery;
21-
use JoliCode\Slack\Api\Client;
2221
use JoliCode\Slack\HttpPlugin\AddSlackPathAndHostPlugin;
2322
use JoliCode\Slack\HttpPlugin\SlackErrorPlugin;
2423
use Psr\Http\Client\ClientInterface;
@@ -43,7 +42,7 @@ public static function create(string $token, ClientInterface $httpClient = null)
4342
]),
4443
]);
4544

46-
// Instantiate an OpenApi client generated by Jane
45+
// Instantiate our client extending the one generated by Jane
4746
return Client::create($pluginClient);
4847
}
4948
}

tests/ClientTest.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of JoliCode's Slack PHP API project.
7+
*
8+
* (c) JoliCode <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace JoliCode\Slack\Tests;
15+
16+
use JoliCode\Slack\Api\Model\ObjsUser;
17+
use JoliCode\Slack\ClientFactory;
18+
use PHPUnit\Framework\TestCase;
19+
20+
class ClientTest extends TestCase
21+
{
22+
protected function setUp(): void
23+
{
24+
if (!\array_key_exists('SLACK_TOKEN', $_SERVER)) {
25+
$this->markTestSkipped('SLACK_TOKEN env var not present, skip the test.');
26+
}
27+
}
28+
29+
public function testItCanIterate()
30+
{
31+
$client = ClientFactory::create($_SERVER['SLACK_TOKEN']);
32+
33+
$users = $client->iterateUsersList([
34+
'limit' => 1000,
35+
]);
36+
37+
self::assertIsIterable($users);
38+
39+
$users = iterator_to_array($users);
40+
41+
self::assertGreaterThan(1000, \count($users));
42+
self::assertInstanceOf(ObjsUser::class, $users[0]);
43+
}
44+
45+
public function testItThrowsExceptionOnUnknownIterate()
46+
{
47+
$client = ClientFactory::create($_SERVER['SLACK_TOKEN']);
48+
49+
self::expectException(\BadMethodCallException::class);
50+
self::expectExceptionMessage('Unknown method JoliCode\Slack\Client::iterateFooBar()');
51+
52+
$client->iterateFooBar();
53+
}
54+
55+
public function testItThrowsExceptionOnUnknownMethod()
56+
{
57+
$client = ClientFactory::create($_SERVER['SLACK_TOKEN']);
58+
59+
self::expectException(\BadMethodCallException::class);
60+
self::expectExceptionMessage('Unknown method JoliCode\Slack\Client::foobar()');
61+
62+
$client->foobar();
63+
}
64+
}

0 commit comments

Comments
 (0)