Skip to content

Commit ae0d8a9

Browse files
authored
Merge pull request #37 from 5am-code/feature/more-filter-types
Feature/more filter types
2 parents bfb45de + 21b907c commit ae0d8a9

File tree

6 files changed

+195
-10
lines changed

6 files changed

+195
-10
lines changed

src/Endpoints/Database.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use FiveamCode\LaravelNotionApi\Entities\Collections\PageCollection;
66
use FiveamCode\LaravelNotionApi\Notion;
7-
use FiveamCode\LaravelNotionApi\Query\Filter;
7+
use FiveamCode\LaravelNotionApi\Query\Filters\Filter;
88
use FiveamCode\LaravelNotionApi\Query\Sorting;
99
use Illuminate\Support\Collection;
1010

@@ -68,7 +68,6 @@ public function query(): PageCollection
6868
if ($this->pageSize !== null)
6969
$postData['page_size'] = $this->pageSize;
7070

71-
7271
$response = $this
7372
->post(
7473
$this->url(Endpoint::DATABASES . "/{$this->databaseId}/query"),

src/Query/CompoundFilter.php renamed to src/Query/Filters/CompoundFilter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<?php
22

3-
namespace FiveamCode\LaravelNotionApi\Query;
3+
namespace FiveamCode\LaravelNotionApi\Query\Filters;
44

55
use FiveamCode\LaravelNotionApi\Exceptions\HandlingException;
6+
use FiveamCode\LaravelNotionApi\Query\QueryHelper;
67

78
/**
89
* Class CompoundFilter

src/Query/Filter.php renamed to src/Query/Filters/Filter.php

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<?php
22

3-
namespace FiveamCode\LaravelNotionApi\Query;
3+
namespace FiveamCode\LaravelNotionApi\Query\Filters;
44

55
use FiveamCode\LaravelNotionApi\Exceptions\HandlingException;
6+
use FiveamCode\LaravelNotionApi\Query\QueryHelper;
67
use Illuminate\Support\Collection;
78

89
/**
@@ -48,17 +49,36 @@ public function __construct(
4849
}
4950

5051
/**
51-
* Returns a text filter instance.
52+
* Creates a number filter instance after checking validity.
5253
*
5354
* @see https://developers.notion.com/reference/post-database-query#text-filter-condition
5455
*
5556
* @param string $property
56-
* @param array $filterConditions
57+
* @param string $comparisonOperator
58+
* @param $value
5759
* @return Filter
5860
*/
59-
public static function textFilter(string $property, array $filterConditions): Filter
61+
public static function textFilter(string $property, string $comparisonOperator, string $value): Filter
6062
{
61-
return new Filter($property, 'text', $filterConditions);
63+
self::isValidComparisonOperatorFor('text', $comparisonOperator);
64+
return new Filter($property, 'text', [$comparisonOperator => $value]);
65+
}
66+
67+
/**
68+
* Creates a number filter instance after checking validity.
69+
*
70+
* @see https://developers.notion.com/reference/post-database-query#number-filter-condition
71+
*
72+
* @param string $property
73+
* @param string $comparisonOperator
74+
* @param float|int $number
75+
* @return Filter
76+
* @throws HandlingException
77+
*/
78+
public static function numberFilter(string $property, string $comparisonOperator, float|int $number): Filter
79+
{
80+
self::isValidComparisonOperatorFor('number', $comparisonOperator);
81+
return new Filter($property, 'number', [$comparisonOperator => $number]);
6282
}
6383

6484
/**
@@ -102,6 +122,17 @@ public function toArray(): array
102122

103123
}
104124

125+
/**
126+
* Semantic wrapper for toArray()
127+
*
128+
* @return array
129+
* @throws HandlingException
130+
*/
131+
public function toQuery(): array
132+
{
133+
return $this->toArray();
134+
}
135+
105136

106137
/**
107138
* @param Collection $filter
@@ -114,12 +145,28 @@ public static function filterQuery(Collection $filter): array
114145
$queryFilter = new Collection();
115146

116147
$filter->each(function (Filter $filter) use ($queryFilter) {
117-
$queryFilter->add($filter->toArray());
148+
$queryFilter->add($filter->toQuery());
118149
});
119150

120151
return $queryFilter->toArray();
121152

122153
}
123154

124155

156+
/**
157+
* Checks if the given comparison operator is valid for the given filter type.
158+
*
159+
* @param $filterType
160+
* @param $operator
161+
* @throws HandlingException
162+
*/
163+
private static function isValidComparisonOperatorFor($filterType, $operator)
164+
{
165+
$validOperators = Operators::getValidComparisonOperators($filterType);
166+
167+
if (!in_array($operator, $validOperators))
168+
throw HandlingException::instance("Invalid comparison operator.", compact("operator"));
169+
}
170+
171+
125172
}

src/Query/Filters/Operators.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace FiveamCode\LaravelNotionApi\Query\Filters;
4+
5+
use FiveamCode\LaravelNotionApi\Exceptions\HandlingException;
6+
7+
class Operators
8+
{
9+
# ToDo: Make this a enum with PHP 8.1
10+
const EQUALS = 'equals';
11+
const DOES_NOT_EQUAL = 'does_not_equal';
12+
const CONTAINS = 'contain';
13+
const DOES_NOT_CONTAIN = 'does_not_contain';
14+
const STARTS_WITH = 'starts_with';
15+
const ENDS_WITH = 'ends_with';
16+
const IS_EMPTY = 'is_empty';
17+
const IS_NOT_EMPTY = 'is_not_empty';
18+
const GREATER_THAN = 'greater_than';
19+
const LESS_THAN = 'less_than';
20+
const GREATER_THAN_OR_EQUAL_TO = 'greater_than_or_equal_to';
21+
const LESS_THAN_OR_EQUAL_TO = 'less_than_or_equal_to';
22+
const BEFORE = 'before';
23+
const AFTER = 'after';
24+
const ON_OR_BEFORE = 'on_or_before';
25+
const ON_OR_AFTER = 'on_or_after';
26+
const PAST_WEEK = 'past_week';
27+
const PAST_MONTH = 'past_month';
28+
const PAST_YEAR = 'past_year';
29+
const NEXT_WEEK = 'next_week';
30+
const NEXT_MONTH = 'next_month';
31+
const NEXT_YEAR = 'next_year';
32+
33+
// TODO: Formula filter condition
34+
35+
36+
static function getValidComparisonOperators($filterType)
37+
{
38+
switch ($filterType) {
39+
case 'text':
40+
return Operators::text();
41+
case 'number':
42+
return Operators::number();
43+
default:
44+
throw HandlingException::instance("Invalid filterType.", compact("filterType"));
45+
}
46+
}
47+
48+
private static function text()
49+
{
50+
return [
51+
Operators::EQUALS,
52+
Operators::DOES_NOT_EQUAL,
53+
Operators::CONTAINS,
54+
Operators::DOES_NOT_CONTAIN,
55+
Operators::STARTS_WITH,
56+
Operators::ENDS_WITH,
57+
Operators::IS_EMPTY,
58+
Operators::IS_NOT_EMPTY
59+
];
60+
}
61+
62+
private static function number()
63+
{
64+
return [
65+
Operators::EQUALS,
66+
Operators::DOES_NOT_EQUAL,
67+
Operators::GREATER_THAN,
68+
Operators::LESS_THAN,
69+
Operators::GREATER_THAN_OR_EQUAL_TO,
70+
Operators::LESS_THAN_OR_EQUAL_TO,
71+
Operators::IS_EMPTY,
72+
Operators::IS_NOT_EMPTY
73+
];
74+
}
75+
76+
}

tests/EndpointDatabaseTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
namespace FiveamCode\LaravelNotionApi\Tests;
44

5+
use FiveamCode\LaravelNotionApi\Query\Filters\Filter;
56
use Notion;
67
use Illuminate\Support\Collection;
78
use Illuminate\Support\Facades\Http;
8-
use FiveamCode\LaravelNotionApi\Query\Filter;
99
use FiveamCode\LaravelNotionApi\Entities\Page;
1010
use FiveamCode\LaravelNotionApi\Query\Sorting;
1111
use FiveamCode\LaravelNotionApi\Endpoints\Database;

tests/FilterTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace FiveamCode\LaravelNotionApi\Tests;
4+
5+
use FiveamCode\LaravelNotionApi\Exceptions\HandlingException;
6+
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
7+
use FiveamCode\LaravelNotionApi\Query\Filters\Filter;
8+
use FiveamCode\LaravelNotionApi\Query\Filters\Operators;
9+
use Notion;
10+
use Illuminate\Support\Facades\Http;
11+
12+
/**
13+
* Class HandlingExceptionTest
14+
* @package FiveamCode\LaravelNotionApi\Tests
15+
*/
16+
class FilterTest extends NotionApiTest
17+
{
18+
19+
/** @test */
20+
public function it_creates_a_text_filter_with_the_given_data()
21+
{
22+
$filter = Filter::textFilter("Name", Operators::EQUALS, "Ada Lovelace");
23+
24+
$this->assertInstanceOf(Filter::class, $filter);
25+
$this->assertArrayHasKey("property", $filter->toQuery());
26+
$this->assertEquals("Name", $filter->toQuery()["property"]);
27+
$this->assertArrayHasKey("text", $filter->toQuery());
28+
$this->assertArrayHasKey("equals", $filter->toQuery()["text"]);
29+
$this->assertEquals("Ada Lovelace", $filter->toQuery()["text"]["equals"]);
30+
}
31+
32+
/** @test */
33+
public function it_creates_a_number_filter_with_the_given_data()
34+
{
35+
$filter = Filter::numberFilter("Awesomeness Level", Operators::GREATER_THAN_OR_EQUAL_TO, 9000);
36+
37+
$this->assertInstanceOf(Filter::class, $filter);
38+
$this->assertArrayHasKey("property", $filter->toQuery());
39+
$this->assertEquals("Awesomeness Level", $filter->toQuery()["property"]);
40+
$this->assertArrayHasKey("number", $filter->toQuery());
41+
$this->assertArrayHasKey("greater_than_or_equal_to", $filter->toQuery()["number"]);
42+
$this->assertEquals("9000", $filter->toQuery()["number"]["greater_than_or_equal_to"]);
43+
}
44+
45+
/** @test */
46+
public function it_throws_an_exception_for_an_invalid_comparison_operator()
47+
{
48+
$this->expectException(HandlingException::class);
49+
$this->expectExceptionMessage("Invalid comparison operator");
50+
$filter = Filter::numberFilter("Awesomeness Level", "non_existing_operator", 9000);
51+
}
52+
53+
/** @test */
54+
public function it_throws_an_exception_for_an_invalid_filter_definition() {
55+
$filter = new Filter("Test");
56+
57+
$this->expectException(HandlingException::class);
58+
$this->expectExceptionMessage("Invalid filter definition.");
59+
$filter->toArray();
60+
}
61+
62+
}

0 commit comments

Comments
 (0)