toArray(); } parent::__construct($options); } public function __destruct() { $this->disconnect(); } /** * Gets the base DN under which objects of interest are located * * @return string */ public function getBaseDn() { return $this->_getBaseDn(); } /** * A global LDAP search routine for finding information. * * @param string $filter * @param string $base_dn * @param integer $scope * @param array $attributes * @param string $sort * @return Zend_Ldap_QueryResult * @throws Zend_Ldap_Exception */ public function search($filter, $basedn=null, $scope=self::SEARCH_SCOPE_SUB, array $attributes=array(), $sort=null) { if ($basedn===null) $basedn=$this->getBaseDn(); if ($scope===self::SEARCH_SCOPE_ONE) { $search=@ldap_list($this->getResource(), $basedn, $filter, $attributes); } else if ($scope===self::SEARCH_SCOPE_BASE) { $search=@ldap_read($this->getResource(), $basedn, $filter, $attributes); } else { $search=@ldap_search($this->getResource(), $basedn, $filter, $attributes); } if($search===false) { throw new Zend_Ldap_Exception($this, 'searching: ' . $filter); } if (!is_null($sort) && is_string($sort)) { $isSorted=@ldap_sort($this->getResource(), $search, $sort); if($search===false) { throw new Zend_Ldap_Exception($this, 'sorting: ' . $sort); } } /** * Zend_Ldap_QueryResult */ require_once 'Zend/Ldap/QueryResult.php'; return new Zend_Ldap_QueryResult($this, $search); } /** * Count items found by given filter. * * @param string $filter * @param string $base_dn * @param integer $scope * @return integer * @throws Zend_Ldap_Exception */ public function count($filter, $basedn=null, $scope=self::SEARCH_SCOPE_SUB) { try { $result=$this->search($filter, $basedn, $scope, array('objectClass'), null); } catch (Zend_Ldap_Exception $e) { if ($e->getCode()===Zend_Ldap_Exception::LDAP_NO_SUCH_OBJECT) return 0; else throw $e; } return $result->count(); } /** * Count children for a given DN. * * @param string $dn * @return integer * @throws Zend_Ldap_Exception */ public function countChildren($dn) { return $this->count('(objectClass=*)', $dn, self::SEARCH_SCOPE_ONE); } /** * Check if a given DN exists. * * @param string $dn * @return boolean * @throws Zend_Ldap_Exception */ public function exists($dn) { return ($this->count('(objectClass=*)', $dn, self::SEARCH_SCOPE_BASE)==1); } /** * Search LDAP registry for entries matching filter and optional attributes * * @param string $filter * @param string $base_dn * @param integer $scope * @param array $attributes * @param string $sort * @return array * @throws Zend_Ldap_Exception */ public function searchEntries($filter, $basedn=null, $scope=self::SEARCH_SCOPE_SUB, array $attributes=array(), $sort=null) { $result=$this->search($filter, $basedn, $scope, $attributes, $sort); return $result->toArray(); } /** * Get LDAP entry by DN * * @param string $dn * @param array $attributes * @param boolean $throwOnNotFound * @return array * @throws Zend_Ldap_Exception */ public function getEntry($dn, array $attributes=array(), $throwOnNotFound=false) { try { $result=$this->search("(objectClass=*)", $dn, self::SEARCH_SCOPE_BASE, $attributes, null); return $result->getFirst(); } catch (Zend_Ldap_Exception $e) { if ($throwOnNotFound) throw $e; } return null; } /** * Prepares an ldap data entry array for insert/update operation * * @param array $entry * @return void * @throws InvalidArgumentException */ public static function prepareLdapEntryArray(array &$entry) { if (array_key_exists('dn', $entry)) unset($entry['dn']); foreach ($entry as $key => $value) { if (is_array($value)) { foreach ($value as $i => $v) { if (is_null($v)) unset($value[$i]); else if (empty($v)) unset($value[$i]); else if (!is_scalar($v)) { throw new InvalidArgumentException('Only scalar values allowed in LDAP data'); } } $entry[$key]=array_values($value); } else { if (is_null($value)) $entry[$key]=array(); else if (empty($value)) $entry[$key]=array(); else $entry[$key]=array($value); } } } /** * Add new information to the LDAP repository * * @param string $dn * @param array $entry * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function add($dn, array $entry) { self::prepareLdapEntryArray($entry); foreach ($entry as $key => $value) { if (is_array($value)) { if (count($value)===0) unset($entry[$key]); } } $dnParts=Zend_Ldap_Helper::explodeDn($dn); $rdnParts=array_shift($dnParts); for ($i=0; $igetResource(), $dn, $entry); if($isAdded===false) { throw new Zend_Ldap_Exception($this, 'adding: ' . $dn); } return $this; } /** * Update LDAP registry * * @param string $dn * @param array $entry * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function update($dn, array $entry) { self::prepareLdapEntryArray($entry); $isModified=@ldap_modify($this->getResource(), $dn, $entry); if($isModified===false) { throw new Zend_Ldap_Exception($this, 'updating: ' . $dn); } return $this; } /** * Save entry to LDAP registry. * * Internally decides if entry will be updated to added by calling * {@link exists()}. * * @param string $dn * @param array $entry * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function save($dn, array $entry) { if ($this->exists($dn)) $this->update($dn, $entry); else $this->add($dn, $entry); return $this; } /** * Delete an LDAP entry * * @param string $dn * @param boolean $recursively * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function delete($dn, $recursively=false) { if ($recursively===true) { if ($this->countChildren($dn)>0) { $children=array(); $search=@ldap_list($this->getResource(), $dn, '(objectClass=*)', array('objectClass')); for ($entry=@ldap_first_entry($this->getResource(), $search); $entry!==false; $entry=@ldap_next_entry($this->getResource(), $entry)) { $childDn=@ldap_get_dn($this->getResource(), $entry); if ($childDn===false) { throw new Zend_Ldap_Exception($this, 'getting dn'); } $children[]=$childDn; } @ldap_free_result($search); foreach ($children as $c) { $this->delete($c, true); } } } $isDeleted=@ldap_delete($this->getResource(), $dn); if($isDeleted===false) { throw new Zend_Ldap_Exception($this, 'deleting: ' . $dn); } return $this; } /** * Moves a LDAP entry from one DN to another subtree. * * @param string $from * @param string $to * @param boolean $recursively * @param boolean $alwaysEmulate * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function moveToSubtree($from, $to, $recursively=false, $alwaysEmulate=false) { $orgDnParts=Zend_Ldap_Helper::explodeDn($from); $newParentDnParts=Zend_Ldap_Helper::explodeDn($to); $newDnParts=array_merge(array(array_shift($orgDnParts)), $newParentDnParts); $newDn=Zend_Ldap_Helper::implodeDn($newDnParts); return $this->rename($from, $newDn, $recursively, $alwaysEmulate); } /** * Moves a LDAP entry from one DN to another DN. * * This is an alias for {@link rename()} * * @param string $from * @param string $to * @param boolean $recursively * @param boolean $alwaysEmulate * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function move($from, $to, $recursively=false, $alwaysEmulate=false) { return $this->rename($from, $to, $recursively, $alwaysEmulate); } /** * Renames a LDAP entry from one DN to another DN. * * This method implicitely moves the entry to another location within the tree. * * @param string $from * @param string $to * @param boolean $recursively * @param boolean $alwaysEmulate * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function rename($from, $to, $recursively=false, $alwaysEmulate=false) { $emulate=(bool)$alwaysEmulate; if (!function_exists('ldap_rename')) $emulate=true; else if ($recursively) $emulate=true; if ($emulate===false) { $newDnParts=Zend_Ldap_Helper::explodeDn($to); $newRdn=Zend_Ldap_Helper::implodeRdn(array_shift($newDnParts)); $newParent=Zend_Ldap_Helper::implodeDn($newDnParts); $isOK=@ldap_rename($this->getResource(), $from, $newRdn, $newParent, true); if($isOK===false) { throw new Zend_Ldap_Exception($this, 'renaming ' . $from . ' to ' . $to); } else if (!$this->exists($to)) $emulate=true; } if ($emulate) { $this->copy($from, $to, $recursively); $this->delete($from, $recursively); } return $this; } /** * Copies a LDAP entry from one DN to another subtree. * * @param string $from * @param string $to * @param boolean $recursively * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function copyToSubtree($from, $to, $recursively=false) { $orgDnParts=Zend_Ldap_Helper::explodeDn($from); $newParentDnParts=Zend_Ldap_Helper::explodeDn($to); $newDnParts=array_merge(array(array_shift($orgDnParts)), $newParentDnParts); $newDn=Zend_Ldap_Helper::implodeDn($newDnParts); return $this->copy($from, $newDn, $recursively); } /** * Copies a LDAP entry from one DN to another DN. * * @param string $from * @param string $to * @param boolean $recursively * @return Zend_Ldap_Ext *Provides a fluid interface* * @throws Zend_Ldap_Exception */ public function copy($from, $to, $recursively=false) { $entry=$this->getEntry($from, array(), true); $toDnParts=Zend_Ldap_Helper::explodeDn($to); $this->add($to, $entry); if ($recursively===true && $this->countChildren($from)>0) { $children=array(); $search=@ldap_list($this->getResource(), $from, '(objectClass=*)', array('objectClass')); for ($e=@ldap_first_entry($this->getResource(), $search); $e!==false; $e=@ldap_next_entry($this->getResource(), $e)) { $cdn=@ldap_get_dn($this->getResource(), $e); if ($cdn===false) { throw new Zend_Ldap_Exception($this, 'getting dn'); } $children[]=$cdn; } @ldap_free_result($search); foreach ($children as $c) { $cDnParts=Zend_Ldap_Helper::explodeDn($c); $newChildParts=array_merge(array(array_shift($cDnParts)), $toDnParts); $newChild=Zend_Ldap_Helper::implodeDn($newChildParts); $this->copy($c, $newChild, true); } } return $this; } /** * Returns the specified DN as a Zend_Ldap_Node * * @param string $dn * @return Zend_Ldap_Node * @throws Zend_Ldap_Exception */ public function getNode($dn) { /** * Zend_Ldap_Node */ require_once 'Zend/Ldap/Node.php'; return Zend_Ldap_Node::fromLdap($dn, $this); } /** * Returns the base node as a Zend_Ldap_Node * * @return Zend_Ldap_Node * @throws Zend_Ldap_Exception */ public function getBaseNode() { return $this->getNode($this->getBaseDn(), $this); } }