Skip to content

Commit 53b168a

Browse files
committed
Refactor grammar into static filter factory
1 parent e1557ec commit 53b168a

File tree

6 files changed

+138
-142
lines changed

6 files changed

+138
-142
lines changed

src/Query/Builder.php

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use LdapRecord\Query\Events\QueryExecuted;
1717
use LdapRecord\Query\Filter\AndGroup;
1818
use LdapRecord\Query\Filter\Filter;
19+
use LdapRecord\Query\Filter\Factory;
1920
use LdapRecord\Query\Filter\Not;
2021
use LdapRecord\Query\Filter\OrGroup;
2122
use LdapRecord\Query\Filter\Raw;
@@ -120,8 +121,7 @@ class Builder
120121
* Constructor.
121122
*/
122123
public function __construct(
123-
protected Connection $connection,
124-
protected Grammar $grammar = new Grammar,
124+
protected Connection $connection
125125
) {}
126126

127127
/**
@@ -134,16 +134,6 @@ public function setConnection(Connection $connection): static
134134
return $this;
135135
}
136136

137-
/**
138-
* Set the current filter grammar.
139-
*/
140-
public function setGrammar(Grammar $grammar): static
141-
{
142-
$this->grammar = $grammar;
143-
144-
return $this;
145-
}
146-
147137
/**
148138
* Set the cache to store query results.
149139
*/
@@ -219,7 +209,7 @@ public function getQuery(): string
219209
$this->whereHas('objectclass');
220210
}
221211

222-
return $this->grammar->compile($this);
212+
return (string) $this->filter;
223213
}
224214

225215
/**
@@ -238,14 +228,6 @@ public function getUnescapedQuery(): string
238228
return EscapedValue::unescape($this->getQuery());
239229
}
240230

241-
/**
242-
* Get the current grammar instance.
243-
*/
244-
public function getGrammar(): Grammar
245-
{
246-
return $this->grammar;
247-
}
248-
249231
/**
250232
* Get the current cache instance.
251233
*/
@@ -834,15 +816,15 @@ public function where(Closure|array|string $attribute, mixed $operator = null, m
834816
$value, $operator, func_num_args() === 2 && ! $this->operatorRequiresValue($operator)
835817
);
836818

837-
if (! in_array($operator, $this->grammar->operators())) {
819+
if (! in_array($operator, Factory::operators())) {
838820
throw new InvalidArgumentException("Invalid LDAP filter operator [$operator]");
839821
}
840822

841823
$value = $this->prepareWhereValue($attribute, $value, $raw);
842824

843825
$attribute = $this->escape($attribute)->forDnAndFilter()->get();
844826

845-
$filter = $this->grammar->makeFilter($operator, $attribute, $value);
827+
$filter = Factory::make($operator, $attribute, $value);
846828

847829
$this->addFilter($filter, $boolean);
848830

src/Query/Filter/Factory.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace LdapRecord\Query\Filter;
4+
5+
use UnexpectedValueException;
6+
7+
class Factory
8+
{
9+
/**
10+
* The query operators and their filter classes.
11+
*/
12+
protected static array $operators = [
13+
'*' => Has::class,
14+
'!*' => [Not::class, Has::class],
15+
'=' => Equals::class,
16+
'!' => [Not::class, Equals::class],
17+
'!=' => [Not::class, Equals::class],
18+
'>=' => GreaterThanOrEquals::class,
19+
'<=' => LessThanOrEquals::class,
20+
'~=' => ApproximatelyEquals::class,
21+
'starts_with' => StartsWith::class,
22+
'not_starts_with' => [Not::class, StartsWith::class],
23+
'ends_with' => EndsWith::class,
24+
'not_ends_with' => [Not::class, EndsWith::class],
25+
'contains' => Contains::class,
26+
'not_contains' => [Not::class, Contains::class],
27+
];
28+
29+
/**
30+
* Get the available operators.
31+
*/
32+
public static function operators(): array
33+
{
34+
return array_keys(static::$operators);
35+
}
36+
37+
/**
38+
* Make a filter instance for the operator.
39+
*
40+
* @throws UnexpectedValueException
41+
*/
42+
public static function make(string $operator, string $attribute, ?string $value = null): Filter
43+
{
44+
if (! array_key_exists($operator, static::$operators)) {
45+
throw new UnexpectedValueException("Invalid LDAP filter operator ['$operator']");
46+
}
47+
48+
$classes = static::$operators[$operator];
49+
50+
// Handle negated operators (Ex: [Not::class, Equals::class])
51+
if (is_array($classes)) {
52+
[$wrapper, $filter] = $classes;
53+
54+
return new $wrapper(static::create($filter, $attribute, $value));
55+
}
56+
57+
return static::create($classes, $attribute, $value);
58+
}
59+
60+
/**
61+
* Create a filter instance.
62+
*/
63+
protected static function create(string $filter, string $attribute, ?string $value = null): Filter
64+
{
65+
return $filter === Has::class
66+
? new $filter($attribute)
67+
: new $filter($attribute, $value);
68+
}
69+
}

src/Query/Grammar.php

Lines changed: 0 additions & 98 deletions
This file was deleted.

src/Query/Model/Builder.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ class Builder
6767
'getconnection',
6868
'getdn',
6969
'getfilters',
70-
'getgrammar',
7170
'getselects',
7271
'gettype',
7372
'getunescapedquery',
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace LdapRecord\Tests\Unit\Query\Filter;
4+
5+
use LdapRecord\Query\Filter\Equals;
6+
use LdapRecord\Query\Filter\Factory;
7+
use LdapRecord\Query\Filter\Has;
8+
use LdapRecord\Query\Filter\Not;
9+
use LdapRecord\Tests\TestCase;
10+
use UnexpectedValueException;
11+
12+
class FactoryTest extends TestCase
13+
{
14+
public function test_all_operators()
15+
{
16+
$expected = [
17+
'*', '!*', '=', '!', '!=', '>=', '<=',
18+
'~=', 'starts_with', 'not_starts_with',
19+
'ends_with', 'not_ends_with', 'contains', 'not_contains',
20+
];
21+
22+
$this->assertEquals($expected, Factory::operators());
23+
}
24+
25+
public function test_make_filter()
26+
{
27+
$filter = Factory::make('=', 'cn', 'John Doe');
28+
29+
$this->assertInstanceOf(Equals::class, $filter);
30+
$this->assertEquals('cn', $filter->getAttribute());
31+
$this->assertEquals('=', $filter->getOperator());
32+
$this->assertEquals('John Doe', $filter->getValue());
33+
}
34+
35+
public function test_make_filter_with_negated_operator()
36+
{
37+
$filter = Factory::make('!=', 'cn', 'John Doe');
38+
39+
$this->assertInstanceOf(Not::class, $filter);
40+
$this->assertInstanceOf(Equals::class, $filter->getFilter());
41+
}
42+
43+
public function test_make_filter_with_has_operator()
44+
{
45+
$filter = Factory::make('*', 'cn');
46+
47+
$this->assertInstanceOf(Has::class, $filter);
48+
}
49+
50+
public function test_make_filter_with_not_has_operator()
51+
{
52+
$filter = Factory::make('!*', 'cn');
53+
54+
$this->assertInstanceOf(Not::class, $filter);
55+
$this->assertInstanceOf(Has::class, $filter->getFilter());
56+
}
57+
58+
public function test_make_filter_with_invalid_operator()
59+
{
60+
$this->expectException(UnexpectedValueException::class);
61+
62+
Factory::make('foo', 'cn');
63+
}
64+
}

tests/Unit/Query/GrammarTest.php

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)