Source for file LDAP2.php
Documentation is available at LDAP2.php
* This file contains the class XML_Query2XML_Driver_LDAP2.
* @author Lukas Feiler <lukas.feiler@lukasfeiler.com>
* @copyright 2007 Lukas Feiler
* @license http://www.gnu.org/copyleft/lesser.html LGPL Version 2.1
* @version CVS: $Id: LDAP2.php 259451 2008-05-09 20:54:26Z lukasfeiler $
* @link http://pear.php.net/package/XML_Query2XML
* XML_Query2XML_Driver_LDAP2 extends XML_Query2XML_Driver.
require_once 'XML/Query2XML.php';
* XML_Query2XML_Driver_LDAP2 uses Net_LDAP2.
require_once 'Net/LDAP2.php';
* Net_LDAP2_Util is required for its escape_filter_value() method.
require_once 'Net/LDAP2/Util.php';
* PEAR is required for its isError() method.
* $driver = XML_Query2XML_Driver::factory(new Net_LDAP2(...));
* This LDAP driver is built upon PEAR Net_LDAP2 and provides three features:
* - prepare & execute like usage of placeholders in "base" and "filter"
* - handling missing attributes
* in LDAP an entity does not have to use all available attributes,
* while XML_Query2XML expects every record to have the same columns;
* this driver solves the problem by setting all missing columns to null.
* - handling multi-value attributes
* XML_Query2XML expects every record to be a one-dimensional associative
* array. In order to achieve this result this driver creates as many
* records for each LDAP entry as are necassary to accomodate all values
* @author Lukas Feiler <lukas.feiler@lukasfeiler.com>
* @copyright 2006 Lukas Feiler
* @license http://www.gnu.org/copyleft/lesser.html LGPL Version 2.1
* @version Release: 1.7.2
* @link http://pear.php.net/package/XML_Query2XML
* @since Release 1.7.0RC1
* In instance of Net_LDAP2
* @param Net_LDAP2 $ldap An instance of PEAR Net_LDAP2.
* Pre-processes LDAP query specifications.
* @param array &$query An array optionally containing the elements
* 'base', 'filter', 'options' and 'data'.
* @param string $configPath The config path; used for exception messages.
* @return string A string representation of $query
* unit test: XML_Query2XML_Driver_LDAP-preprocessQuery/
* throwConfigException_queryNotAnArray.phpt
$configPath .
': array expected, ' .
gettype($query) .
' given.'
$queryStatement =
'basedn:';
if (isset
($query['base'])) {
$queryStatement .=
$query['base'];
$queryStatement .=
'default';
if (isset
($query['filter'])) {
$query['filter'] instanceof
Net_LDAP2_Filter
$queryStatement .=
'; filter:' .
$query['filter']->asString();
$queryStatement .=
'; filter:' .
$query['filter'];
if (isset
($query['options'])) {
$queryStatement .=
'; options:' .
print_r($query['options'], 1);
* Execute a LDAP query stement and fetch all results.
* @param mixed $query The SQL query as a string or an array.
* @param string $configPath The config path; used for exception messages.
* @return array An array of records.
* @throws XML_Query2XML_LDAP2Exception If Net_LDAP2::search() returns an error.
* @see XML_Query2XML_Driver::getAllRecords()
if (isset
($query['base'])) {
if (isset
($query['filter'])) {
$filter =
$query['filter'];
if (isset
($query['options'])) {
$options =
$query['options'];
if (isset
($options['query2xml_placeholder'])) {
$placeholder =
$options['query2xml_placeholder'];
unset
($options['query2xml_placeholder']);
if (isset
($query['data']) &&
is_array($query['data'])) {
$data =
Net_LDAP2_Util::escape_filter_value($query['data']);
$base =
self::_replacePlaceholders($base, $data, $placeholder);
$filter =
self::_replacePlaceholders($filter, $data, $placeholder);
$search =
$this->_ldap->search($base, $filter, $options);
if (PEAR::isError($search)) {
* unit test: getXML/throwLDAPException_queryError.phpt
$configPath .
': Could not run LDAP search query: '
$entries =
$search->entries();
foreach ($entries as $key =>
$entry) {
$records[] =
$entry->getValues();
$records =
self::_processMultiValueAttributes($records);
// set missing attriubtes to null
if (isset
($options['attributes']) &&
is_array($options['attributes'])) {
foreach ($options['attributes'] as $attribute) {
for ($i =
0; $i <
count($records); $i++
) {
$records[$i][$attribute] =
null;
* Creates multiple records for each entry that has mult-value attributes.
* XML_Query2XML can only handle records represented by a one-dimensional
* associative array. An entry like
* dn: cn=John Doe,ou=people,dc=example,dc=com
* mail: john.doe@example.com
* therefore has to be converted into multiple one-dimensional associative
* -------------------------------------------------------
* John Doe john.doe@example.com 555-666-777
* John Doe jdoe@example.com 666-777-888
* John Doe jd@example.com 555-666-777
* Note that no cartasian product of the mail-values and the mobile-values
* is produced. The number of records returned is equal to the number
* values assigned to the attribute that has the most values (here
* it's the mail attribute that has 3 values). To make sure that every
* record has valid values for all attributes/columns, we start with
* the first value after reaching the last one (e.g. the last record
* for jd@example.com has a mobile of 555-666-777).
* @param array $entries A multi-dimensional associative array.
private static function _processMultiValueAttributes($entries)
foreach ($entries as $entry) {
$multiValueAttributes =
array();
// will hold the name of the attribute with the most values
$maxValuesAttribute =
null;
// loop over all attributes
foreach ($entry as $attributeName =>
$attribute) {
$multiValueAttributes[$attributeName] =
array($attribute, 0);
if ($maxValues <
count($attribute)) {
$maxValues =
count($attribute);
$maxValuesAttribute =
$attributeName;
$multiValueAttributesMap[$attributeName] =
count($attribute);
if (count($multiValueAttributes) >
0) {
* $multiValueAttributes is something like:
* 0 // index used to keep track of where we are
* ['telephoneNumber'] => array(
* 0 // index used to keep track of where we are
$maxValuesAttributeValues =
$multiValueAttributes[$maxValuesAttribute][0];
unset
($multiValueAttributes[$maxValuesAttribute]);
foreach ($maxValuesAttributeValues as $value) {
$combination[$maxValuesAttribute] =
$value;
* Get the next value for each multi-value attribute.
* When the last value has been reached start again at
foreach (array_keys($multiValueAttributes) as $attributeName) {
$values =
& $multiValueAttributes[$attributeName][0];
$index =
& $multiValueAttributes[$attributeName][1];
$count =
& count($values);
$combination[$attributeName] =
$values[$index++
];
$combinations[] =
$combination;
foreach ($combinations as $combination) {
* Replaces all placeholder strings (e.g. '?') with replacement strings.
* @param string $string The string in which to replace the placeholder
* @param array &$replacements An array of replacement strings.
* @param string $placeholder The placeholder string.
* @return string The modified version of $string.
private static function _replacePlaceholders($string,
while (($pos =
strpos($string, $placeholder)) !==
false) {
if (count($replacements) >
0) {
$string =
substr($string, 0, $pos) .
* Exception for LDAP errors
* @author Lukas Feiler <lukas.feiler@lukasfeiler.com>
* @license http://www.gnu.org/copyleft/lesser.html LGPL Version 2.1
* @link http://pear.php.net/package/XML_Query2XML
* @param string $message The error message.
Documentation generated on Sun, 03 Apr 2011 13:13:09 +0200 by phpDocumentor 1.4.1