File indexing completed on 2024-12-22 05:36:48

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  * @subpackage Node
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @see Zend_Ldap_Attribute
0025  */
0026 // require_once 'Zend/Ldap/Attribute.php';
0027 /**
0028  * @see Zend_Ldap_Dn
0029  */
0030 // require_once 'Zend/Ldap/Dn.php';
0031 
0032 /**
0033  * Zend_Ldap_Node_Abstract provides a bas eimplementation for LDAP nodes
0034  *
0035  * @category   Zend
0036  * @package    Zend_Ldap
0037  * @subpackage Node
0038  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0039  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0040  */
0041 abstract class Zend_Ldap_Node_Abstract implements ArrayAccess, Countable
0042 {
0043     protected static $_systemAttributes=array('createtimestamp', 'creatorsname',
0044         'entrycsn', 'entrydn', 'entryuuid', 'hassubordinates', 'modifiersname',
0045         'modifytimestamp', 'structuralobjectclass', 'subschemasubentry',
0046         'distinguishedname', 'instancetype', 'name', 'objectcategory', 'objectguid',
0047         'usnchanged', 'usncreated', 'whenchanged', 'whencreated');
0048 
0049     /**
0050      * Holds the node's DN.
0051      *
0052      * @var Zend_Ldap_Dn
0053      */
0054     protected $_dn;
0055 
0056     /**
0057      * Holds the node's current data.
0058      *
0059      * @var array
0060      */
0061     protected $_currentData;
0062 
0063     /**
0064      * Constructor.
0065      *
0066      * Constructor is protected to enforce the use of factory methods.
0067      *
0068      * @param  Zend_Ldap_Dn $dn
0069      * @param  array        $data
0070      * @param  boolean      $fromDataSource
0071      */
0072     protected function __construct(Zend_Ldap_Dn $dn, array $data, $fromDataSource)
0073     {
0074         $this->_dn = $dn;
0075         $this->_loadData($data, $fromDataSource);
0076     }
0077 
0078     /**
0079      * @param  array   $data
0080      * @param  boolean $fromDataSource
0081      * @throws Zend_Ldap_Exception
0082      */
0083     protected function _loadData(array $data, $fromDataSource)
0084     {
0085         if (array_key_exists('dn', $data)) {
0086             unset($data['dn']);
0087         }
0088         ksort($data, SORT_STRING);
0089         $this->_currentData = $data;
0090     }
0091 
0092     /**
0093      * Reload node attributes from LDAP.
0094      *
0095      * This is an online method.
0096      *
0097      * @param  Zend_Ldap $ldap
0098      * @return Zend_Ldap_Node_Abstract Provides a fluent interface
0099      * @throws Zend_Ldap_Exception
0100      */
0101     public function reload(Zend_Ldap $ldap = null)
0102     {
0103         if ($ldap !== null) {
0104             $data = $ldap->getEntry($this->_getDn(), array('*', '+'), true);
0105             $this->_loadData($data, true);
0106         }
0107         return $this;
0108     }
0109 
0110     /**
0111      * Gets the DN of the current node as a Zend_Ldap_Dn.
0112      *
0113      * This is an offline method.
0114      *
0115      * @return Zend_Ldap_Dn
0116      */
0117     protected function _getDn()
0118     {
0119         return $this->_dn;
0120     }
0121 
0122     /**
0123      * Gets the DN of the current node as a Zend_Ldap_Dn.
0124      * The method returns a clone of the node's DN to prohibit modification.
0125      *
0126      * This is an offline method.
0127      *
0128      * @return Zend_Ldap_Dn
0129      */
0130     public function getDn()
0131     {
0132         $dn = clone $this->_getDn();
0133         return $dn;
0134     }
0135 
0136     /**
0137      * Gets the DN of the current node as a string.
0138      *
0139      * This is an offline method.
0140      *
0141      * @param  string $caseFold
0142      * @return string
0143      */
0144     public function getDnString($caseFold = null)
0145     {
0146         return $this->_getDn()->toString($caseFold);
0147     }
0148 
0149     /**
0150      * Gets the DN of the current node as an array.
0151      *
0152      * This is an offline method.
0153      *
0154      * @param  string $caseFold
0155      * @return array
0156      */
0157     public function getDnArray($caseFold = null)
0158     {
0159         return $this->_getDn()->toArray($caseFold);
0160     }
0161 
0162     /**
0163      * Gets the RDN of the current node as a string.
0164      *
0165      * This is an offline method.
0166      *
0167      * @param  string $caseFold
0168      * @return string
0169      */
0170     public function getRdnString($caseFold = null)
0171     {
0172         return $this->_getDn()->getRdnString($caseFold);
0173     }
0174 
0175     /**
0176      * Gets the RDN of the current node as an array.
0177      *
0178      * This is an offline method.
0179      *
0180      * @param  string $caseFold
0181      * @return array
0182      */
0183     public function getRdnArray($caseFold = null)
0184     {
0185         return $this->_getDn()->getRdn($caseFold);
0186     }
0187 
0188     /**
0189      * Gets the objectClass of the node
0190      *
0191      * @return array
0192      */
0193     public function getObjectClass()
0194     {
0195         return $this->getAttribute('objectClass', null);
0196     }
0197 
0198     /**
0199      * Gets all attributes of node.
0200      *
0201      * The collection contains all attributes.
0202      *
0203      * This is an offline method.
0204      *
0205      * @param  boolean $includeSystemAttributes
0206      * @return array
0207      */
0208     public function getAttributes($includeSystemAttributes = true)
0209     {
0210         $data = array();
0211         foreach ($this->getData($includeSystemAttributes) as $name => $value) {
0212             $data[$name] = $this->getAttribute($name, null);
0213         }
0214         return $data;
0215     }
0216 
0217     /**
0218      * Returns the DN of the current node. {@see getDnString()}
0219      *
0220      * @return string
0221      */
0222     public function toString()
0223     {
0224         return $this->getDnString();
0225     }
0226 
0227     /**
0228      * Cast to string representation {@see toString()}
0229      *
0230      * @return string
0231      */
0232     public function __toString()
0233     {
0234         return $this->toString();
0235     }
0236 
0237     /**
0238      * Returns an array representation of the current node
0239      *
0240      * @param  boolean $includeSystemAttributes
0241      * @return array
0242      */
0243     public function toArray($includeSystemAttributes = true)
0244     {
0245         $attributes = $this->getAttributes($includeSystemAttributes);
0246         return array_merge(array('dn' => $this->getDnString()), $attributes);
0247     }
0248 
0249     /**
0250      * Returns a JSON representation of the current node
0251      *
0252      * @param  boolean $includeSystemAttributes
0253      * @return string
0254      */
0255     public function toJson($includeSystemAttributes = true)
0256     {
0257         return json_encode($this->toArray($includeSystemAttributes));
0258     }
0259 
0260     /**
0261      * Gets node attributes.
0262      *
0263      * The array contains all attributes in its internal format (no conversion).
0264      *
0265      * This is an offline method.
0266      *
0267      * @param  boolean $includeSystemAttributes
0268      * @return array
0269      */
0270     public function getData($includeSystemAttributes = true)
0271     {
0272         if ($includeSystemAttributes === false) {
0273             $data = array();
0274             foreach ($this->_currentData as $key => $value) {
0275                 if (!in_array($key, self::$_systemAttributes)) {
0276                     $data[$key] = $value;
0277                 }
0278             }
0279             return $data;
0280         } else {
0281             return $this->_currentData;
0282         }
0283     }
0284 
0285     /**
0286      * Checks whether a given attribute exists.
0287      *
0288      * If $emptyExists is false empty attributes (containing only array()) are
0289      * treated as non-existent returning false.
0290      * If $emptyExists is true empty attributes are treated as existent returning
0291      * true. In this case method returns false only if the attribute name is
0292      * missing in the key-collection.
0293      *
0294      * @param  string  $name
0295      * @param  boolean $emptyExists
0296      * @return boolean
0297      */
0298     public function existsAttribute($name, $emptyExists = false)
0299     {
0300         $name = strtolower($name);
0301         if (isset($this->_currentData[$name])) {
0302             if ($emptyExists) return true;
0303             return count($this->_currentData[$name])>0;
0304         }
0305         else return false;
0306     }
0307 
0308     /**
0309      * Checks if the given value(s) exist in the attribute
0310      *
0311      * @param  string      $attribName
0312      * @param  mixed|array $value
0313      * @return boolean
0314      */
0315     public function attributeHasValue($attribName, $value)
0316     {
0317         return Zend_Ldap_Attribute::attributeHasValue($this->_currentData, $attribName, $value);
0318     }
0319 
0320     /**
0321      * Gets a LDAP attribute.
0322      *
0323      * This is an offline method.
0324      *
0325      * @param  string  $name
0326      * @param  integer $index
0327      * @return mixed
0328      * @throws Zend_Ldap_Exception
0329      */
0330     public function getAttribute($name, $index = null)
0331     {
0332         if ($name == 'dn') {
0333             return $this->getDnString();
0334         }
0335         else {
0336             return Zend_Ldap_Attribute::getAttribute($this->_currentData, $name, $index);
0337         }
0338     }
0339 
0340     /**
0341      * Gets a LDAP date/time attribute.
0342      *
0343      * This is an offline method.
0344      *
0345      * @param  string  $name
0346      * @param  integer $index
0347      * @return array|integer
0348      * @throws Zend_Ldap_Exception
0349      */
0350     public function getDateTimeAttribute($name, $index = null)
0351     {
0352         return Zend_Ldap_Attribute::getDateTimeAttribute($this->_currentData, $name, $index);
0353     }
0354 
0355     /**
0356      * Sets a LDAP attribute.
0357      *
0358      * This is an offline method.
0359      *
0360      * @param  string $name
0361      * @param  mixed  $value
0362      * @return null
0363      * @throws BadMethodCallException
0364      */
0365     public function __set($name, $value)
0366     {
0367         throw new BadMethodCallException();
0368     }
0369 
0370     /**
0371      * Gets a LDAP attribute.
0372      *
0373      * This is an offline method.
0374      *
0375      * @param  string $name
0376      * @return array
0377      * @throws Zend_Ldap_Exception
0378      */
0379     public function __get($name)
0380     {
0381         return $this->getAttribute($name, null);
0382     }
0383 
0384     /**
0385      * Deletes a LDAP attribute.
0386      *
0387      * This method deletes the attribute.
0388      *
0389      * This is an offline method.
0390      *
0391      * @param  string $name
0392      * @return null
0393      * @throws BadMethodCallException
0394      */
0395     public function __unset($name)
0396     {
0397         throw new BadMethodCallException();
0398     }
0399 
0400     /**
0401      * Checks whether a given attribute exists.
0402      *
0403      * Empty attributes will be treated as non-existent.
0404      *
0405      * @param  string $name
0406      * @return boolean
0407      */
0408     public function __isset($name)
0409     {
0410         return $this->existsAttribute($name, false);
0411     }
0412 
0413     /**
0414      * Sets a LDAP attribute.
0415      * Implements ArrayAccess.
0416      *
0417      * This is an offline method.
0418      *
0419      * @param  string $name
0420      * @param  mixed  $value
0421      * @return null
0422      * @throws BadMethodCallException
0423      */
0424     public function offsetSet($name, $value)
0425     {
0426         throw new BadMethodCallException();
0427     }
0428 
0429     /**
0430      * Gets a LDAP attribute.
0431      * Implements ArrayAccess.
0432      *
0433      * This is an offline method.
0434      *
0435      * @param  string $name
0436      * @return array
0437      * @throws Zend_Ldap_Exception
0438      */
0439     public function offsetGet($name)
0440     {
0441         return $this->getAttribute($name, null);
0442     }
0443 
0444     /**
0445      * Deletes a LDAP attribute.
0446      * Implements ArrayAccess.
0447      *
0448      * This method deletes the attribute.
0449      *
0450      * This is an offline method.
0451      *
0452      * @param  string $name
0453      * @return null
0454      * @throws BadMethodCallException
0455      */
0456     public function offsetUnset($name)
0457     {
0458         throw new BadMethodCallException();
0459     }
0460 
0461     /**
0462      * Checks whether a given attribute exists.
0463      * Implements ArrayAccess.
0464      *
0465      * Empty attributes will be treated as non-existent.
0466      *
0467      * @param  string $name
0468      * @return boolean
0469      */
0470     public function offsetExists($name)
0471     {
0472         return $this->existsAttribute($name, false);
0473     }
0474 
0475     /**
0476      * Returns the number of attributes in node.
0477      * Implements Countable
0478      *
0479      * @return int
0480      */
0481     public function count()
0482     {
0483         return count($this->_currentData);
0484     }
0485 }