diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 3474ba9b..83b5ef3d 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -850,19 +850,23 @@ public function addSelect(array|string $column): static /** * Add an order by control to the query. */ - public function orderBy(string $attribute, string $direction = 'asc'): static + public function orderBy(string $attribute, string $direction = 'asc', array $options = []): static { return $this->addControl(LDAP_CONTROL_SORTREQUEST, true, [ - ['attr' => $attribute, 'reverse' => $direction === 'desc'], + [ + ...$options, + 'attr' => $attribute, + 'reverse' => $direction === 'desc', + ], ]); } /** * Add an order by descending control to the query. */ - public function orderByDesc(string $attribute): static + public function orderByDesc(string $attribute, array $options = []): static { - return $this->orderBy($attribute, 'desc'); + return $this->orderBy($attribute, 'desc', $options); } /** diff --git a/tests/Unit/Query/BuilderTest.php b/tests/Unit/Query/BuilderTest.php index 5476b4e1..bce992bb 100644 --- a/tests/Unit/Query/BuilderTest.php +++ b/tests/Unit/Query/BuilderTest.php @@ -3,6 +3,7 @@ namespace LdapRecord\Tests\Unit\Query; use DateTime; +use InvalidArgumentException; use LdapRecord\Connection; use LdapRecord\Container; use LdapRecord\LdapRecordException; @@ -109,7 +110,7 @@ public function test_add_filter() public function test_adding_filter_with_invalid_bindings_throws_exception() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); // Missing 'value' key. $this->newBuilder()->addFilter('and', [ @@ -120,7 +121,7 @@ public function test_adding_filter_with_invalid_bindings_throws_exception() public function test_adding_invalid_filter_type_throws_exception() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->newBuilder()->addFilter('non-existent', [ 'field' => 'cn', @@ -467,7 +468,7 @@ public function test_or_where_ends_with() public function test_where_invalid_operator() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $b = $this->newBuilder(); @@ -476,7 +477,7 @@ public function test_where_invalid_operator() public function test_or_where_invalid_operator() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $b = $this->newBuilder(); @@ -1025,6 +1026,80 @@ public function test_get() $this->assertEquals($result, $b->get()); } + public function test_order_by() + { + $b = $this->newBuilder(); + + $b->orderBy('foo', 'asc'); + + $this->assertEquals($b->controls, [ + LDAP_CONTROL_SORTREQUEST => [ + 'oid' => LDAP_CONTROL_SORTREQUEST, + 'isCritical' => true, + 'value' => [ + [ + 'attr' => 'foo', + 'reverse' => false, + ], + ], + ], + ]); + } + + public function test_order_by_desc() + { + $b = $this->newBuilder(); + + $b->orderByDesc('foo'); + + $this->assertEquals($b->controls, [ + LDAP_CONTROL_SORTREQUEST => [ + 'oid' => LDAP_CONTROL_SORTREQUEST, + 'isCritical' => true, + 'value' => [ + [ + 'attr' => 'foo', + 'reverse' => true, + ], + ], + ], + ]); + } + + public function test_order_by_with_options() + { + $b = $this->newBuilder(); + + $b->orderBy('foo', 'asc', [ + 'oid' => $oid = '2.5.13.2', + ]); + + $this->assertEquals($b->controls, [ + LDAP_CONTROL_SORTREQUEST => [ + 'oid' => LDAP_CONTROL_SORTREQUEST, + 'isCritical' => true, + 'value' => [ + [ + 'attr' => 'foo', + 'reverse' => false, + 'oid' => $oid, + ], + ], + ], + ]); + } + + public function test_has_order_by() + { + $b = $this->newBuilder(); + + $this->assertFalse($b->hasOrderBy()); + + $b->orderBy('foo', 'asc'); + + $this->assertTrue($b->hasOrderBy()); + } + public function test_first() { $b = $this->newBuilder();