diff --git a/Relay/Connection/Paginator.php b/Relay/Connection/Paginator.php index b3eb9a18f..a59031c07 100644 --- a/Relay/Connection/Paginator.php +++ b/Relay/Connection/Paginator.php @@ -33,11 +33,14 @@ public function __construct(callable $fetcher) /** * @param Argument|array $args * @param int|callable $total + * @param array $callableArgs * * @return Connection */ - public function backward($args, $total) + public function backward($args, $total, array $callableArgs = []) { + $total = is_callable($total) ? call_user_func_array($total, $callableArgs) : $total; + $args = $this->protectArgs($args); $limit = $args['last']; $offset = max(0, ConnectionBuilder::getOffsetWithDefault($args['before'], $total) - $limit); @@ -79,15 +82,16 @@ public function forward($args) /** * @param Argument|array $args * @param int|callable $total + * @param array $callableArgs * * @return Connection */ - public function auto($args, $total) + public function auto($args, $total, $callableArgs = []) { $args = $this->protectArgs($args); if ($args['last']) { - return $this->backward($args, is_callable($total) ? call_user_func($total) : $total); + return $this->backward($args, $total, $callableArgs); } else { return $this->forward($args); } diff --git a/Resources/doc/helpers/relay-paginator.md b/Resources/doc/helpers/relay-paginator.md index d9eb7c6b8..d12cf32da 100644 --- a/Resources/doc/helpers/relay-paginator.md +++ b/Resources/doc/helpers/relay-paginator.md @@ -152,3 +152,45 @@ The callback function will receive: - `$limit = 3` And it must return at least `['C','D','E']` + +#### With a `last` relay parameter + +```php +data, $offset); + } + + public function count($array) + { + return count($array); + } +} + +$backend = new DataBackend(); + +$paginator = new Paginator(function ($offset, $limit) use ($backend) { + return $backend->getData($offset); +}); + +$result = $paginator->backward( + new Argument( + [ + 'last' => 4, + ] + ), + [$backend, 'count'], + ['array' => $backend->getData] +); +``` + +You should get the 4 last items of the _data set_. diff --git a/Tests/Relay/Connection/PaginatorBackend.php b/Tests/Relay/Connection/PaginatorBackend.php new file mode 100644 index 000000000..03556784e --- /dev/null +++ b/Tests/Relay/Connection/PaginatorBackend.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Overblog\GraphQLBundle\Tests\Relay\Connection; + +/** + * Class PaginatorBackend. + */ +class PaginatorBackend +{ + public function count($array) + { + return count($array); + } +} diff --git a/Tests/Relay/Connection/PaginatorTest.php b/Tests/Relay/Connection/PaginatorTest.php index 47411a88b..e330e0713 100644 --- a/Tests/Relay/Connection/PaginatorTest.php +++ b/Tests/Relay/Connection/PaginatorTest.php @@ -253,4 +253,33 @@ public function testAutoBackwardWithCallable() $this->assertSameEdgeNodeValue(['B', 'C', 'D', 'E'], $result); $this->assertTrue($result->pageInfo->hasPreviousPage); } + + public function testTotalCallableWithArguments() + { + $paginatorBackend = new PaginatorBackend(); + + $callable = [ + $paginatorBackend, + 'count', + ]; + + $this->assertSame(5, call_user_func_array($callable, ['array' => $this->data])); + + $paginator = new Paginator(function ($offset, $limit) { + $this->assertSame(1, $offset); + $this->assertSame(4, $limit); + + return $this->getData($offset); + }); + + $result = $paginator->auto( + new Argument(['last' => 4]), + $callable, + ['array' => $this->data] + ); + + $this->assertCount(4, $result->edges); + $this->assertSameEdgeNodeValue(['B', 'C', 'D', 'E'], $result); + $this->assertTrue($result->pageInfo->hasPreviousPage); + } }