, (*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)