Skip to content

Commit dc9a31a

Browse files
committed
Fixed issue with legacy find() method not working as expected
1 parent d33b903 commit dc9a31a

File tree

5 files changed

+106
-164
lines changed

5 files changed

+106
-164
lines changed

Adapter/ExtLdap/Collection.php

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,90 +24,102 @@ class Collection implements CollectionInterface
2424
private $search;
2525
private $entries;
2626

27-
public function __construct(Connection $connection, Query $search, array $entries = array())
27+
public function __construct(Connection $connection, Query $search)
2828
{
2929
$this->connection = $connection;
3030
$this->search = $search;
31-
$this->entries = array();
3231
}
3332

3433
/**
3534
* {@inheritdoc}
3635
*/
3736
public function toArray()
3837
{
39-
$this->initialize();
38+
if (null === $this->entries) {
39+
$this->entries = iterator_to_array($this->getIterator(), false);
40+
}
4041

4142
return $this->entries;
4243
}
4344

4445
public function count()
4546
{
46-
$this->initialize();
47+
if (false !== $count = ldap_count_entries($this->connection->getResource(), $this->search->getResource())) {
48+
return $count;
49+
}
4750

48-
return count($this->entries);
51+
throw new LdapException(sprintf('Error while retrieving entry count: %s', ldap_error($this->connection->getResource())));
4952
}
5053

5154
public function getIterator()
5255
{
53-
return new ResultIterator($this->connection, $this->search);
56+
$con = $this->connection->getResource();
57+
$search = $this->search->getResource();
58+
$current = ldap_first_entry($con, $search);
59+
60+
if (0 === $this->count()) {
61+
return;
62+
}
63+
64+
if (false === $current) {
65+
throw new LdapException(sprintf('Could not rewind entries array: %s', ldap_error($con)));
66+
}
67+
68+
yield $this->getSingleEntry($con, $current);
69+
70+
while (false !== $current = ldap_next_entry($con, $current)) {
71+
yield $this->getSingleEntry($con, $current);
72+
}
5473
}
5574

5675
public function offsetExists($offset)
5776
{
58-
$this->initialize();
77+
$this->toArray();
5978

6079
return isset($this->entries[$offset]);
6180
}
6281

6382
public function offsetGet($offset)
6483
{
84+
$this->toArray();
85+
6586
return isset($this->entries[$offset]) ? $this->entries[$offset] : null;
6687
}
6788

6889
public function offsetSet($offset, $value)
6990
{
70-
$this->initialize();
91+
$this->toArray();
7192

7293
$this->entries[$offset] = $value;
7394
}
7495

7596
public function offsetUnset($offset)
7697
{
77-
$this->initialize();
98+
$this->toArray();
7899

79100
unset($this->entries[$offset]);
80101
}
81102

82-
private function initialize()
103+
private function getSingleEntry($con, $current)
83104
{
84-
if (null === $this->entries) {
85-
return;
86-
}
105+
$attributes = ldap_get_attributes($con, $current);
87106

88-
$con = $this->connection->getResource();
89-
90-
$entries = ldap_get_entries($con, $this->search->getResource());
91-
92-
if (false === $entries) {
93-
throw new LdapException(sprintf('Could not load entries: %s', ldap_error($con)));
107+
if (false === $attributes) {
108+
throw new LdapException(sprintf('Could not fetch attributes: %s', ldap_error($con)));
94109
}
95110

96-
if (0 === $entries['count']) {
97-
return array();
98-
}
111+
$attributes = $this->cleanupAttributes($attributes);
99112

100-
unset($entries['count']);
113+
$dn = ldap_get_dn($con, $current);
101114

102-
$this->entries = array_map(function (array $entry) {
103-
$dn = $entry['dn'];
104-
$attributes = $this->cleanupAttributes($entry);
115+
if (false === $dn) {
116+
throw new LdapException(sprintf('Could not fetch DN: %s', ldap_error($con)));
117+
}
105118

106-
return new Entry($dn, $attributes);
107-
}, $entries);
119+
return new Entry($dn, $attributes);
108120
}
109121

110-
private function cleanupAttributes(array $entry = array())
122+
private function cleanupAttributes(array $entry)
111123
{
112124
$attributes = array_diff_key($entry, array_flip(range(0, $entry['count'] - 1)) + array(
113125
'count' => null,

Adapter/ExtLdap/ResultIterator.php

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

LdapClient.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,34 @@ public function find($dn, $query, $filter = '*')
6464

6565
$query = $this->ldap->query($dn, $query, array('filter' => $filter));
6666
$entries = $query->execute();
67-
$result = array();
67+
$result = array(
68+
'count' => 0,
69+
);
6870

6971
foreach ($entries as $entry) {
7072
$resultEntry = array();
7173

7274
foreach ($entry->getAttributes() as $attribute => $values) {
73-
$resultAttribute = $values;
75+
$resultAttribute = array(
76+
'count' => count($values),
77+
);
78+
79+
foreach ($values as $val) {
80+
$resultAttribute[] = $val;
81+
}
82+
$attributeName = strtolower($attribute);
7483

7584
$resultAttribute['count'] = count($values);
76-
$resultEntry[] = $resultAttribute;
77-
$resultEntry[$attribute] = $resultAttribute;
85+
$resultEntry[$attributeName] = $resultAttribute;
86+
$resultEntry[] = $attributeName;
7887
}
7988

8089
$resultEntry['count'] = count($resultEntry) / 2;
90+
$resultEntry['dn'] = $entry->getDn();
8191
$result[] = $resultEntry;
8292
}
8393

84-
$result['count'] = count($result);
94+
$result['count'] = count($result) - 1;
8595

8696
return $result;
8797
}

Tests/Adapter/ExtLdap/AdapterTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,22 @@ public function testLdapQuery()
4747
$this->assertEquals(array('Fabien Potencier'), $entry->getAttribute('cn'));
4848
$this->assertEquals(array('fabpot@symfony.com', 'fabien@potencier.com'), $entry->getAttribute('mail'));
4949
}
50+
51+
/**
52+
* @group functional
53+
*/
54+
public function testLdapQueryIterator()
55+
{
56+
$ldap = new Adapter($this->getLdapConfig());
57+
58+
$ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony');
59+
$query = $ldap->createQuery('dc=symfony,dc=com', '(&(objectclass=person)(ou=Maintainers))', array());
60+
$result = $query->execute();
61+
$iterator = $result->getIterator();
62+
$iterator->rewind();
63+
$entry = $iterator->current();
64+
$this->assertInstanceOf(Entry::class, $entry);
65+
$this->assertEquals(array('Fabien Potencier'), $entry->getAttribute('cn'));
66+
$this->assertEquals(array('fabpot@symfony.com', 'fabien@potencier.com'), $entry->getAttribute('mail'));
67+
}
5068
}

0 commit comments

Comments
 (0)