| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Classes and functions for the LDAP tree. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @author The phpLDAPadmin development team | 
					
						
							|  |  |  |  * @package phpLDAPadmin | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Abstract class which represents the LDAP tree view ; the draw() method | 
					
						
							|  |  |  |  * must be implemented by subclasses | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package phpLDAPadmin | 
					
						
							|  |  |  |  * @subpackage Tree | 
					
						
							|  |  |  |  * @see HTMLTree AJAXTree | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | abstract class Tree { | 
					
						
							|  |  |  | 	# Server that this tree represents
 | 
					
						
							|  |  |  | 	private $server_id = null; | 
					
						
							|  |  |  | 	# List of entries in the tree view cache
 | 
					
						
							|  |  |  | 	protected $entries = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Displays the LDAP tree | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	abstract public function draw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected function __construct($server_id) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->server_id = $server_id; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Create an instance of the tree - this is used when we call this class directly | 
					
						
							|  |  |  | 	 * Tree::getInstance($index) | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return object Tree | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	static public function getInstance($server_id) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$tree = get_cached_item($server_id,'tree'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (! $tree) { | 
					
						
							|  |  |  | 			$server = $_SESSION[APPCONFIG]->getServer($server_id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (! $server) | 
					
						
							|  |  |  | 				return null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			$treeclass = $_SESSION[APPCONFIG]->getValue('appearance','tree'); | 
					
						
							| 
									
										
										
										
											2011-07-27 18:52:53 +00:00
										 |  |  | 			$tree = new $treeclass($server_id); | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			# If we are not logged in, just return the empty tree.
 | 
					
						
							|  |  |  | 			if (is_null($server->getLogin(null))) | 
					
						
							|  |  |  | 				return $tree; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			foreach ($server->getBaseDN(null) as $base) | 
					
						
							| 
									
										
										
										
											2011-07-06 08:49:10 +00:00
										 |  |  | 				if ($base) { | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 					$tree->addEntry($base); | 
					
						
							| 
									
										
										
										
											2011-07-06 08:49:10 +00:00
										 |  |  | 					$baseEntry = $tree->getEntry($base); | 
					
						
							|  |  |  | 					$baseEntry->open(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2011-06-26 10:44:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			set_cached_item($server_id,'tree','null',$tree); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $tree; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Get the Server ID for this tree | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return int Server ID that this tree is for | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	protected function getServerID() { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->server_id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $this->server_id; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Get the server Object for this tree | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return object Server Object for this tree | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	protected function getServer() { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $_SESSION[APPCONFIG]->getServer($this->server_id); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Get the entries that are BaseDN entries. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return array Base DN entries | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function getBaseEntries() { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$return = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		foreach ($this->entries as $details) | 
					
						
							|  |  |  | 			if ($details->isBaseDN()) | 
					
						
							|  |  |  | 				array_push($return,$details); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * This function will take the DN, convert it to lowercase and strip unnessary | 
					
						
							|  |  |  | 	 * commas. This result will be used as the index for the tree object. | 
					
						
							|  |  |  | 	 * Any display of a DN should use the object->dn entry, not the index. | 
					
						
							|  |  |  | 	 * The reason we need to do this is because: | 
					
						
							|  |  |  | 	 * uid=User A,ou=People,c=AU and | 
					
						
							|  |  |  | 	 * uid=User B, ou=PeOpLe, c=au | 
					
						
							|  |  |  | 	 * are infact in the same branch, but PLA will show them inconsistently. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param dn DN to clean | 
					
						
							|  |  |  | 	 * @return dn Lowercase clean DN | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	private function indexDN($dn) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$index = strtolower(implode(',',pla_explode_dn($dn))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED) | 
					
						
							|  |  |  | 			debug_log('Result (%s)',1,0,__FILE__,__LINE__,__METHOD__,$index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $index; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Get a tree entry | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param dn DN to retrieve | 
					
						
							|  |  |  | 	 * @return object Tree DN object | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function getEntry($dn) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$dnlower = $this->indexDN($dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (isset($this->entries[$dnlower])) | 
					
						
							|  |  |  | 			return $this->entries[$dnlower]; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return null; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Add an entry in the tree view ; the entry is added in the | 
					
						
							|  |  |  | 	 * children array of its parent | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param dn DN to add | 
					
						
							|  |  |  | 	 * @param string $dn the dn of the entry to create | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function addEntry($dn) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$server = $this->getServer(); | 
					
						
							|  |  |  | 		$dnlower = $this->indexDN($dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# @todo Temporarily removed, some non-ascii char DNs that do exist, fail here for some reason?
 | 
					
						
							|  |  |  | 		#if (! ($server->dnExists($dn)))
 | 
					
						
							|  |  |  | 		#	return;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (isset($this->entries[$dnlower])) | 
					
						
							|  |  |  | 			debug_dump_backtrace('Calling add entry to an entry that ALREADY exists?',1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED) | 
					
						
							|  |  |  | 			debug_log('New ENTRY (%s).',64,0,__FILE__,__LINE__,__METHOD__,$dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$tree_factory = new TreeItem($server->getIndex(),$dn); | 
					
						
							|  |  |  | 		$tree_factory->setObjectClasses($server->getDNAttrValue($dn,'objectClass')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((($isleaf = $server->getDNAttrValue($dn,'hassubordinates')) && ! strcasecmp($isleaf[0],'false'))) | 
					
						
							|  |  |  | 			$tree_factory->setLeaf(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->entries[$dnlower] = $tree_factory; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Is this entry in a base entry?
 | 
					
						
							|  |  |  | 		if (in_array_ignore_case($dn,$server->getBaseDN(null))) { | 
					
						
							|  |  |  | 			$this->entries[$dnlower]->setBase(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# If the parent entry is not in the tree, we add it. This routine will in itself
 | 
					
						
							|  |  |  | 		# recall this method until we get to the top of the tree (the base).
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			$parent_dn = $server->getContainer($dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (DEBUG_ENABLED) | 
					
						
							|  |  |  | 				debug_log('Parent DNs (%s)',64,0,__FILE__,__LINE__,__METHOD__,$parent_dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if ($parent_dn) { | 
					
						
							|  |  |  | 				$parent_entry = $this->getEntry($parent_dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (! $parent_entry) { | 
					
						
							|  |  |  | 					$this->addEntry($parent_dn); | 
					
						
							|  |  |  | 					$parent_entry = $this->getEntry($parent_dn); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				# Update this DN's parent's children list as well.
 | 
					
						
							|  |  |  | 				$parent_entry->addChild($dn); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Delete an entry from the tree view ; the entry is deleted from the | 
					
						
							|  |  |  | 	 * children array of its parent | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param dn DN to remote | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function delEntry($dn) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$server = $this->getServer(); | 
					
						
							|  |  |  | 		$dnlower = $this->indexDN($dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (isset($this->entries[$dnlower])) | 
					
						
							|  |  |  | 			unset($this->entries[$dnlower]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Delete entry from parent's children as well.
 | 
					
						
							|  |  |  | 		$parent_dn = $server->getContainer($dn); | 
					
						
							|  |  |  | 		$parent_entry = $this->getEntry($parent_dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ($parent_entry) | 
					
						
							|  |  |  | 			$parent_entry->delChild($dn); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Rename an entry in the tree | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param dn Old DN | 
					
						
							|  |  |  | 	 * @param dn New DN | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function renameEntry($dnOLD,$dnNEW) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$server = $this->getServer(); | 
					
						
							|  |  |  | 		$dnlowerOLD = $this->indexDN($dnOLD); | 
					
						
							|  |  |  | 		$dnlowerNEW = $this->indexDN($dnNEW); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->entries[$dnlowerNEW] = $this->entries[$dnlowerOLD]; | 
					
						
							|  |  |  | 		if ($dnlowerOLD != $dnlowerNEW) | 
					
						
							|  |  |  | 			unset($this->entries[$dnlowerOLD]); | 
					
						
							|  |  |  | 		$this->entries[$dnlowerNEW]->rename($dnNEW); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Update the parent's children
 | 
					
						
							|  |  |  | 		$parentNEW = $server->getContainer($dnNEW); | 
					
						
							|  |  |  | 		$parentOLD = $server->getContainer($dnOLD); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$parent_entry = $this->getEntry($parentNEW); | 
					
						
							|  |  |  | 		if ($parent_entry) | 
					
						
							|  |  |  | 			$parent_entry->addChild($dnNEW); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$parent_entry = $this->getEntry($parentOLD); | 
					
						
							|  |  |  | 		if ($parent_entry) | 
					
						
							|  |  |  | 			$parent_entry->delChild($dnOLD); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Read the children of a tree entry | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param dn DN of the entry | 
					
						
							|  |  |  | 	 * @param boolean LDAP Size Limit | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function readChildren($dn,$nolimit=false) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$server = $this->getServer(); | 
					
						
							|  |  |  | 		$dnlower = $this->indexDN($dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (! isset($this->entries[$dnlower])) | 
					
						
							|  |  |  | 			debug_dump_backtrace('Reading children on an entry that isnt set? '.$dnlower,true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$ldap['child_limit'] = $nolimit ? 0 : $_SESSION[APPCONFIG]->getValue('search','size_limit'); | 
					
						
							|  |  |  | 		$ldap['filter'] = $_SESSION[APPCONFIG]->getValue('appearance','tree_filter'); | 
					
						
							|  |  |  | 		$ldap['deref'] = $_SESSION[APPCONFIG]->getValue('deref','tree'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Perform the query to get the children.
 | 
					
						
							|  |  |  | 		$ldap['children'] = $server->getContainerContents($dn,null,$ldap['child_limit'],$ldap['filter'],$ldap['deref']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (! count($ldap['children'])) { | 
					
						
							|  |  |  | 			$this->entries[$dnlower]->unsetSizeLimited(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED) | 
					
						
							|  |  |  | 			debug_log('Children of (%s) are (%s)',64,0,__FILE__,__LINE__,__METHOD__,$dn,$ldap['children']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Relax our execution time, it might take some time to load this
 | 
					
						
							|  |  |  | 		if ($nolimit) | 
					
						
							|  |  |  | 			@set_time_limit($_SESSION[APPCONFIG]->getValue('search','time_limit')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->entries[$dnlower]->readingChildren(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		foreach ($ldap['children'] as $child) { | 
					
						
							|  |  |  | 			if (DEBUG_ENABLED) | 
					
						
							|  |  |  | 				debug_log('Adding (%s)',64,0,__FILE__,__LINE__,__METHOD__,$child); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (! in_array($child,$this->entries[$dnlower]->getChildren())) | 
					
						
							|  |  |  | 				$this->entries[$dnlower]->addChild($child); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->entries[$dnlower]->readingChildren(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (count($this->entries[$dnlower]->getChildren()) == $ldap['child_limit']) | 
					
						
							|  |  |  | 			$this->entries[$dnlower]->setSizeLimited(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			$this->entries[$dnlower]->unsetSizeLimited(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Return the number of children an entry has. Optionally autoread the child entry. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param dn DN of the entry | 
					
						
							|  |  |  | 	 * @param boolean LDAP Size Limit | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	protected function readChildrenNumber($dn,$nolimit=false) { | 
					
						
							|  |  |  | 		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) | 
					
						
							|  |  |  | 			debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$dnlower = $this->indexDN($dn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (! isset($this->entries[$dnlower])) | 
					
						
							|  |  |  | 			debug_dump_backtrace('Reading children on an entry that isnt set?',true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Read the entry if we havent got it yet.
 | 
					
						
							|  |  |  | 		if (! $this->entries[$dnlower]->isLeaf() && ! $this->entries[$dnlower]->getChildren()) | 
					
						
							|  |  |  | 			$this->readChildren($dn,$nolimit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return count($this->entries[$dnlower]->getChildren()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ?>
 |