Skip to content

Commit 8ffe09f

Browse files
committed
Add support for multiple where calls in collections
1 parent 56cd446 commit 8ffe09f

File tree

2 files changed

+82
-15
lines changed

2 files changed

+82
-15
lines changed

src/Collection/Type.php

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public function getTimestampHash($timestamp_field)
139139
}
140140

141141
$table_name = $this->getTableName();
142-
$conditions = $this->conditions ? " WHERE $this->conditions" : '';
142+
$conditions = $this->getConditions() ? " WHERE {$this->getConditions()}" : '';
143143

144144
if ($this->count() > 0) {
145145
if ($join_expression = $this->getJoinExpression()) {
@@ -238,7 +238,7 @@ private function getSelectSql($all_fields = true)
238238

239239
$fields = $all_fields ? '*' : '`id`';
240240
$table_name = $this->connection->escapeTableName($this->getTableName());
241-
$conditions = $this->conditions ? "WHERE $this->conditions" : '';
241+
$conditions = $this->getConditions() ? "WHERE {$this->getConditions()}" : '';
242242

243243
if ($order_by = $this->getOrderBy()) {
244244
$order_by = "ORDER BY $this->order_by";
@@ -267,7 +267,7 @@ public function count()
267267
}
268268

269269
$table_name = $this->connection->escapeTableName($this->getTableName());
270-
$conditions = $this->conditions ? " WHERE $this->conditions" : '';
270+
$conditions = $this->getConditions() ? " WHERE {$this->getConditions()}" : '';
271271

272272
if ($join_expression = $this->getJoinExpression()) {
273273
return (integer) $this->connection->executeFirstCell("SELECT COUNT($table_name.`id`) FROM $table_name $join_expression $conditions");
@@ -340,7 +340,16 @@ public function &orderBy($value)
340340
*
341341
* @var string
342342
*/
343-
private $conditions;
343+
private $conditions = [];
344+
345+
/**
346+
* Cached conditions as string.
347+
*
348+
* Call to where() resets this value to false, and getConditions() rebuilds it if it FALSE on request.
349+
*
350+
* @var string|bool
351+
*/
352+
private $conditions_as_string = false;
344353

345354
/**
346355
* Return conditions.
@@ -349,27 +358,52 @@ public function &orderBy($value)
349358
*/
350359
public function getConditions()
351360
{
352-
return $this->conditions;
361+
if ($this->conditions_as_string === false) {
362+
switch (count($this->conditions)) {
363+
case 0:
364+
$this->conditions_as_string = '';
365+
break;
366+
case 1:
367+
$this->conditions_as_string = $this->conditions[0];
368+
break;
369+
default:
370+
$this->conditions_as_string = implode(' AND ', array_map(function($condition) {
371+
return "($condition)";
372+
}, $this->conditions));
373+
}
374+
}
375+
376+
return $this->conditions_as_string;
353377
}
354378

355379
/**
356380
* Set collection conditions.
357381
*
358-
* @param mixed ...$arguments
382+
* @param string $pattern
383+
* @param array $arguments
359384
* @return $this
360385
*/
361-
public function &where()
386+
public function &where($pattern, ...$arguments)
362387
{
363-
$number_of_arguments = func_num_args();
388+
if (empty($pattern)) {
389+
throw new InvalidArgumentException('Pattern argument is required');
390+
}
364391

365-
if ($number_of_arguments === 1) {
366-
$this->conditions = $this->connection->prepareConditions(func_get_arg(0));
367-
} elseif ($number_of_arguments > 1) {
368-
$this->conditions = $this->connection->prepareConditions(func_get_args());
392+
if (is_string($pattern)) {
393+
$this->conditions[] = $this->connection->prepareConditions(array_merge([$pattern], $arguments));
394+
} elseif (is_array($pattern)) {
395+
if (!empty($arguments)) {
396+
throw new LogicException('When pattern is an array, no extra arguments are allowed');
397+
}
398+
399+
$this->conditions[] = $this->connection->prepareConditions($pattern);
369400
} else {
370-
throw new InvalidArgumentException('At least one argument expected');
401+
throw new InvalidArgumentException('Pattern can be string or an array');
371402
}
372403

404+
// Force rebuild of conditions as string on next getConditions() call
405+
$this->conditions_as_string = false;
406+
373407
return $this;
374408
}
375409

test/src/TypeCollectionTest.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ public function testSetConditionsFromArray()
6666
$this->assertEquals($collection->getConditions(), "type = 'File'");
6767
}
6868

69+
/**
70+
* @expectedException \LogicException
71+
* @expectedExceptionMessage When pattern is an array, no extra arguments are allowed
72+
*/
73+
public function testSetConditionsFromArrayAcceptsOnlyPatternArgument()
74+
{
75+
$collection = new WritersCollection($this->connection, $this->pool);
76+
77+
$collection->where(['type = ?', 'File'], 1, 2, 3);
78+
}
79+
6980
/**
7081
* Test set conditions from array of arguments.
7182
*/
@@ -79,20 +90,42 @@ public function testSetConditionsFromArrayOfArguments()
7990

8091
/**
8192
* @expectedException \InvalidArgumentException
93+
* @expectedExceptionMessage Pattern argument is required
8294
*/
83-
public function testEmptyListOfArgumentsThrowsAnException()
95+
public function testEmptyPatternStringThrowsAnException()
8496
{
85-
(new WritersCollection($this->connection, $this->pool))->where();
97+
(new WritersCollection($this->connection, $this->pool))->where('');
8698
}
8799

88100
/**
89101
* @expectedException \InvalidArgumentException
102+
* @expectedExceptionMessage Pattern argument is required
103+
*/
104+
public function testEmptyPatternArrayThrowsAnException()
105+
{
106+
(new WritersCollection($this->connection, $this->pool))->where([]);
107+
}
108+
109+
/**
110+
* @expectedException \InvalidArgumentException
111+
* @expectedExceptionMessage Pattern can be string or an array
90112
*/
91113
public function testInvalidConditionsTypeThrowsAnException()
92114
{
93115
(new WritersCollection($this->connection, $this->pool))->where(123);
94116
}
95117

118+
public function testSetMultipleConditions()
119+
{
120+
$collection = new WritersCollection($this->connection, $this->pool);
121+
122+
$collection->where('type = ?', 'File');
123+
$collection->where('type = ?', 'YouTubeVideo');
124+
$collection->where('type = ?', 'GoogleDocument');
125+
126+
$this->assertEquals($collection->getConditions(), "(type = 'File') AND (type = 'YouTubeVideo') AND (type = 'GoogleDocument')");
127+
}
128+
96129
/**
97130
* Test set order by.
98131
*/

0 commit comments

Comments
 (0)