and_where($column,$op,$value); } /** * Creates a new "AND WHERE" condition for the query. * * @param mixed column name or array($column,$alias) or object * @param string logic operator * @param mixed column value * @return $this */ public function and_where($column,$op,$value) { $this->_where[] = array('AND' => array($column,$op,$value)); return $this; } /** * Creates a new "OR WHERE" condition for the query. * * @param mixed column name or array($column,$alias) or object * @param string logic operator * @param mixed column value * @return $this */ public function or_where($column,$op,$value) { $this->_where[] = array('OR' => array($column,$op,$value)); return $this; } /** * Alias of and_where_open() * * @return $this */ public function where_open() { return $this->and_where_open(); } /** * Opens a new "AND WHERE (...)" grouping. * * @return $this */ public function and_where_open() { $this->_where[] = array('AND' => '('); return $this; } /** * Opens a new "OR WHERE (...)" grouping. * * @return $this */ public function or_where_open() { $this->_where[] = array('OR' => '('); return $this; } public function compile($db = NULL) { $filter = ''; return $this->_compile_conditions($db,$this->_where); } /** * Closes an open "AND WHERE (...)" grouping. * * @return $this */ public function where_close() { return $this->and_where_close(); } /** * Closes an open "AND WHERE (...)" grouping. * * @return $this */ public function and_where_close() { $this->_where[] = array('AND' => ')'); return $this; } /** * Closes an open "OR WHERE (...)" grouping. * * @return $this */ public function or_where_close() { $this->_where[] = array('OR' => ')'); return $this; } /** * Compiles an array of conditions into an LDAP filter. * * @param object Database instance * @param array condition statements * @return string */ protected function _compile_conditions(Database $db,array $conditions,$index=0) { $current_condition = $last_condition = NULL; $filter = ''; $sub = 0; foreach ($conditions as $key => $group) { // If we have been called again, we need to skip ahead, or skip what has been processed if ($key < $index OR $sub) continue; // Process groups of conditions foreach ($group as $logic => $condition) { if ($condition === '(') { $filter .= $this->_compile_conditions($db,$conditions,$key+1); $sub = 1; } elseif ($condition === ')') { if ($index) { // As we return, we'll include our condition switch ($current_condition) { case 'AND': return '(&'.$filter.')'; case 'OR': return '(|'.$filter.')'; default: throw new Kohana_Exception('Condition :condition not handled.',array(':condition'=>$condition)); } } $sub = 0; } else { // We currently cant handle when a condition changes, without brackets. if ($filter AND $current_condition AND $current_condition != $logic) throw new Kohana_Exception('Condition changed without brackets'); $current_condition = $logic; // Split the condition list($column,$op,$value) = $condition; // Database operators are always uppercase $op = strtoupper($op); if ((is_string($value) AND array_key_exists($value,$this->_parameters)) === FALSE) { // Quote the value, it is not a parameter $value = $db->quote($value); } if ($column) { // Apply proper quoting to the column $column = $db->quote_column($column); } // Append the statement to the query $filter .= trim('('.$column.$op.$value.')'); } $last_condition = $condition; } } switch ($current_condition) { case 'AND': return '(&'.$filter.')'; case 'OR': return '(|'.$filter.')'; default: throw new Kohana_Exception('Condition :condition not handled.',array(':condition'=>$condition)); } } } ?>