Im trying to add a captcha using yii to my contact form, but there is some problem with validation.
My model
class ContactForm extends CFormModel
{
public $verifyCode;
public function rules()
{
return array(
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(),'on'=>'captchaRequired'),
array('verifyCode', 'safe'),
);
}
}
Code in my controller
public function filters()
{
return array(
'accessControl',
);
}
public function accessRules()
{
return array(
array( 'allow', //allow all users to perform advertise and index action
'actions' => array('advertise','index', 'captcha'),
'users' => array('*'),
),
);
}
public function actions() {
return array(
// captcha action renders the CAPTCHA image displayed on the contact page
'captcha' => array(
'class' => 'CCaptchaAction',
'backColor' => 0xFFFFFF,
'testLimit'=> '2',
),
)
}
public actionAdvertise()
{ $model = new ContactForm;
$model->scenario = 'captchaRequired';
if($model->validate()){
//some code
} else {
$this->render('advertise', array('model' => $model));
}
}
}
Code in my advertise.php view
<form action="" method="post">
<?php
$form=$this->beginWidget('CActiveForm',array(
'id'=>'contact-form',
'enableAjaxValidation'=>false,
));
?>
<?php if(CCaptcha::checkRequirements()){ ?>
<div class="row">
<div class="contact_field_wrapper">
<?php echo '<b>ARE YOU HUMAN?</b><br />'.$form->labelEx($model, 'verifyCode'); ?>
<div class="captcha user-captcha">
<?php $this->widget('CCaptcha',array( 'captchaAction'=>'site/captcha' ));
?>
<?php echo $form->error($model, 'verifyCode'); ?>
<?php echo '<br />'.$form->textField($model,'verifyCode'); ?>
<div class="hint">Please enter the letters as they are shown in the image above.<br/>
Letters are not case-sensitive.
</div>
</div>
</div>
</div>
<?php } ?>
<?php $this->endWidget(); ?>
</form>
The problem is that $model->validate() returns false when correct code in inputted.
$model->getErrors() is always returning 'Verification code is incorrect'.
your model is empty , because you didn't pass any value to $model->attriburtes
Do this :
if($_POST['ContactForm'])
{
$model->attributes() = $_POST['ContactForm'];
if($model->validate())
{
//some code
}
}
$this->render('advertise', array('model' => $model));
Related
I am using yii2 basic for my application. When I login to my application by typing wrong username or password, it does not set any message like incorrect username or password. The browser simply refreshes the page.
This is my site/login.php file:
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
/* #var $this yii\web\View */
/* #var $form yii\bootstrap\ActiveForm */
/* #var $model app\models\LoginForm */
$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-login">
<h1><?= Html::encode($this->title) ?></h1>
<p>Please fill out the following fields to login:</p>
<?php $form = ActiveForm::begin([
'id' => 'login-form',
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => [
'template' => "{label}\n<div class=\"col-lg-3\">{input}</div>\n<div class=\"col-lg-8\">{error}</div>",
'labelOptions' => ['class' => 'col-lg-1 control-label'],
],
]); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'rememberMe')->checkbox([
'template' => "<div class=\"col-lg-offset-1 col-lg-3\">{input} {label}</div>\n<div class=\"col-lg-8\">{error}</div>",
]) ?>
<div class="form-group">
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
<!-- <div class="col-lg-offset-1" style="color:#999;">
You may login with <strong>admin/admin</strong> or <strong>demo/demo</strong>.<br>
To modify the username/password, please check out the code <code>app\models\User::$users</code>.
</div> -->
</div>
And here is my action for login:
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post())) {
$model->password = md5($model->password);
$model->login();
return $this->redirect(['site/index']);
}
return $this->render('login', [
'model' => $model,
]);
}
Any help would be greatly appreciated.
You can add a custom message error in your rules.
public function rules()
{
return [
['username', 'required', 'message' => 'Please choose a username.'],
];
}
It creates a JavaScript vaidation and shows the error in message if validation was wrong.
See Validating Input and Customizing Error Messages section.
EDIT:
If you are using the basic app, make sure that your LoginForm.php has the login form calls validate. Something like this:
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
} else {
return false;
}
}
This is from the advanced template but is similar.
The if ($model->load())-statement does no validation at all. It simply determines if the form in question was POSTed and that the POST data was loaded into the form instance. I'm assuming that the login() function returns a bool so you'll have to check its return result as well:
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post())) {
$model->password = md5($model->password);
if ($model->login()) {
return $this->redirect(['site/index']);
}
}
return $this->render('login', [
'model' => $model,
]);
}
If the login function correctly uses the model::addError() function it should then also display errors.
The login-function of the basic application does run the validation, as #Sageth pointed out, so the change I proposed will work as expected.
my problem is with two or more files.
this codes is form Yii application development cookbook(2nd edition), chapter 4
i use Yii 1.1.14
controller:
<?php
class UploadController extends Controller
{
function actionIndex()
{
$dir = Yii::getPathOfAlias('application.uploads');
$uploaded = false;
$model=new Upload();
if(isset($_POST['Upload']))
{
$model->attributes=$_POST['Upload'];
$files=CUploadedFile::getInstances($model,'file');
if($model->validate()){
foreach($files as $file)
$file->saveAs($dir.'/'.$file->getName());
}
}
$this->render('index', array(
'model' => $model,
'dir' => $dir,
));
}
}
model:
<?php
class Upload extends CFormModel
{
public $file;
public function rules()
{
return [
['file', 'file', 'types'=>'jpg'],
];
}
}
view:
<?php if($uploaded):?>
<p>File was uploaded. Check <?php echo $dir?>.</p>
<?php endif ?>
<?php echo CHtml::beginForm('','post',array('enctype'=>'multipart/form- data'))?>
<?php echo CHtml::error($model, 'file')?>
<?php echo CHtml::activeFileField($model, "[0]file")?>
<?php echo CHtml::activeFileField($model, "[1]file")?>
<?php echo CHtml::submitButton('Upload')?>
<?php echo CHtml::endForm()?>
help me, please
You should fix form enctype, use multipart/form-data instead of multipart/form- data.
You could use CMultiFileUpload
controller:
$images = CUploadedFile::getInstancesByName('image');
foreach ($images as $image => $pic) {
}
view:
$this->widget('CMultiFileUpload', array(
'name' => 'image',
'accept' => 'jpeg|jpg|gif|png',
'duplicate' => 'Duplicate file!',
'denied' => 'Invalid file type',
));
Add to model 'maxFiles' param, if you need validation to work properly for multifiles upload.
public function rules()
{
return array(
array('image', 'file', 'types'=>'jpg,gif,png', 'maxSize'=>'204800', 'allowEmpty'=>true, 'maxFiles'=>4),
);
}
I have a question and trouble with my code,
I am doing login through codeigniter framework, but having issue with login,
When i enter user\password in login form it again coming back to same login page instead of moving to Home1 class.
My guess is this problem due to form_open('index.php/welcome/login') in login page form, i am not sure how this works for login,
Below two are my class from controller,
public function login() //this used for login
{
$this->load->view('login');
$this->m_user->user_login();
}
public function home1()//this will be redirecting class
{
$this->load->view('home1');
}
this is model,
public function index()
{
if(($this->session->userdata('email')!=""))
{
$this->welcome();
}
else
{
$data['title']='Home';
$this->load->view('login',$data);
}
}
function user_login()
{
$user_email=$this->input->post('user_email');
$user_password=md5($this->input->post('user_password'));
$this->db->where('user_email',$user_email);
$this->db->where('user_password',$user_password);
$query=$this->db->get('ca_user');
if($query->num_rows()>0)
{
foreach($query->result() as $rows)
{
//add all data to session
$_userdata = array(
'user_id' => $rows->user_id,
'user_firstname' => $rows->user_firstname,
'user_lastname' => $rows->user_lastname,
'user_email' => $rows->user_email,
'logged_in' => TRUE,
);
}
$this->session->set_userdata($_userdata);
redirect('home1','refresh');
return true;
}
return false;
redirect('signup','refresh');
}
and this is login page
<?php echo validation_errors('<p class="error">'); ?>
<?php echo form_open('index.php/welcome/login'); ?>
<input type="text" placeholder="Username" class="input-field form-control user" name="username" value="<?php echo set_value('user_email');?>" />
<input type="password" placeholder="Password" class="input-field form-control password" name="password" value="<?php echo set_value('user_password');?>" />
<button type="submit" class="btn btn-login ladda-button" data-style="expand-left" name="submit"><span class="ladda-label">login</span></button>
<?php echo form_close(); ?>
First, you cant load a view from your model. Usually model is where your logic placed. To the point i will give you basic sample login method in CI using MVC.
Your Model:
class Login extends CI_Model
{
// validation setting
public function LoginRules()
{
# code...
$login_user = [
[
'field' => 'email',
'label' => 'Email Adress',
'rules' => 'required'
],
[
'field' => 'password',
'label' => 'Password',
'rules' => 'required'
]
];
return $this->form_validation->set_rules($login_user);
}
// validation method
public function validate()
{
if ($this->LoginRules())
{
if ($this->form_validation->run())
{
# code...
return TRUE;
}
else
{
return FALSE;
}
}
}
//Check the user data in database
public function CheckUser()
{
$query = $this->db->where('email', $this->input->post('email'))
->where('password', $this->input->post('password'))
->limit(1)
->get('your table name');
foreach ($query->result() as $result) ;
if ($query->num_rows() == 1)
{
$userData = [
'email' => $pengguna->email,
'username' => $pengguna->username,
'login' => TRUE
];
$this->session->set_userdata($userData);
return TRUE;
}
else
{
return FALSE;
}
}
//logout function
public function destroy()
{
$this->session->unset_userdata(
[
'username' => '',
'email' => '',
'login' => FALSE,
]
);
$this->session->sess_destroy();
}
}
Then your controller:
public function UserLogSuccess()
{
if ($this->session->userdata('login') == FALSE)
{
//flash msg data for login failure
$data = [
'msg' => 'Must login'
];
$this->session->set_flashdata('msg', $data);
//redirect user back to login form
redirect('login');
}
else
{
// give access
$data = [
'uname' => $this->session->userdata('username'),
'email' => $this->session->userdata('email')
];
$this->load->view('user/index', $data);
}
}
And minimal login form:
<div>
<?php
if (!empty($this->session->flashdata('msg')))
{
// you may ignore this
foreach ($this->session->flashdata('msg') as $key => $message)
{
echo $message['access_tanpa_login'];
}
}
echo form_open('login', ['class' => 'form', 'method' => 'POST']);
?>
<fieldset>
<label>Username</label>
<input type="text" name="email" class="form-control">
<?php echo form_error('email', '<span class="error">', '</span>'); ?>
</fieldset>
<fieldset>
<label>Password</label>
<input type="password" name="password" class="form-control">
<?php echo form_error('password', '<span class="error">', '</span>'); ?>
</fieldset>
<fieldset>
<input type="submit" value="Login" class="form-button">
</fieldset>
</form>
</div>
Addition : Sample of validate user on controller
public function MyLoginProceed()
{
if ($this->login->validate())
{
//load the validation model
if ($this->login->CheckUser())
{
// if TRUE, then redirect
redirect('any/where/you/like');
}
else
{
// Login Fail, set flash msg here
$data = ['msg' => 'Fail'];
$this->session->set_flashdata('msg', $data);
// Redirect back to login
redirect('login');
}
}
}
Edit til fit your need. This is just basic approach as example, not clean or bullet proof. Learning purpose.
what form_open('index.php/welcome/login') actaully does is that it generates a html form open tag for you .
For eg : form_open('index.php/welcome/login'); will generate
>/index.php/welcome/login"> and if CSRF is set to true it will generate a hidden input containing CSRF cookie code also.
So when your page loads right click on the page and view source and see if the form open html tag is generated or not . If it has generated that means form_open is working.
A suggestion form my side - looking at your code it seems you are not following the model view controller framework properly. Try to just access the database in model and do the redirects in controller . Get the inputs in variables in controller and send them as arguments to models.
I am new to CakePHP, i am creating simple form to add/edit/delete post as it is explain on its official website, my issue, while adding post to database it is not saving data,it is creating blank entries to database
Here is Code for Postscontroller.php
<?php
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
public $components = array('Session');
public function add() {
if ($this->request->is('post')) {
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
//debug($this->Post->validationErrors);
$this->Session->setFlash(__('Unable to add your post.'));
}
}
}
?>
Here is Code for Model Post.php :
<?php
class Post extends AppModel {
public $validate = array(
'title' => array(
'rule' => 'notEmpty'
),
'body' => array(
'rule' => 'notEmpty'
)
);
}
?>
Here is code for View add.ctp :
<h1>Add Post</h1>
<?php
echo $this->Form->create('post');
echo $this->Form->input('title');
echo $this->Form->input('body');
echo $this->Form->end('Save Post');
?>
can anyone suggest me what is causing blank entries to database ?
In the add.ctp :
The form name is Post not post...
<h1>Add Post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body');
echo $this->Form->end('Save Post');
?>
In config/core.php file change the debug label to 2.(Configure::write('debug', 2)) and try saving again. The model name should be Post in the form. Please check the post data before saving.
debug($this->request->data);
exit;
I have created a form using widget -bootstrap.widgets.TbActiveForm with form elements like textFieldRow, TbTypeahead, CJuiDatePicker and TbButton. I have implemented ajax form submission and it works fine. And I have included a simple client side validation,the rules are defined in the EmployeeRegister model. Its a simple validation for empty fields only. The problem is that when I submit the form with required fields empty, the form get submitted. That is, no validation is performed. But it displays error message "Name cannot be blank." or "Address cannot be blank.". Can anyone help me to fix this issue??
I am attaching my code below.
// MOdel- EmployeeRegister
class EmployeeRegister extends CActiveRecord{
public $name;
public $address;
public $position;
public $joinDate;
public $age;
public $phone;
public $search;
public $id;
private $_identity;
public function rules(){
return array(
array('name,address,position,phone','required'),
array('joinDate,age,search,id','safe'),
);
}
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'emp_registration';
}
//View- edit.php
$form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'id'=>'employeeregister-form',
//'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions'=>array('validateOnSubmit'=>true),
'htmlOptions'=>array('class'=>'well',),
)); ?>
<?php echo $form->textFieldRow($model, 'name',array('class'=>'span3','style'=>'height:30px','id'=>'emp_name')); ?>
<?php echo $form->textFieldRow($model, 'address', array('class'=>'span3','style'=>'height:30px','id'=>'emp_address')); ?>
<?php // echo $form->textFieldRow($model, 'position', array('class'=>'span3','value'=>$result['position'],'style'=>'height:30px')); ?>
<?php echo "<br/> Position <br/>";?>
<?php $this->widget('bootstrap.widgets.TbTypeahead', array(
'model'=>$model,
'htmlOptions'=>array('style'=>'height:30px','id'=>'emp_position'),
'attribute'=>'position',
'options'=>array(
'source'=>array(
'Junior Software Engineer','Software Engineer','Designer'),
'items'=>4,
'matcher'=>"js:function(item) {
return ~item.toLowerCase().indexOf(this.query.toLowerCase());
}",
)));
?>
<?php //echo $form->textFieldRow($model, 'joinDate', array('class'=>'span3','value'=>$result['joinDate'],'id'=>'datepicker')); ?>
<?php echo "<br/> Join Date <br/>";?>
<?php $this->widget('zii.widgets.jui.CJuiDatePicker',array(
'model'=>$model,
'attribute'=>'joinDate',
//'value'=>$result['joinDate'] ? $result['joinDate'] : "",
// additional javascript options for the date picker plugin
'options'=>array(
'showAnim'=>'fold',
'dateFormat'=>'yy-mm-dd',
),
'htmlOptions'=>array(
'style'=>'height:30px;','id'=>'emp_date'
)
)); ?>
<?php echo $form->textFieldRow($model, 'age', array('class'=>'span3','style'=>'height:30px','id'=>'emp_age')); ?>
<?php echo $form->textFieldRow($model, 'phone', array('class'=>'span3','style'=>'height:30px','id'=>'emp_phone')); ?>
<?php echo $form->textFieldRow($model, 'id', array('class'=>'span3','style'=>'height:30px; display:none;','id'=>'emp_id')); ?>
<?php echo "<br/>";?>
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'ajaxSubmit', 'label'=>'Update','type'=>'primary','htmlOptions'=>array('name'=>'update_button',),
'url'=>CController::createUrl('site/update'),
'ajaxOptions'=>array(
'type'=>'POST',
'dataType'=>'json',
'data'=>'js:$("#employeeregister-form").serialize()',
'success'=>'js:function(data){
//$("#update_err").html(data);
alert(data);
}',
'async' => true,
)); ?>
<?php //echo $form->error($model,'name,address,position,phone'); ?>
<?php $this->endWidget(); ?>
<div id="update_err"></div>
<?php echo CHtml::link('Back to List',array('site/index')); ?>
//Controller
$model= new EmployeeRegister();
$model->attributes = $_POST['EmployeeRegister'];
if(Yii::app()->getRequest()->getIsAjaxRequest()) {
echo CActiveForm::validate( array( $model));
Yii::app()->end();
}
$update_id= $model->id;
$name = $model->name;
$address = $model->address;
$position = $model->position;
$joinDate = $model->joinDate;
$age = $model->age;
$phone = $model->phone;
if(EmployeeRegister::model()->updateByPk($update_id, array('id'=>$update_id,'name'=>$name,'address'=>$address,'position'=>$position,'joinDate'=>$joinDate,'age'=>$age,'phone'=>$phone)))
echo $name."'s details updated successfully";
else
echo "Update failed";
use Latest version of yii framework that may solve your problem you may refer to this page