I’m migrating a project from Cake 4 to 5.1, and I’m getting deprecation warnings about calling isEmpty() on the paginated results.
Warning:Calling `Cake\ORM\ResultSet` methods, such as `isEmpty()`, on PaginatedResultSet is deprecated. You must call `items()` first (for example, `items()->isEmpty()`)
So I add a call to ->items() before ->isEmpty(), which makes the deprecation warning disappear, but my IDE (PHP Storm) gives me warning about potentially polymorphic call, since it doesn’t know what items() returns, except a Traversable instance.
The bake plugin only gives docblock as @var iterable<\App\Model\Entity\Product> $products.
How can I docblock the template variable, so it supports calls to isEmpty, and the entity items returns on a loop?
I’ve tried this, but it doesn’t give me the proper typehints: @var \Cake\Datasource\Paging\PaginatedResultSet<\Cake\ORM\ResultSet<\App\Model\Entity\Product>> $products
Example code simplified:
ProductsController.php
public function index(): void
{
$products = $this->paginate($this->Products);
$this->set(compact('products'));
}
$products->items() always returns just a simple Traversable as you can see here
Technically in runtime its of course a Cake\ORM\ResultSet object, but static analysis doesn’t know that because the PaginatedInterface could be implemented in another way as well.
And that type is not a generic, therefore you can’t define it via PHPDoc like you tried.
Your simplest solution would be to force-overwrite the type like so:
I was afraid you’d say that It’s ugly code, if you ask me. Can’t even call ->items() in the controller, 'cause then the PaginatorHelper can’t create links or give information about page count, etc.