framework: (regression) Impossilbe to use JsonResource::collection with paginated query (not eloquent)
- Laravel Version: 5.8.35
- PHP Version: 7.2.5
- Database Driver & Version: Mysq 5.7
Description:
Laravel 5.8.34:
function actionWithoutPaginate() {
$result = DB::query(...difficult query where is not possible to use eloquent...)->get();
return CustomResource::collection($result);
}
function actionWithPaginate() {
$result = DB::query(...dificult query where is not possible to use eloquent...)->paginate();
return CustomResource::collection($result);
}
class CustomResource extends Resource {
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
*
* @return array
*/
public function toArray($request) {
$image = get_object_vars($this->resource);
if (isset($image['last_changed'])) {
$service = app()->make(MyService::class);
$format = $service->getConnection()->getQueryGrammar()->getDateFormat();
$carbon = Carbon::createFromFormat($format, $image['last_changed']);
$image['last_changed'] = $carbon;
}
return $image;
}
}
Since 5.8.35:
actionWithoutPaginate
- works fineactionWithPaginate
- broken[2019-09-09 08:08:55] testing.ERROR: Cannot use object of type stdClass as array {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Cannot use object of type stdClass as array at vendor\\laravel\\framework\\src\\Illuminate\\Http\\Resources\\DelegatesToResource.php:53) [stacktrace] #0 vendor\\laravel\\framework\\src\\Illuminate\\Support\\Arr.php(148): Illuminate\\Http\\Resources\\Json\\JsonResource->offsetExists('resource') #1 vendor\\laravel\\framework\\src\\Illuminate\\Support\\helpers.php(524): Illuminate\\Support\\Arr::exists(Object(Yggdrasil\\Http\\Http\\Resources\\ObjectResource), 'resource') #2 vendor\\laravel\\framework\\src\\Illuminate\\Support\\Arr.php(387): data_get(Object(Yggdrasil\\Http\\Http\\Resources\\ObjectResource), Array) #3 vendor\\laravel\\framework\\src\\Illuminate\\Support\\Collection.php(1107): Illuminate\\Support\\Arr::pluck(Array, Array, NULL) #4 vendor\\laravel\\framework\\src\\Illuminate\\Support\\Traits\\ForwardsCalls.php(23): Illuminate\\Support\\Collection->pluck('resource') #5 vendor\\laravel\\framework\\src\\Illuminate\\Pagination\\AbstractPaginator.php(647): Illuminate\\Pagination\\AbstractPaginator->forwardCallTo(Object(Illuminate\\Support\\Collection), 'pluck', Array) #6 vendor\\laravel\\framework\\src\\Illuminate\\Http\\Resources\\Json\\PaginatedResourceResponse.php(28): Illuminate\\Pagination\\AbstractPaginator->__call('pluck', Array) #7 vendor\\laravel\\framework\\src\\Illuminate\\Support\\helpers.php(1124): Illuminate\\Http\\Resources\\Json\\PaginatedResourceResponse->Illuminate\\Http\\Resources\\Json\\{closure}(Object(Illuminate\\Http\\JsonResponse)) #8 vendor\\laravel\\framework\\src\\Illuminate\\Http\\Resources\\Json\\PaginatedResourceResponse.php(31): tap(Object(Illuminate\\Http\\JsonResponse), Object(Closure)) #9 vendor\\laravel\\framework\\src\\Illuminate\\Http\\Resources\\Json\\ResourceCollection.php(71): Illuminate\\Http\\Resources\\Json\\PaginatedResourceResponse->toResponse(Object(Illuminate\\Http\\Request)) #10 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(733): Illuminate\\Http\\Resources\\Json\\ResourceCollection->toResponse(Object(Illuminate\\Http\\Request)) #11 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(720): Illuminate\\Routing\\Router::toResponse(Object(Illuminate\\Http\\Request), Object(Yggdrasil\\Http\\Http\\Resources\\ResourceCollection)) #12 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(680): Illuminate\\Routing\\Router->prepareResponse(Object(Illuminate\\Http\\Request), Object(Yggdrasil\\Http\\Http\\Resources\\ResourceCollection)) #13 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(30): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #14 app\\Http\\Middleware\\CheckClientCredentials.php(29): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #15 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): App\\Http\\Middleware\\CheckClientCredentials->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'marinexprocurem...') #16 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #17 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Middleware\\SubstituteBindings.php(41): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #18 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #19 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #20 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Middleware\\ThrottleRequests.php(58): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #21 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure), 600, '1') #22 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #23 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #24 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure)) #25 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request)) #26 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route)) #27 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request)) #28 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request)) #29 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(30): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request)) #30 vendor\\fideloper\\proxy\\src\\TrustProxies.php(57): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #31 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #32 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #33 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #34 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #35 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #36 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #37 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #38 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #39 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php(27): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #40 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #41 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #42 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php(62): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #43 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #44 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #45 vendor\\laravel\\framework\\src\\Illuminate\\Http\\Middleware\\FrameGuard.php(18): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #46 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Http\\Middleware\\FrameGuard->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #47 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #48 packages\\yggdrasil-core\\src\\Http\\Http\\Middleware\\Cors.php(25): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #49 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Yggdrasil\\Http\\Http\\Middleware\\Cors->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #50 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #51 packages\\yggdrasil-core\\src\\Http\\Http\\Middleware\\ForceWantsJson.php(22): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #52 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Yggdrasil\\Http\\Http\\Middleware\\ForceWantsJson->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #53 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #54 vendor\\itsgoingd\\clockwork\\Clockwork\\Support\\Laravel\\ClockworkMiddleware.php(27): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #55 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Clockwork\\Support\\Laravel\\ClockworkMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure)) #56 vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request)) #57 vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request)) #58 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure)) #59 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request)) #60 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Testing\\Concerns\\MakesHttpRequests.php(375): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request)) #61 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Testing\\Concerns\\MakesHttpRequests.php(347): Illuminate\\Foundation\\Testing\\TestCase->call('GET', '/api/v1/MarineX...', Array, Array, Array, Array, '[]') #62 tests\\Feature\\Api\\v1\\MarineXProcurement\\RecipesControllerTest.php(75): Illuminate\\Foundation\\Testing\\TestCase->json('GET', '/api/v1/MarineX...') #63 vendor\\phpunit\\phpunit\\src\\Framework\\TestCase.php(1154): Tests\\Feature\\Api\\v1\\MarineXProcurement\\RecipesControllerTest->testIndex() #64 vendor\\phpunit\\phpunit\\src\\Framework\\TestCase.php(842): PHPUnit\\Framework\\TestCase->runTest() #65 vendor\\phpunit\\phpunit\\src\\Framework\\TestResult.php(693): PHPUnit\\Framework\\TestCase->runBare() #66 vendor\\phpunit\\phpunit\\src\\Framework\\TestCase.php(796): PHPUnit\\Framework\\TestResult->run(Object(Tests\\Feature\\Api\\v1\\MarineXProcurement\\RecipesControllerTest)) #67 vendor\\phpunit\\phpunit\\src\\Framework\\TestSuite.php(746): PHPUnit\\Framework\\TestCase->run(Object(PHPUnit\\Framework\\TestResult)) #68 vendor\\phpunit\\phpunit\\src\\TextUI\\TestRunner.php(652): PHPUnit\\Framework\\TestSuite->run(Object(PHPUnit\\Framework\\TestResult)) #69 vendor\\phpunit\\phpunit\\src\\TextUI\\Command.php(206): PHPUnit\\TextUI\\TestRunner->doRun(Object(PHPUnit\\Framework\\TestSuite), Array, true) #70 vendor\\phpunit\\phpunit\\src\\TextUI\\Command.php(162): PHPUnit\\TextUI\\Command->run(Array, true) #71 vendor\\phpunit\\phpunit\\phpunit(61): PHPUnit\\TextUI\\Command::main() #72 {main} "}
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 3
- Comments: 20 (13 by maintainers)
Commits related to this issue
- Restore php 7.4 compatibility for paginator resources Restores php 7.4 compatibility for paginator resources that receives objects (for example from the query builder) instead of models. Fixes #3170... — committed to kevinpijning/framework by kevinpijning 4 years ago
- Fix of pagination of JsonResources in Laravel - bug: https://github.com/laravel/framework/issues/29916 - JSON API paginations were broken, (e.g. /api/banners) — committed to remp2020/remp by miroc 4 years ago
- Fix of pagination of JsonResources in Laravel - bug: https://github.com/laravel/framework/issues/29916 - JSON API paginations were broken, (e.g. /api/banners) — committed to remp2020/laravel-helpers by miroc 4 years ago
I can confirm this issue is still present.
PHP 7.2 Mysql 5.7 Laravel 6.1.0
We ended up adding this lines to our Resource
For php 7.2/7.3 you can just copy
offsetExists
from v5.8.34:Seems
array_key_exists
deprecated for objects in 7.4 (but I’m on 7.2 now and not 100% sure…)@Nilanth See the comment directly above yours. Nothing to fix but could be discussed in the ideas repo.
@Lloople we didn’t add an notice to the upgrade guide because there weren’t breaking changes.
We had to make some adjustments for PHP 7.4 (see https://github.com/laravel/framework/pull/29842). Unfortunately that removed the accidental support for the query builder.
Btw, nothing says that we can’t look into making it compatible again but that’s a discussion for the ideas repo.
@LastDragon-ru I just realized this can’t possible work because resources are eloquent specific. We don’t support using it with the query builder. Because stdClass doesn’t implements array access it doesn’t work like that. See https://laravel.com/docs/6.x/eloquent-resources
@stsepelin @Lloople Please see the above note.
This works for me on a fresh Laravel 5.8 installation:
Since this has been fixed as well in Laravel 6.0 I want to ask you all to upgrade please. Thanks.