Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down
83 changes: 79 additions & 4 deletions tests/Unit/Query/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace LdapRecord\Tests\Unit\Query;

use DateTime;
use InvalidArgumentException;
use LdapRecord\Connection;
use LdapRecord\Container;
use LdapRecord\LdapRecordException;
Expand Down Expand Up @@ -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', [
Expand All @@ -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',
Expand Down Expand Up @@ -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();

Expand All @@ -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();

Expand Down Expand Up @@ -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();
Expand Down