Skip to content

Commit 2ce8f98

Browse files
committed
Adding ability to use a closure in andWhere
1 parent 852c521 commit 2ce8f98

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

lib/Cake/Model/Datasource/Database/Expression/QueryExpression.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
class QueryExpression implements Countable {
77

8-
protected $_conjuction;
8+
protected $_conjunction;
99

1010
protected $_conditions = [];
1111

@@ -33,9 +33,12 @@ public function type($conjunction = null) {
3333
public function add($conditions, $types = []) {
3434
if (is_string($conditions)) {
3535
$this->_conditions[] = $conditions;
36+
return $this;
3637
}
37-
if ($conditions instanceof self && count($conditions) > 0) {
38+
39+
if ($conditions instanceof QueryExpression && count($conditions) > 0) {
3840
$this->_conditions[] = $conditions;
41+
return $this;
3942
}
4043

4144
$this->_addConditions($conditions, $types);

lib/Cake/Model/Datasource/Database/Query.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,11 @@ public function where($conditions = null, $types = [], $overwrite = false) {
247247
}
248248

249249
public function andWhere($conditions, $types = []) {
250-
$where = $this->_parts['where'] ?: new QueryExpression();
250+
$where = $this->_parts['where'] ?: new QueryExpression;
251+
252+
if (is_callable($conditions)) {
253+
$conditions = $conditions(new QueryExpression, $this);
254+
}
251255

252256
if ($where->type() === 'AND') {
253257
$where->add($conditions, $types);

lib/Cake/Test/TestCase/Model/Datasource/Database/QueryTest.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,13 @@ public function testSelectAndWhereNoPreviousCondition() {
485485
$this->assertEquals(['id' => 1], $result->fetch('assoc'));
486486
}
487487

488-
public function testSelectAndWhereUsingClosure() {
488+
/**
489+
* Tests that it is possible to pass a closure to where() to build a set of
490+
* conditions and return the expression to be used
491+
*
492+
* @return void
493+
**/
494+
public function testSelectWhereUsingClosure() {
489495
$this->_insertDateRecords();
490496
$query = new Query($this->connection);
491497
$result = $query
@@ -523,4 +529,37 @@ public function testSelectAndWhereUsingClosure() {
523529
->execute();
524530
$this->assertCount(0, $result);
525531
}
532+
533+
/**
534+
* Tests that it is possible to pass a closure to andWhere() to build a set of
535+
* conditions and return the expression to be used
536+
*
537+
* @return void
538+
**/
539+
public function testSelectAndWhereUsingClosure() {
540+
$this->_insertDateRecords();
541+
$query = new Query($this->connection);
542+
$result = $query
543+
->select(['id'])
544+
->from('dates')
545+
->where(['id' => '1'])
546+
->andWhere(function($exp) {
547+
return $exp->equals('posted', new \DateTime('2012-12-21 12:00'), 'datetime');
548+
})
549+
->execute();
550+
$this->assertCount(1, $result);
551+
$this->assertEquals(['id' => 1], $result->fetch('assoc'));
552+
553+
$query = new Query($this->connection);
554+
$result = $query
555+
->select(['id'])
556+
->from('dates')
557+
->where(['id' => '1'])
558+
->andWhere(function($exp) {
559+
return $exp->equals('posted', new \DateTime('2022-12-21 12:00'), 'datetime');
560+
})
561+
->execute();
562+
$this->assertCount(0, $result);
563+
}
564+
526565
}

0 commit comments

Comments
 (0)