_db = $db; $this->_base = is_null($base) ? $this->base() : $base; } /** * Handles pass-through to database methods. Calls to query methods * (query, get, insert, update) are not allowed. Query builder methods * are chainable. * * @param string $method Method name * @param array $args Method arguments * @return mixed */ public function __call($method,array $args) { if (in_array($method,Database_LDAP_Search::$_properties)) { /* // @todo To Implement if ($method === 'validation') { if ( ! isset($this->_validation)) { // Initialize the validation object $this->_validation(); } } */ // Return the property return $this->{'_'.$method}; } elseif (in_array($method,Database_LDAP_Search::$_db_methods)) { // Add pending database call which is executed after query type is determined $this->_db_pending[] = array('name' => $method,'args' => $args); return $this; } else { throw new Kohana_Exception('Invalid method :method called in :class', array(':method' => $method,':class' => get_class($this))); } } private function _build() { $search = new Database_LDAP_Search_Builder_Query(); // Process pending database method calls foreach ($this->_db_pending as $method) { $name = $method['name']; $args = $method['args']; $this->_db_applied[$name] = $name; call_user_func_array(array($search,$name),$args); } return $search; } /** * Figure out the bases */ public function base() { // If the base is set in the configuration file, then just return that. if (! is_null($x=Kohana::$config->load('database.default.connection.database'))) return $x; $x = LDAP::factory('auth'); $u = $x->search(array('')) ->scope('base') ->run(); // Remove the '' base $u = array_pop($u); // Quick validation if ($u->count() > 1) throw HTTP_Exception::factory(501,'We got more than 1 null DN?'); return isset($u['']['namingcontexts']) ? $u['']['namingcontexts'] : array(); } public function deref($val) { $this->_deref = $val; return $this; } /** * Search the LDAP database */ public function run($as_object=FALSE,$object_params=NULL) { $query = array(); // Query Defaults $attrs_only = 0; // Compile our query if ($this->_db_pending) $this->_filter = $this->_build(); $result = array(); foreach ($this->_base as $base) { $search = NULL; if ($this->_lifetime !== NULL AND $this->_db->caching()) { // Set the cache key based on the database instance name and SQL $cache_key = 'Database::query("'.$this->_db.'","'.$base.'","'.$this->_scope.'","'.$this->_filter.'")'; // Read the cache first to delete a possible hit with lifetime <= 0 if (($result = Kohana::cache($cache_key, NULL, $this->_lifetime)) !== NULL AND ! $this->_force_execute) { // Return a cached result $search = new Database_Result_Cached($result, array('b'=>$base,'s'=>$this->_scope,'f'=>$this->_filter), $as_object, $object_params); } } // Search is not cached, OR caching is disabled, so we'll query if (! $search) { switch ($this->_scope) { case 'base': $search = ldap_read($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); break; case 'one': $search = ldap_list($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); break; case 'sub': default: $search = ldap_search($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); break; } $result[$base] = new Database_LDAP_Result(array('l'=>$this->_db->connection(),'r'=>$search),array('b'=>$base,'s'=>$this->_scope,'f'=>$this->_filter),$as_object,$object_params); } } return $result; } public function size_limit($val) { $this->_size_limit = $val; return $this; } public function scope($val) { switch ($val) { case 'base': case 'sub': case 'one': $this->_scope = $val; break; default: throw new Kohana_Exception('Unknown search scope :scope',array(':scope',$val)); } return $this; } public function time_limit($val) { $this->_time_limit = $val; return $this; } } ?>