I have used capcha in one of my forms. It always give verification code incorrect error.
Below is my code:
SchoolsController.php
public function actions() {
return [
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fontFile' => '#yii/captcha/SpicyRice.ttf',
'padding' => '0',
]
];
}
Model:
['verifyCode', 'captcha', 'captchaAction' => 'schools/captcha'],
View:
echo $form->field($modelSchoolRequestEarlyAccess, 'verifyCode')->widget(Captcha::className(), [
'options' => [
'placeholder' => 'Enter characters in the image',
'autocomplete' => 'off',
'maxlength' => 20
],
'captchaAction' => 'schools/captcha',
'template' => "<div class='field'><span><strong>*</strong>".Yii::t('frontend/quicksignup','VerifyCodeLabel').":</span></span>\n<div>{image}{input}<i class='refresh-code-icn' id='get-new-code'></i></div></div>"
])->label(false);
I have specified the captcha action as schools/captcha in model as well as view. But it always show verification incorrect.
What am I doing wrong??
You wrote SchoolController.php and your route is to schools. So you probably need to adjust your route to school/captcha
Did you add the rules?
public function rules()
{
$rules = parent::rules();
$rules[] = ['captcha', 'required'];
$rules[] = ['captcha', 'captcha'];
return $rules;
}
Related
Whan I add 'on' => 'create' in my rule my captcha always incorrect
Off that work good why?
I try to let it to other controller support/captcha but still incorrect
MyView
<?= Captcha::widget([
'id' => 'captcha',
'model' => $model,
'attribute' => 'verifyCode',
'options' => ['class' => 'form-control',
'data-v-rule' => '',
'captchaAction' => 'support/captcha',
'data-v-msg' => $i18n->t('please.input.verify.code'),
'placeholder' => $i18n->t('please.input.verify.code', '', false)]
]); ?>
Myrule
...
[['verifyCode'], 'captcha', 'message' => $i18n->t('error.verifyCode'),'captchaAction' => 'support/captcha' , 'on' => 'create'],
...
I get seesion
$_SESSION = [
'__flash' => [],
'__captcha/site/captcha' => 'nnbioo',
'__captcha/site/captchacount' => 1,
'__captcha/support/captcha' => 'cacijq',
'__captcha/support/captchacount' => 1,
];
Mycontroller
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => CaptchaAction::className(),
],
];
}
$customerServiceModel->load($post) is not working, because attribute verifyCode is not safe in this case. Your rule is specified with 'on' => 'create' - so it means, it's save on scenario create. You didn't assigned this scenario to the model so there's 2 solutions:
Remove 'on' => 'create' from rule
Assign create scenario to model by $customerServiceModel->scenario = 'create'; before using load().
I have a page that contains multi captcha in separated forms form example login and register modals , etc.
if I use below codes the problem is that when refresh one captcha then another captcha will be unusable because they use same session varible:
1) Login
login modal (view):
echo Captcha::widget([
'id' => 'Login-captcha',
'name' => 'LoginModel[captcha]',
'captchaAction' => '/site/captcha'
]);
LoginModel :
public function rules()
{
return [
['captcha', 'captcha'],
];
}
2) Register
register modal (view):
echo Captcha::widget([
'id' => 'register-captcha',
'name' => 'RegisterModel[captcha]',
'captchaAction' => '/site/captcha'
]);
RegisterModel:
public function rules()
{
return [
['captcha', 'captcha'],
];
}
to solve session problem I used different captcha actions to set different session variables:
1)Login
login modal view:
echo Captcha::widget([
'id' => 'Login-captcha',
'name' => 'LoginModel[captcha]',
'captchaAction' => '/site/captcha-login'
]);
LoginModel :
public function rules()
{
return [
['captcha', 'captcha', 'captchaAction' => 'site/captcha-login',],
];
}
2) Register
register modal (view):
echo Captcha::widget([
'id' => 'register-captcha',
'name' => 'RegisterModel[captcha]',
'captchaAction' => '/site/captcha-register'
]);
RegisterModel:
public function rules()
{
return [
['captcha', 'captcha', 'captchaAction' => 'site/captcha-register',],
];
}
until now everything is ok but when I move sessions from regular php files to database by below config in commponent section of main config file:
'session' => [
'class' => 'yii\web\DbSession',
],
then captchas in the first page load not works and have to refresh them to work correctly.
what is the problem?
Try this, it is for yii1 but you can get the idea, more detail
public function rules()
{
return array(
...
array('verifyCode1', 'captcha', ...
array('verifyCode2', 'verifycaptcha2', ...
);
}
public function verifycaptcha2($attribute, $params)
{
$captcha2 = Yii::app()->getController()->createAction('captcha2nd');
if (!$captcha2->validate($this->verifyCode2, false))
{
$this->addError('verifyCode2', 'invalid captcha.');
}
}
Also see this
i'm building multi lingual site with English and Arabic
url for English
url for Arabic
I want to switch language from any page exactly to the same page of the other language
so i made code like below.
$route = Yii::$app->controller->route;
$params = $_GET;
array_unshift($params, '/'.$route);
<?php if(Yii::$app->language == 'ar'){ ?>
<?= Html::a('English', [Yii::$app->urlManager->createUrl($params), 'language'=>'en']); ?>
<?php }else{?>
<?= Html::a('Arabic', [Yii::$app->urlManager->createUrl($params), 'language'=>'ar']); } ?>
and my url generating like below
/multi/backend/web/en/multi/backend/web/ar/site/index?val=hii&net=good
English
don't know what is wrong?
I'm using this for language management.
please check my main.php under backend/config
<?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-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'language' => 'en',
'sourceLanguage' => 'en_UK',
'bootstrap' => ['log'],
'modules' => [],
'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',
],
'i18n' => [
'translations' => [
'app' => [
'class' => 'yii\i18n\DbMessageSource',
'sourceLanguage' => 'en_UK',
],
],
],
'urlManager' => [
'class' => 'codemix\localeurls\UrlManager',
'languages' => ['en', 'ar'],
'enableDefaultLanguageUrlCode' => false,
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
],
'params' => $params,
];
If you are doing it as in your example, you have to think about it on every link you create. This can be automated easily.
URL-Rule
You can solve this with an url-rule in your config file like so:
'<language:[\w]{2,2}>/<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
This will assert the proper routing to your controller and provide you the desired language in the language-variable.
Custom UrlManager
You can extend the UrlManager-class and make sure the current language is always appended to the params:
class MyUrlManager extends \yii\web\UrlManager
{
// ...
/**
* #inheritdoc
*/
public function createUrl($params)
{
if (!isset($params['language'])) {
$params['language'] = Yii::$app->language;
}
return parent::createUrl($params);
}
// ...
}
This will automate the process of adding the language to the links you create.
Custom Application
Now you should also override the Application-class and always set the language to the one provided or choose a default (in this case en):
class MyApplication extends \yii\web\Application
{
// ...
/**
* #inheritdoc
*/
public function init()
{
parent::init();
$lang = Yii::$app->request->get('language', 'en');
Yii::$app->language = $lang;
}
// ...
}
Now your language will always be set to the default value or the one provided viathe query param as specified above.
Final thoughts
This should give you the basic idea on how to solve your problem. Adjust as necessary...especially the last part with the Application-class and how you retrieve the value of the language-var. I hope it helped!
Possible problems with your code and the extension provided
If you read the docs of the extension the urls are generated differently. It tells you to create the urls as follows:
Url::to(['demo/action', 'language'=>'ar'])
You are createing a simple link-tag and overwrite the $params. Try this instead:
echo Html::a('Arabic', Url::to(['site/index', 'language'=>'ar']));
For redirection to the current page just replace the first part with the current route.
after lots of trying ..i found a solution.. now its worked for me.
$route = Yii::$app->controller->route;
if(Yii::$app->language == 'ar'){
$_GET['language'] = 'en';
}else{
$_GET['language'] = 'ar';
}
$params = $_GET;
array_unshift($params, '/'.$route);
<?php if(Yii::$app->language == 'ar'){ ?>
<?= Html::a('English', Yii::$app->urlManager->createUrl($params)); ?>
<?php }else{?>
<?= Html::a('Arabic', Yii::$app->urlManager->createUrl($params)); } ?>
its working for the url like
http://localhost/multi/backend/web/site/index?page=2&per-page=6
and
http://localhost/multi/backend/web/site/index
I am using kartik yii2 editable extension to edit inline in gridview.
The extension is working fine.
Please refer this screen-shot link [http://awesomescreenshot.com/00753dvb73][1]
In this screen-shot the source field is a dropdown and I want the value of source instead id its id
My View
use kartik\editable\Editable;
[
'attribute'=>'source',
'format'=>'raw',
'value'=> function($data){
//$s = $data->getBacklog_source();//var_dump($s);exit;
return Editable::widget([
'name'=>'source',
'model'=>$data,
'value'=>$data->source,
'header' => 'Source',
'type'=>'primary',
'size'=> 'sm',
'format' => Editable::FORMAT_BUTTON,
'inputType' => Editable::INPUT_DROPDOWN_LIST,
'data'=>$data->getSource(), // any list of values
'options' => ['class'=>'form-control', 'prompt'=>'Select Source'],
'editableValueOptions'=>['class'=>'text-danger'],
'afterInput' => Html::hiddenInput('id',$data->id),
]);
}
],
The relation I made is:
public function getSource()
{
$source = BacklogSource::find()->all();
return ArrayHelper::map($source, 'id', 'Source');
}
public function getBacklog_complexity()
{
return $this->hasOne(BacklogComplexity::className(), [
'id' => 'complexity'
]);
}
Thanks for help in advance
I got the solution something like this:
[
'attribute'=>'status',
'format'=>'raw',
'value'=> function($data){
$s = BacklogStatus::findOne($data->status);
return Editable::widget([
'name'=>'status',
'model'=>$data,
'value'=>$s->Status,
'header' => 'Status',
'type'=>'primary',
'size'=> 'sm',
'format' => Editable::FORMAT_BUTTON,
'inputType' => Editable::INPUT_DROPDOWN_LIST,
'data'=>$data->getStatus(), // any list of values
'options' => ['class'=>'form-control', 'prompt'=>'Select Source'],
'editableValueOptions'=>['class'=>'text-danger'],
'afterInput' => Html::hiddenInput('id',$data->id),
]);
}
],
I have used the gii tool to create crud application. I have 3 tables the tbl_targetcities, lib_cities, and lib_provinces. I was able to connect lib_cities to tbl_targetciteis but not the lib_provinces. And also the sorting of city / Municipality does not work. It seems that it sorts according ti the ID.
tbl_target_cities
lib_cities
lib_provinces
sample View
So far here is my relation in the model.
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code']);
}
in my view file...
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute'=>'city_code',
'value'=>'cityName.city_name'
],
[
'attribute'=>'prov code',
'value'=>'cityName.city_name'
],
'kc_classification',
'cluster',
'grouping',
'priority',
'launch_year',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
How to display the prov_name from lib_provinces???
EDIT to answer user2839376 question in the comment box
IN THE SEARCH MODEL CLASS
$query = TblSpBub::find();
$query->joinWith('brgyCode')->joinWith(['cityCode'])->joinWith(['cityCode.provCode']);
$covered= LibAreas::find()->where(['user_id'=>yii::$app->user->identity->id])->all();
$query->all();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort'=> ['defaultOrder' => ['id'=>SORT_DESC]],
]);
$dataProvider->sort->attributes['city'] = [
'asc' => ['lib_Cities.city_name' => SORT_ASC],
'desc' => ['lib_Cities.city_name' => SORT_DESC],
];
$dataProvider->sort->attributes['province'] = [
'asc' => ['lib_provinces.prov_name' => SORT_ASC],
'desc' => ['lib_provinces.prov_name' => SORT_DESC],
];
In LibCities model add new relation:
public function getProvince()
{
return $this->hasOne(LibProvince::className(),['prov_code'=>'prov_code']);
}
And change getCityName relation. You should add with() for relation:
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code'])->with(['province']);
}
And in view correct your columnto this:
[
'attribute'=>'prov code',
'value'=>'cityName.province.prov_name'
],
You have to use the function relations() in models.
In tbl_target_cities model:
public function relations()
{
return array(
'city' => array(self::HAS_ONE, 'LibCities', 'city_code'),
);
}
In LibCities model :
public function relations()
{
return array(
'province' => array(self::HAS_ONE, 'LibProvinces', 'prov_code'),
'targets' => array(self::HAS_MANY, 'TargetCity', 'city_code',
);
}
This will allowed you to jump throw the LibCities model,
now you can simply acces to prov name like this :
$model->city->province->prov name;
Note : You need to have the 3 models defined.
EDIT
array(
'name' => 'province name',
'value' => $data->city->province->prov_name;
),
Done it, Heres how.
in addition to the above code (original post)
// in Model I added an additional function
public function getTaskowner()
{
return $this->hasOne(Tasks::className(), ['id' => 'task_id'])
->with(
['location','taskowner']
);
}
and in view i did this
....
'columns' => [
....
[
'class' => 'kartik\grid\DataColumn',
'value'=> 'tasks.location.taskowner.name',
.....
],
.....
and it worked
key points. used an array with the 'with->(..)' to include both then in the view added 'tasks.location.taskowner.name', to join them all