PageRenderTime 49ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Ldap/Collection/DefaultIterator.php

http://github.com/zendframework/zf2
PHP | 339 lines | 193 code | 33 blank | 113 comment | 27 complexity | a3f41af0fbeb0852845b9cac77b020e5 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Ldap\Collection;
  10. use Countable;
  11. use Iterator;
  12. use Zend\Ldap;
  13. use Zend\Ldap\Exception;
  14. use Zend\Stdlib\ErrorHandler;
  15. /**
  16. * Zend\Ldap\Collection\DefaultIterator is the default collection iterator implementation
  17. * using ext/ldap
  18. */
  19. class DefaultIterator implements Iterator, Countable
  20. {
  21. const ATTRIBUTE_TO_LOWER = 1;
  22. const ATTRIBUTE_TO_UPPER = 2;
  23. const ATTRIBUTE_NATIVE = 3;
  24. /**
  25. * LDAP Connection
  26. *
  27. * @var \Zend\Ldap\Ldap
  28. */
  29. protected $ldap = null;
  30. /**
  31. * Result identifier resource
  32. *
  33. * @var resource
  34. */
  35. protected $resultId = null;
  36. /**
  37. * Current result entry identifier
  38. *
  39. * @var resource
  40. */
  41. protected $current = null;
  42. /**
  43. * Number of items in query result
  44. *
  45. * @var int
  46. */
  47. protected $itemCount = -1;
  48. /**
  49. * The method that will be applied to the attribute's names.
  50. *
  51. * @var integer|callable
  52. */
  53. protected $attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
  54. /**
  55. * Constructor.
  56. *
  57. * @param \Zend\Ldap\Ldap $ldap
  58. * @param resource $resultId
  59. * @throws \Zend\Ldap\Exception\LdapException if no entries was found.
  60. * @return DefaultIterator
  61. */
  62. public function __construct(Ldap\Ldap $ldap, $resultId)
  63. {
  64. $this->ldap = $ldap;
  65. $this->resultId = $resultId;
  66. $resource = $ldap->getResource();
  67. ErrorHandler::start();
  68. $this->itemCount = ldap_count_entries($resource, $resultId);
  69. ErrorHandler::stop();
  70. if ($this->itemCount === false) {
  71. throw new Exception\LdapException($this->ldap, 'counting entries');
  72. }
  73. }
  74. public function __destruct()
  75. {
  76. $this->close();
  77. }
  78. /**
  79. * Closes the current result set
  80. *
  81. * @return bool
  82. */
  83. public function close()
  84. {
  85. $isClosed = false;
  86. if (is_resource($this->resultId)) {
  87. ErrorHandler::start();
  88. $isClosed = ldap_free_result($this->resultId);
  89. ErrorHandler::stop();
  90. $this->resultId = null;
  91. $this->current = null;
  92. }
  93. return $isClosed;
  94. }
  95. /**
  96. * Gets the current LDAP connection.
  97. *
  98. * @return \Zend\Ldap\Ldap
  99. */
  100. public function getLDAP()
  101. {
  102. return $this->ldap;
  103. }
  104. /**
  105. * Sets the attribute name treatment.
  106. *
  107. * Can either be one of the following constants
  108. * - Zend\Ldap\Collection\DefaultIterator::ATTRIBUTE_TO_LOWER
  109. * - Zend\Ldap\Collection\DefaultIterator::ATTRIBUTE_TO_UPPER
  110. * - Zend\Ldap\Collection\DefaultIterator::ATTRIBUTE_NATIVE
  111. * or a valid callback accepting the attribute's name as it's only
  112. * argument and returning the new attribute's name.
  113. *
  114. * @param int|callable $attributeNameTreatment
  115. * @return DefaultIterator Provides a fluent interface
  116. */
  117. public function setAttributeNameTreatment($attributeNameTreatment)
  118. {
  119. if (is_callable($attributeNameTreatment)) {
  120. if (is_string($attributeNameTreatment) && !function_exists($attributeNameTreatment)) {
  121. $this->attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
  122. } elseif (is_array($attributeNameTreatment)
  123. && !method_exists($attributeNameTreatment[0], $attributeNameTreatment[1])
  124. ) {
  125. $this->attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
  126. } else {
  127. $this->attributeNameTreatment = $attributeNameTreatment;
  128. }
  129. } else {
  130. $attributeNameTreatment = (int) $attributeNameTreatment;
  131. switch ($attributeNameTreatment) {
  132. case self::ATTRIBUTE_TO_LOWER:
  133. case self::ATTRIBUTE_TO_UPPER:
  134. case self::ATTRIBUTE_NATIVE:
  135. $this->attributeNameTreatment = $attributeNameTreatment;
  136. break;
  137. default:
  138. $this->attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
  139. break;
  140. }
  141. }
  142. return $this;
  143. }
  144. /**
  145. * Returns the currently set attribute name treatment
  146. *
  147. * @return int|callable
  148. */
  149. public function getAttributeNameTreatment()
  150. {
  151. return $this->attributeNameTreatment;
  152. }
  153. /**
  154. * Returns the number of items in current result
  155. * Implements Countable
  156. *
  157. * @return int
  158. */
  159. public function count()
  160. {
  161. return $this->itemCount;
  162. }
  163. /**
  164. * Return the current result item
  165. * Implements Iterator
  166. *
  167. * @return array|null
  168. * @throws \Zend\Ldap\Exception\LdapException
  169. */
  170. public function current()
  171. {
  172. if (!is_resource($this->current)) {
  173. $this->rewind();
  174. }
  175. if (!is_resource($this->current)) {
  176. return;
  177. }
  178. $entry = array('dn' => $this->key());
  179. $berIdentifier = null;
  180. $resource = $this->ldap->getResource();
  181. ErrorHandler::start();
  182. $name = ldap_first_attribute(
  183. $resource, $this->current,
  184. $berIdentifier
  185. );
  186. ErrorHandler::stop();
  187. while ($name) {
  188. ErrorHandler::start();
  189. $data = ldap_get_values_len($resource, $this->current, $name);
  190. ErrorHandler::stop();
  191. if (!$data) {
  192. $data = array();
  193. }
  194. if (isset($data['count'])) {
  195. unset($data['count']);
  196. }
  197. switch ($this->attributeNameTreatment) {
  198. case self::ATTRIBUTE_TO_LOWER:
  199. $attrName = strtolower($name);
  200. break;
  201. case self::ATTRIBUTE_TO_UPPER:
  202. $attrName = strtoupper($name);
  203. break;
  204. case self::ATTRIBUTE_NATIVE:
  205. $attrName = $name;
  206. break;
  207. default:
  208. $attrName = call_user_func($this->attributeNameTreatment, $name);
  209. break;
  210. }
  211. $entry[$attrName] = $data;
  212. ErrorHandler::start();
  213. $name = ldap_next_attribute(
  214. $resource, $this->current,
  215. $berIdentifier
  216. );
  217. ErrorHandler::stop();
  218. }
  219. ksort($entry, SORT_LOCALE_STRING);
  220. return $entry;
  221. }
  222. /**
  223. * Return the result item key
  224. * Implements Iterator
  225. *
  226. * @throws \Zend\Ldap\Exception\LdapException
  227. * @return string|null
  228. */
  229. public function key()
  230. {
  231. if (!is_resource($this->current)) {
  232. $this->rewind();
  233. }
  234. if (is_resource($this->current)) {
  235. $resource = $this->ldap->getResource();
  236. ErrorHandler::start();
  237. $currentDn = ldap_get_dn($resource, $this->current);
  238. ErrorHandler::stop();
  239. if ($currentDn === false) {
  240. throw new Exception\LdapException($this->ldap, 'getting dn');
  241. }
  242. return $currentDn;
  243. } else {
  244. return;
  245. }
  246. }
  247. /**
  248. * Move forward to next result item
  249. * Implements Iterator
  250. *
  251. * @throws \Zend\Ldap\Exception\LdapException
  252. */
  253. public function next()
  254. {
  255. $code = 0;
  256. if (is_resource($this->current) && $this->itemCount > 0) {
  257. $resource = $this->ldap->getResource();
  258. ErrorHandler::start();
  259. $this->current = ldap_next_entry($resource, $this->current);
  260. ErrorHandler::stop();
  261. if ($this->current === false) {
  262. $msg = $this->ldap->getLastError($code);
  263. if ($code === Exception\LdapException::LDAP_SIZELIMIT_EXCEEDED) {
  264. // we have reached the size limit enforced by the server
  265. return;
  266. } elseif ($code > Exception\LdapException::LDAP_SUCCESS) {
  267. throw new Exception\LdapException($this->ldap, 'getting next entry (' . $msg . ')');
  268. }
  269. }
  270. } else {
  271. $this->current = false;
  272. }
  273. }
  274. /**
  275. * Rewind the Iterator to the first result item
  276. * Implements Iterator
  277. *
  278. *
  279. * @throws \Zend\Ldap\Exception\LdapException
  280. */
  281. public function rewind()
  282. {
  283. if (is_resource($this->resultId)) {
  284. $resource = $this->ldap->getResource();
  285. ErrorHandler::start();
  286. $this->current = ldap_first_entry($resource, $this->resultId);
  287. ErrorHandler::stop();
  288. if ($this->current === false
  289. && $this->ldap->getLastErrorCode() > Exception\LdapException::LDAP_SUCCESS
  290. ) {
  291. throw new Exception\LdapException($this->ldap, 'getting first entry');
  292. }
  293. }
  294. }
  295. /**
  296. * Check if there is a current result item
  297. * after calls to rewind() or next()
  298. * Implements Iterator
  299. *
  300. * @return bool
  301. */
  302. public function valid()
  303. {
  304. return (is_resource($this->current));
  305. }
  306. }