web-dev-qa-db-fra.com

Yii2 REST question

Hy. J'ai un ProductController qui étend le yii\rest\ActiveController . La question est que comment puis-je faire des requêtes via la requête HTTP GET.

Comme: http: //api.test.loc/v1/products/search? Name = iphone

Et l’objet de retour contient tous les produits portant le nom iphone.

18
Kedves Hunor

Ok, je l'ai compris, il suffit de mettre cela dans votre contrôleur et de modifier le routeur URL dans la configuration.

public function actionSearch()
{
    if (!empty($_GET)) {
        $model = new $this->modelClass;
        foreach ($_GET as $key => $value) {
            if (!$model->hasAttribute($key)) {
                throw new \yii\web\HttpException(404, 'Invalid attribute:' . $key);
            }
        }
        try {
            $provider = new ActiveDataProvider([
                'query' => $model->find()->where($_GET),
                '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');
    }
}

Et la règle d'URL (modifier)

'urlManager' => [
        'enablePrettyUrl' => true,
        'enableStrictParsing' => true,
        'showScriptName' => false,
        'rules' => [
            ['class' => 'yii\rest\UrlRule', 'controller' => ['v1/product'], 'extraPatterns' => ['GET search' => 'search']],
        ],
    ],
25
Kedves Hunor

Je ne recommanderais pas d'utiliser Superglobals $ _GET directement. Au lieu de cela, vous pouvez utiliser Yii :: $ app-> request-> get ().

Voici un exemple d'utilisation d'une action de recherche générique dans le contrôleur.

À la fin du contrôleur

public function actions() {

$actions = [
    'search' => [
        'class'       => 'app\[YOUR NAMESPACE]\SearchAction',
        'modelClass'  => $this->modelClass,
        'checkAccess' => [$this, 'checkAccess'],
        'params'      => \Yii::$app->request->get()
    ],
];

return array_merge(parent::actions(), $actions);
}

public function verbs() {

    $verbs = [
        'search'   => ['GET']
    ];
    return array_merge(parent::verbs(), $verbs);
}

Action de recherche personnalisée

<?php

namespace app\[YOUR NAMESPACE];

use Yii;
use yii\data\ActiveDataProvider;
use yii\rest\Action;


class SearchAction extends Action {

    /**
     * @var callable a PHP callable that will be called to prepare a data provider that
     * should return a collection of the models. If not set, [[prepareDataProvider()]] will be used instead.
     * The signature of the callable should be:
     *
     * ```php
     * function ($action) {
     *     // $action is the action object currently running
     * }
     * ```
     *
     * The callable should return an instance of [[ActiveDataProvider]].
     */
    public $prepareDataProvider;
    public $params;

    /**
     * @return ActiveDataProvider
     */
    public function run() {
        if ($this->checkAccess) {
            call_user_func($this->checkAccess, $this->id);
        }

        return $this->prepareDataProvider();
    }

    /**
     * Prepares the data provider that should return the requested collection of the models.
     * @return ActiveDataProvider
     */
    protected function prepareDataProvider() {
        if ($this->prepareDataProvider !== null) {
            return call_user_func($this->prepareDataProvider, $this);
        }

        /**
         * @var \yii\db\BaseActiveRecord $modelClass
         */
        $modelClass = $this->modelClass;

        $model = new $this->modelClass([
        ]);

        $safeAttributes = $model->safeAttributes();
        $params = array();

        foreach($this->params as $key => $value){
            if(in_array($key, $safeAttributes)){
               $params[$key] = $value;                
            }
        }

        $query = $modelClass::find();

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        if (empty($params)) {
            return $dataProvider;
        }


        foreach ($params as $param => $value) {
            $query->andFilterWhere([
                $param => $value,
            ]);
        }

        return $dataProvider;
    }

}
8
Rx Seven

Dans Config/web.php -> Add 'extraPatterns' => ['GET search' => 'search']

'urlManager' => [
        'enablePrettyUrl' => true,
        'showScriptName' => false,
        'rules' => [['class' => 'yii\rest\UrlRule', 'controller' => 'v1/basicinfo', 'pluralize'=>false,'extraPatterns' => ['GET search' => 'search']]]]

** Au repos Api Controller: - Moduels/v1/contrôleurs/** 

basicinfo: - Votre nom de contrôleur, son nom et votre âge sont-ils votre nom de champs.Vous pouvez ajouter tous les paramètres existants dans votre table.

URL de recherche LIKE: - basicinfo/search? Name = yogi & age = 12-23

Include utilise yii\data\ActiveDataProvider;

 public function actionSearch()
{
    if (!empty($_GET)) {
        $model = new $this->modelClass;
        foreach ($_GET as $key => $value) {
            if (!$model->hasAttribute($key)) {
                throw new \yii\web\HttpException(404, 'Invalid attribute:' . $key);
            }
        }
        try {

           $query = $model->find();
            foreach ($_GET as $key => $value) {
                 if ($key != 'age') {
                    $query->andWhere(['like', $key, $value]);
                  }
                  if ($key == 'age') {
                  $agevalue = explode('-',$value);
                  $query->andWhere(['between', $key,$agevalue[0],$agevalue[1]]);

             }

            }

            $provider = new ActiveDataProvider([
                'query' => $query,
                'sort' => [
                    'defaultOrder' => [
                        'updated_by'=> SORT_DESC
                    ]
                ],
                  'pagination' => [
                'defaultPageSize' => 20,
            ],
            ]);
        } 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');
    }
}
2
Gaurav verma

Depuis yii 2.0.13, yii\rest\IndexAction a une nouvelle propriété, - dataFilter, ce qui simplifie le processus de filtrage. Par défaut, ActiveController utilise yii\rest\IndexAction pour l'action index:

    class ActiveController extends Controller {
        public function actions()
        {
            return [
                'index' => [
                    'class' => 'yii\rest\IndexAction',
                    'modelClass' => $this->modelClass,
                    'checkAccess' => [$this, 'checkAccess'],
                ]
        }
}

Procédez comme suit dans le contrôleur ProductController:

class ProductController extends ActiveController
{
    public function actions()
    {
        $actions = parent::actions();

        $actions['index']['dataFilter'] = [
            'class' => 'yii\data\ActiveDataFilter',
            'searchModel' => 'app\models\ProductSearch'
        ];

        return $actions;
    }
}

Supposons que app\models\ProductSearch est un modèle de filtre de produit.

0
mirushaki