I have a Yii form accept first name, last name and email from user. Using an add more link, users can add multiple rows of those three elements.
For email validation, unique and required are set in model rules and everything works fine. I am using JavaScript to create addition row on clicking add more link.
Problem
On the first row my values are John, Newman, johnnewman#gmail.com and the second row, i'm entering Mathew, Heyden, johnnewman#gmail.com. In this case email address is duplicated. None of the validation rules (require and unique) is capable of validating this. Can some one suggest a better method to validate this ?
Update:
I created a custom validation function and i guess this is enough to solve my problem. Can someone tell me how to access the whole form data / post data in a custom validation function ?
public function uniqueOnForm($attribute){
// This post data is not working
error_log($_REQUEST, true);
$this->addError($attribute, 'Sorry, email address shouldn\'t be repeated');
}
You can try this:
<?php
public function rules()
{
return array(
array('first_name', 'checkUser')
);
}
public function checkUser($attribute)
{
if($this->first_name == $this->other_first_name){
$this->addError($attribute, 'Please select another first name');
}
}
?>
You can also look into this extension
You can write custom validator:
//protected/extensions/validators
class UniqueMailValidator extends CValidator
{
/**
* #inheritdoc
*/
protected function validateAttribute($object, $attribute)
{
$record = YourModel::model()->findAllByAttributes(array('email' => $object->$attribute));
if ($record) {
$object->addError($attribute, 'Email are exists in db.');
}
}
}
// in your model
public function rules()
{
return array(
array('email', 'ext.validators.UniqueMailValidator'),
...
Or better try to use THIS
public function rules(){
return array(
//other rules
array('email', 'validEmail'),
)
}
public function validEmail($attribute, $params){
if(!empty($this->email) && is_array($this->email)){
$isduplicate = $this->isDuplicate($this->email);
if($isduplicate){
$this->addError('email', 'Email address must be unique!');
}
}
}
private function isDuplicate($arr){
if(count(array_unique($arr)) < count($arr)){
return true;
}
else {
return false;
}
}
because you are using tabular input (multiple row) , so make sure input field as an array. might be like this :
<?php echo $form->textField($model, 'email[]'); ?>
Related
I'm using yii framework. I have made a condition where users are not allowed to insert a same data.
here is my code
model
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('DEP_CD', 'length', 'max'=>5),
array('DEP_CD', 'required'),
array('DEP_CD', 'cekPK'),
);
}
public function cekPK()
{
$model = self::findByPk(array($this->DEP_CD));
if ($model)
$this->addError('field1', 'Data sudah ada');
}
this code works for not allowing user to insert a same data. but when they edit/update the data, it keep saying that data is exist. I need to make users allowed to edit but not inserting the same data only
thanks
A work around could be:
public function cekPK()
{
if ($this->isNewRecord)
{
$model = self::findByPk(array($this->DEP_CD));
if ($model)
$this->addError('field1', 'Data sudah ada');
}
}
I was given a project to update certain extensions and modules on without any documentation.
The issue I'm having is for one of the variables in the model, it is being regarded as not defined when using localhost (but works fine on the server version which is the exact same code).
From what I can see, it makes a single row in the database and assigns it a value of 1 or 0.
What could be causing this?
Keep in mind, this works fine on the server. I have turned global variables in my php.ini to On. No change. The Row is definitely created and exists in the database with a value. The page errors out after clicking "create new group".
Edit. Error message : Property "EventGroups.delegates_select_event_group " is not defined.
Code below is the model, controller and form. (and the options)
First off, the form view.
echo $form->switchGroup($model, 'delegates_select_event_group', array('class' => 'col-md-6'));
Model
public $delegates_select_event_group;
public function rules() {
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('name, description, guest_invites_per_user, delegates_select_event_group ', 'required'),
);
}
Options
//Options
// Event group selectable
const KEY_DELEGATES_SELECT_EVENT_GROUP = 'delegates_select_event_group';
public static function isDelegatesSelectEventGroup() {
return self::getValue(self::KEY_DELEGATES_SELECT_EVENT_GROUP, false);
}
public static function setDelegatesSelectEventGroup($value) {
return self::setValue(self::KEY_DELEGATES_SELECT_EVENT_GROUP, $value);
}
const KEY_DEFAULT_EVENT_GROUP_ID = 'default_event_group_id';
public static function getDefaultEventGroupID() {
$model = EventGroups::model()->find();
if ($model === null) {
return self::getValue(self::KEY_DEFAULT_EVENT_GROUP_ID, 1);
} else {
return self::getValue(self::KEY_DEFAULT_EVENT_GROUP_ID, $model->id);
}
}
public static function setDefaultEventGroupID($value) {
return self::setValue(self::KEY_DEFAULT_EVENT_GROUP_ID, $value);
}
Controller
public function actionCreate() {
$model = new EventGroups;
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if (isset($_POST['EventGroups'])) {
$model->attributes = $_POST['EventGroups'];
if ($model->validate()) {
// Valid Save
$model->save(false);
$this->redirect(array('event/create'));
}
}
$this->render('create', array(
'model' => $model,
));
}
I have a simple registration form with an address-entity.
I do validate the value of each property using the loadValidatorMetadata(...) {...} method.
I want to check if the email is valide (by characters, etc...) and if email1 is equal to email2 and email1 hasn't to be in the bad-index-array.
Setting the validation is easy. But how can I define different errors-messages for each case?
code example:
public $email;
public $email2;
static function loadValidatorMetadata(ClassMetadata $metadata)
{
...
$metadata->addGetterConstraint('email', new Assert\False(array(
'message' => 'validation.addressFormEmail'
)));
...
}
public function getEmail()
{
if ($this->email == $this->email2) {
return false;
}
return false;
}
Symfony2 has a repeated form type where you can set your message if the value isn't repeated.
then in your entity validation you can set a custom message for email validation.
http://symfony.com/doc/current/reference/forms/types/repeated.html#validation
http://symfony.com/doc/current/reference/constraints/Email.html
I got this code:
public function actionJoin() {
$user = new RUser;
if (isset($_POST['RUser']))
$user->attributes = $_POST['RUser'];
$this->render('join',
array(
'user' => $user
)
);
}
Which will not yet allow user to register. What I want to know is how to send data back to user. I mean, if user form haven't passed verification I have to send some data back, so there is no need for user to re-enter it again.
I can do so with this:
$user->mail = $_POST['RUser']['mail'];
But it's looks like dropping back to plain PHP and not using powers of the framework here.
Addition. Publishing RUser class, if needed:
class RUser extends CFormModel
{
public $mail;
public $alias;
public function safeAttributes()
{
return array(
'mail', 'alias'
);
}
}
Which version of Yii you use.
In Yii 1.1, there are no safeAttributes. You use the followings,
public function rules()
{
return array(
array('mail, alias', 'safe'),
);
}
I want to limit my registration to emails with #mywork.com I made the following in My_Form_validation.
public function email_check($email)
{
$findme='mywork.com';
$pos = strpos($email,$findme);
if ($pos===FALSE)
{
$this->CI->form_validation->set_message('email_check', "The %s field does not have our email.");
return FALSE;
}
else
{
return TRUE;
}
}
I use it as follows. I use CI rules for username and password and it works, for email it accepts any email address. Any I appreciate any help.
function register_form($container)
{
....
....
/ Set Rules
$config = array(
...//for username
// for email
array(
'field'=>'email',
'label'=>$this->CI->lang->line('userlib_email'),
'rules'=>"trim|required|max_length[254]|valid_email|callback_email_check|callback_spare_email"
),
...// for password
);
$this->CI->form_validation->set_rules($config);
The problem with creating a callback directly in the controller is that it is now accessible in the url by calling http://localhost/yourapp/yourcontroller/yourcallback which isn't desirable. There is a more modular approach that tucks your validation rules away into configuration files. I recommend:
Your controller:
<?php
class Your_Controller extends CI_Controller{
function submit_signup(){
$this->load->library('form_validation');
if(!$this->form_validation->run('submit_signup')){
//error
}
else{
$p = $this->input->post();
//insert $p into database....
}
}
}
application/config/form_validation.php:
<?php
$config = array
(
//this array key matches what you passed into run()
'submit_signup' => array
(
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'required|max_length[255]|valid_email|belongstowork'
)
/*
,
array(
...
)
*/
)
//you would add more run() routines here, for separate form submissions.
);
application/libraries/MY_Form_validation.php:
<?php
class MY_Form_validation extends CI_Form_validation{
function __construct($config = array()){
parent::__construct($config);
}
function belongstowork($email){
$endsWith = "#mywork.com";
//see: http://stackoverflow.com/a/619725/568884
return substr_compare($endsWith, $email, -strlen($email), strlen($email)) === 0;
}
}
application/language/english/form_validation_lang.php:
Add: $lang['belongstowork'] = "Sorry, the email must belong to work.";
Are you need validation something like this in a Codeigniter callback function?
$this->form_validation->set_rules('email', 'email', 'trim|required|max_length[254]|valid_email|xss_clean|callback_spare_email[' . $this->input->post('email') . ']');
if ($this->form_validation->run() == FALSE)
{
// failed
echo 'FAIL';
}
else
{
// success
echo 'GOOD';
}
function spare_email($str)
{
// if first_item and second_item are equal
if(stristr($str, '#mywork.com') !== FALSE)
{
// success
return $str;
}
else
{
// set error message
$this->form_validation->set_message('spare_email', 'No match');
// return fail
return FALSE;
}
}
A correction to Jordan's answer, the language file that you need to edit should be located in
system/language/english/form_validation_lang.php
not application/.../form_validation_lang.php. If you create the new file under the application path with the same name, it will overwrite the original in the system path. Thus you will lose all the usage of the original filters.