/** * WHERE part of the query. * * The method requires a $condition parameter, and optionally a $params parameter * specifying the values to be bound to the query. * * The $condition parameter should be either a string (e.g. 'id=1') or an array. * Key-value must be in one of the following format: * * - key values: `['column1' => value1, 'column2' => value2, ...]` * - operator based: `[column, value, operator, (tableAlias)]` * - bind params: `[queryString, param1 => value1, param2 => value2, ...]` * * In key-value presentation this generates the following SQL expression in general: * `column1=value1 AND column2=value2 AND ...`. It could replace findByAttributes() * In case when a value is an array, an `IN` expression will be generated. * And if a value is null, `IS NULL` will be used. * Examples: * - `['type' => 1, 'status' => 2]` generates `type = 1 AND status = 2`. * - `['id' => [1, 2, 3], 'status' => 2]` generates `id IN (1, 2, 3) AND status = 2`. * - `['status' => null] generates `status IS NULL` * * A condition in operator format the oparator need to be in $this->operators or * - `['<', 'ctime', time()]` generates `ctime < 1431233223`. * - `['IN', 'id'm [1,2,3]]` generates `id IN (1, 2, 3)`. * - `['LIKE', 'q', 'michael'] generates `q LIKE '%michael%'` * - `['=', 'name', 'michael'] generates `name = 'michael'` * * The Bind params presentation will use a string the has `:param` in it. No * variables should be concatenated into this string. The :param parts will * be filled with key value from the rest of the array. eg. * - `['user.name = :user OR email = :email, 'user'=>'michael','email'=>'*****@*****.**']` * - `['ctime != mtime AND ctime < :time', 'time' => time()]` * - `[''(ctime > :time || mtime < :time) AND delete=1', 'time'=>time()]` * * @param string|array $condition the conditions that should be put in the WHERE part. * @param string|boolean $merge 'AND'|'OR'|true add condition to previously added criteria * @return static the query object itself * @see andWhere() * @see orWhere() */ public function where($condition, $merge = null) { $criteria = FindCriteria::newInstance(); if (!isset($condition[0])) { // key value pairs foreach ($condition as $field => $value) { if (is_array($value)) { $criteria->addInCondition($field, $value); } else { $criteria->addCondition($field, $value); } } } elseif (!isset($condition[1])) { //string + bind params $criteria->addRawCondition($condition[0]); array_shift($condition); foreach ($condition as $param => $value) { $criteria->addBindParameter(':' . $param, $value); } } else { // condition specified $operator = strtoupper($condition[0]); if (in_array($operator, $this->operators)) { $alias = isset($condition[3]) ? $condition[3] : 't'; switch ($operator) { case 'IN': $criteria->addInCondition($condition[1], $condition[2], $alias); break; case 'NOT IN': $criteria->addInCondition($condition[1], $condition[2], $alias, true, true); break; case 'LIKE': $criteria->addSearchCondition($condition[1], $condition[2], $alias); break; case 'NOT LIKE': $criteria->addSearchCondition($condition[1], $condition[2], $alias, true, true); break; default: $criteria->addCondition($condition[1], $condition[2], $operator, $alias); } } else { throw new \Exception('Found unknown operator in query: ' . $operator); } } if ($merge === true) { return $criteria; } if ($merge !== null && $this->criteria !== null) { if ($merge === 'AND') { $this->criteria->mergeWith($criteria, true); } if ($merge === 'OR') { $this->criteria->mergeWith($criteria, false); } } else { $this->criteria = $criteria; } return $this; }
/** * Merge an other FindCriteria object together with this FindCriteria object. * Then returns the complete merged FindCriteria object. * * @param FindCriteria $criteria The FindCriteria object that needs to be merged with this FindCriteria object. * @param Boolean $useAnd True for 'AND', false for 'OR'. Default: true. * @return FindCriteria The complete FindCriteria object is given as a return value. */ public function mergeWith(FindCriteria $criteria, $useAnd = true) { $condition = $criteria->getCondition(); if (!empty($condition)) { $operator = $useAnd ? 'AND' : 'OR'; $thisCondition = $this->getCondition(); if (!empty($thisCondition)) { $this->_condition = ' (' . $thisCondition . ') ' . $operator . ' (' . $condition . ')'; } else { $this->_condition = '(' . $condition . ')'; } } //always merge params. FindParams::join can add params without a condtion. $this->_params = array_merge($this->getParams(), $criteria->getParams()); return $this; }