how to change a model safe attributes in yii - php

I have a CActiveRecord model, and I need to change safe attributes list in that model.
I have defined the safeAttributes method inside my model, like the following :
public function safeAttributes()
{
return array(
'name, bio',
);
}
the problem is 'bio' is not being considered in my safe attribute assign. I tried to dump the model safeAttributeNames attribute in my model, and what I've got was completely different from what safeAttributes should return.
Am I doing this in the right way ?
cheers,
Firas

Assuming that you are using Yii 1.0.x then that is the correct way to do it.
If you are using Yii 1.1.x then it's changed. Have another read of the documentation.
public function rules()
{
return array(
array('username, password', 'required'),
array('rememberMe', 'boolean'),
array('password', 'authenticate'),
array('something', 'safe'),
array('someOtherThing', 'unsafe'),
);
}

Related

Php Yii define form field validation outwith model

I'm using yii framework in my current project. I have a page with a form (submitting to database) which defines the required fields in the rules of the model - as standard. On this page, I also have a dynamic form I've built, as a component which pulls additional fields in.
However, I need to be able to also define some of these as required fields. Is there any way of defining required fields outside of the model?
Make following changes in your model:
- Define additional fields as public
- Add 'Required Rule' for additional fields
class ExampleModel extends CActiveRecord {
// Define additional fields as public
public $addField1;
public $addField2;
public $addField3;
public function rules() {
return array(
// Add 'Required Rule' for additional fields
array('existField1, existField2, addField1, addField2, addField3', 'required'),
...
);
}
public function attributeLabels() {
return array(
...,
'addField1' => 'Additional Field 1',
'addField2' => 'Additional Field 2',
'addField3' => 'Additional Field 3',
);
}
}
Hope this help you! Let me know if there is any concern from this.

There are <select> populated with (key->value), and field "key" in a model. How I can display it's "value" in a view, instead of "key"?

In model:
public function getOptionsGender()
{
array(0=>'Any', 1=>Male', 2=>'Female');
}
In view (edit):
echo $form->dropDownList($model, 'gender', $model->optionsGender);
but I have a CDetailView with "raw" attributes, and it displays numbers instead of genders.
$attributes = array(
...
'gender',
)
What is appropriate way to convert these numbers back to genders? Should I do it in a model, replacing fields such as $this->gender = getOptionsGender($this->gender)? Any github examples will be very appreciated.
I had to choose gender, age, city, country etc. in a few views that are not related to this one. Where should I place my getOptionsGender function definitions?
Thank for your help, the problem is solved.
In model:
public function getGenderOptions() { ... }
public function genderText($key)
{
$options = $this->getGenderOptions();
return $options[$key];
}
In view:
$attributes = array(
array (
'name'=>'gender',
'type'=>'raw',
'value'=>$model->genderText($model->gender), //or $this->genderText(...)
),
);
$this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>$attributes,
));
The working example can be found here:
https://github.com/cdcchen/e23passport/blob/c64f50f9395185001d8dd60285b0798098049720/protected/controllers/UserController.php
In Jeffery Winsett's book "Agile Web Application Development with Yii 1.1", he deals with the issue using class constants in the model you are using. In your case:
class Model extends CActiveRecord
{
const GENDER_ANY=0;
const GENDER_MALE=1;
const GENDER_FEMALE=2;
public function getGenderOptions(){
return array(
self::GENDER_ANY=>'Any',
self::GENDER_MALE=>'Male',
self::GENDER_FEMALE=>'Female',
);
}
public function getGenderText(){
$genderOptions=$this->genderOptions();
return isset($genderOptions[$this->gender]) ? $genderOptions[$this->gender] : "unkown gender({$this->gender})";
}
}
Then in your CDetailView you would have to alter it from gender to:
array(
'name'=>'gender',
'value'=>CHtml::encode($model->genderText()),
),
If several models have the same data, you may want to create a base model that extends CActiveRecord and then extend the new model instead of CActiveRecord. If this model is the only one with that data (ie User model only has gender), but other views use that model to display data, then I would leave it just in the single model class. Also keep in mind that if you place getGenderOptions in the extended class, and you extend ALL your models, they will all have that option available, but may not have the attributes needed and will throw an error if you aren't checking for it.
All this being said, I still think it is a matter or preference. You can handle it however you want, wherever you want. This is just one example from a book I have specifically on Yii.

Yii: BELONGS_TO relation returns null if I change its name

I would like to know why the framework might have this strange behavior.
If I define the relation in my Event model as weird or any other name besides interest, it works properly getting an object of the class Interest.
public function relations()
{
return array_merge(
parent::relations(),
array(
'weird' => array(self::BELONGS_TO, 'Interest', 'interest_id'),
));
}
But if I change the name to interest it returns null
public function relations()
{
return array(
'interest' => array(self::BELONGS_TO, 'Interest', 'interest_id'),
);
}
So simply changing the name to interest means the relation will return null
Do you have any variables on the Event called interest you can't override native class variables with Yii specials like relations and magic methods. If not then something stranger is going on here.

How do I modify a model to return specific db fields?

A Yii question:
The Situation:
I generated a model using Yii's gii code generator tool. The model returns all fields in a given table in a MySQL database.
The Problem:
I want to return only fields related to a specific logged-in user based on their user id (which I get from Yii::app()->user->getId())
The Question:
How can I modify my model to do this?
Code:
(The 'rules' section of my Model class)
public function rules()
{
return array(
array('user_id, title, description', 'required'),
array('user_id', 'numerical', 'integerOnly'=>true),
array('description', 'length', 'max'=>255),
array('id, user_id, title', 'safe', 'on'=>'search'),
// Is the solution something like this?
//array('user_id', 'compare', 'user_id'=>Yii::app()->user->getId());
);
}
You don't need to modify the model -- how are you doing your search? If you want to use Active Record, you can do something like:
User::model()->find(array('condition'=>'user_id='.Yii::app()->user->getId()));
if the user id is the primary key then:
User::model()->findByPk(Yii::app()->user->getId());
and if you did want to add the condition to your model, you probably want to use a scope to define a search condition, rules are for checking data when it's submitted for insert/update.
For scopes, put this function in your model:
public function scopes() {
return array(
'userid'=>array(
'condition' => 't.user_id = ' . Yii::app()->user->getId(),
),
);
}
then you can use something like this to fetch the data:
User::model()->userid()->find();
(In the above change "User" to the name of your model.)
I would strongly recommend you read the db documentation and work through some tutorials.

Kohana 3.1 ORM: How to implement a "unique" validation rule?

does exists a "unique" validation rule (if does, how to implement it?) or must be implemented via callback?
Thanks.
)
As far as I know there is no universal "unique" (or "is_unique") rule of Validation class.
That's probably because of not regular nature of this kind of check.
However, if you would like do it nicely, you could create a 'base model' for all your models you use in your application (make them extend the base one).
Then, the uniqueness could be checked more or less like this:
public function is_unique($id)
{
return ! (bool) DB::select(array(DB::expr('COUNT(id)'), 'total'))
->from($this->_table_name)
->where('id', '=', $id)
->execute()
->get('total');
}
In your validation rules you have to add this rule:
array('id' => array(array(array($this, 'is_unique')));
I have internal model rules stored in the method rules(), as recommended.
So this could be a live example:
class Model_Base_Model extends ORM
{
public function rules()
{
return array(
'id' => array(
array(array($this, 'is_unique')),
);
}
public function is_unique($id)
{
return ! (bool) DB::select(array(DB::expr('COUNT(id)'), 'total'))
->from($this->_table_name)
->where('id', '=', $id)
->execute()
->get('total');
}
}
Now every model extending the Model_Base_Model will be now able to check it's uniqueness while creating.
Hope this helps! :)
In Kohana 3.2 ORM has a unique() method that does the check, I'm not sure if it exists in 3.1, but it should.
With that you can just add a rule to your model like this:
array(array($this, 'unique'), array('some_field', ':value')),
and it will check if some_field is unique
Read this: http://kohanaframework.org/3.1/guide/kohana/security/validation

Categories