'JOIN', self::JOIN_TYPE_LEFT => 'LEFT JOIN', self::JOIN_TYPE_RIGHT => 'RIGHT JOIN', self::JOIN_TYPE_INNER => 'INNER JOIN', self::JOIN_TYPE_OUTER => 'OUTER JOIN', ); private $select = array(); private $distinct = ''; private $where = array(); private $group_by = array(); private $order = array('sort' => array(), 'order' => array()); private $limit = ''; /** * @var SqlModel */ private $model; private $sql_expression; private $sql_expression_params = array(); private $sql_join_expressions = array(); /** * @param $model SqlModel * @param $sql_expression string|null Sql expression with SELECT and FROM operators. If fetched, then SqlCriteria::select(), SqlCriteria::distinct() disabled for use. * @param $sql_expression_params array additional params to be replaced in sql expression */ public function __construct($model, $sql_expression = null, $sql_expression_params = array()) { $this->model = $model; $this->sql_expression = $sql_expression; $this->sql_expression_params = $sql_expression_params; } /** * @return SqlResultProvider */ public function find() { // preparing link expressions (if exists) if ($this->sql_join_expressions) { if (!$this->sql_expression) { $select = $this->model->getDb()->selectExpr($this->select, $this->distinct); $this->sql_expression = 'SELECT ' . $select . ' FROM :table'; } $this->sql_expression .= ' ' . implode(' ', $this->sql_join_expressions); } return $this->model->find($this->select, $this->distinct, $this->where, $this->order, $this->limit, null, $this->group_by, $this->sql_expression, $this->sql_expression_params); } public function delete() { return $this->model->find('', '', $this->where, null, null, null, null, 'DELETE FROM :table', $this->sql_expression_params)->affectedRows(); } public function count() { return $this->model->find(new DbExpr('COUNT(*) as count'), '', $this->where, null, null, null, null, $this->sql_expression, $this->sql_expression_params)->fetchField('count'); } public function join($join_table_name, $join_field_name, $donor_table_name = null, $donor_field_name = null, $join_type = self::JOIN_TYPE_DEFAULT) { $donor_field_name = $donor_field_name ? : $join_field_name; $donor_table_name = $donor_table_name ? : 'table'; $this->sql_join_expressions[] = self::$join_type_to_reserved_keyword[$join_type] . ' :' . $join_table_name . ' ON :' . $donor_table_name . '.' . $donor_field_name . '=' . ':' . $join_table_name . '.' . $join_field_name; $this->sql_expression_params[$join_table_name] = new DbExpr($this->model->identify($join_table_name)); return $this; } /** * @param $cond string|array Condition with "?" placeholder @ex 'field=?' or 'field=1' or array('field=?' => 1', 'field=1') * @param $value string|array|DbExpr|null Value. Array transformed to DbExpr(implode(',' Array)) All elements in the array mast be integer * @return SqlCriteria * @desc Allow multiple calls */ public function where($cond, $value = null) { if (is_null($value)) { if (is_array($cond)) { $this->where = $this->where + $cond; } else { $this->where[] = $cond; } } else { $this->where[$cond] = $value; } return $this; } /** * @param $field string * @param $value array * @return SqlCriteria */ public function whereIn($field, $value) { return $this->where($field . ' in ?', $value); } /** * @param $field string * @param $value array * @return SqlCriteria */ public function whereNotIn($field, $value) { return $this->where($field . ' not in ?', $value); } /** * @param $field string * @param $value array * @return SqlCriteria * @deprecated */ public function whereNot($field, $value) { return $this->whereNotIn($field, $value); } public function groupBy($fields) { if (is_array($fields)) { $this->group_by = $this->group_by + $fields; } else { $this->group_by[] = $fields; } return $this; } /** * @param $field string Field @ex 'field' * @param $order_desc bool Descendant sort direction * @return SqlCriteria * @desc Allow multiple calls */ public function order($field, $order_desc = false) { $this->order['sort'][] = $field; if ($order_desc) { $this->order['order'][$field] = 'desc'; } return $this; } /** * @param $offset int * @param $limit int * @return SqlCriteria */ public function limit($offset = 0, $limit) { if ($offset) { $this->limit = (int) $offset . ','; } $this->limit .= (int) $limit; return $this; } /** * @param string|array $fields * @param bool $convert_to_db_expression * @ex SqlCriteria::select('field') * @ex SqlCriteria->select(array('field1', 'field2')) * @ex SqlCriteria->select('field1,field2') * @return SqlCriteria */ public function select($fields, $convert_to_db_expression = false) { if (!is_array($fields)) { $fields = explode(',', $fields); } $fields = array_map(function($item){return trim($item);},$fields); if ($convert_to_db_expression) { $fields = array_map(function($item){return new DbExpr($item);},$fields); } $this->select = array_merge($this->select,$fields); return $this; } /** * @param $field string|bool If true then distinct by * * @return SqlCriteria */ public function distinct($field) { $this->distinct = $field; return $this; } }