Reputation: 5395
CakePHP 3.7
I'm trying to paginate some data from a custom finder and it's either not working or giving errors.
What I have:
// src/Model/Table/FiltersTable.php
public function findFilters($rf_keywords = '')
{
// ...
}
The function above, findFilters()
is a custom finder which accepts a parameter $rf_keywords
and performs a search across various tables. I know this works because in a Controller I can do this:
$Filters = TableRegistry::getTableLocator()->get('Filters');
debug($Filters->findFilters('foo'));
This outputs an array of data based on searching for a string "foo". However this can return >1000 records so I want to paginate it to 25 per page.
So I've read https://book.cakephp.org/3.0/en/controllers/components/pagination.html and tried to modify my Controller:
Loading the Paginator
component:
public function initialize()
{
parent::initialize();
$this->loadComponent('Paginator');
}
Setting $paginate
to use my custom finder:
public $paginate = [
'finder' => 'filters',
'limit' => 25
];
Following the information on the docs above passing in the request data and getting it to paginate:
$request_data = $this->request->getParam('pass');
$customFinderOptions = [
'filters' => $request_data
];
$this->paginate = [
'finder' => [
'filters' => $customFinderOptions
]
];
When I do debug($this->paginate($this->Filters));
it gives a Runtime Exception:
Unable to locate an object compatible with paginate.
The Controller I'm using is src/Controller/WizardController.php
. In this case there is no FiltersController.php
but I don't think that's the source of the error?
Please can someone advise how to get this working?
I'm also unsure how to pass in $rf_keywords
. Previously I passed it in as a parameter, i.e.
$rf_keywords = trim($this->request->getData('rf_keywords'));
$data = $Filters->getFilters($rf_keywords);
Since this is request data is it passed in the equivalent of $request_data
in my code above? I don't see how that would work as it's using a parameter called pass
.
Upvotes: 0
Views: 600
Reputation: 1237
Firstly, cakephp has convenient method to create custom finders.
In model, You should create finder like this:
// src/Model/Table/FiltersTable.php
public function findFilters(Query $query, array $options = []): Query
{
return $query
->where(['column' => $options['rf_keywords']]);
}
In WizardsController
, You should load model Filters
first, then call this finder not directly by calling method FiltersTable::findFilters()
but by passing finder name as param to FiltersTable::find()
method
/**
* @method GET
* @return Cake\Http\Response|NULL
*/
public function index()
{
$this->loadComponent('Paginator');
$this->loadModel('Filters');
$finder = $this
->Filters
->find('filters' , [
'rf_keywords' => $this->request->getData('rf_keywords')
]);
$result = $this
->paginate($finder)
->toArray();
dump($result);die;
}
Remember: In controller $this->request->getData($param)
allows You to access POST params
To access GET params, You can use $this->request->getQuery($param)
Upvotes: 1