, (*1)
StackableFinder Plugin for CakePHP 2.x
Requirements
Installation
- Put
StackableFinder directory into your plugin directory. You can also install via Composer.
- Enable
StackableFinder plugin in your app/Config/bootstrap.php file.
- Enable
StackableFinder.StackableFinder behavior in your model.
Usage
$articles = $this->Article->q()
->find('all', ['conditions' => ['Article.created >=' => '2015-01-01']])
->findAllByUserId(1) // Magic finder
->find('published') // Custom finder
->find('list')
->exec();
You can start stacking finders by calling q(), and you can execute the query and get the resutls by calling exec()., (*2)
Note that q() method returns an instance of StackableFinder. The object also has find() method like a Model - so you can use fluent interface, but it is not a sub-class of Model., (*3)
So you cannot call any other methods implemented by Model., (*4)
$this->Article->q()->read(); // Error
Instead, you can use where() or some other 3.x compatible methods for building queries., (*5)
$articles = $this->Article->q()
->select(['Article.id', 'Article.title'])
->contain('Author')
->where(['Article.user_id' => 1])
->order(['Article.id' => 'DESC'])
->limit(10)
->offset(0)
->exec();
Subqueries
You can make subqueries like the following:, (*6)
$q = $this->User->q()->select('id');
$articles = $this->Article->q()
->where([
'user_id IN ?' => [$q]
])
->exec();
You will see that IN ? appears after the field name in the left-hand side, and you will see also that $q appears inside an [] in the right-hand side., (*7)
It is not compatible with 3.x but it is nessecary at this time in 2.x., (*8)
Getting results
As mentioned above, you can do it by calling exec() but there are some other ways to get the results of the query., (*9)
You can iterate the StackableFinder object directly., (*10)
$q = $this->Article->q()->find('list');
foreach ($q as $id => $title) {
// ...
}
Or you can use first() or count() instead of exec()., (*11)
$articles = $this->Article->q()
->find('published')
->first();
This is same as the following:, (*12)
$articles = $this->Article->q()
->find('published')
->find('first')
->exec();
But, note that stacking find('first') or first() after find('list') doesn't work.
Because _findFirst() doen't returns the first result actually. That returns the element with index 0., (*13)
So this is a bad example:, (*14)
$articles = $this->Article->q()
->find('list')
->first();
You will get an empty array instead of the first item of the list., (*15)
Also note that stacking find('count') or count() after find('list') doesn't work.
Because _findCount() expects an array like [['Model' => ['count' => N ]]], but _findList changes the array before it get called., (*16)
You can override these methods in your model to change the behaviors, if necessary., (*17)