Skip to content
Permalink
Browse files

feature #21856 [LDAP] Allow adding and removing values to/from multi-…

…valued attributes (jean-gui)

This PR was merged into the 4.1-dev branch.

Discussion
----------

[LDAP] Allow adding and removing values to/from multi-valued attributes

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| License       | MIT

`EntryManagerInterface::update(Entry $entry)` is extremely slow in some specific cases such as adding or removing members to or from huge groupOfNames if you also enable the memberOf overlay in OpenLDAP. Disabling memberOf does make things a lot better, but it is still slow compared to inserting/removing only the elements you want.

This PR adds two methods to Symfony\Component\Ldap\Adapter\ExtLdap\EntryManager taking advantage of ldap_mod_add and ldap_mod_del.

I thought about using them directly in the update method, but since you need to know what values to add and remove, it would be necessary to retrieve the old values from LDAP.

I'm also unsure whether these two methods should be in an interface. I think that adding them to EntryManagerInterface would break BC, but I could create another interface, similarly to RenameEntryInterface.

Commits
-------

fa9db29 Allow adding and removing values to/from multi-valued attributes
  • Loading branch information...
fabpot committed Apr 4, 2018
2 parents fe6aa64 + fa9db29 commit 2a4d024bcd071b9aa4dcf94a036665ac42f61f65
@@ -67,6 +67,36 @@ public function remove(Entry $entry)
}
}
/**
* Adds values to an entry's multi-valued attribute from the LDAP server.
*
* @throws NotBoundException
* @throws LdapException
*/
public function addAttributeValues(Entry $entry, string $attribute, array $values)
{
$con = $this->getConnectionResource();
if (!@ldap_mod_add($con, $entry->getDn(), array($attribute => $values))) {
throw new LdapException(sprintf('Could not add values to entry "%s", attribute %s: %s.', $entry->getDn(), $attribute, ldap_error($con)));
}
}
/**
* Removes values from an entry's multi-valued attribute from the LDAP server.
*
* @throws NotBoundException
* @throws LdapException
*/
public function removeAttributeValues(Entry $entry, string $attribute, array $values)
{
$con = $this->getConnectionResource();
if (!@ldap_mod_del($con, $entry->getDn(), array($attribute => $values))) {
throw new LdapException(sprintf('Could not remove values from entry "%s", attribute %s: %s.', $entry->getDn(), $attribute, ldap_error($con)));
}
}
/**
* {@inheritdoc}
*/
@@ -1,6 +1,12 @@
CHANGELOG
=========

4.1.0
-----

* Added support for adding values to multi-valued attributes
* Added support for removing values from multi-valued attributes

4.0.0
-----

@@ -192,4 +192,50 @@ public function testLdapRenameWithoutRemovingOldRdn()
$this->executeSearchQuery(1);
}
public function testLdapAddRemoveAttributeValues()
{
$entryManager = $this->adapter->getEntryManager();
$result = $this->executeSearchQuery(1);
$entry = $result[0];
$entryManager->addAttributeValues($entry, 'mail', array('fabpot@example.org', 'fabpot2@example.org'));
$result = $this->executeSearchQuery(1);
$newEntry = $result[0];
$this->assertCount(4, $newEntry->getAttribute('mail'));
$entryManager->removeAttributeValues($newEntry, 'mail', array('fabpot@example.org', 'fabpot2@example.org'));
$result = $this->executeSearchQuery(1);
$newNewEntry = $result[0];
$this->assertCount(2, $newNewEntry->getAttribute('mail'));
}
public function testLdapRemoveAttributeValuesError()
{
$entryManager = $this->adapter->getEntryManager();
$result = $this->executeSearchQuery(1);
$entry = $result[0];
$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(LdapException::class);
$entryManager->removeAttributeValues($entry, 'mail', array('fabpot@example.org'));
}
public function testLdapAddAttributeValuesError()
{
$entryManager = $this->adapter->getEntryManager();
$result = $this->executeSearchQuery(1);
$entry = $result[0];
$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(LdapException::class);
$entryManager->addAttributeValues($entry, 'mail', $entry->getAttribute('mail'));
}
}

0 comments on commit 2a4d024

Please sign in to comment.
You can’t perform that action at this time.