I'm developing an API REST application with Yii2 and I have this query problem:
I receive a get request by url with two params like this:
http://localhost/yii2/rest/web/index.php/v1/functions/search?name=test&code=int
I would like to treat the get params with an Or condition in my SQL query, instead of an And condition.
I know that using this way it works:
$provider = new ActiveDataProvider([
'query' => $model->find()->select('idFunction')->where(['or',['name'=>'test'],['code'=>'int']]),
'pagination' => false
]);
But this way doesn't work. It behaves as an And condition:
$provider = new ActiveDataProvider([
'query' => $model->find()->select('idFunction')->where(['or',$params]),
'pagination' => false
]);
I think it has to do the way the variable $params
is converted.
Here is my entire code:
public function actionSearch()
{
$params = \Yii::$app->request->queryParams;
exit(print_r($params));
if (!empty($params)) {
$model = new $this->modelClass;
foreach ($params as $key => $value) {
if (!$model->hasAttribute($key)) {
throw new \yii\web\HttpException(404, 'Invalid attribute:' . $key);
}
}
try {
$provider = new ActiveDataProvider([
'query' => $model->find()->select('idFunction')->where(['or',$params]),
'pagination' => false
]);
} catch (Exception $ex) {
throw new \yii\web\HttpException(500, 'Internal server error');
}
if ($provider->getCount() <= 0) {
throw new \yii\web\HttpException(404, 'No entries found with this query string');
} else {
return $provider;
}
} else {
throw new \yii\web\HttpException(400, 'There are no query string');
}
}
Using array_unshift($conditions, 'or')
like I suggested on the comments does not work. The method expects an array where each element, except the operand itself, is itself, an array with only one element.
Something that works, I just tried, but it isn't very pretty, is to iterate over the elements and return an array of the expected form.
$orQuery = ['or'];
foreach ($params as $key => $value) {
$orQuery[] = [$key => $value];
}
$query->where($orQuery);
This returns the array that the query()
method expects.
['or', ['name1' => 'value1'], ['name2' => 'value2'], ...]
That produces the SQL:
SELECT * FROM table WHERE ('name1'='value1') OR ('name2'='value2')...;