From 7b1d845c4b7ced8baa427562a19200f234a872da Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Wed, 23 Apr 2025 12:05:47 -0400 Subject: [PATCH] transformed data --- src/Illuminate/Pagination/CursorPaginator.php | 32 ++++++++++++++++++- tests/Pagination/CursorPaginatorTest.php | 31 ++++++++++++++++-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Pagination/CursorPaginator.php b/src/Illuminate/Pagination/CursorPaginator.php index e68281086ab8..0389e85e2f36 100644 --- a/src/Illuminate/Pagination/CursorPaginator.php +++ b/src/Illuminate/Pagination/CursorPaginator.php @@ -32,6 +32,13 @@ class CursorPaginator extends AbstractCursorPaginator implements Arrayable, Arra */ protected $hasMore; + /** + * The function that transforms before rendering. + * + * @var \Closure(TValue): mixed + */ + protected $transformer; + /** * Create a new paginator instance. * @@ -142,6 +149,29 @@ public function onLastPage() return ! $this->hasMorePages(); } + /** + * Set how data is transformed before rendering to JSON. + * + * @param \Closure(TValue): mixed $tranformer + * @return $this + */ + public function setTransformer($tranformer) + { + $this->transformer = $tranformer; + + return $this; + } + + /** + * Prepare data for rendering. + * + * @return array + */ + protected function transformedData() + { + return $this->transformer ? $this->items->map($this->transformer)->toArray() : $this->items->toArray(); + } + /** * Get the instance as an array. * @@ -150,7 +180,7 @@ public function onLastPage() public function toArray() { return [ - 'data' => $this->items->toArray(), + 'data' => $this->transformedData(), 'path' => $this->path(), 'per_page' => $this->perPage(), 'next_cursor' => $this->nextCursor()?->encode(), diff --git a/tests/Pagination/CursorPaginatorTest.php b/tests/Pagination/CursorPaginatorTest.php index 11cfb4c009a7..44430d63b19a 100644 --- a/tests/Pagination/CursorPaginatorTest.php +++ b/tests/Pagination/CursorPaginatorTest.php @@ -70,13 +70,14 @@ public function testCanTransformPaginatorItems() $options = ['path' => 'http://website.com/test', 'parameters' => ['id']]); $p->through(function ($item) { - $item['id'] = $item['id'] + 2; + $item['zid'] = $item['id'] + 2; + unset($item['id']); return $item; }); $this->assertInstanceOf(CursorPaginator::class, $p); - $this->assertSame([['id' => 6], ['id' => 7]], $p->items()); + $this->assertSame([['zid' => 6], ['zid' => 7]], $p->items()); } public function testCursorPaginatorOnFirstAndLastPage() @@ -120,6 +121,32 @@ public function testReturnEmptyCursorWhenItemsAreEmpty() ], $p->toArray()); } + public function testCanTransformOutput() + { + $p = new CursorPaginator([['id' => 4], ['id' => 5], ['id' => 6]], 2, null, + ['path' => 'http://website.com/test', 'parameters' => ['id']] + ); + + $p->setTransformer(function ($item) { + return [ + 'slug' => 'slug-'.$item['id'], + 'name' => 'Test '.$item['id'], + ]; + }); + + $this->assertInstanceOf(CursorPaginator::class, $p); + $this->assertEquals([ + 'data' => [['slug' => 'slug-4', 'name' => 'Test 4'], ['slug' => 'slug-5', 'name' => 'Test 5']], + 'path' => 'http://website.com/test', + 'per_page' => 2, + 'next_cursor' => 'eyJpZCI6NSwiX3BvaW50c1RvTmV4dEl0ZW1zIjp0cnVlfQ', + 'next_page_url' => 'http://website.com/test?cursor=eyJpZCI6NSwiX3BvaW50c1RvTmV4dEl0ZW1zIjp0cnVlfQ', + 'prev_cursor' => null, + 'prev_page_url' => null, + ], $p->toArray()); + $this->assertEquals([ ['id' => 4], ['id' => 5]], $p->items()); + } + protected function getCursor($params, $isNext = true) { return (new Cursor($params, $isNext))->encode();