CakePHP 3- Validation for changing password don't work - php

I am making a app with cakephp 3, now i am tring to make a function that allow users change their passwords. The problem is that the validation of the password doesn't work. I don't know if i am doing correctly.
Here is the chage_password.ctp file:
<div class="users form large-9 medium-9 columns">
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Actualice su contraseña') ?></legend>
<?= $this->Form->input('password1',['type'=>'password' ,'label'=>'Ingrese Contraseña']) ?>
<?= $this->Form->input('password2',['type' => 'password' , 'label'=>'Reescriba su Contraseña'])?>
</fieldset>
<?= $this->Form->button(__('Agregar')) ?>
<?= $this->Form->end() ?>
Here is the changePassword function in the UsersControler.php:
public function changePassword($id)
{
$user_data=$this->Users->get($id);
if (!empty($this->request->data)) {
$user = $this->Users->patchEntity($user_data, [
'password' => $this->request->data['password1']
],
['validate' => 'password']
);
$time = Time::now();
$user->set('fecha_cambio_password',$time);
if ($this->Users->save($user)) {
$this->Flash->success('Contraseña Actualizada');
$this->redirect('/users/login');
} else {
debug($user);die;
$this->Flash->error('No se pudo actualizar la contraseña!');
}
}
}
And finally the validation in UsersTable.php:
public function validationPassword(Validator $validator)
{
$validator
->add('password1', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'El largo minimo es 6',
]
])
->add('password1',[
'match'=>[
'rule'=> ['compareWith','password2'],
'message'=>'Los campos no coinciden',
]
])
->notEmpty('password1');
$validator
->add('password2', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'El largo minimo es 6',
]
])
->add('password2',[
'match'=>[
'rule'=> ['compareWith','password1'],
'message'=>'Los campos no coinciden',
]
])
->notEmpty('password2');
return $validator;
}

I found the solution!
You need to pass the password fields in the 2nd argument of the patchEntity() method
$user = $this->Users->patchEntity($user, [
'old_password' => $this->request->data['old_password'],
'password' => $this->request->data['password1'],
'password1' => $this->request->data['password1'],
'password2' => $this->request->data['password2']
],
['validate' => 'password']
);
In order to check the old password you need to modify your current validator as follows:
public function validationPassword(Validator $validator )
{
$validator
->add('old_password','custom',[
'rule'=> function($value, $context){
$user = $this->get($context['data']['id']);
if ($user) {
if ((new DefaultPasswordHasher)->check($value, $user->password)) {
return true;
}
}
return false;
},
'message'=>'The old password is not correct!',
])
->notEmpty('old_password');
$validator
->add('password1', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'Min value is 6',
]
])
->add('password1',[
'match'=>[
'rule'=> ['compareWith','password2'],
'message'=>'Los campos no coinciden',
]
])
->notEmpty('password1');
$validator
->add('password2', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'El largo minimo es 6',
]
])
->add('password2',[
'match'=>[
'rule'=> ['compareWith','password1'],
'message'=>'Los campos no coinciden',
]
])
->notEmpty('password2');
return $validator;
}
Cheers!

Related

Yii2 - DynamicModel validation

I have a form and I want to change my DynamicModel rule validations depedending on the value chosen in a specific select input. I've read this doc but I don't understand why my code doesn't work. I've tried the following with no results:
MyController
private function createFormModel(){
$model = new DynamicModel([
'indicador',
'mes'
]);
$model->addRule(['indicador'], 'required',['message' => 'This field is required']);
$model->addRule(['mes'], 'string');
$model->addRule(
'mes',
function ($attribute, $params, $validator) use ($model) {
if ($model->indicador == 'semana') {
$model->addError('mes', 'This field is required');
}
}
);
return $model;
}
MyView
<?php $form = ActiveForm::begin(); ?>
<!-- indicador -->
<div class="form-group">
<?= $form->field($model, 'indicador')->widget(Select2::class, [
'options' => ['id'=>'indicador'],
'data' => [
'dia' => 'Actividad por Día',
'semana' => 'Actividad por Semana',
'resumen' => 'Resumen de actividad'
],
'pluginOptions' => [
'placeholder'=>'Seleccionar indicador',
'allowClear' => true
],
]); ?>
</div>
<!-- /.indicador -->
<!-- mes -->
<div id = "semana" class="form-group hidden">
<?= $form->field($model, 'mes')->widget(DepDrop::class, [
'type' => DepDrop::TYPE_SELECT2,
'options' => ['id' => 'mes'],
'select2Options' => ['pluginOptions' => ['allowClear' => true]],
'pluginOptions' => [
'depends' => ['indicador'],
'placeholder'=>'Seleccionar mes',
'url' => Url::to(['/campus/subindicador']),
'loadingText' => 'Cargando ...',
'initialize' => true,
]
]);?>
</div>
<!-- /.mes -->
<?= Html::submitButton('Aplicar filtros', ['class' => 'btn btn-block btn-default']) ?>
<?php ActiveForm::end(); ?>
You need to use when with required validator.
$model = new DynamicModel(['indicador', 'mes']);
$model->addRule(['indicador'], 'required', ['message' => 'This field is required']);
$model->addRule(['mes'], 'string');
$model->addRule(['mes'], 'required', ['when' => function ($dModel) {
return $dModel->indicador == 'semana';
}, 'message' => 'This field is required']);

Unable to locate message source for category 'mtrelt'

If I try to update records,I get following error without any ideas, what's about or what this error could have been caused by.
Furthermore, it's strange, that this error only will be bred by records having been imported by a dump. There will be no error, if I will update a record having been created using saveasnew option. Unfortunately, I can't delete this record in order to recreate it,'cause it would expel against referential integrity.
Here is error:
Invalid Configuration – yii\base\InvalidConfigException
Unable to locate message source for category 'mtrelt'.
throw new InvalidConfigException("Unable to locate message source for category '$category'.")
2. in ...\vendor\yiisoft\yii2\i18n\I18N.php at line 88 – yii\i18n\I18N::getMessageSource('mtrelt')
3. in ...\vendor\yiisoft\yii2\BaseYii.php at line 509 – yii\i18n\I18N::translate('mtrelt', 'Data can't be deleted because it...', [], 'de-DE')
4. in ...\vendor\mootensai\yii2-relation-trait\RelationTrait.php at line 312 – yii\BaseYii::t('mtrelt', 'Data can't be deleted because it...')
Here is model:
<?php
namespace common\modules\lookup\models\base;
use Yii;
use mootensai\behaviors\UUIDBehavior;
class LPersonArt extends \yii\db\ActiveRecord
{
use \mootensai\relation\RelationTrait;
public function relationNames()
{
return [
'eAppEinstellungArts',
'lKontaktVerwendungszwecks',
'people'
];
}
public function rules()
{
return [
[['person_art'], 'string', 'max' => 50],
[['zieltabelle'], 'string', 'max' => 100],
[['bemerkung'], 'string', 'max' => 255]
];
}
public static function tableName()
{
return 'l_person_art';
}
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'person_art' => Yii::t('app', 'Personengruppen'),
'zieltabelle' => Yii::t('app', 'Zieltabelle'),
'bemerkung' => Yii::t('app', 'Bemerkung'),
];
}
public function getEAppEinstellungArts()
{
return $this->hasMany(\common\modules\erweiterung\models\EAppEinstellungArt::className(), ['id_person_art' => 'id']);
}
public function getLKontaktVerwendungszwecks()
{
return $this->hasMany(\common\modules\lookup\models\LKontaktVerwendungszweck::className(), ['id_person_art' => 'id']);
}
public function getPeople()
{
return $this->hasMany(\common\modules\basis\models\Person::className(), ['id_person_art' => 'id']);
}
public function behaviors()
{
return [
'uuid' => [
'class' => UUIDBehavior::className(),
'column' => 'id',
],
];
}
public static function find()
{
return new \common\modules\lookup\models\LPersonArtQuery(get_called_class());
}
}
Here is Controller:
public function actionUpdate($id)
{
$model = new LPersonArt();
if (!Yii::$app->request->post('_asnew') == '1'){
$model = $this->findModel($id);
}
if ($model->load(Yii::$app->request->post()) && $model->saveAll()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
Here is view:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="lperson-art-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->errorSummary($model); ?>
<?= $form->field($model, 'id', ['template' => '{input}'])->textInput(['style' => 'display:none']); ?>
<?=
$form->field($model, 'person_art')->widget(\jlorente\remainingcharacters\RemainingCharacters::classname(), [
'type' => \jlorente\remainingcharacters\RemainingCharacters::INPUT_TEXTAREA,
'text' => Yii::t('app', '{n} characters remaining'),
'options' => [
'rows' => '3',
'class' => 'col-md-12',
'maxlength' => 50,
'placeholder' => Yii::t('app', 'Write something')
]
])
?>
<?=
$form->field($model, 'bemerkung')->widget(\jlorente\remainingcharacters\RemainingCharacters::classname(), [
'type' => \jlorente\remainingcharacters\RemainingCharacters::INPUT_TEXTAREA,
'text' => Yii::t('app', '{n} characters remaining'),
'options' => [
'rows' => '3',
'class' => 'col-md-12',
'maxlength' => 255,
'placeholder' => Yii::t('app', 'Write something')
]
])
?>
<div class="form-group">
<?php if (Yii::$app->controller->action->id != 'save-as-new'): ?>
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?php endif; ?>
<?php if (Yii::$app->controller->action->id != 'create'): ?>
<?= Html::submitButton(Yii::t('app', 'Save As New'), ['class' => 'btn btn-info', 'value' => '1', 'name' => '_asnew']) ?>
<?php endif; ?>
<?= Html::a(Yii::t('app', 'Cancel'), Yii::$app->request->referrer, ['class' => 'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Problem will be solved adding following code into components of
common/config/main-local.php
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#backend/messages', // if advanced application, set #frontend/messages
'sourceLanguage' => 'de',
],
],
],
I was having a similar problem, but the Yii2 error message was
Unable to locate message source for category ''
I was running Gii from console:
php yii gii/crud --controllerClass="app\controllers\StcDocumentTypeController" --messageCategory="stc_document_type" --enableI18N=1 --enablePjax=1 --interactive=0 --modelClass="app\models\StcDocumentType" --searchModelClass="app\models\StcDocumentTypeSearch" --overwrite=1
The solution was to add the i18n configuration on the console.php config file:
'components' => [
...
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
'sourceLanguage' => 'en-US',
],
]
],
...
]
If you're running from web check also that config in web.php

captcha doen't validate in yii2

tips : username and email is check by ajaxValidation with validate method.
all is correct but i guess captcha is changed in server but the old picture is in client.
i googling alot no result found.
this is view:
<?php
$form = \yii\widgets\ActiveForm::begin([
'id' => 'form-signup',
'action' => 'signup',
'enableAjaxValidation' => false,
'enableClientValidation' => true,
'validationUrl' => 'validation',
'validateOnBlur' => true,
'fieldConfig' => [
'template' => '<div class="col-md-4" >{label}{input}{error}</div>'
]
]);
?>
<?= $form->field($signup, 'username', ['enableAjaxValidation' => true]) ?>
<?= $form->field($signup, 'name') ?>
<?= $form->field($signup, 'family') ?>
<?= $form->field($signup, 'mobile') ?>
<?= $form->field($signup, 'password')->passwordInput() ?>
<?= $form->field($signup, 'password_repeat')->passwordInput() ?>
<?= $form->field($signup, 'email', ['enableAjaxValidation' => true]) ?>
<?= $form->field($signup, 'verifyCode', ['enableAjaxValidation' => false])->widget(yii\captcha\Captcha::className()) ?>
<div class="form-group">
<?= yii\helpers\Html::submitButton('signup', ['class' => 'btn btn-green margin-right', 'name' => 'signup-button']) ?>
</div>
controller:
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if ($model->validate()) {
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
} else {
;
\yii\widgets\ActiveForm::validate($model);
}
} else {
return $this->render('/partials/_signup', ['signup' => $model]);
}
ajax validation controller method:
public function actionValidation() {
$model = new SignupForm();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = 'json';
return \yii\widgets\ActiveForm::validate($model);
}
}
model:
public $name;
public $family;
public $mobile;
public $username;
public $email;
public $password;
public $password_repeat;
public $verifyCode;
public function rules() {
return [
[['name', 'family', 'mobile'], 'default'],
['name', 'string', 'max' => 50],
['family', 'string', 'max' => 50],
['mobile', 'string', 'max' => 11],
['username', 'filter', 'filter' => 'trim'],
['username', 'required'],
['username', 'string', 'min' => 2, 'max' => 255],
[['username'], 'unique', 'targetClass' => '\frontend\models\User', 'message' => 'username already taken.'],
['email', 'filter', 'filter' => 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\frontend\models\User', 'message' => 'email name already taken.'],
['password', 'required'],
['password', 'string', 'min' => 6, 'max' => 255],
['password_repeat', 'string', 'min' => 6, 'max' => 255],
['password_repeat', 'compare', 'compareAttribute' => 'password'],
['verifyCode', 'captcha'],
];
}
there is no behaviour in controller
enableAjaxValidation of a form takes precedence over that of a field, so it's hard to tell what exactly you are trying to do with your current settings
Make sure you have verifyCode declared as an attribute on your model
Captcha verification code is saved in the session. The session key is a combination of controller's and action's ids. So you might have a misconfigured session. Or your captcha's action name is not 'captcha', - you are missing that part of your source code in the question.

How to get validation when saving multiple records with newEntities() CakePhp 3.x?

For some reason I am not getting any validation errors when saving multiple records. I can grab the errors using print_r($user->errors()); but they are not automatically injected into the form like when adding a single user. According to the docs "Validating entities before saving is done automatically when using the newEntity(), newEntities()." I am not sure if there is a specific way to set up the form to make it return validation for multiple records or if you have to do special validation in the model for inputs that have indexes or what?
view:
<div class="page-wrap">
<div class="form">
<h1>Join Now</h1>
<?php
echo $this->Form->create(null, ['controller' => 'users', 'action' => 'addMultiple']);
echo $this->Form->input('1.full_name');
echo $this->Form->input('1.username');
echo $this->Form->input('1.email');
echo $this->Form->input('1.password');
echo $this->Form->input('1.password_confirmation', array('type' => 'password'));
if ($current_user['role'] === 1 && isset($logged_in)) {
echo $this->Form->input('1.role', ['type' => 'select', 'options' => ['1' => 'Admin', '2' => 'Editor', '3' => 'Author', '4' => 'Reader'], 'default' => '4']);
}
echo $this->Form->input('2.full_name');
echo $this->Form->input('2.username');
echo $this->Form->input('2.email');
echo $this->Form->input('2.password');
echo $this->Form->input('2.password_confirmation', array('type' => 'password'));
if ($current_user['role'] === 1 && isset($logged_in)) {
echo $this->Form->input('2.role', ['type' => 'select', 'options' => ['1' => 'Admin', '2' => 'Editor', '3' => 'Author', '4' => 'Reader'], 'default' => '4']);
}
echo $this->Form->button(__('Sign Up'));
echo $this->Form->end();
?>
</div>
</div>
Controller:
public function addMultiple()
{
$users = $this->Users->newEntities($this->request->data());
if ($this->request->is('post')) {
foreach($users as $user) {
if( empty($this->request->session()->read('Auth.User')) || $this->request->session()->read('Auth.User.role') !== 1 ) {
$user->role = 4;
}
if ($this->Users->save($user)) {
$this->Flash->success(__('You have been added.'));
} else {
$this->Flash->error(__('You could not be added. Please, try again.'));
}
}
}
}
Table:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('MembershipOrders', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->hasMany('MembershipOrders', [
'foreignKey' => 'affiliate_token',
'joinType' => 'INNER'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->notEmpty('full_name', 'A full name is required')
->add('full_name', 'notBlank', [
'rule' => 'notBlank',
'message' => __('A full name is required'),
]);
$validator
->notEmpty('username', 'A username is required')
->add('username', [
'notBlank' => [
'rule' => 'notBlank',
'message' => __('A username is required'),
]
]);
$validator
->notEmpty('email', 'An email is required')
->add('email', [
'notBlank' => [
'rule' => 'notBlank',
'message' => __('A full name is required'),
],
'unique' => [
'rule' => 'validateUnique',
'provider' => 'table',
'message' => __('That email has already been used.'),
]
]);
$validator
->notEmpty('old_password', 'You must enter your old password is required')
->add('old_password', 'notBlank', [
'rule' => 'notBlank',
'message' => __('Your old password is required'),
]);
$validator
->notEmpty('password', 'A password is required')
->add('password', 'notBlank', [
'rule' => 'notBlank',
'message' => __('A full name is required'),
]);
$validator
->notEmpty('password_confirmation', 'Password confirmation is required')
->add('password_confirmation',
'comareWith', [
'rule' => ['compareWith', 'password'],
'message' => 'Passwords do not match.'
]);
$validator
->notEmpty('role', 'A role is required')
->add('role', 'inList', [
'rule' => ['inList', ['1', '2', '3', '4']],
'message' => 'Please enter a valid role'
]);
return $validator;
}
You can use 'addNestedMany()' : http://book.cakephp.org/3.0/en/core-libraries/validation.html#nesting-validators
You have to pass the entity object to the Form->create(... function, instead of passing nullas the following:
echo $this->Form->create($user, .....

Trouble with laravel (NotFoundHttpException)

I'm getting this error.
Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException
I have a login view with a form, I validate the form with ajax, without a problem. When I try to return a view once I've successfuly logged in.
if ($validation->fails()){
return Response::json(array( 'success' => false, 'errors' => $validation->getMessageBag()->toArray() ));
}else if(Auth::attempt($loginData)){
$usuario=Usuario::find(Input::get('rut'));
return View::make('logged')->with(array('nombre' => $usuario->primer_nombre.' '.$usuario->apellido_paterno.' '.$usuario->apellido_materno,
'rut' => $usuario->id_usuario,
'tipo' => $usuario->id_tipo));
}else{ return Response::json(array( 'exists' => false, 'message' => 'El usuario no existe o la contraseña es inválida.' )); }
I guess the problem is in the last else statement,I get an 404 error.
This is the route:
Route::post('ingresar','LoginController#login');
The action on the form is ingresar then I use the login method in LoginController
public function login(){
if(Request::ajax()){
//validamos el formulario.
$loginData = array(
'id_usuario' => Input::get('rut'),
'password' => Input::get('password')
);
$rules = array(
'rut' => 'required',
'password' => 'required',
);
$messages = array(
'required' => 'El campo :attribute es obligatorio.',
);
$validation = Validator::make(Input::all(), $rules, $messages);
if ($validation->fails()){
return Response::json(array(
'success' => false,
'errors' => $validation->getMessageBag()->toArray()
));
}else if(Auth::attempt($loginData)){
$usuario=Usuario::find(Input::get('rut'));
return View::make('logged')->with(array('nombre' => $usuario->primer_nombre.' '.$usuario->apellido_paterno.' '.$usuario->apellido_materno,
'rut' => $usuario->id_usuario,
'tipo' => $usuario->id_tipo));
}else{
return Response::json(array(
'exists' => false,
'message' => 'El usuario no existe o la contraseña es inválida.'
));
}
}
}

Categories