In my data model, I've got a field that should be admin-editable only. Normal users can edit records in the model and view this specific field, but they should not be able to edit it. Is there a simple/clean approach to do this? I guess that it's necessary to create an extra admin_edit controller action, but what's the best way to "lock" a data field in the controller?
It's not necessary to create a new controller action, but you may decide so. Note that you can still use the same view for it using $this->render("edit") see: http://book.cakephp.org/view/428/render
I think you should:
use the same controller action, if that's not confusing for the users and admins
display an input field only if the user is admin, and output the text for other users
check for authorization in the controller
Depending on your setup, this could easily be handled as a validation method in the model. Write a custom function in the model to check if the user has permission.
You could also do it in model with beforeSave(). If the field is there and they don't have permission, remove it.
you can simly check on the admin role in the edit view
if (hasRoleAdmin) {
echo $this->Form->input(...);
}
Related
I am using free version of the script Open Real Estate.
I need to add some extra fields to the booking page.
I added the HTML part in "/themes/classic/views/modules/booking/views/_form.php" and I now need to add them to the PHP code, part which I find a bit tricky.
Can anyone suggest how to approach the problem?
PS: The extra fields should only be sent by email to the owner and not listed in the admin panel.
Regards!
Well it's not tricky at all, you just have to take it one step at the time.
Since you already modified the _form file I think the next step is to add properties to the model. In your model add public properties that should be named exactly like the name of the input type in the view. You can set the validation for them if you like but if you don't care just list them as safe ( which means safe to assign without any custom validation ). Now go into the appropriate action of the controller and after you mass assign the $_POST to the model and use those properties in your mailer function after booking has been saved. Alternative approach is to do the mailing in afterSave() in your model.
Ok, lets say there are two associated models, where the main model has a hasMany relationship with the other model. ex Donor hasMany Donations. I have read most of cake's documentation and I also took note of this (from the doc):
'When working with associated models, it is important to realize that
saving model data should always be done by the corresponding CakePHP
model. If you are saving a new Post and its associated Comments, then
you would use both Post and Comment models during the save operation'(http://book.cakephp.org/2.0/en/models/saving-your-data.html)
And as also pointed out by #burzum on another one of my questions : CakePHP - Controller or No Controller? , I am still struggling on how to decide which works best.
So taking the 'Donor and Donation' example mentioned earlier, let's say we want the user to add donation to a donor. So for the user to add a donation, one would need to view a donor, accessing a url of the sort : 'domain/donors/view/1', meaning the user is currently viewing donor with id of 1. Then within that view, let us assume there is button which allows the user to add a donation. Now from what I have been told and from what I read, the add(donation) action should belong to the donationsController.
Let us also assume that the add(donation) action has its own view.. So if I am at 'domain/donors/view/1' the user is redirected to 'domain/donations/add/donor_id:1' where the id of the donor is then retrieved using
$this->request->params['named']['post_id']
and set to the FK like so :
`$this->request->data['Donation']['donor_id'] = $id;
But I have a gut feeling telling me that this is not the proper way to go and it feels like bad practice jumping from one controller to the other, when having associated models.
Any insight on this ? Is there a general rule of thumb one could apply or follow ? Is it ok to redirect the user from the donorsController's view action to the donationsController's add action ?
Thanks in advance!
As far as I know your approach is not wrong, and linking other controllers from a view is normal.
However i prefer (and that's my rule of thumb, i'm not sure is a "best practice") to give the user the change of add an associated model - donations in your case - directly from the view of the "main" model. I've used this kind of approach in my applications, mostly considering the user experience (don't know if it is your case). So, if you are in the edit action of Donor, in the respective view the user can add the Donation and send it to still the edit action of Donor. Here you can save the associated model if the request data are well formatted:
data['Donor'] = array('id'=> XX);
data['Donation'] = array('id' => YY, 'amount' => blabla,...);
$this->Donor->save(data);
That would respect the MVC (no ugly ClassRegistry::Load ... ) and keep the code simple, avoiding to jump from one controller to another.
Just my opinion :D
Regards.
I have a Yii form based off a database model/table that I now want to add a custom field too that can then be accessed in the corresponding controller.
So the custom field DOES NOT correspond to a column in the database table.
Can this be done? If so how?
My motivation for doing this is to add a form value that I check, and I only process the form IFF that form value is empty. The field is hidden using CSS, so humans won't see it, and will hopefully be a simple convenient way to minimize spam. Since a bot is likely to fill out the form indiscriminately.
CAPTCHA Alternatives
Hope this makes sense.
Thanks!
You need to add simple property to model:
class User extends CActiveRecord {
public $myField;
}
Also do not forget to add its field in rules() if so required
Between start & end of rendering your form insert hidden (for example) next:
<?php echo CHtml::hiddenField('hidden_secret',''); ?>
Than in controller:
$hidden_secret = Yii::app()->request->getParam('hidden_secret'));
How can i pull data from different tables(models) into view in yii. actually i done this with loadModel method. but my question is how can we import the rules into the view too. Here comes my scenario
I have a User model and Profile model. The User model contains username and password and Profile model contains userid,name,address etc. so in my profile edit view i need all these data with the rules, username-unique,password,confirm pasword-required, etc., i can implement the required rule to all these, but i dunno how to import the table related rules like unique.
So basically this is a form that takes in two models and displays that data for you to edit and submit.
Simply make the render call to your view and pass both the models. e.g. $this->render('aview', array('model1'=>$model1, 'model2'=>$model2));
Get your view to display the form elements based upon these models.
When you submit simply create new objects for respective models and populate them with the data received. e.g.
$model1 = new model1;
$model1=>id = id; //id received from the form submit.
...............
Once you have the models populated you can call validate() on each of them to figure out if the data is according to your rules. If it is you proceed otherwise you display error. I hope this helps unless I missed something in your question.
I have a form which collects a name, password and email_address which are all part of the User model. The same form also collects car_make which is part of the Car model. I know I can collect these as
$form->input("User.name"); or $form->input("Car.make");
and they are available in the action which the form submits to as
$this->data["User"] or $this->data["Car"]
But at this point I just want to save the User data and redirect to an action in the car controller which has the value they put in $form->input("Car.make"); available.
How do I go about doing this?
are you sure you want to redirect to the cars controller? Or you just want to save that Car.make information?
If redirect, $this->redirect(array('controller'=>'cars','action'=>'some_action','make'=>$this->data['Car']['make']));
If save: loadModel('Car') if Car is not related to User in anyway. Then save the data using that Car model object. Just something like $this->User->Car->save($this->data);
You need to pass that information along with the redirect to your car controller. The best way to do this is either by adding parameters to the end of the url like adding ?car_make=MAKE. Another option is to pass the make as a parameter of the method in the car controller, where the url would be car/method/MAKE.