/** * DQL CONDITION PARSER * parses the join condition/where/having part of the query string * * @param string $str * @return string */ public function parse($str) { $tmp = trim($str); $parts = Doctrine_Tokenizer::bracketExplode($str, array(' AND '), '(', ')'); if (count($parts) > 1) { $ret = array(); foreach ($parts as $part) { $part = Doctrine_Tokenizer::bracketTrim($part, '(', ')'); $ret[] = $this->parse($part); } $r = implode(' AND ', $ret); } else { $parts = Doctrine_Tokenizer::bracketExplode($str, array(' \\|\\| ', ' OR '), '(', ')'); if (count($parts) > 1) { $ret = array(); foreach ($parts as $part) { $part = Doctrine_Tokenizer::bracketTrim($part, '(', ')'); $ret[] = $this->parse($part); } $r = implode(' OR ', $ret); } else { if (substr($parts[0], 0, 1) == '(' && substr($parts[0], -1) == ')') { return $this->parse(substr($parts[0], 1, -1)); } else { return $this->load($parts[0]); } } } return '(' . $r . ')'; }
public function load($condition) { $condition = trim($condition); $e = Doctrine_Tokenizer::sqlExplode($condition); if (count($e) > 2) { $a = explode('.', $e[0]); $field = array_pop($a); $reference = implode('.', $a); $operator = $e[1]; $value = $e[2]; $alias = $this->query->getTableAlias($reference); $map = $this->query->getAliasDeclaration($reference); $table = $map['table']; // check if value is enumerated value $enumIndex = $table->enumIndex($field, trim($value, "'")); if (substr($value, 0, 1) == '(') { // trim brackets $trimmed = Doctrine_Tokenizer::bracketTrim($value); if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') { // subquery found $q = new Doctrine_Query(); $value = '(' . $q->parseQuery($trimmed)->getQuery() . ')'; } elseif (substr($trimmed, 0, 4) == 'SQL:') { $value = '(' . substr($trimmed, 4) . ')'; } else { // simple in expression found $e = Doctrine_Tokenizer::sqlExplode($trimmed, ','); $value = array(); foreach ($e as $part) { $index = $table->enumIndex($field, trim($part, "'")); if ($index !== false) { $value[] = $index; } else { $value[] = $this->parseLiteralValue($part); } } $value = '(' . implode(', ', $value) . ')'; } } else { if ($enumIndex !== false) { $value = $enumIndex; } else { $value = $this->parseLiteralValue($value); } } switch ($operator) { case '<': case '>': case '=': case '!=': if ($enumIndex !== false) { $value = $enumIndex; } default: $condition = $alias . '.' . $field . ' ' . $operator . ' ' . $value; } } return $condition; }
/** * parse * Parses given field and field value to DQL condition * and parameters. This method should always return * prepared statement conditions (conditions that use * placeholders instead of literal values). * * @param string $alias component alias * @param string $field the field name * @param mixed $value the value of the field * @return void */ public function parseSingle($alias, $field, $value) { if (strpos($value, "'") !== false) { $value = Doctrine_Tokenizer::bracketTrim($value, "'", "'"); $a[] = $alias . '.' . $field . ' LIKE ?'; $this->params[] = $value . '%'; } else { $e2 = explode(' ', $value); foreach ($e2 as $v) { $v = trim($v); $a[] = $alias . '.' . $field . ' LIKE ?'; $this->params[] = $v . '%'; } } return implode(' OR ', $a); }
/** * parses an EXISTS expression * * @param string $where query where part to be parsed * @param boolean $negation whether or not to use the NOT keyword * @return string */ public function parseExists($where, $negation) { $operator = $negation ? 'EXISTS' : 'NOT EXISTS'; $pos = strpos($where, '('); if ($pos == false) { throw new Doctrine_Query_Exception("Unknown expression, expected '('"); } $sub = Doctrine_Tokenizer::bracketTrim(substr($where, $pos)); return $operator . ' (' . $this->query->createSubquery()->parseQuery($sub, false)->getQuery() . ')'; }