3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Ldap\Collection
;
15 use Zend\Ldap\Exception
;
16 use Zend\Stdlib\ErrorHandler
;
19 * Zend\Ldap\Collection\DefaultIterator is the default collection iterator implementation
22 class DefaultIterator
implements Iterator
, Countable
24 const ATTRIBUTE_TO_LOWER
= 1;
25 const ATTRIBUTE_TO_UPPER
= 2;
26 const ATTRIBUTE_NATIVE
= 3;
31 * @var \Zend\Ldap\Ldap
33 protected $ldap = null;
36 * Result identifier resource
40 protected $resultId = null;
43 * Current result entry identifier
47 protected $current = null;
50 * Number of items in query result
54 protected $itemCount = -1;
57 * The method that will be applied to the attribute's names.
59 * @var integer|callable
61 protected $attributeNameTreatment = self
::ATTRIBUTE_TO_LOWER
;
66 * @param \Zend\Ldap\Ldap $ldap
67 * @param resource $resultId
68 * @throws \Zend\Ldap\Exception\LdapException if no entries was found.
69 * @return DefaultIterator
71 public function __construct(Ldap\Ldap
$ldap, $resultId)
74 $this->resultId
= $resultId;
76 $resource = $ldap->getResource();
77 ErrorHandler
::start();
78 $this->itemCount
= ldap_count_entries($resource, $resultId);
80 if ($this->itemCount
=== false) {
81 throw new Exception\
LdapException($this->ldap
, 'counting entries');
85 public function __destruct()
91 * Closes the current result set
95 public function close()
98 if (is_resource($this->resultId
)) {
99 ErrorHandler
::start();
100 $isClosed = ldap_free_result($this->resultId
);
101 ErrorHandler
::stop();
103 $this->resultId
= null;
104 $this->current
= null;
110 * Gets the current LDAP connection.
112 * @return \Zend\Ldap\Ldap
114 public function getLDAP()
120 * Sets the attribute name treatment.
122 * Can either be one of the following constants
123 * - Zend\Ldap\Collection\DefaultIterator::ATTRIBUTE_TO_LOWER
124 * - Zend\Ldap\Collection\DefaultIterator::ATTRIBUTE_TO_UPPER
125 * - Zend\Ldap\Collection\DefaultIterator::ATTRIBUTE_NATIVE
126 * or a valid callback accepting the attribute's name as it's only
127 * argument and returning the new attribute's name.
129 * @param int|callable $attributeNameTreatment
130 * @return DefaultIterator Provides a fluent interface
132 public function setAttributeNameTreatment($attributeNameTreatment)
134 if (is_callable($attributeNameTreatment)) {
135 if (is_string($attributeNameTreatment) && !function_exists($attributeNameTreatment)) {
136 $this->attributeNameTreatment
= self
::ATTRIBUTE_TO_LOWER
;
137 } elseif (is_array($attributeNameTreatment)
138 && !method_exists($attributeNameTreatment[0], $attributeNameTreatment[1])
140 $this->attributeNameTreatment
= self
::ATTRIBUTE_TO_LOWER
;
142 $this->attributeNameTreatment
= $attributeNameTreatment;
145 $attributeNameTreatment = (int) $attributeNameTreatment;
146 switch ($attributeNameTreatment) {
147 case self
::ATTRIBUTE_TO_LOWER
:
148 case self
::ATTRIBUTE_TO_UPPER
:
149 case self
::ATTRIBUTE_NATIVE
:
150 $this->attributeNameTreatment
= $attributeNameTreatment;
153 $this->attributeNameTreatment
= self
::ATTRIBUTE_TO_LOWER
;
162 * Returns the currently set attribute name treatment
164 * @return int|callable
166 public function getAttributeNameTreatment()
168 return $this->attributeNameTreatment
;
172 * Returns the number of items in current result
173 * Implements Countable
177 public function count()
179 return $this->itemCount
;
183 * Return the current result item
184 * Implements Iterator
187 * @throws \Zend\Ldap\Exception\LdapException
189 public function current()
191 if (!is_resource($this->current
)) {
194 if (!is_resource($this->current
)) {
198 $entry = array('dn' => $this->key());
199 $berIdentifier = null;
201 $resource = $this->ldap
->getResource();
202 ErrorHandler
::start();
203 $name = ldap_first_attribute(
204 $resource, $this->current
,
207 ErrorHandler
::stop();
210 ErrorHandler
::start();
211 $data = ldap_get_values_len($resource, $this->current
, $name);
212 ErrorHandler
::stop();
218 if (isset($data['count'])) {
219 unset($data['count']);
222 switch ($this->attributeNameTreatment
) {
223 case self
::ATTRIBUTE_TO_LOWER
:
224 $attrName = strtolower($name);
226 case self
::ATTRIBUTE_TO_UPPER
:
227 $attrName = strtoupper($name);
229 case self
::ATTRIBUTE_NATIVE
:
233 $attrName = call_user_func($this->attributeNameTreatment
, $name);
236 $entry[$attrName] = $data;
238 ErrorHandler
::start();
239 $name = ldap_next_attribute(
240 $resource, $this->current
,
243 ErrorHandler
::stop();
245 ksort($entry, SORT_LOCALE_STRING
);
250 * Return the result item key
251 * Implements Iterator
253 * @throws \Zend\Ldap\Exception\LdapException
254 * @return string|null
256 public function key()
258 if (!is_resource($this->current
)) {
261 if (is_resource($this->current
)) {
262 $resource = $this->ldap
->getResource();
263 ErrorHandler
::start();
264 $currentDn = ldap_get_dn($resource, $this->current
);
265 ErrorHandler
::stop();
267 if ($currentDn === false) {
268 throw new Exception\
LdapException($this->ldap
, 'getting dn');
278 * Move forward to next result item
279 * Implements Iterator
281 * @throws \Zend\Ldap\Exception\LdapException
283 public function next()
287 if (is_resource($this->current
) && $this->itemCount
> 0) {
288 $resource = $this->ldap
->getResource();
289 ErrorHandler
::start();
290 $this->current
= ldap_next_entry($resource, $this->current
);
291 ErrorHandler
::stop();
292 if ($this->current
=== false) {
293 $msg = $this->ldap
->getLastError($code);
294 if ($code === Exception\LdapException
::LDAP_SIZELIMIT_EXCEEDED
) {
295 // we have reached the size limit enforced by the server
297 } elseif ($code > Exception\LdapException
::LDAP_SUCCESS
) {
298 throw new Exception\
LdapException($this->ldap
, 'getting next entry (' . $msg . ')');
302 $this->current
= false;
307 * Rewind the Iterator to the first result item
308 * Implements Iterator
311 * @throws \Zend\Ldap\Exception\LdapException
313 public function rewind()
315 if (is_resource($this->resultId
)) {
316 $resource = $this->ldap
->getResource();
317 ErrorHandler
::start();
318 $this->current
= ldap_first_entry($resource, $this->resultId
);
319 ErrorHandler
::stop();
320 if ($this->current
=== false
321 && $this->ldap
->getLastErrorCode() > Exception\LdapException
::LDAP_SUCCESS
323 throw new Exception\
LdapException($this->ldap
, 'getting first entry');
329 * Check if there is a current result item
330 * after calls to rewind() or next()
331 * Implements Iterator
335 public function valid()
337 return (is_resource($this->current
));