Skip to content

Commit e0c64c8

Browse files
soyukaclaude
andcommitted
feat(doctrine): ne (not equal) operator for ComparisonFilter
| Q | A | ------------- | --- | Branch? | main | Tickets | ∅ | License | MIT | Doc PR | ∅ * Add `ne` operator to ORM (`!=`) and ODM (`notEqual`) ComparisonFilter * Add functional tests for both backends Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5a876cc commit e0c64c8

3 files changed

Lines changed: 25 additions & 1 deletion

File tree

src/Doctrine/Odm/Filter/ComparisonFilter.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ final class ComparisonFilter implements FilterInterface, OpenApiParameterFilterI
4444
'gte' => 'gte',
4545
'lt' => 'lt',
4646
'lte' => 'lte',
47+
'ne' => 'notEqual',
4748
];
4849

4950
public function __construct(private readonly FilterInterface $filter)
@@ -91,6 +92,7 @@ public function getOpenApiParameters(Parameter $parameter): array
9192
new OpenApiParameter(name: "{$key}[gte]", in: $in),
9293
new OpenApiParameter(name: "{$key}[lt]", in: $in),
9394
new OpenApiParameter(name: "{$key}[lte]", in: $in),
95+
new OpenApiParameter(name: "{$key}[ne]", in: $in),
9496
];
9597
}
9698

@@ -108,6 +110,7 @@ public function getSchema(Parameter $parameter): array
108110
'gte' => $innerSchema,
109111
'lt' => $innerSchema,
110112
'lte' => $innerSchema,
113+
'ne' => $innerSchema,
111114
],
112115
];
113116
}

src/Doctrine/Orm/Filter/ComparisonFilter.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ final class ComparisonFilter implements FilterInterface, OpenApiParameterFilterI
4545
'gte' => '>=',
4646
'lt' => '<',
4747
'lte' => '<=',
48+
'ne' => '!=',
4849
];
4950

5051
public const ALLOWED_DQL_OPERATORS = ['=', '>', '>=', '<', '<=', '!=', '<>'];
@@ -91,6 +92,7 @@ public function getOpenApiParameters(Parameter $parameter): array
9192
new OpenApiParameter(name: "{$key}[gte]", in: $in),
9293
new OpenApiParameter(name: "{$key}[lt]", in: $in),
9394
new OpenApiParameter(name: "{$key}[lte]", in: $in),
95+
new OpenApiParameter(name: "{$key}[ne]", in: $in),
9496
];
9597
}
9698

@@ -108,6 +110,7 @@ public function getSchema(Parameter $parameter): array
108110
'gte' => $innerSchema,
109111
'lt' => $innerSchema,
110112
'lte' => $innerSchema,
113+
'ne' => $innerSchema,
111114
],
112115
];
113116
}

tests/Functional/Parameters/ComparisonFilterTest.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,24 @@ public function testCombinedGtAndLt(): void
9898
$this->assertSame(['Bravo', 'Charlie'], $names);
9999
}
100100

101+
public function testNe(): void
102+
{
103+
// ne "Bravo": all names except "Bravo" → Alpha, Charlie, Delta
104+
$response = self::createClient()->request('GET', '/chickens?nameComparison[ne]=Bravo');
105+
$this->assertResponseIsSuccessful();
106+
$names = array_map(static fn ($c) => $c['name'], $response->toArray()['member']);
107+
sort($names);
108+
$this->assertSame(['Alpha', 'Charlie', 'Delta'], $names);
109+
}
110+
111+
public function testNeNoMatch(): void
112+
{
113+
// ne "Unknown": no chicken has that name, so all are returned
114+
$response = self::createClient()->request('GET', '/chickens?nameComparison[ne]=Unknown&itemsPerPage=10');
115+
$this->assertResponseIsSuccessful();
116+
$this->assertCount(4, $response->toArray()['member']);
117+
}
118+
101119
public function testGtNoResults(): void
102120
{
103121
// gt "ZZZZ": no name is alphabetically after "ZZZZ"
@@ -125,7 +143,7 @@ public function testOpenApiDocumentation(): void
125143
$parameters = $openApiDoc['paths']['/chickens']['get']['parameters'];
126144
$parameterNames = array_column($parameters, 'name');
127145

128-
foreach (['nameComparison[gt]', 'nameComparison[gte]', 'nameComparison[lt]', 'nameComparison[lte]'] as $expectedName) {
146+
foreach (['nameComparison[gt]', 'nameComparison[gte]', 'nameComparison[lt]', 'nameComparison[lte]', 'nameComparison[ne]'] as $expectedName) {
129147
$this->assertContains($expectedName, $parameterNames, \sprintf('Expected parameter "%s" in OpenAPI documentation', $expectedName));
130148
}
131149

0 commit comments

Comments
 (0)