I've had a working registration/update model, I wanted to expand on my models so I added in a regex to the password field. I have checked the regex works online and even my client side validation shows it works, but the model refuses to save now. I'm not really sure why, could anyone help me out please?
return array(
array('firstName, lastName, email, password', 'required'),
array('firstName', 'length', 'max'=>45),
array('lastName', 'length', 'max'=>80),
array('email', 'length', 'max'=>120),
// email must be valid email
array('email', 'email'),
// email must be unique
array('email', 'unique'),
// Regex for password
array('password','match', 'pattern'=>'/^[a-z0-9_-]{7,20}$/i',
'message'=>'The password must be between 7 and 20 characters
long'),
array('password', 'length', 'min'=>7, 'max'=>64),
array('date_modified', 'safe'),
array('active, date_modified', 'default', 'setOnEmpty' => true, 'value' => null),
array('id, first_name, last_name, email, pass, active, date_created, date_modified, live', 'safe', 'on'=>'search'),
);
Thanks
Jonny
You can create your own validation rule.
http://www.yiiframework.com/wiki/168/create-your-own-validation-rule/
Or else you can define validation rule in YII Model, something like this:
return array(
array('password', 'length', 'min'=>7, 'max'=>64),
array('password','pattern'=>'/^[A-Za-z0-9_!##$%^&*()+=?.,]+$/u', 'message'=>'Spaces or given characters are not allowed'),
);
There are more validation you can specify in your model.
Related
This is my model:
public function rules() {
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
if ($this->scenario == "insert") {
return array(
array('requisition_id, sync', 'numerical', 'integerOnly' => true),
array('lastname, firstname, email, dob, phone, cv_path, experienceMonths, experienceYears, competencies, token', 'required', 'message' => "Câmpul este obligatoriu"),
array('email', 'email', 'message' => "Emailul este invalid!"),
array('dob', 'validateDob'),
array('dayOfBirth, monthOfBirth, yearOfBirth', 'safe'),
array('taleo_id, sync', 'required', 'on' => 'taleoUpdate'),
array('verifyCode', 'on' => 'insert'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
);
} else if ($this->scenario == 'taleoUpdate') {
return array(
array('taleo_id, sync', 'required'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
);
}
else if($this->scenario == 'notjobapply'){
return array(
array('lastname, firstname, email, phone, cv_path, requisition_id', 'required', 'message'=>'Câmpul este obligatoriu'),
array('email', 'email', 'message' => "Emailul este invalid!"),
);
}
return array(
array('id, lastname, email, phone, dob, requisition_id, experienceMonths, experienceYears, sync, cv_path, created', 'safe', 'on' => 'search'),
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(),'on'=>'captchaRequired'),
);
}
My problem is that it does not validate the letters from the image. I don't know why. I think that my validation is not correct in the rules. Anyone any clues?
Yes you have a lot of scenarios and applying different rules to them.
Make sure that the scenario that you're currently running does have a validation rule.
I can see that you use scenarios in two ways, one is the conditions you're using that I'm not fully sure they work, but maybe they do.
And the second is the Yii way, by specifying in the 'on' attribute in every rule declaration.
I would recommend writing all the rules again from scratch in this structure:
return array(
// scenarioA
array('field1, field2', 'required', 'on' => 'scenarioA'),
array('field1, field2', 'required', 'on' => 'scenarioA'),
array('field1, field2', 'required', 'on' => 'scenarioA'),
// scenarioB
array('field3, field4', 'required', 'on' => 'scenarioB'),
array('field3, field4', 'required', 'on' => 'scenarioB'),
array('field3, field4', 'required', 'on' => 'scenarioB'),
// scenarioC
array('field5, field6', 'required', 'on' => 'scenarioC'),
array('field5, field6', 'required', 'on' => 'scenarioC'),
array('field5, field6', 'required', 'on' => 'scenarioC'),
);
Or you could keep your condition blocks solution if you test that they behave correctly, but in that case you should remove the 'on' parameter from the rules inside the blocks.
Because for example here:
if ($this->scenario == "insert") {
return array(
...
array('taleo_id, sync', 'required', 'on' => 'taleoUpdate'),
You're putting code inside the condition where you verify that scenario is 'insert' but then again you specify the 'on' that will make that rule only be applied on 'taleoUpdate' scenario so it makes no sense.
Oh and as for the captcha, as you can see with your format you only reach the rule for it if the scenario is different from those you've specified above.
I'm having problem to show data on cgridview using foreign keys.
This is my case, i have table employee(id, username), client(id, username), and transaction(id, employeeId, clientId). employeeId foreign key to employee.id, and clientId is foreign key to client.id. Now, I want to show employee's name and client's name instead of their id on transaction admin.php.
This is my code:
class Transaction extends CActiveRecord
{
public $client_search;
public $employee_search;
public function rules()
{
return array(
.
.
.
array('id, employeeId, clientId, balance, status, date, client_search, employee_search', 'safe', 'on'=>'search'),
);
}
public function relations()
{
return array(
'employee' => array(self::BELONGS_TO, 'Employee', 'employeeId'),
'client' => array(self::BELONGS_TO, 'Client', 'clientId'),
);
}
public function search()
{
$criteria=new CDbCriteria;
$criteria->with = array( 'client', 'employee' );
$criteria->together = true;
$criteria->compare('t.id',$this->id,true);
$criteria->compare('employee.username', $this->employee_search, true );
$criteria->compare('client.username', $this->client_search, true );
$criteria->compare('t.balance',$this->balance,true);
$criteria->compare('t.status',$this->status);
$criteria->compare('t.date',$this->date,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
//the other functions are there, i don't edit it.
}
that is my model/Transaction.php
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'transaction-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
array(
'header' => 'Employee',
'name' => 'employee_search',
'value' => '$data->employee->username',
),
array(
'header' => 'Client',
'name' => 'client_search',
'value' => '$data->client->username',
),
array(
'class'=>'CButtonColumn',
),
),
));
that is my views/transaction/admin.php.
and this code gave me error Trying to get property of non-object ($data->employee->id marked).
Actually I have succed to show the employee's name instead of employee's id, but, after that I use the same method for the client, and the error appear.
anyone can help me? My method is making public employee_search, add the rules, add the relation, adding $creiteria->with, then change the admin.php. Anyone please help me.
//UPDATE
SOLVED. Its actually my fault. There is an error in the database about the relation (foreign key). My coding is fine.
It's hard to guess without being able to debug your code but here are some things that could help (I'll add more as I can think of them).
It might be because both the default joinType for relations is LEFT OUTER JOIN and maybe you have a Transaction where one of them is null? If you try to access attributes on null object (as opposed to an actual ActiveRecord object), that's precisely the error message you would be seeing.
You could change it by doing:
public function relations()
{
return array(
'employee' => array(self::BELONGS_TO, 'Employee', 'employeeId',array('joinType'=>'INNER JOIN')),
'client' => array(self::BELONGS_TO, 'Client', 'clientId',array('joinType'=>'INNER JOIN')),
);
}
P.S.: INNER JOIN is the same as just JOIN
Not sure if it will help you, but it's worth trying.
More information at: http://www.yiiframework.com/doc/api/1.1/CActiveRecord#relations-detail
I can change form validator error message by these code in my model:
array('name, email, subject, body', 'required'
'message'=>'Please enter a value for {attribute}.'),
but i don't know where the {attribute} came from and how can i change it for each field, so any help would be appreciated.
I'm not sure if i understand your question right, but you asked where the {attribute} came from:
Some validators introduce placeholders like the {attribute} in your example. If validation fails, they will be replaced with the attribute name. So if no name was entered and your message is 'Please enter a valid {attribute}.' the error message will be "Please enter a valid name".
While the {attribute} placeholder can be used with every validator, some of them introduce even more placeholders. For example with the CStringValidator you can use {min}, {max} or {length}. They will be replace with the number of minimum, maximum or exact characters respecitvely.
Here's an example:
array('firstname,lastname', 'string', 'min'=>3,
'tooShort'=>'Your {attribute} must contain at least {min} letters.'
),
This will give "Your firstname must contain at least 3 letters." if the users enters less than 3 letters. This has the advantage that if you change the min parameter, your message will automatically be updated. So it's less error prone.
Use these :
return array(
// name, email, subject and body are required
array('name', 'required',
'message'=>'Please enter a value for name.'),
array('email', 'required',
'message'=>'Please enter a value for email.'),
array('subject', 'required',
'message'=>'Please enter a value for subject.'),
array('body', 'required',
'message'=>'Please enter a value for body.'),
The {attribute} is taken from your function:
public function attributeLabels() {
return array(
'id' => 'ID',
'name' => 'Name',
'password' => 'Password',
'email' => 'Email',
);
}
on your model.
I'm new to YII. I created a table with text fields and created model and crud generators, I created text fields for dates. Then I replaced it with datepicker, but I don't know how to connect my new datepicker with model.
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('name, gender, age, dob, doj, class,
no_seats, train_name, proof_1, proof_2, proof_3', 'required'),
array('age, class, no_seats', 'numerical', 'integerOnly'=>true),
array('name', 'length', 'max'=>20),
array('gender', 'length', 'max'=>6),
array('train_name', 'length', 'max'=>23),
//I created the below statement instead of the previous //one
//created for text field but it is not working
array('dob','date','format'=>Yii::app()->
locale->getDateFormat('medium')),
array('proof_1', 'length', 'max'=>7),
array('proof_2', 'length', 'max'=>8),
array('proof_3', 'length', 'max'=>9),
array('status', 'length', 'max'=>1),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('refid, name, gender, age, dob, doj,
class, no_seats, train_name, proof_1, proof_2,
proof_3, created, lastmodified, status', 'safe', 'on'=>'search'),
);
}
// View
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'model'=>$model,
'attribute'=>'date',
// additional javascript options for the date picker plugin
'options'=>array(
'showAnim'=>'fold',
'dateFormat'=>'yy-mm-dd',
),
'htmlOptions'=>array(
'style'=>'height:20px;'
),
));
// add to Model rules
array('date', 'type', 'type'=>'date', 'dateFormat'=>'dd-MM-yy'),
You can use a datepicker widget like the following in place of any text input attribute you have. This will create correct fields in the form and in $_POST, and is ready to be manipulated by model functions. Note that there is a validator 'date' that you can put in rules for your model. You should have the same dateFormat in the widget and in the rules.
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'model'=>$model,
'attribute'=>'date',
// additional javascript options for the date picker plugin
'options'=>array(
'showAnim'=>'fold',
'dateFormat'=>'yy-mm-dd',
),
'htmlOptions'=>array(
'style'=>'height:20px;'
),
));
?>
Since you were specifically asking about the rules:
public function rules()
{return array(
array('date_field', 'date'),
);}
Here is a good summary for validators:
http://www.yiiframework.com/wiki/56/
I had write the following code in my Zend Form:
$newpassword = new Zend_Form_Element_Password('newpassword');
$newpassword->setLabel("Enter your New Password :")
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator(
'NotEmpty',
TRUE,
array('messages' => array(
'isEmpty' => 'Please enter new password.'
)
)
)
->addValidator(
'Alnum',
TRUE,
array('messages' => array(
'alnumInvalid' => 'Please enter a valid new password.',
'notAlnum' => 'Please enter a valid new password.',
'alnumStringEmpty' => 'Please enter a valid new password.'
)
)
)
->addValidator('StringLength', false, array(4, 25))
->getValidator('StringLength')->setMessage("Should be 4-25 characters long.");
$retypepassword = new Zend_Form_Element_Password('retypepassword');
$retypepassword->setLabel("Retype-Password :")
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator(
'NotEmpty',
TRUE,
array('messages' => array(
'isEmpty' => 'Please enter confirm password.'
)
)
)
->addValidator(
new Zend_Validate_Identical('newpassword'),
TRUE,
array('messages' => array(
'notSame' => 'New password and confirm password are not matching. They must be same.',
'missingToken' => 'New password and confirm password are not matching. They must be same.'
)
)
)
->addValidator('StringLength', false, array(4, 25))
->getValidator('StringLength')->setMessage("Should be 4-25 characters long.");
As you can see that I had override the error messages for Zend_Validate_Identical i.e. for notSame and missignToken, but still the form is showing the default error message i.e. "The two given tokens do not match"
Can anyone please help me.
Thanks In Advance...
The $options parameter to Zend_Form_Element::addValidator gets ignored completely if you pass it a validator object (which you're doing by passing new Zend_Validate_Identical).
Instead, you want to do something closer to the way you've added your other validators:
$this->addValidator(
'Identical',
TRUE,
array('token' => 'newpassword',
'messages' => array(
'notSame' => 'New password and confirm password are not matching. They must be same.',
'missingToken' => 'New password and confirm password are not matching. They must be same.'
)
)
);