yii2 retype password not working - yii2-validation

I am try to implement retype password field in my registration form. but unfortunately i didn't work for me. please help me.
public $repeatpassword;
public function rules() {
[['Fname','Lname','username','email', 'password'], 'required'],
[['password'],'string', 'min' => 3],
[['repeatpassword'],'required'],
['repeatpassword', 'compare','compareAttribute'=>'password',
'message'=>"Passwords don't match", 'on' => 'create']
}

Try this:
['repeatpassword', 'compare', 'compareAttribute' => 'password',
'message'=>"Passwords don't match"]

Related

Why the Validation of my form in Livewire does'nt work?

I'm doing a form on livewire as i always did it. But tonight it decides to mess with me.
I have my protected rules, and, in order to apply them, i have the "$this->validate" as you can see it on my code.
Problem is, with "$this->validate" nothing happens, no data in my table.
When i do it without "$this->validate"...it works..but of course, the rules are not applied.
Have you an idea?
`
<?php
namespace App\Http\Livewire;
use App\Models\Demande;
use Livewire\Component;
class CreateDemande extends Component
{
public $content, $annonce,
$phone, $mail, $user_id;
protected $rules = [
'content' => 'required',
'user_id' => 'required',
];
public function store()
{
$user_id = auth()->user()->id;
$this->validate();
Demande::create([
'content' => $this->content,
'user_id' => $user_id,
]);
}
public function render()
{
return view('livewire.create-demande');
}
}
`
Maybe a trait's missing ?
I tried to create a new component and doing it again, but doesn't worked too.
I tried to pass my rules in the validation :
`
$this->validate(
[
'content' => 'required',
'user_id' => 'required',
]);
Demande::create([
'content' => $this->content,
'user_id' => $user_id,
]);
`
Is there some error on my code i can't see here?
Edit : Sorry dont know why but the "hello" i wrote on the begining don't want to show him

Laminas / ZF3: Add manually Error to a field

is it possible to add manually an Error Message to a Field after Field Validation and Input Filter ?
I would need it in case the Username and Password is wrong, to mark these Fields / Display the Error Messages.
obviously in ZF/ZF2 it was possible with $form->getElement('password')->addErrorMessage('The Entered Password is not Correct'); - but this doesnt work anymore in ZF3/Laminas
Without knowing how you do your validation (there are a few methods, actually), the cleanest solution is to set the error message while creating the inputFilter (and not to set it to the element after it has been added to the form).
Keep in mind that form configuration (elements, hydrators, filters, validators, messages) should be set on form creation and not in its usage.
Here the form is extended (with its inputfilter), as shown in the documentation:
use Laminas\Form\Form;
use Laminas\Form\Element;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Validator\NotEmpty;
class Password extends Form implements InputFilterProviderInterface {
public function __construct($name = null, $options = []) {
parent::__construct($name, $options);
}
public function init() {
parent::init();
$this->add([
'name' => 'password',
'type' => Element\Password::class,
'options' => [
'label' => 'Password',
]
]);
}
public function getInputFilterSpecification() {
$inputFilter[] = [
'name' => 'password',
'required' => true,
'validators' => [
[
'name' => NotEmpty::class,
'options' => [
// Here you define your custom messages
'messages' => [
// You must specify which validator error messageyou are overriding
NotEmpty::IS_EMPTY => 'Hey, you forgot to type your password!'
]
]
]
]
];
return $inputFilter;
}
}
There are other way to create the form, but the solution is the same.
I also suggest you to take a look at the laminas-validator's documentation, you'll find a lot of useful informations
The Laminas\Form\Element class has a method named setMessages() which expects an array as parameter, for example
$form->get('password')
->setMessages(['The Entered Password is not Correct']);
Note that this will clear all error messages your element may already have. If you want to add your messages as in the old addErrorMessage() method you can do like so:
$myMessages = [
'The Entered Password is not Correct',
'..maybe a 2nd custom message'
];
$allMessages = array_merge(
$form->get('password')->getMessages(),
$myMessages);
$form
->get('password')
->setMessages($allMessages);
You can also use the error-template-name Laminas uses for its error messages as key in your messages-array to override a specific error message:
$myMessages = [
'notSame' => 'The Entered Password is not Correct'
];

yii2 how to make a notification by e-mail to the user after changing his status

yii2 how to make a notification by e-mail to the user after changing his status?? Help me, Please!
Model
class Applicants extends \yii\db\ActiveRecord
{
public $file;
public static function tableName()
{
return 'applicants';
}
public function rules()
{
return [
[['user_id', 'type_passport_id', 'passport_number', 'date', 'expiration_date', 'passport_path', 'diplom_number', 'diplom_path', 'phone_number', 'mobile_number', 'country_id', 'city_id', 'address', 'faculty_id', 'spec_id', 'stage_id', 'training_id', 'dormitories_id'], 'required'],
[['user_id', 'type_passport_id', 'country_id', 'city_id', 'status_id', 'faculty_id', 'spec_id', 'stage_id', 'training_id', 'dormitories_id'], 'integer'],
[['passport_number', 'mobile_number', 'applicants_comment'], 'string', 'max' => 250],
[['expiration_date'], 'string', 'max' => 120],
[['file'], 'file', 'skipOnEmpty' => true, 'extensions' => 'pdf'],
[['passport_path', 'diplom_path', 'address'], 'string', 'max' => 255],
[['diplom_number'], 'string', 'max' => 50],
[['phone_number'], 'string', 'max' => 30],
[['user_id'], 'unique'],
[['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
];
}
Help me, Please!
You can use afterSave($insert,$changedAttributes) to check for changed attributes and send the email.
According to the DOCS $changedAttributes parameter has old values of attributes that had changed and were saved. You can use this parameter to take action based on the changes made for example send an email when the password had changed or implement audit trail that tracks all the changes. $changedAttributes gives you the old attribute values while the active record ($this) has already the new, updated values.
public function afterSave( $insert , $changedAttributes ) {
if ( !$insert && isset ( $changedAttributes['status'] ) ) {
$this->sendEmail ();
}
return parent::afterSave ( $insert , $changedAttributes );
}
private function sendEmail() {
//your code to email
}
public function afterSave($insert, $changedAttributes){
if (!$insert && array_key_exists('status_id', $changedAttributes) && $this->status_id != $changedAttributes['status_id']){
$this->sendEmail();
}
return parent::afterSave($insert, $changedAttributes);
}
private function sendEmail() {
//your code to email
}
The best way to check is an attribute has changed afterSave(). See Note in this answer

Set unique rule to a field on update action on yii2 rest

I am creating a rest api with yii2 to create and update user information. Below is the rule function in the model class.
public function rules()
{
return [
[['name', 'emailId', 'contactNumber'], 'required'],
[['name', 'emailId', 'contactNumber'], 'string', 'max' => 255]
[['emailId', 'username', 'contactNumber'], 'unique'],
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]]
];
}
Here I mentioned emailId, username, contactNumber fields should be unique. When I try to create, it is checking whether the field is unique or not. if unique it is throwing the error else it is saving. That is fine.
But when I try to update the value there also it is checking the particular value for the field is unique or not. But it should not be like that. The unique validation should not work on update action. So I updated the rule with 'on'=>'update' as like Yii 1. Check the below function.
public function rules()
{
return [
[['name', 'emailId', 'contactNumber'], 'required'],
[['name', 'emailId', 'contactNumber'], 'string', 'max' => 255]
[['emailId', 'username', 'contactNumber'], 'unique', 'on'=>'update'],
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]]
];
}
But when i check the official documentation there is no option like on to check the particular action. When i use 'on'=>'update', both(while creating and update) places it is not validating. Might be because of the on. Just leave that. I need to add unique validation for those fields in create action only not in update action.
So, Please anybody help me with how to add unique validation to those fields only in create action.
Thanks.
You can set scenario for your REST actions in your ActiveController:
public function actions()
{
$actions = parent::actions();
$actions['update']['scenario'] = 'update';
$actions['create']['scenario'] = 'create';
return $actions;
}
And then use it in rules:
[['emailId', 'username', 'contactNumber'], 'unique', 'on'=>'create']
Also you must specify list of active attributes for each scenario in the particular model class:
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['update'] = ['type', 'title', 'description'];
$scenarios['create'] = ['type', 'title', 'description', 'affiliate_id'];
return $scenarios;
}

Symfony2 entity field type alternatives to "property" or "__toString()"?

Using Symfony2 entity field type one should specify property option:
$builder->add('customers', 'entity', array(
'multiple' => true,
'class' => 'AcmeHelloBundle:Customer',
'property' => 'first',
));
But sometimes this is not sufficient: think about two customers with the same name, so display the email (unique) would be mandatory.
Another possibility is to implement __toString() into the model:
class Customer
{
public $first, $last, $email;
public function __toString()
{
return sprintf('%s %s (%s)', $this->first, $this->last, $this->email);
}
}
The disadvances of the latter is that you are forced to display the entity the same way in all your forms.
Is there any other way to make this more flexible? I mean something like a callback function:
$builder->add('customers', 'entity', array(
'multiple' => true,
'class' => 'AcmeHelloBundle:Customer',
'property' => function($data) {
return sprintf('%s %s (%s)', $data->first, $data->last, $data->email);
},
));
I found this really helpful, and I wound a really easy way to do this with your code so here is the solution
$builder->add('customers', 'entity', array(
'multiple' => true,
'class' => 'AcmeHelloBundle:Customer',
'property' => 'label',
));
And in the class Customer (the Entity)
public function getLabel()
{
return $this->lastname .', '. $this->firstname .' ('. $this->email .')';
}
eh voila :D the property get its String from the Entity not the Database.
Passing a closure does not work yet, but will be added to Symfony soon: https://github.com/symfony/symfony/issues/4067
It seems this can be achievable by adding following block after elseif ($this->labelPath) block in ObjectChoiceList.php.
elseif (is_callable($this->labelPath)) {
$labels[$i] = call_user_func($this->labelPath, $choice);
}
Haven't tried it though :).