_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(); } /** * Enables the query to be cached for a specified amount of time. * * @param integer $lifetime number of seconds to cache, 0 deletes it from the cache * @param boolean whether or not to execute the query during a cache hit * @return $this * @uses Kohana::$cache_life */ public function cached($lifetime=NULL,$force=FALSE) { if ($lifetime === NULL) { // Use the global setting $lifetime = Kohana::$cache_life; } $this->_force_execute = $force; $this->_lifetime = $lifetime; return $this; } 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) { $result[$base] = 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 (($search = Kohana::cache($cache_key, NULL, $this->_lifetime)) !== NULL AND ! $this->_force_execute) { // Return a cached result $result[$base] = new Database_LDAP_Result_Cached($search, 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 (! $result[$base]) { 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); // Cache the result array if (isset($cache_key) AND $this->_lifetime > 0) Kohana::cache($cache_key,$result[$base]->as_array(),$this->_lifetime); } } 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; } } ?>