-
-
Notifications
You must be signed in to change notification settings - Fork 596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[3.x] Re-worked pagination to not mutate the api classes #907
Conversation
@GrahamCampbell I'm testing this PR but it doesn't seem to work. Is it a bug or am I doing something wrong? $paginator = new Github\ResultPager($client);
$api = $client->api('user');
$api = $api->perPage(2);
$result = $paginator->fetch($api, 'repositories', ['acrobat']); This fetch function still uses the default of 100 items per page |
Yeh, that is what I would expect to happen, and it's also how the current paginator works. |
The paginator intentionally doesn't allow users to change the internal number of items per page. |
Well actually this does work with the old pager dev-master <?php
require_once 'vendor/autoload.php';
$client = new \Github\Client();
$client->authenticate('xxxxxx', \Github\Client::AUTH_ACCESS_TOKEN);
$paginator = new Github\ResultPager($client);
$api = $client->api('user');
$api->setPerPage(2);
$result = $paginator->fetch($api, 'repositories', ['knplabs']);
echo \count($result) .PHP_EOL;
while (($result = $paginator->fetchNext()) !== []) {
echo \count($result) .PHP_EOL;
} Output
pager changes code: <?php
require_once 'vendor/autoload.php';
$client = new \Github\Client();
$client->authenticate('xxxxx', \Github\Client::AUTH_ACCESS_TOKEN);
$paginator = new Github\ResultPager($client);
$api = $client->api('user');
$api = $api->perPage(2);
$result = $paginator->fetch($api, 'repositories', ['knplabs']);
echo \count($result) .PHP_EOL;
while (($result = $paginator->fetchNext()) !== []) {
echo \count($result) .PHP_EOL;
} output
Previously the php-github-api/lib/Github/ResultPager.php Line 62 in 9b01208
https://github.com/KnpLabs/php-github-api/pull/907/files#diff-40de580826089d3ae27bf74e6b2b9402R76 |
Hmm, right. I suppose my question is why would anyone want to do that? |
I can see use cases for this like forexample the travis-ci settings page where you show all available repositories to enable. This could be a paginated list with 20 items per page. If there is no usecase for changing the per page amount, why do we have the |
The perPage method allows the paginator to set the number of pages it wants. It has to be able to interface with the api classes somehow. |
Hmm I see there was the confusion on my part. Setting the per page amount in the resultpager constructor does the job. $paginator = new Github\ResultPager($client, 2); But now I thinking that this might be confusing to for the users of this library. Could we keep the private property but use a closure bind setup to clone and update the perpage value without having a public perpage method which doesn't actually work with the paginator? What do you think @GrahamCampbell? public function fetch(ApiInterface $api, string $method, array $parameters = [])
{
$paginatorPerPage = $this->perPage;
$closure = \Closure::bind(function (AbstractApi $api) use ($paginatorPerPage) {
$clone = clone $api;
$clone->perPage = $paginatorPerPage;
return $clone;
}, null, AbstractApi::class);
$api = $closure($api);
$result = $api->$method(...$parameters);
$this->postFetch();
return $result;
} |
@GrahamCampbell what do you think of the solution above? Would this be the way to finish this PR? |
@GrahamCampbell what do you think of the proposed solution? I would like to finish this PR and release the 3.0 😄 |
Sorry for the delay here. I will get to this soon. NB There are currently merge conflicts. |
No worries! 😄 |
Rebased and made the relevant changes you wanted. How is this looking now, @acrobat? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few things already, I will also try this change in my small test app later!
Co-Authored-By: Jeroen Thora <1374857+acrobat@users.noreply.github.com>
I've applied the changes you asked for. :) |
Yes, thank you! I will try to do a review and test in my demo app later tonight! |
My "test app" for the pagination worked great and intuitive with the latest changes 👌 I will do a quick code review later and prepare a PR for 2.x to deprecate some things changed/removed in this PR |
Thank you @GrahamCampbell |
This re-works pagination to avoid mutating the API classes. It took a few attempts to get the implementation details right. Let me explain why I chose to use clone:
new static(...)
, then I would have had to have made the abstract api constructor final. This could cause problems for people mocking the api classes, and also limits the possibility to thunk up arguments to the api classes, say if we want to introduce an api class which takes an extra parameter which is always used (this is common place in the gitlab fork of this library).This PR partially addresses #904.
So, I think cloning then setting the private property, within the abstract api class is the way to go, and nicely separates responsibilities. Classes that extend the abstract api class cannot mutate the property, and outsiders also cannot either. They have to call perPage which gives a fresh instance (one we've cloned).