Skip to content

Commit

Permalink
Allow to create filters from operators
Browse files Browse the repository at this point in the history
  • Loading branch information
henriquemoody committed Sep 5, 2014
1 parent b7aeb2e commit 0f4c1f7
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ The example above convert all Record objects into an array.
## Finding multiple records into a collection

```php
$storage->users->findAll(array('name' => 'Henrique Moody')); // Return an Collection object with the partial result (if any)
$storage->users->findAll(array('status !=' => false)); // Return an Collection object with the partial result (if any)
```

## Finding single record into a collection

```php
$storage->users->find(array('name' => 'Henrique Moody')); // Return an Record object with the first matched result (if any) or NULL
$storage->users->find(array('priority >=' => 4)); // Return an Record object with the first matched result (if any) or NULL
```

## Using Criteria object
Expand Down
33 changes: 32 additions & 1 deletion src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@

class Factory
{
protected $operatorsToFilters = array(
'=' => 'equalTo',
'!=' => 'notEqualTo',
'<' => 'lessThan',
'<=' => 'lessThanOrEqualTo',
'>' => 'greaterThan',
'>=' => 'greaterThanOrEqualTo',
'BETWEEN' => 'between',
'NOT BETWEEN' => 'notBetween',
'ILIKE' => 'iLike',
'NOT ILIKE' => 'notILike',
'IN' => 'in',
'NOT IN' => 'notIn',
'LIKE' => 'like',
'NOT LIKE' => 'notLike',
'REGEX' => 'regex',
'NOT REGEX' => 'notRegex',
);

public function collection($collection = null)
{
if (! $collection instanceof Collection) {
Expand Down Expand Up @@ -41,7 +60,14 @@ public function criteria($criteria = null)
continue;
}

$criteria->addFilter($key, new EqualTo($value));
$index = strstr($key, ' ', true) ?: $key;
$operator = trim(strstr($key, ' ') ?: '=');
if (false === strpos($operator, 'BETWEEN')) {
$value = array($value);
}
$filter = $this->filter($operator, $value);

$criteria->addFilter($index, $filter);
}
}

Expand All @@ -51,6 +77,11 @@ public function criteria($criteria = null)
public function filter($filter, array $arguments = array())
{
if (! $filter instanceof Filter) {

if (isset($this->operatorsToFilters[$filter])) {
return $this->filter($this->operatorsToFilters[$filter], $arguments);
}

if (0 === strpos($filter, 'not')) {
$filterName = substr($filter, 3);
$filter = $this->filter($filterName, $arguments);
Expand Down
37 changes: 37 additions & 0 deletions tests/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,43 @@ public function testShouldCreateACriteriaFromAKeyValueArrayOfNonFilters()
$this->assertEquals($expectedFilter, $actualFilters[0][1]);
}

public function operatorsProvider()
{
return array(
array('=', 42, new Filter\EqualTo(42)),
array('!=', 42, new Filter\Not(new Filter\EqualTo(42))),
array('<', 42, new Filter\LessThan(42)),
array('<=', 42, new Filter\OneOf(array(new Filter\LessThan(42), new Filter\EqualTo(42)))),
array('>', 42, new Filter\GreaterThan(42)),
array('>=', 42, new Filter\OneOf(array(new Filter\GreaterThan(42), new Filter\EqualTo(42)))),
array('BETWEEN', array(1, 3), new Filter\Between(1, 3)),
array('NOT BETWEEN', array(1, 3), new Filter\Not(new Filter\Between(1, 3))),
array('ILIKE', 'String%', new Filter\ILike('String%')),
array('NOT ILIKE', 'String%', new Filter\Not(new Filter\ILike('String%'))),
array('IN', array(1, 2, 3), new Filter\In(array(1, 2, 3))),
array('NOT IN', array(1, 2, 3), new Filter\Not(new Filter\In(array(1, 2, 3)))),
array('LIKE', 'String%', new Filter\Like('String%')),
array('NOT LIKE', 'String%', new Filter\Not(new Filter\Like('String%'))),
array('REGEX', '/[a-z]/', new Filter\Regex('/[a-z]/')),
array('NOT REGEX', '/[a-z]/', new Filter\Not(new Filter\Regex('/[a-z]/'))),
);
}

/**
* @dataProvider operatorsProvider
*/
public function testShouldCreateACriteriaFromAKeyValueArrayOfNonFiltersUsingOperator($operator, $value, $expectedFilter)
{
$inputFilters = array(
'name ' . $operator => $value,
);
$factory = new Factory();
$criteria = $factory->criteria($inputFilters);
$actualFilters = $criteria->getFilters();

$this->assertEquals($expectedFilter, $actualFilters[0][1]);
}

public function testShouldReturnInputIfInputIsAlreadyAFilter()
{
$filter = new Filter\EqualTo(42, 'identical');
Expand Down

0 comments on commit 0f4c1f7

Please sign in to comment.