Closed shyandsy closed 9 years ago
Do you have both backend and frontend on the same domain?
Add Your captcha controller and action to validation rule. ['verifyCode', 'captcha', 'captchaAction' => 'user/captcha', 'caseSensitive' => false,]
@samdark the url for frontend http://127.0.0.1/shyclouds/advanced/frontend/web/index.php?r=site%2Fcontact
the url for backend http://127.0.0.1/shyclouds/advanced/backend/web/index.php?r=site%2Fcontact
I haven't do anything on the backend.
@jafaripur
I just changed the initial project. You know there is a contactForm in the initial project.
Is that mean I should write a controller for all captcha by my self?
No, you can use yii\captcha\CaptchaAction
via actions
method of controller.
If the problem is still there, check http://www.yiiframework.com/doc-2.0/guide-tutorial-shared-hosting.html#separate-sessions-and-cookies
Hi, i tried that. but it does not work.
I just run the advanced template in the locally XAMPP environment.
and I guess this problem isnot about the request.
It is in same one request. The validate action is called twice. but in the vendor\yiii2soft\yii2\captcha\CaptchaAction.php $code = $this->getVerifyCode();
it get different code for $model->validate() and $model->save();
@shyandsy out of ideas. The best thing to do now is to try reproducing the problem with clean installation of advanced application + minimum amount of modifications for it. If it's there then we'll need clear steps on how to reproduce it locally.
the following is the processing to reproding the same problem
1.composer setup the project composer create-project --prefer-dist yiisoft/yii2-app-advanced reproducing
2.execute command cd reproducing init (choose development mode)
3.phpmyadmin create database create database reproducing
4.create table
CREATE TABLE IF NOT EXISTS `message_board` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(255) NOT NULL,
`lastname` varchar(255) NOT NULL,
`telephone` varchar(128) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`content` varchar(8192) DEFAULT NULL,
`date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
5.modify common/config/main.php
<?php
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
]
],
];
6.modify frontend/config/main.php
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);
return [
'id' => 'app-frontend',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'frontend\controllers',
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=reproducing', // MySQL, MariaDB
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
'params' => $params,
];
7.create .htaccess file in \frontend\web
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
8.use gii module to generate frontend\models\MessageBoard
<?php
namespace frontend\models;
use Yii;
/**
* This is the model class for table "message_board".
*
* @property integer $id
* @property string $firstname
* @property string $lastname
* @property string $telephone
* @property string $email
* @property string $content
* @property string $date_added
*/
class MessageBoard extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'message_board';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['firstname', 'lastname'], 'required'],
[['date_added'], 'safe'],
[['firstname', 'lastname', 'email'], 'string', 'max' => 255],
[['telephone'], 'string', 'max' => 128],
[['content'], 'string', 'max' => 8192]
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'firstname' => 'Firstname',
'lastname' => 'Lastname',
'telephone' => 'Telephone',
'email' => 'Email',
'content' => 'Content',
'date_added' => 'Date Added',
];
}
}
9.modify the frontend\controller\SiteController.php, function actionContact
use frontend\models\ContactForm;
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
//'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
public function actionContact()
{
$model = new MessageBoard();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->save();
return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}
10.modify the \frontend\views\site\contact.php
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\captcha\Captcha;
/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \frontend\models\ContactForm */
$this->title = 'Contact';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-contact">
<h1><?= Html::encode($this->title) ?></h1>
<p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
<?= $form->field($model, 'firstname') ?>
<?= $form->field($model, 'lastname') ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'telephone') ?>
<?= $form->field($model, 'content')->textArea(['rows' => 6]) ?>
<?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
]) ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
11.modify the \frontend\models\MessageBoard.php
public function rules()
{
return [
[['firstname', 'lastname', 'email', 'content'], 'required'],
//[['date_added'], 'safe'],
[['firstname', 'lastname', 'email', 'content'], 'string', 'max' => 255],
[['telephone'], 'string', 'max' => 10],
// verifyCode needs to be entered correctly
['verifyCode', 'captcha']
];
}
now, you will see the captcha changed after $model->validate
@samdark so what is that exact mean?
this is whole process to create a new project based initial project to show that problem
use frontend\models\ContactForm;
public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], 'captcha' => [ 'class' => 'yii\captcha\CaptchaAction', //'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, 'TestLimit'=>99, //try it ], ]; }
@HLH12321 I haven't use the ContactForm model, instead , I create MessageBoard for myself
I'm trying to isolate the problem by throwing out everything that is most probably not related to the problem.
Hi, i ran into the same problem, here are some details i got so far
when i do a
$session = Yii::$app->session;
var_dump($session);
right before i output the captcha widget, i get the following output
object(yii\web\Session)[323]
public 'flashParam' => string '__flash' (length=7)
public 'handler' => null
private '_cookieParams' =>
array (size=1)
'httponly' => boolean true
private '_hasSessionId' => null
private '_events' (yii\base\Component) =>
array (size=0)
empty
private '_behaviors' (yii\base\Component) => null
The letters on the image are "jasamql", i enter them correctly, the client side validator accepts them
When i submit the form to the server, the result from this code executed in the Controller
$model->validate();
var_dump( $model->errors );
var_dump($_POST);
var_dump($_SESSION);
is the following
array (size=1)
'verifyCode' =>
array (size=1)
0 => string 'The verification code is incorrect.' (length=35)
array (size=2)
'_csrf' => string 'cjJWc2lMaW85SmY5BiJQKktWCTchfgAKLQQbAT4oLRofXDkKLS0YPQ==' (length=56)
'NewsComment' =>
array (size=5)
'reply_id' => string '' (length=0)
'name' => string 'asdf' (length=4)
'email' => string 'asdasd@asd.asd' (length=14)
'comment' => string 'asdf' (length=4)
'verifyCode' => string 'jasamql' (length=7)
array (size=5)
'__flash' =>
array (size=0)
empty
'interests' => string 'sadf,test123,test,minewolf,minewolf ,asdfsadf,mine,asdfasdf,qwerqwrqwrwqrqwrqwasfasdfasd,adsf,qwerqwerwqrqwrqwrwqrqwasfsa,sfdsdvgggggv6e4g6bve56he,sldfghsdlkghsjdhg,hberhybertyhberyebtybeybnjhdbhfg,dgh sdhg h sh gfh fgh ,gdsfghsdhfghsdghsldhgshdgsdgdfg,asdfasdfffffvgfwe,minewolf\,mineowlf,minewlf' (length=297)
'experts_message' => int 1
'__captcha/site/captcha' => string 'hevevlu' (length=7)
'__captcha/site/captchacount' => int 2
{"success":false,"replies_count":"0","parent_id":"","is_reply":false}
as You can see the letters i had displayed in the captcha image are different from the
'__captcha/site/captcha' => string 'hevevlu' (length=7)
i am entering the captcha letters right after i refresh tha page, without any other interactions on the page
it is maybe important to say that i submit the form using jquery ajax post (using a method shown as an example here in Github by Qiang Xue) because Pjax was not right for the situation, so the form is submitted via Ajax call. As you can see the data for the captcha field is sent to the server successfully.
At the moment i don't have idea what else to check for , so i'll wait for some response.
We are using Yii 2.0 stable, advanced application and the backend and frontend are on different domains.
Tomorrow i may try to create a simple page with a simple model and form and see what happens then.
Thanks.
@martingeorg could you format you code and dump data.
That will make information more clearly..
could you format you code and dump data.
I have updated it.
Hi again, it turned out to be related to that https://github.com/yiisoft/yii2/commit/c8c6882fc4ef8de11d1d5fa402b4303a06ab4079 , i had a call to validate() before the save() and that's what changed the captcha code.
There is actually a documentation about that here http://stuff.cebe.cc/yii2docs/yii-captcha-captchavalidator.html "Note that once CAPTCHA validation succeeds, a new CAPTCHA will be generated automatically. As a result, CAPTCHA validation should not be used in AJAX validation mode because it may fail the validation even if a user enters the same code as shown in the CAPTCHA image which is actually different from the latest CAPTCHA code." maybe it should be with H1 tags :)
By calling save() with false parameter e.g. $model->save(false); resolved the issue.
As i see, @shyandsy code also has a call to validate(), so i'm guessing that using save(false) will resolve his issue as well, hopefully.
I apologize if i wasted Your time :/
If someone can now help me with that question http://www.yiiframework.com/forum/index.php/topic/59588-captcha-custom-template-how-to-get-error-into-the-widgets-template/ it would be great :)
Again Thanks .
@samdark @martingeorg thanks for your work. That is the problem.
Hi @shyandsy, i have same problem. my captcha is always given incorrect when form submit. any solution?? i am very tired.
@nageennayak11
As mentioned by @martingeorg you might be calling $model->validate()
more than once.
$model->save()
internally calls $model->validate()
.
So if you have $model->validate()
and $model->save()
then replace $model->save()
with $model->save(false)
.
messageBoard model
sitecontroller, the problem is on the actionContact
captcha file: vendor\yiii2soft\yii2\captcha\CaptchaAction.php
when the code run to $model->validate(), the captcha verify return true
but after that, in the process of $model->save(), the captcha is changed. and validate return false.
then I cant save data because the captcha is always incorrect