Override default rest action in Yii2 - php

I created rest api in yii2 for the users. I can access list of users like this "api/web/v1/users" but the problem is that it is giving the data of all the columns including password, I saw in yii2 documentation that it is internally calling "user/index" method, is there any way to override the index method like this?
class UserController extends ActiveController {
public $modelClass = 'common\models\User';
public function actionIndex(){
//return selected columns here of the user table
}
}
It still gives the list of all users with all columns that I don't want. Please help.

In your case, you must use fields() method and override this method. As Yii defines fields():
By overriding [[yii\base\Model::fields()|fields()]] and/or [[yii\base\Model::extraFields()|extraFields()]], you may specify what data, called fields, in the resource can be put into its array representation.You can override fields() to add, remove, rename or redefine fields
For example:
public function fields()
{
return [
'id','name','username'
];
}
Above method, tells yii that only show id,name,username fields. So, Password will never be sent to client.
In cases that you want only remove one or more specific fields, you can do like below:
public function fields()
{
$fields=parent::fields();
unset($fields['password']);
return $fields;
}

While the accepted answer does work and is an important method to know for basic control of what fields are shared via rest and general "object exporting" functions like Json::encode(), I feel it is important to also understand how to completely override an action like the OP references.
I've answered this question here: https://stackoverflow.com/a/50744982/3337682, and I feel it would be helpful, added information for the OP.
Hope this helps someone!
~ Cheers :)

Related

Why does Symfony look for "addWooklyExercise()" instead of "addWeeklyExercise()"

I changed, by client requirement, an entity textfield (weekly_exercise) to a 1:n relation. Everything works normally so far, but when trying to save the form Symfony looks out for a "changed" method name.
That's the error message I get
Neither the property "weekly_exercise" nor one of the methods "addWooklyExercise()"/"removeWooklyExercise()", "setWeeklyExercise()", "weeklyExercise()", "__set()" or "__call()" exist and have public access in class "XXX\CourseBundle\Entity\Course".
Of course "addWooklyExercise()"/"removeWooklyExercise()" don't exist. I could put them in and proxy to the real methods, but that would only be an ugly hack.
I've been looking through all my files and couldn't find a anything that could be responsible for this issue.
I'm on Symfony 2.5.7 as my client doesn't allow me to update!!
Files involved in the issue https://gist.github.com/mhauptma73
EDIT:
For some reason the method
public function addWooklyExercise(\BDA\CourseBundle\Entity\CourseWeeklyExercise $weeklyExercise)
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'addWooklyExercise', array($weeklyExercise));
return parent::addWooklyExercise($weeklyExercise);
}
is being added in the cache proxy. But there is also the correctly spelled method, before the misspelled one.
Follow the naming convention like when you add the property for oneToMany then it's plural and for add or remove method change it to singular.
protected $tags;
public function addTag(Tag $tag)
{
//...
}
public function removeTag(Tag $tag)
{
// ...
}
See more details read this doc:
http://symfony.com/doc/2.7/form/form_collections.html#form-collections-new-prototype
That looks like you have a typo somewhere, probably your Entity, your Form-Type or when outputting a form in a template. Try doing a search over the whole src/ directory for wookly and you will probably find it.

what is $var means on save($var) on laravel

I have a question ,
public function addNote(makenote $note) {
return $this->makenote()->save($note);
}
why there is note var on save method ?
what does it do?
In this case I believe $note refers to the instance of a related model that you want to save.
public function addNote(MakeNote $note) {
return $this->makenote()->save($note);
}
I would assume that on your Model there is a method that looks something like this. This method tell Eloquent that there is a model that is related to your current model.
public function makenote()
{
return $this->hasMany('App\MakeNote');
}
If you do not pass an instance of MakeNote, the $note in this case, there will be nothing to relate to your current model, thus nothing to save.
I'd really go check out the documentation on Laravel also if you want more tutorials Laracasts is a great resource.
Your question is getting down-voted too, because you should include more information about your question and some more examples of your code.

What is this line of Yii code trying to do?

Just a quick question. I see the following code in an extension and I am not sure what it is doing.
public function actionCreate() {
$model = new User('register'); <----(this is the line I am confused about)
//other stuff...
}
What is the "('register')" doing there? Is it an argument going into the
"User" class? I've looked in the user model, useridentidy, and webuser, and cwebuser classes, but can't find anything. I know that without the proper context, this might be difficult to explain, but in general, what is this extra stuff after the declaration of a new object in Yii? I've been creating objects to use as active records by just typing this:
$model = new User;
(using the "User" class again just as an example)
I'd appreciate any help to clarify this issue.
It's a scenario. Models in Yii can have multiple "scenarios" affecting how validation is performed and which attributes can be assigned in bulk. In this case an object of User class is instantiated with the register scenario, which defines a registration-specific set of validation rules.
$model = new User('register');
This line is for binding the object i.e $model in this case to a scenario which is 'register'.
It is similar to
$model=new User;
$model->scenario='register';
You can set the scenario in this way too. But in order to avoid multiple lines or for the ease of the developers it can be done in this way too :)
Also you can call different scenario in one model:
In your Model rules function:
public function rules(){
return array(
array('username,email', 'required','on'=>'register,update'),
array('firstname,lastname', 'required','on'=>'other scenario here'),
);
}
And where you want to call your custom scenario like in Controller action!
$model = new User('update');
Or
$model = new User('register');
It's an argument being passed to the constructor. Look in the User class for a function called __construct, it will probably accept an argument, and you can see what it is doing.
This is not unique to Yii, any class can accept arguments in it's constructor.

Hide columns when serializing via toArray()

I have a simple problem where I often return CRUD type Ajax requests with array serialized versions of Doctrine 1.2 models. I'd love to be able to simply return the toArray() method after the execute() result, however, this will display data about my models that I don't wish to expose. A simple example is on my user model the password and salt get displayed. While I realize those are already hashed values, it's something I'd rather not return as a JSON response.
I've poured over the Doctrine 1.2 manual, but did not find anything that offered the type of functionality I'm looking for. I realize I can iterate over the result to manually unset() the columns I wish to hide, but I'm hoping a more native solution is out there that I've overlooked.
Why don't you build your own toArray() ?
If you want to do that, you will have to extends the sfDoctrineRecord class that inherit from all Base* class. It is describe in the doc.
You have to put the configureDoctrine() inside config/ProjectConfiguration.class.php.
Then you will have a class like that:
class myDoctrineRecord extends sfDoctrineRecord
{
}
So you can easily add your custom toArray() here:
class myDoctrineRecord extends sfDoctrineRecord
{
public function toArray($deep = true, $prefixKey = false, array $excludeFields = array())
{
// do every thing like the original toArray
// but when a column match one entry in $excludeFields, don't add it
}
}
So, when using the toArray() method with an array of fields for the third parameters, they will be excluded from the result.

MVC pattern (need view object in model)

I'm using the MVC pattern in my application.
Now I need the view object in a model.
I don't want to add the view as a parameter for my function in the model (since I need it in other functions as well). And I don't want to keep on passing it.
Should a add the view as an attribute for the constructor of the model?
Is there another way? Shouldn't I be needing the view object in the model in the first place?
What would be the preferred way of doing it?
Example:
Controller
function someAction()
{
$somemodel->add();
}
Model
class SomeModel()
{
function add()
{
if ($view->user) {
// do stuff
$this->mail();
} else {
// do other stuff
}
}
function mail()
{
Mailer::send($view->user->email, $this->getitems(), $view->layout);
}
function getitems()
{
return Items::getitems($view->user);
}
}
If you're really doing MVC, then you won't need the view in the model, because only the controller should have access to the view.
Looking at the code you've provided, I can tell one thing: the add() method should not reference $view in any way (even for accessing its properties). Instead, the model should be provided with the $view->user value from the controller. The same goes for the mail() method.
Consider fixing those issues. Otherwise, you'll get into something worse later on.
The model should be separate from the view. So, as mkArtak said, the controller should be the only thing that communicates with the view. Which then passes only the necessary information to the model.
As for the model, it should really only deal with the information that it understands.
i.e. if you had a Car model... you don't want to build it dependent on it's factory. If you did, you would have to change your code if you wanted to build it in different factory.
The controller is where you 'bake' everything prepare for render. By bake I mean you consider any passed in $_REQUEST params, make model API calls to get the data you need, and set template variables to be rendered. Your action, at the end of this process should make a call to a template (view) you choose in order to render the 'baked' template variables.

Categories