Search code examples
restyii2

Yii2 API Rest query parameters or condition


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');
    }
}    

Solution

  • You can iterate over the parameter array to modify it.

    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.

    Yii2 operator format docs

    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')...;