Skip to content

Instantly share code, notes, and snippets.

@ThaDafinser
Created February 23, 2017 08:58
Show Gist options
  • Save ThaDafinser/6d8ea903357fb31bf23eac86f82b209c to your computer and use it in GitHub Desktop.
Save ThaDafinser/6d8ea903357fb31bf23eac86f82b209c to your computer and use it in GitHub Desktop.
<?php
namespace Account\Service;
use Zend\Ldap\Collection;
use Zend\Ldap\Ldap;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Stdlib\ErrorHandler;
class FetchPaged implements ServiceLocatorAwareInterface
{
use ServiceLocatorAwareTrait;
private $returnAttributes = null;
private $serverConfig = null;
/**
*
* @var Ldap
*/
private $ldap;
private $filter;
/**
*
* @var boolean
*/
private $cookie = true;
/**
*
* @var null false array
*/
private $result;
public function setServerConfig($config)
{
$this->serverConfig = $config;
}
public function getServerConfig()
{
if ($this->serverConfig === null) {
$config = $this->getServiceLocator()->get('config');
$this->serverConfig = $config['ldap']['servers']['globalCatalog'];
}
return $this->serverConfig;
}
/**
*
* @return \Zend\Ldap\Ldap
*/
public function getLdap()
{
if ($this->ldap === null) {
$this->ldap = new Ldap($this->getServerConfig());
}
return $this->ldap;
}
public function setFilter($filter)
{
$this->filter = $filter;
}
public function getFilter()
{
return $this->filter;
}
public function setReturnAttributes($attr = [])
{
$this->returnAttributes = $attr;
}
/**
* Fetch one object from the result (like for database one row fetch / fetchRow)
*
* @return \stdClass | false
*/
public function fetch()
{
if ($this->result === null || count($this->result) === 0) {
// result is empty -> fetch first or next
$this->result = $this->fetchPageResult();
if ($this->result !== false) {
$this->result = $this->result->toArray();
}
}
if (is_array($this->result) && count($this->result) === 0) {
$this->result = false;
}
if ($this->result === false) {
// End reached
return false;
}
// through array_shift always the next is used!
return $this->convertAttributes(array_shift($this->result));
}
/**
*
* @return \Zend\Ldap\Collection boolean
*/
private function fetchPageResult()
{
if ($this->cookie != '' && $this->cookie !== null) {
if ($this->cookie === true) {
// First fetch!
$this->cookie = '';
}
$ldap = $this->getLdap();
$resource = $ldap->getResource();
ldap_control_paged_result($resource, 100, true, $this->cookie);
if ($this->returnAttributes !== null) {
$result = ldap_search($resource, $ldap->getBaseDn(), $this->getFilter(), $this->returnAttributes);
} else {
$result = ldap_search($resource, $ldap->getBaseDn(), $this->getFilter());
}
if (! is_resource($result)) {
throw new \Exception('ldap_search returned something wrong...' . ldap_error($resource));
}
ErrorHandler::start();
$return = ldap_control_paged_result_response($resource, $result, $this->cookie);
ErrorHandler::stop();
if ($return !== true) {
$errNo = ldap_errno($resource);
if ($errNo == 10) {
return false;
}
throw new \Exception('Paged result was empty' . ldap_error($resource));
}
$iterator = new Collection\DefaultIterator($this->getLdap(), $result);
return new Collection($iterator);
}
return false;
}
/**
*
* @param array $entry
* @return stdClass
*/
private function convertAttributes($entry)
{
$returnObject = new \stdClass();
foreach ($entry as $attrKey => $value) {
if ($attrKey == 'usercertificate') {
continue;
}
$ranged = explode(';', $attrKey);
if (count($ranged) === 2) {
$returnObject->$ranged[0] = $value;
}
if (is_array($value) && count($value) > 0) {
$returnObject->$attrKey = (count($value) > 1) ? $value : $value[0];
} else {
$returnObject->$attrKey = $value;
}
}
return $returnObject;
}
}
function getPartRecursive(\Zend\Ldap\Ldap $ldap, $dn, $currentValue, $attrName, $currentOffset, $maxPerRequest)
{
$limit = $currentOffset + $maxPerRequest - 1;
var_dump($dn);
var_dump($attrName . ';range=' . $currentOffset . '-' . $limit);
$ldap = new \Zend\Ldap\Ldap($ldap->getOptions());
$entry2 = $ldap->getEntry($dn, [
$attrName . ';range=' . $currentOffset . '-' . $limit
], true);
foreach ($entry2 as $key => $value) {
if (stripos($key, $attrName) !== false && stripos($key, ';range=') !== false) {
$currentValue = array_merge($currentValue, $value);
// range result (pagination)
$keyExploded = explode(';range=', $key);
$range = explode('-', $keyExploded[1]);
$rangeEnd = (int) $range[1];
if ($range[0] == $currentOffset && $range[1] == $limit) {
// more pages
$currentValue = getPartRecursive($ldap, $dn, $currentValue, $keyExploded[0], $rangeEnd + 1, $maxPerRequest);
}
}
}
return $currentValue;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment