How do you set a script when making a quiet call in Yii2 to return certain fields

I am currently creating a Yii2 RESTful system using AngularJs.

In my database, I have several columns that I want to return when I make a specific call from a specific point on my system.

The problem I am facing is how can I only return a few fields, for example (id, title and stub) from the rest of the call in another part of my system in order to ignore other fields in the table.

Ideally, I would like it to work in the same way that model rules work with scripts in yii.

+5
source share
3 answers

There are two methods, I think:

1. use options

// returns all fields as declared in fields() http://localhost/users // only returns field id and email, provided they are declared in fields() http://localhost/users?fields=id,email // returns all fields in fields() and field profile if it is in extraFields() http://localhost/users?expand=profile // only returns field id, email and profile, provided they are in fields() and extraFields() http://localhost/users?fields=id,email&expand=profile 

2. redefining model fields ()

 // explicitly list every field, best used when you want to make sure the changes // in your DB table or model attributes do not cause your field changes (to keep API backward compatibility). public function fields() { return [ // field name is the same as the attribute name 'id', // field name is "email", the corresponding attribute name is "email_address" 'email' => 'email_address', // field name is "name", its value is defined by a PHP callback 'name' => function () { return $this->first_name . ' ' . $this->last_name; }, ]; } // filter out some fields, best used when you want to inherit the parent implementation // and blacklist some sensitive fields. public function fields() { $fields = parent::fields(); // remove fields that contain sensitive information unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']); return $fields; } 

in more detail, refer to https://github.com/yiisoft/yii2/blob/master/docs/guide/rest-resources.md

+1
source

You can use scripts inside your model for this, but you will need to extend the toArray method so that it works correctly:

 public function scenarios() { return array_merge(parent::scenarios(), [ 'simple_info' => [ 'email', 'name', ], 'login' => [ 'id', 'email', 'name', 'auth_token', ], ]); } public function toArray(array $fields = array(), array $expand = array(), $recursive = true) { $scenarios = $this->scenarios(); $scenario = $this->getScenario(); if (!empty($scenarios[$scenario])) { $data = parent::toArray($fields, $expand, $recursive); return array_intersect_key($data, array_flip($scenarios[$scenario])); } return parent::toArray($fields, $expand, $recursive); } 

After that, you can simply do something like this:

  $model = new LoginForm(); if ($model->load(Yii::$app->request->post(), '') && $model->login()) { $user = $model->getUser(); // Lets change scenario to login in order to get `auth_token` for authorization $user->setScenario('login'); $user->generateAuthKey(); $user->save(FALSE); return $user; } else { return $model; } 
0
source

As a side note (extension of answer from @Ganiks), if you manually return the list of models, you will need to return them as a DataProvider (and not just as an array of models) for fields in order to have an effect.

For example, if you do something like this ...

 class UserController extends yii\rest\Controller { public function actionIndex() { return User::find()->all(); // Not what you want } // ... } 

... then the fields parameter will not have the desired effect. However, if you do this ...

 class UserController extends yii\rest\Controller { public function actionIndex() { return new ActiveDataProvider([ 'query' => User::find(), 'pagination' => false, ]); } // ... } 

... then the returned fields will be only those that you specified in the fields parameter.

0
source

Source: https://habr.com/ru/post/1200823/


All Articles