diff --git a/src/Symfony/Component/Ldap/Adapter/AbstractQuery.php b/src/Symfony/Component/Ldap/Adapter/AbstractQuery.php index 41889da1333d4..5cacad79b249e 100644 --- a/src/Symfony/Component/Ldap/Adapter/AbstractQuery.php +++ b/src/Symfony/Component/Ldap/Adapter/AbstractQuery.php @@ -34,8 +34,11 @@ public function __construct(ConnectionInterface $connection, $dn, $query, array 'timeout' => 0, 'deref' => static::DEREF_NEVER, 'attrsOnly' => 0, + 'scope' => static::SCOPE_SUB, )); $resolver->setAllowedValues('deref', array(static::DEREF_ALWAYS, static::DEREF_NEVER, static::DEREF_FINDING, static::DEREF_SEARCHING)); + $resolver->setAllowedValues('scope', array(static::SCOPE_BASE, static::SCOPE_ONE, static::SCOPE_SUB)); + $resolver->setNormalizer('filter', function (Options $options, $value) { return is_array($value) ? $value : array($value); }); diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php index 0e8eae7d21d17..0bad59a5400d5 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php @@ -60,7 +60,21 @@ public function execute() $con = $this->connection->getResource(); - $this->search = @ldap_search( + switch ($this->options['scope']) { + case static::SCOPE_BASE: + $func = 'ldap_read'; + break; + case static::SCOPE_ONE: + $func = 'ldap_list'; + break; + case static::SCOPE_SUB: + $func = 'ldap_search'; + break; + default: + throw new LdapException(sprintf('Could not search in scope %s', $this->options['scopen'])); + } + + $this->search = @$func( $con, $this->dn, $this->query, diff --git a/src/Symfony/Component/Ldap/Adapter/QueryInterface.php b/src/Symfony/Component/Ldap/Adapter/QueryInterface.php index ba26de791efe8..5f8f95fde39d1 100644 --- a/src/Symfony/Component/Ldap/Adapter/QueryInterface.php +++ b/src/Symfony/Component/Ldap/Adapter/QueryInterface.php @@ -23,6 +23,10 @@ interface QueryInterface const DEREF_FINDING = 0x02; const DEREF_ALWAYS = 0x03; + const SCOPE_BASE = 'base'; + const SCOPE_ONE = 'one'; + const SCOPE_SUB = 'sub'; + /** * Executes a query and returns the list of Ldap entries. * diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php index f25d181896d35..fb4a5b3e1fb86 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php @@ -13,6 +13,7 @@ use Symfony\Component\Ldap\Adapter\ExtLdap\Adapter; use Symfony\Component\Ldap\Adapter\ExtLdap\Collection; +use Symfony\Component\Ldap\Adapter\ExtLdap\Query; use Symfony\Component\Ldap\Entry; use Symfony\Component\Ldap\LdapInterface; @@ -65,4 +66,37 @@ public function testLdapQueryIterator() $this->assertEquals(array('Fabien Potencier'), $entry->getAttribute('cn')); $this->assertEquals(array('fabpot@symfony.com', 'fabien@potencier.com'), $entry->getAttribute('mail')); } + + public function testLdapQueryScopeBase() + { + $ldap = new Adapter($this->getLdapConfig()); + + $ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony'); + + $query = $ldap->createQuery('cn=Fabien Potencier,dc=symfony,dc=com', '(objectclass=*)', array( + 'scope' => Query::SCOPE_BASE, + )); + $result = $query->execute(); + + $entry = $result[0]; + $this->assertEquals($result->count(), 1); + $this->assertEquals(array('Fabien Potencier'), $entry->getAttribute('cn')); + } + + public function testLdapQueryScopeOneLevel() + { + $ldap = new Adapter($this->getLdapConfig()); + + $ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony'); + + $one_level_result = $ldap->createQuery('ou=Components,dc=symfony,dc=com', '(objectclass=*)', array( + 'scope' => Query::SCOPE_ONE, + ))->execute(); + + $subtree_count = $ldap->createQuery('ou=Components,dc=symfony,dc=com', '(objectclass=*)')->execute()->count(); + + $this->assertNotEquals($one_level_result->count(), $subtree_count); + $this->assertEquals($one_level_result->count(), 1); + $this->assertEquals($one_level_result[0]->getAttribute('ou'), array('Ldap')); + } } diff --git a/src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif b/src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif index 21dc42d77edd4..43842146b2837 100644 --- a/src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif +++ b/src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif @@ -12,3 +12,15 @@ ou: Maintainers ou: Founder givenName: Fabien Potencier description: Founder and project lead @Symfony + +dn: ou=Components,dc=symfony,dc=com +objectclass: organizationalunit +ou: Components + +dn: ou=Ldap,ou=Components,dc=symfony,dc=com +objectclass: organizationalunit +ou: Ldap + +dn: ou=Ldap scoping,ou=Ldap,ou=Components,dc=symfony,dc=com +objectclass: organizationalunit +ou: Ldap scoping