$val) { if (is_int($key)) # Full expression $cond = $val; else { # Key => Val expression if (is_string($val) and strlen($val) and $val[0] == ":") $cond = $key." = ".$val; else { if (substr($key, -4) == " not") { # Negation $key = substr($key, 0, -4); $param = str_replace(array("(", ")"), "_", $key); if (is_array($val)) $cond = $key." NOT IN ".self::build_in($val); elseif ($val === null) $cond = $key." IS NOT NULL"; else { $cond = $key." != :".$param; $params[":".$param] = $val; } } elseif (substr($key, -5) == " like") { # LIKE $key = substr($key, 0, -5); $param = str_replace(array("(", ")"), "_", $key); $cond = $key." LIKE :".$param; $params[":".$param] = $val; } elseif (substr($key, -9) == " not like") { # NOT LIKE $key = substr($key, 0, -9); $param = str_replace(array("(", ")"), "_", $key); $cond = $key." NOT LIKE :".$param; $params[":".$param] = $val; } elseif (substr_count($key, " ")) { # Custom operation, e.g. array("foo >" => $bar) list($param,) = explode(" ", $key); $param = str_replace(array("(", ")"), "_", $param); $cond = $key." :".$param; $params[":".$param] = $val; } else { # Equation if (is_array($val)) $cond = $key." IN ".self::build_in($val); elseif ($val === null) $cond = $key." IS NULL"; else { $param = str_replace(array("(", ")"), "_", $key); $cond = $key." = :".$param; $params[":".$param] = $val; } } } } if ($tables) self::tablefy($cond, $tables); $conditions[] = $cond; } return $conditions; } public static function build_in($vals) { $return = array(); foreach ($vals as $val) $return[] = SQL::current()->escape($val); return "(".join(",", $return).")"; } /** * Function: build_select * Creates a full SELECT query. */ public static function build_select($tables, $fields, $conds, $order = null, $limit = null, $offset = null, $group = null, $left_join = array(), &$params = array()) { $query = "SELECT ".self::build_select_header($fields, $tables)."\n". "FROM ".self::build_from($tables)."\n"; foreach ($left_join as $join) $query.= "LEFT JOIN __".$join["table"]." ON ".self::build_where($join["where"], $join["table"], $params)."\n"; $query.= ($conds ? "WHERE ".self::build_where($conds, $tables, $params) : "")."\n". ($group ? "GROUP BY ".self::build_group($group, $tables) : "")."\n". ($order ? "ORDER BY ".self::build_order($order, $tables) : "")."\n". self::build_limits($offset, $limit); return $query; } /** * Function: tablefy * Automatically prepends tables and table prefixes to a field if it doesn't already have them. * * Parameters: * $field - The field to "tablefy". * $tables - An array of tables. The first one will be used for prepending. */ public static function tablefy(&$field, $tables) { if (!preg_match_all("/(\(|[\s]+|^)(?!__)([a-z0-9_\.\*]+)(\)|[\s]+|$)/", $field, $matches)) return; foreach ($matches[0] as $index => $full) { $before = $matches[1][$index]; $name = $matches[2][$index]; $after = $matches[3][$index]; if (is_numeric($name)) continue; # Does it not already have a table specified? if (!substr_count($full, ".")) { # Don't replace things that are already either prefixed or paramized. $field = preg_replace("/([^\.:'\"_]|^)".preg_quote($full, "/")."/", "\\1".$before."__".$tables[0].".".$name.$after, $field, 1); } else { # Okay, it does, but is the table prefixed? if (substr($full, 0, 2) != "__") { # Don't replace things that are already either prefixed or paramized. $field = preg_replace("/([^\.:'\"_]|^)".preg_quote($full, "/")."/", "\\1".$before."__".$name.$after, $field, 1); } } } $field = preg_replace("/AS ([^ ]+)\./i", "AS ", $field); } }