File indexing completed on 2025-03-02 05:29:31

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Ldap
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /**
0023  * Zend_Ldap_Collection_Iterator_Default is the default collection iterator implementation
0024  * using ext/ldap
0025  *
0026  * @category   Zend
0027  * @package    Zend_Ldap
0028  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0029  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0030  */
0031 class Zend_Ldap_Collection_Iterator_Default implements Iterator, Countable
0032 {
0033     const ATTRIBUTE_TO_LOWER  = 1;
0034     const ATTRIBUTE_TO_UPPER  = 2;
0035     const ATTRIBUTE_NATIVE    = 3;
0036 
0037     /**
0038      * LDAP Connection
0039      *
0040      * @var Zend_Ldap
0041      */
0042     protected $_ldap = null;
0043 
0044     /**
0045      * Result identifier resource
0046      *
0047      * @var resource
0048      */
0049     protected $_resultId = null;
0050 
0051     /**
0052      * Current result entry identifier
0053      *
0054      * @var resource
0055      */
0056     protected $_current = null;
0057 
0058     /**
0059      * Number of items in query result
0060      *
0061      * @var integer
0062      */
0063     protected $_itemCount = -1;
0064 
0065     /**
0066      * The method that will be applied to the attribute's names.
0067      *
0068      * @var  integer|callback
0069      */
0070     protected $_attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
0071 
0072     /**
0073      * Constructor.
0074      *
0075      * @param  Zend_Ldap $ldap
0076      * @param  resource  $resultId
0077      * @return void
0078      */
0079     public function __construct(Zend_Ldap $ldap, $resultId)
0080     {
0081         $this->_ldap = $ldap;
0082         $this->_resultId = $resultId;
0083         $this->_itemCount = @ldap_count_entries($ldap->getResource(), $resultId);
0084         if ($this->_itemCount === false) {
0085             /**
0086              * @see Zend_Ldap_Exception
0087              */
0088             // require_once 'Zend/Ldap/Exception.php';
0089             throw new Zend_Ldap_Exception($this->_ldap, 'counting entries');
0090         }
0091     }
0092 
0093     public function __destruct()
0094     {
0095         $this->close();
0096     }
0097 
0098     /**
0099      * Closes the current result set
0100      *
0101      * @return bool
0102      */
0103     public function close()
0104     {
0105         $isClosed = false;
0106         if (is_resource($this->_resultId)) {
0107              $isClosed = @ldap_free_result($this->_resultId);
0108              $this->_resultId = null;
0109              $this->_current = null;
0110         }
0111         return $isClosed;
0112     }
0113 
0114     /**
0115      * Gets the current LDAP connection.
0116      *
0117      * @return Zend_Ldap
0118      */
0119     public function getLdap()
0120     {
0121         return $this->_ldap;
0122     }
0123 
0124     /**
0125      * Sets the attribute name treatment.
0126      *
0127      * Can either be one of the following constants
0128      * - Zend_Ldap_Collection_Iterator_Default::ATTRIBUTE_TO_LOWER
0129      * - Zend_Ldap_Collection_Iterator_Default::ATTRIBUTE_TO_UPPER
0130      * - Zend_Ldap_Collection_Iterator_Default::ATTRIBUTE_NATIVE
0131      * or a valid callback accepting the attribute's name as it's only
0132      * argument and returning the new attribute's name.
0133      *
0134      * @param  integer|callback $attributeNameTreatment
0135      * @return Zend_Ldap_Collection_Iterator_Default Provides a fluent interface
0136      */
0137     public function setAttributeNameTreatment($attributeNameTreatment)
0138     {
0139         if (is_callable($attributeNameTreatment)) {
0140             if (is_string($attributeNameTreatment) && !function_exists($attributeNameTreatment)) {
0141                 $this->_attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
0142             } else if (is_array($attributeNameTreatment) &&
0143                     !method_exists($attributeNameTreatment[0], $attributeNameTreatment[1])) {
0144                 $this->_attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
0145             } else {
0146                 $this->_attributeNameTreatment = $attributeNameTreatment;
0147             }
0148         } else {
0149             $attributeNameTreatment = (int)$attributeNameTreatment;
0150             switch ($attributeNameTreatment) {
0151                 case self::ATTRIBUTE_TO_LOWER:
0152                 case self::ATTRIBUTE_TO_UPPER:
0153                 case self::ATTRIBUTE_NATIVE:
0154                     $this->_attributeNameTreatment = $attributeNameTreatment;
0155                     break;
0156                 default:
0157                     $this->_attributeNameTreatment = self::ATTRIBUTE_TO_LOWER;
0158                     break;
0159             }
0160         }
0161         return $this;
0162     }
0163 
0164     /**
0165      * Returns the currently set attribute name treatment
0166      *
0167      * @return integer|callback
0168      */
0169     public function getAttributeNameTreatment()
0170     {
0171         return $this->_attributeNameTreatment;
0172     }
0173 
0174     /**
0175      * Returns the number of items in current result
0176      * Implements Countable
0177      *
0178      * @return int
0179      */
0180     public function count()
0181     {
0182         return $this->_itemCount;
0183     }
0184 
0185     /**
0186      * Return the current result item
0187      * Implements Iterator
0188      *
0189      * @return array|null
0190      * @throws Zend_Ldap_Exception
0191      */
0192     public function current()
0193     {
0194         if (!is_resource($this->_current)) {
0195             $this->rewind();
0196         }
0197         if (!is_resource($this->_current)) {
0198             return null;
0199         }
0200 
0201         $entry = array('dn' => $this->key());
0202         $ber_identifier = null;
0203         $name = @ldap_first_attribute($this->_ldap->getResource(), $this->_current,
0204             $ber_identifier);
0205         while ($name) {
0206             $data = @ldap_get_values_len($this->_ldap->getResource(), $this->_current, $name);
0207             unset($data['count']);
0208 
0209             switch($this->_attributeNameTreatment) {
0210                 case self::ATTRIBUTE_TO_LOWER:
0211                     $attrName = strtolower($name);
0212                     break;
0213                 case self::ATTRIBUTE_TO_UPPER:
0214                     $attrName = strtoupper($name);
0215                     break;
0216                 case self::ATTRIBUTE_NATIVE:
0217                     $attrName = $name;
0218                     break;
0219                 default:
0220                     $attrName = call_user_func($this->_attributeNameTreatment, $name);
0221                     break;
0222             }
0223             $entry[$attrName] = $data;
0224             $name = @ldap_next_attribute($this->_ldap->getResource(), $this->_current,
0225                 $ber_identifier);
0226         }
0227         ksort($entry, SORT_LOCALE_STRING);
0228         return $entry;
0229     }
0230 
0231     /**
0232      * Return the result item key
0233      * Implements Iterator
0234      *
0235      * @return string|null
0236      */
0237     public function key()
0238     {
0239         if (!is_resource($this->_current)) {
0240             $this->rewind();
0241         }
0242         if (is_resource($this->_current)) {
0243             $currentDn = @ldap_get_dn($this->_ldap->getResource(), $this->_current);
0244             if ($currentDn === false) {
0245                 /** @see Zend_Ldap_Exception */
0246                 // require_once 'Zend/Ldap/Exception.php';
0247                 throw new Zend_Ldap_Exception($this->_ldap, 'getting dn');
0248             }
0249             return $currentDn;
0250         } else {
0251             return null;
0252         }
0253     }
0254 
0255     /**
0256      * Move forward to next result item
0257      * Implements Iterator
0258      *
0259      * @throws Zend_Ldap_Exception
0260      */
0261     public function next()
0262     {
0263         if (is_resource($this->_current) && $this->_itemCount > 0) {
0264             $this->_current = @ldap_next_entry($this->_ldap->getResource(), $this->_current);
0265             /** @see Zend_Ldap_Exception */
0266             // require_once 'Zend/Ldap/Exception.php';
0267             if ($this->_current === false) {
0268                 $msg = $this->_ldap->getLastError($code);
0269                 if ($code === Zend_Ldap_Exception::LDAP_SIZELIMIT_EXCEEDED) {
0270                     // we have reached the size limit enforced by the server
0271                     return;
0272                 } else if ($code > Zend_Ldap_Exception::LDAP_SUCCESS) {
0273                      throw new Zend_Ldap_Exception($this->_ldap, 'getting next entry (' . $msg . ')');
0274                 }
0275             }
0276         } else {
0277             $this->_current = false;
0278         }
0279     }
0280 
0281     /**
0282      * Rewind the Iterator to the first result item
0283      * Implements Iterator
0284      *
0285      * @throws Zend_Ldap_Exception
0286      */
0287     public function rewind()
0288     {
0289         if (is_resource($this->_resultId)) {
0290             $this->_current = @ldap_first_entry($this->_ldap->getResource(), $this->_resultId);
0291             /** @see Zend_Ldap_Exception */
0292             // require_once 'Zend/Ldap/Exception.php';
0293             if ($this->_current === false &&
0294                     $this->_ldap->getLastErrorCode() > Zend_Ldap_Exception::LDAP_SUCCESS) {
0295                 throw new Zend_Ldap_Exception($this->_ldap, 'getting first entry');
0296             }
0297         }
0298     }
0299 
0300     /**
0301      * Check if there is a current result item
0302      * after calls to rewind() or next()
0303      * Implements Iterator
0304      *
0305      * @return boolean
0306      */
0307     public function valid()
0308     {
0309         return (is_resource($this->_current));
0310     }
0311 
0312 }