From 17743298abb5f7e546bf96b11b4c5f6207d42fe9 Mon Sep 17 00:00:00 2001 From: Mauro Cassani Date: Tue, 17 Oct 2017 12:40:20 +0200 Subject: [PATCH] Date Filters GT_DATE GTE_DATE LT_DATE LTE_DATE EQUALS_DATE --- README.md | 28 +++++- src/Filters/Criterion/ArrayMatchFilter.php | 2 +- src/Filters/Criterion/ContainsFilter.php | 2 +- src/Filters/Criterion/EqualsDateFilter.php | 27 ++++++ src/Filters/Criterion/EqualsFilter.php | 2 +- src/Filters/Criterion/FilterInterface.php | 2 +- .../Criterion/GreaterThanDateFilter.php | 27 ++++++ .../Criterion/GreaterThanEqualsDateFilter.php | 27 ++++++ .../Criterion/GreaterThanEqualsFilter.php | 2 +- src/Filters/Criterion/GreaterThanFilter.php | 2 +- src/Filters/Criterion/InArrayFilter.php | 2 +- .../Criterion/InArrayInversedFilter.php | 2 +- src/Filters/Criterion/LessThanDateFilter.php | 27 ++++++ .../Criterion/LessThanEqualsDateFilter.php | 27 ++++++ .../Criterion/LessThanEqualsFilter.php | 2 +- src/Filters/Criterion/LessThanFilter.php | 2 +- src/Filters/Criterion/NotEqualsFilter.php | 2 +- src/Filters/CriterionFilter.php | 7 +- src/QueryBuilder.php | 7 +- tests/QueryBuilderTest.php | 90 +++++++++++++++++++ tests/files/users.json | 20 +++++ 21 files changed, 293 insertions(+), 16 deletions(-) create mode 100644 src/Filters/Criterion/EqualsDateFilter.php create mode 100644 src/Filters/Criterion/GreaterThanDateFilter.php create mode 100644 src/Filters/Criterion/GreaterThanEqualsDateFilter.php create mode 100644 src/Filters/Criterion/LessThanDateFilter.php create mode 100644 src/Filters/Criterion/LessThanEqualsDateFilter.php diff --git a/README.md b/README.md index b800903..f580ec2 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,11 @@ foreach ($qb->getResults() as $element){ * `<=` * `>=` * `!=` +* `GT_DATE` +* `GTE_DATE` +* `LT_DATE` +* `LTE_DATE` +* `EQUALS_DATE` * `IN_ARRAY` * `IN_ARRAY_INVERSED` * `ARRAY_MATCH` @@ -106,9 +111,9 @@ foreach ($qb->getResults() as $element){ * `ASC` (default operator, can be omitted) * `DESC` -## Limit and Offset +## Performing Queries -You can specify limit and offset for your query results: +You can add criteria and specify limit and offset for your query results: ```php use ArrayQuery\QueryBuilder; @@ -125,6 +130,25 @@ foreach ($qb->getResults() as $element){ } ``` +## Working with dates + +You can perform queries based on datetime fields. You must specify **date format**: + +```php +use ArrayQuery\QueryBuilder; + +$qb = QueryBuilder::create($array); +$qb + ->addCriterion('registration_date', '01/05/2017', 'GT_DATE', 'd/m/Y') + ->addCriterion('rate', '3', '>') + ->sortedBy('title') + ->limit(0, 10); + +foreach ($qb->getResults() as $element){ + // ... +} +``` + ## Support If you found an issue or had an idea please refer [to this section](https://github.com/mauretto78/array-query/issues). diff --git a/src/Filters/Criterion/ArrayMatchFilter.php b/src/Filters/Criterion/ArrayMatchFilter.php index fd0e2a8..7a361c1 100644 --- a/src/Filters/Criterion/ArrayMatchFilter.php +++ b/src/Filters/Criterion/ArrayMatchFilter.php @@ -17,7 +17,7 @@ class ArrayMatchFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return count(array_intersect($value, $valueToCompare)) ? true : false; } diff --git a/src/Filters/Criterion/ContainsFilter.php b/src/Filters/Criterion/ContainsFilter.php index 677c901..5a3ccc1 100644 --- a/src/Filters/Criterion/ContainsFilter.php +++ b/src/Filters/Criterion/ContainsFilter.php @@ -17,7 +17,7 @@ class ContainsFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return stripos($value, $valueToCompare) !== false; } diff --git a/src/Filters/Criterion/EqualsDateFilter.php b/src/Filters/Criterion/EqualsDateFilter.php new file mode 100644 index 0000000..4e58a87 --- /dev/null +++ b/src/Filters/Criterion/EqualsDateFilter.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ArrayQuery\Filters\Criterion; + +class EqualsDateFilter implements FilterInterface +{ + /** + * @param $value + * @param $valueToCompare + * @return bool + */ + public function match($value, $valueToCompare, $dateFormat = null) + { + $valueDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $value); + $valueToComapareDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $valueToCompare); + + return $valueDate == $valueToComapareDate; + } +} diff --git a/src/Filters/Criterion/EqualsFilter.php b/src/Filters/Criterion/EqualsFilter.php index 16e8a5d..b2b3068 100644 --- a/src/Filters/Criterion/EqualsFilter.php +++ b/src/Filters/Criterion/EqualsFilter.php @@ -17,7 +17,7 @@ class EqualsFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return $value === $valueToCompare; } diff --git a/src/Filters/Criterion/FilterInterface.php b/src/Filters/Criterion/FilterInterface.php index 85b31cd..531e42d 100644 --- a/src/Filters/Criterion/FilterInterface.php +++ b/src/Filters/Criterion/FilterInterface.php @@ -17,5 +17,5 @@ interface FilterInterface * @param $valueToCompare * @return mixed */ - public function match($value, $valueToCompare); + public function match($value, $valueToCompare, $dateFormat = null); } diff --git a/src/Filters/Criterion/GreaterThanDateFilter.php b/src/Filters/Criterion/GreaterThanDateFilter.php new file mode 100644 index 0000000..e1592d2 --- /dev/null +++ b/src/Filters/Criterion/GreaterThanDateFilter.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ArrayQuery\Filters\Criterion; + +class GreaterThanDateFilter implements FilterInterface +{ + /** + * @param $value + * @param $valueToCompare + * @return bool + */ + public function match($value, $valueToCompare, $dateFormat = null) + { + $valueDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $value); + $valueToComapareDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $valueToCompare); + + return $valueDate > $valueToComapareDate; + } +} diff --git a/src/Filters/Criterion/GreaterThanEqualsDateFilter.php b/src/Filters/Criterion/GreaterThanEqualsDateFilter.php new file mode 100644 index 0000000..0e0fc69 --- /dev/null +++ b/src/Filters/Criterion/GreaterThanEqualsDateFilter.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ArrayQuery\Filters\Criterion; + +class GreaterThanEqualsDateFilter implements FilterInterface +{ + /** + * @param $value + * @param $valueToCompare + * @return bool + */ + public function match($value, $valueToCompare, $dateFormat = null) + { + $valueDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $value); + $valueToComapareDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $valueToCompare); + + return $valueDate >= $valueToComapareDate; + } +} diff --git a/src/Filters/Criterion/GreaterThanEqualsFilter.php b/src/Filters/Criterion/GreaterThanEqualsFilter.php index 00f86bb..c099731 100644 --- a/src/Filters/Criterion/GreaterThanEqualsFilter.php +++ b/src/Filters/Criterion/GreaterThanEqualsFilter.php @@ -17,7 +17,7 @@ class GreaterThanEqualsFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return $value >= $valueToCompare; } diff --git a/src/Filters/Criterion/GreaterThanFilter.php b/src/Filters/Criterion/GreaterThanFilter.php index d92a69c..3abc657 100644 --- a/src/Filters/Criterion/GreaterThanFilter.php +++ b/src/Filters/Criterion/GreaterThanFilter.php @@ -17,7 +17,7 @@ class GreaterThanFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return $value > $valueToCompare; } diff --git a/src/Filters/Criterion/InArrayFilter.php b/src/Filters/Criterion/InArrayFilter.php index 7b3a5da..f4b9acf 100644 --- a/src/Filters/Criterion/InArrayFilter.php +++ b/src/Filters/Criterion/InArrayFilter.php @@ -17,7 +17,7 @@ class InArrayFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return in_array($value, (array) $valueToCompare); } diff --git a/src/Filters/Criterion/InArrayInversedFilter.php b/src/Filters/Criterion/InArrayInversedFilter.php index 418b540..7a2749b 100644 --- a/src/Filters/Criterion/InArrayInversedFilter.php +++ b/src/Filters/Criterion/InArrayInversedFilter.php @@ -17,7 +17,7 @@ class InArrayInversedFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return in_array($valueToCompare, (array) $value); } diff --git a/src/Filters/Criterion/LessThanDateFilter.php b/src/Filters/Criterion/LessThanDateFilter.php new file mode 100644 index 0000000..a277ac3 --- /dev/null +++ b/src/Filters/Criterion/LessThanDateFilter.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ArrayQuery\Filters\Criterion; + +class LessThanDateFilter implements FilterInterface +{ + /** + * @param $value + * @param $valueToCompare + * @return bool + */ + public function match($value, $valueToCompare, $dateFormat = null) + { + $valueDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $value); + $valueToComapareDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $valueToCompare); + + return $valueDate < $valueToComapareDate; + } +} diff --git a/src/Filters/Criterion/LessThanEqualsDateFilter.php b/src/Filters/Criterion/LessThanEqualsDateFilter.php new file mode 100644 index 0000000..5074ced --- /dev/null +++ b/src/Filters/Criterion/LessThanEqualsDateFilter.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ArrayQuery\Filters\Criterion; + +class LessThanEqualsDateFilter implements FilterInterface +{ + /** + * @param $value + * @param $valueToCompare + * @return bool + */ + public function match($value, $valueToCompare, $dateFormat = null) + { + $valueDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $value); + $valueToComapareDate = \DateTimeImmutable::createFromFormat(($dateFormat) ?: 'Y-m-d', $valueToCompare); + + return $valueDate <= $valueToComapareDate; + } +} diff --git a/src/Filters/Criterion/LessThanEqualsFilter.php b/src/Filters/Criterion/LessThanEqualsFilter.php index 08d30e5..1a28b51 100644 --- a/src/Filters/Criterion/LessThanEqualsFilter.php +++ b/src/Filters/Criterion/LessThanEqualsFilter.php @@ -17,7 +17,7 @@ class LessThanEqualsFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return $value <= $valueToCompare; } diff --git a/src/Filters/Criterion/LessThanFilter.php b/src/Filters/Criterion/LessThanFilter.php index 0e729bf..ac43444 100644 --- a/src/Filters/Criterion/LessThanFilter.php +++ b/src/Filters/Criterion/LessThanFilter.php @@ -17,7 +17,7 @@ class LessThanFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return $value < $valueToCompare; } diff --git a/src/Filters/Criterion/NotEqualsFilter.php b/src/Filters/Criterion/NotEqualsFilter.php index cb7298d..0b60800 100644 --- a/src/Filters/Criterion/NotEqualsFilter.php +++ b/src/Filters/Criterion/NotEqualsFilter.php @@ -17,7 +17,7 @@ class NotEqualsFilter implements FilterInterface * @param $valueToCompare * @return bool */ - public function match($value, $valueToCompare) + public function match($value, $valueToCompare, $dateFormat = null) { return $value !== $valueToCompare; } diff --git a/src/Filters/CriterionFilter.php b/src/Filters/CriterionFilter.php index c4a3221..1388716 100644 --- a/src/Filters/CriterionFilter.php +++ b/src/Filters/CriterionFilter.php @@ -24,6 +24,11 @@ class CriterionFilter extends AbstractFilter '<' => 'LessThanFilter', '<=' => 'LessThanEqualsFilter', '!=' => 'NotEqualsFilter', + 'GT_DATE' => 'GreaterThanDateFilter', + 'GTE_DATE' => 'GreaterThanEqualsDateFilter', + 'LT_DATE' => 'LessThanDateFilter', + 'LTE_DATE' => 'LessThanEqualsDateFilter', + 'EQUALS_DATE' => 'EqualsDateFilter', 'IN_ARRAY' => 'InArrayFilter', 'IN_ARRAY_INVERSED' => 'InArrayInversedFilter', 'ARRAY_MATCH' => 'ArrayMatchFilter', @@ -44,6 +49,6 @@ public static function filter($criterion, $element) /** @var FilterInterface $filter */ $filter = new $filterClass(); - return $filter->match($value, $valueToCompare); + return $filter->match($value, $valueToCompare, $criterion['date_format']); } } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 229b499..4898279 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -78,10 +78,11 @@ private function setArray(array $array) * @param $key * @param $value * @param string $operator + * @param null $dateFormat * @return $this * @throws NotValidCriterionOperatorException */ - public function addCriterion($key, $value, $operator = '=') + public function addCriterion($key, $value, $operator = '=', $dateFormat = null) { if (!$this->isAValidCriterionOperator($operator)) { throw new NotValidCriterionOperatorException($operator.' is not a valid operator.'); @@ -91,6 +92,7 @@ public function addCriterion($key, $value, $operator = '=') 'key' => $key, 'value' => $value, 'operator' => $operator, + 'date_format' => $dateFormat ]; return $this; @@ -209,7 +211,8 @@ private function applyCriteriaFilter() $results = array_filter( (isset($results)) ? $results : $this->array, function ($element) use ($criterion) { return CriterionFilter::filter($criterion, $element); - }); + } + ); } return $results; diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index 56f66dd..7e3e0ea 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -345,4 +345,94 @@ public function it_should_get_results_from_a_query_with_a_nested_key() $this->assertEquals('Glenna Reichert', $results[0]['name']); } } + + /** + * @test + */ + public function it_should_get_results_from_a_query_with_gt_date() + { + foreach ($this->usersArrays as $array) { + $qb = QueryBuilder::create($array) + ->addCriterion('registration_date', '01/05/2017', 'GT_DATE', 'd/m/Y') + ->sortedBy('id', 'DESC'); + + $results = $qb->getResults(); + + $this->assertEquals(6, $qb->getCount()); + $this->assertEquals(7, $results[0]['id']); + $this->assertEquals('Kurtis Weissnat', $results[0]['name']); + } + } + + /** + * @test + */ + public function it_should_get_results_from_a_query_with_gte_date() + { + foreach ($this->usersArrays as $array) { + $qb = QueryBuilder::create($array) + ->addCriterion('registration_date', '01/05/2017', 'GTE_DATE', 'd/m/Y') + ->sortedBy('id', 'DESC'); + + $results = $qb->getResults(); + + $this->assertEquals(7, $qb->getCount()); + $this->assertEquals(7, $results[0]['id']); + $this->assertEquals('Kurtis Weissnat', $results[0]['name']); + } + } + + /** + * @test + */ + public function it_should_get_results_from_a_query_with_lt_date() + { + foreach ($this->usersArrays as $array) { + $qb = QueryBuilder::create($array) + ->addCriterion('registration_date', '01/05/2017', 'LT_DATE', 'd/m/Y') + ->sortedBy('id', 'DESC'); + + $results = $qb->getResults(); + + $this->assertEquals(3, $qb->getCount()); + $this->assertEquals(10, $results[0]['id']); + $this->assertEquals('Clementina DuBuque', $results[0]['name']); + } + } + + /** + * @test + */ + public function it_should_get_results_from_a_query_with_lte_date() + { + foreach ($this->usersArrays as $array) { + $qb = QueryBuilder::create($array) + ->addCriterion('registration_date', '01/05/2017', 'LTE_DATE', 'd/m/Y') + ->sortedBy('id', 'DESC'); + + $results = $qb->getResults(); + + $this->assertEquals(4, $qb->getCount()); + $this->assertEquals(10, $results[0]['id']); + $this->assertEquals('Clementina DuBuque', $results[0]['name']); + } + } + + /** + * @test + */ + public function it_should_get_results_from_a_query_with_equals_date() + { + foreach ($this->usersArrays as $array) { + $qb = QueryBuilder::create($array) + ->addCriterion('update_date', '2017-08-30', 'EQUALS_DATE', 'Y-m-d') + ->sortedBy('id', 'ASC'); + + $results = $qb->getResults(); + + $this->assertEquals(2, $qb->getCount()); + $this->assertEquals(5, $results[0]['id']); + $this->assertEquals('Chelsey Dietrich', $results[0]['name']); + } + } } diff --git a/tests/files/users.json b/tests/files/users.json index 7f48505..d4764fb 100644 --- a/tests/files/users.json +++ b/tests/files/users.json @@ -21,6 +21,8 @@ "catchPhrase": "Multi-layered client-server neural-net", "bs": "harness real-time e-markets" }, + "registration_date": "27/10/2017", + "update_date": "2017-10-30", "tags": [ "apple", "pear", @@ -49,6 +51,8 @@ "catchPhrase": "Proactive didactic contingency", "bs": "synergize scalable supply-chains" }, + "registration_date": "01/10/2017", + "update_date": "2017-10-20", "tags": [ "apple", "pinapple", @@ -79,6 +83,8 @@ "catchPhrase": "Face to face bifurcated interface", "bs": "e-enable strategic applications" }, + "registration_date": "01/05/2017", + "update_date": "2017-05-30", "tags": [ "apple", "pinapple", @@ -108,6 +114,8 @@ "catchPhrase": "Multi-tiered zero tolerance productivity", "bs": "transition cutting-edge web services" }, + "registration_date": "01/07/2017", + "update_date": "2017-07-30", "tags": [ "apple", "pinapple", @@ -137,6 +145,8 @@ "catchPhrase": "User-centric fault-tolerant solution", "bs": "revolutionize end-to-end systems" }, + "registration_date": "01/08/2017", + "update_date": "2017-08-30", "tags": [ "apple", "pinapple", @@ -165,6 +175,8 @@ "catchPhrase": "Synchronised bottom-line interface", "bs": "e-enable innovative applications" }, + "registration_date": "10/06/2017", + "update_date": "2017-06-30", "tags": [ "apple", "pinapple", @@ -193,6 +205,8 @@ "catchPhrase": "Configurable multimedia task-force", "bs": "generate enterprise e-tailers" }, + "registration_date": "15/08/2017", + "update_date": "2017-08-30", "tags": [ "apple", "pinapple", @@ -221,6 +235,8 @@ "catchPhrase": "Implemented secondary concept", "bs": "e-enable extensible e-tailers" }, + "registration_date": "01/03/2017", + "update_date": "2017-03-30", "tags": [ "apple", "pinapple", @@ -249,6 +265,8 @@ "catchPhrase": "Switchable contextually-based project", "bs": "aggregate real-time technologies" }, + "registration_date": "01/02/2017", + "update_date": "2017-02-30", "tags": [ "apple", "pinapple", @@ -278,6 +296,8 @@ "catchPhrase": "Centralized empowering task-force", "bs": "target end-to-end models" }, + "registration_date": "31/01/2017", + "update_date": "2017-01-30", "tags": [ "apple", "pinapple",