/** * build a condition for the SQL WHERE clause. * this method call itself recursively. * @param jDaoCondition $cond a condition object which contains conditions data * @param array $fields array of jDaoProperty * @param array $params list of parameters name of the method * @param boolean $withPrefix true if the field name should be preceded by the table name/table alias * @param boolean $principal should be true for the first call, and false for recursive call * @return string a WHERE clause (without the WHERE keyword) * @see jDaoGenerator::buildConditions * @internal */ protected function buildOneSQLCondition($condition, $fields, $params, $withPrefix, $principal = false) { $r = ' '; //direct conditions for the group $first = true; foreach ($condition->conditions as $cond) { if (!$first) { $r .= ' ' . $condition->glueOp . ' '; } $first = false; $prop = $fields[$cond['field_id']]; $pattern = isset($cond['field_pattern']) && !empty($cond['field_pattern']) ? $cond['field_pattern'] : '%s'; if ($withPrefix) { if ($pattern == '%s') { $f = $this->_encloseName($prop->table) . '.' . $this->_encloseName($prop->fieldName); } else { $f = str_replace(array("'", "%s"), array("\\'", $this->_encloseName($prop->table) . '.' . $this->_encloseName($prop->fieldName)), $pattern); } } else { if ($pattern == '%s') { $f = $this->_encloseName($prop->fieldName); } else { $f = str_replace(array("'", "%s"), array("\\'", $this->_encloseName($prop->fieldName)), $pattern); } } $r .= $f . ' '; if ($cond['operator'] == 'IN' || $cond['operator'] == 'NOT IN') { if ($cond['isExpr']) { $phpexpr = $this->_preparePHPCallbackExpr($prop); $phpvalue = 'implode(\',\', array_map( ' . $phpexpr . ', is_array(' . $cond['value'] . ')?' . $cond['value'] . ':array(' . $cond['value'] . ')))'; $value = '(\'.' . $phpvalue . '.\')'; } else { $value = '(' . str_replace("'", "\\'", $cond['value']) . ')'; } $r .= $cond['operator'] . ' ' . $value; } elseif ($cond['operator'] == 'IS NULL' || $cond['operator'] == 'IS NOT NULL') { $r .= $cond['operator'] . ' '; } else { if ($cond['isExpr']) { $value = str_replace("'", "\\'", $cond['value']); // we need to know if the expression is like "$foo" (1) or a thing like "concat($foo,'bla')" (2) // because of the nullability of the parameter. If the value of the parameter is null and the operator // is = or <>, then we need to generate a thing like : // - in case 1: ($foo === null ? 'IS NULL' : '='.$this->_conn->quote($foo)) // - in case 2: '= concat('.($foo === null ? 'NULL' : $this->_conn->quote($foo)).' ,\'bla\')' if ($value[0] == '$') { $value = '\'.' . $this->_preparePHPExpr($value, $prop, !$prop->requiredInConditions, $cond['operator']) . '.\''; } else { foreach ($params as $param) { $value = str_replace('$' . $param, '\'.' . $this->_preparePHPExpr('$' . $param, $prop, !$prop->requiredInConditions) . '.\'', $value); } $value = $cond['operator'] . ' ' . $value; } } else { $value = $cond['operator'] . ' '; if ($cond['operator'] == 'LIKE' || $cond['operator'] == 'NOT LIKE') { $value .= $this->tools->escapeValue('varchar', $cond['value'], false, true); } else { $value .= $this->tools->escapeValue($prop->unifiedType, $cond['value'], false, true); } } $r .= $value; } } //sub conditions foreach ($condition->group as $conditionDetail) { if (!$first) { $r .= ' ' . $condition->glueOp . ' '; } $r .= $this->buildOneSQLCondition($conditionDetail, $fields, $params, $withPrefix); $first = false; } //adds parenthesis around the sql if needed (non empty) if (strlen(trim($r)) > 0 && (!$principal || $principal && $condition->glueOp != 'AND')) { $r = '(' . $r . ')'; } return $r; }