Can be used exist validator with a DynamicModel in Yii2 - validation

I need validate a user input against a database, if the input exist, the field should be validate. I have created a Dynamic Model in this way:
$modelDynamic=new DynamicModel(['TIN','Business_Code']);
and added the next exist rule validator:
$modelDynamic->addRule('TIN','exist',[
'targetClass'=>'frontend\modules\profiles\models\PorfBusiness',
'targetAttribute'=>'TIN',
'skipOnEmpty'=>true
])->validate();
all of them in my controller ProfPersonController.
And create this form in a view called profile:
if (isset($modelDynamic)) {
$formDynamic = ActiveForm::begin([
'type'=>ActiveForm::TYPE_HORIZONTAL,
'formConfig'=>[],
]);
echo $formDynamic->errorSummary($modelDynamic);
echo $formDynamic->field($modelDynamic,'TIN')
->textInput()
->label(Yii::t('app','TIN'));
echo $formDynamic->field($modelDynamic,'Business_Code')
->textInput()
->label(Yii::t('app','Business Code'));
echo HTML::submitButton('Submit');
ActiveForm::end();
}
(Imge with a wrong code)
The validation makes nothing, nor if the input is correct, nor if is incorrect. No errorSummary is sended neither.
Any error? Any idea? Thanks in advance.

Change Your Controller Code as
$modelDynamic= new DynamicModel(['TIN','Business_Code']);
$modelDynamic->addRule('TIN','exist',[
'targetClass'=>'frontend\modules\profiles\models\PorfBusiness',
'targetAttribute'=>'TIN',
'skipOnEmpty' => true
]);
if($modelDynamic->load(Yii::$app->request->post())&& $modelDynamic->validate()){
//Model is Validated and ready to go throgh
}
You must validate() your model after load() of your DynamicModel

Related

cakephp 3 form validation for associated model data

I need help with validation of associated model data. I have a form with User data (UsersTable) with additional fields from Model Companies (Users hasMany Companies).
My form view look like this:
echo $this->Form->create($contentData);
echo $this->Form->control('User.person_name');
echo $this->Form->control('User.email');
echo $this->Form->control('User.phone');
echo $this->Form->control('Companies.0.company_name');
//I try Companies.company_name too
echo $this->Form->control('Companies.0.nip');
Action in controller look like this:
$userTable = TableRegistry::get('Users');
$contentData = $userTable->newEntity(null, ['associated' => ['Companies']]);
if ($this->request->is(['post', 'put'])) {
$formData = $this->request->getData();
$contentData = $userTable->newEntity($this->request->getData(),
['validate' => true, 'associated' => ['Companies']]);
pr($contentData->getErrors());
die();
}
Unfortunately debug return error from UsersTable validation, except CompaniesTable.
Could U any idea, where did i go wrong ?
For the main model (User), you shouldn't need the model name at all in the form. For associated models, the convention is lower case plural.
echo $this->Form->control('person_name');
echo $this->Form->control('email');
echo $this->Form->control('phone');
echo $this->Form->control('companies.0.company_name');
echo $this->Form->control('companies.0.nip');
Unrelated notes: you initialize $formData but never use it, you shouldn't need to pass any parameters to the first newEntity call, and typical usage is to use patchEntity instead of newEntity inside the if.

Form input values not remain after flash error message

How to solve above issue? I want to keep test even after a validation failure in the submission. But after session error message is passed all the entered data will be gone.
To re-fill the form with the input data again, check the input validation then if validation fails, redirect the user back along with his input data and validation errors.
$validator = Validator::make($request->all(), [
// your validation rules.
'name' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
// Continue your app logic.
You'll find more information in Laravel validation docs
You should send back the input also to the view.
Like Sameh Salama already mentioned, use the following code:
function () {
return redirect()->back()->withErrors($validator)->withInput();
}
Notice the withInput() function, it returns the old input.
Use it in the View as
<input type="something" value="{{$input->first_something}}" />

"Node no longer exists" Yii

I want to keep the data between 2 actions in Yii by session. i'm writing the data in one action
Yii::app()->session['resultsData'] = $data;
and try to get it in next action
$this->resultsData = Yii::app()->session['resultsData'];
but when i want print_r this data in view...
<? print_r($this->resultsData); ?>
i'm get
PHP warning
print_r() [<a href='function.print-r'>function.print-r</a>]: Node no longer exists
actually, any manipulate with this data array, like serialize or json_encode, returns this error. can it be because of corrupted data? thank you.
Yii::app()->session['resultsData'];No need to use $this in action just assign the variable as shown
Yii::app()->session['resultsData'] = $data;
resultsData =Yii::app()->session['resultsData'];
and access it in another action as
echo Yii::app()->session['resultsData'] ;
If U want to acces the resultData in another u need to pass that variable to that action as shown
$this->redirect(array('actionname','resultData'=>$resultData));
And in your actionname echo it or print_r and check
Send it to view as shown
$this->render('ViewName',array('resultData'=>resultData));
From view to action use this
Yii::app()->createAbsoluteUrl('ControllerName/actionName',array('data'->$data));
Maybe this helps you:
$model = new CompanyForm('step1');
if (is_array(Yii::app()->session['step1']))
$model->attributes = Yii::app()->session['step1'];
if (!is_array(Yii::app()->session['step1']))
$this->redirect(array('createStep1'));
$this->render('create', array(
'model' => $model,
'step' => 'step1'
));
maybe you are saving the data in the wrong place;
maybe you have a post or get action;
and also, print_r the $data and see wat you get before saving the data in session

CakePHP validation not working for contact form

I am trying to do some very simple validation in my CakePHP contact form, but validation does not work eventhough I think I did everything necessary. Here's what I did:
I made a model like this:
class Office extends AppModel
{
var $name = 'Office';
var $useTable = false;
public $validate = array('onderwerp' => 'notEmpty');
}
(I also tried many other values for $validate from the CakePHP online manual)
In Config/bootstrap.php I made this rule for not letting CakePHP expect plural "Offices":
Inflector::rules('plural', array('rules' => array(),
'irregular' => array(),
'uninflected' => array('office')));
In OfficeController, I do this in my method contact():
$this->Office->set($this->request->data);
if($this->Office->validates()){
echo "code validates";
} else {
print_r($this->Office->validationErrors);
}
And in my Office/contact.ctp view, I have (amongst other code like starting and ending the form) this code:
$this->Form->input('onderwerp', array('label'=>false, 'size' => 60));
Now, even when I fill in the form, leaving empty the field 'onderwerp', it executes the code that should be executed when the code is executed.
When I print_r($this->request->data) or print_r($this->Office) I see that my onderwerp field is there and that it is empty (or filled when I do fill in something).
Now, when I add a public function validates() in my model and echo something there, it IS being displayed. So I'd say CakePHP knows where to find my model, and does execute my controller code. I also tried adding return parent::validates(); in my validates() function, but this also yielded no validation error, or any other error for that matter. My debug level is set to 2.
I guess I'm missing a needle in this haystack. Thanks for helping me finding it!
so drop all the inflector stuff.
and use the right model in your Form->create()
either
$this->Form->create(null)
or
$this->Form->create('Office');
and if you follow my advice to use a table less model with schema you will also have more power over input creation and validation.

Disabling validation for specific form (user login)

The problem
I have a login form available on every page (in the right menu). The problem is that when the user is on the register page, the fields from the login form are validated. I have username and password fields in both forms, and both are validated.
Ideas:
Different field names for registration form (register_username, register_password, register_email) and then set normal names before saving.
Different model (but albo using the users table) for login form?
Anyway, I just wonder what is the best way to solve this.
I'm guessing that both forms would submit to different actions, with the registration form submitting to Users->register() and the login form submitting to Users->login().
I would suggest that when you're in the register() action, you could try copying the relevant variable into another associative array and then validating and saving that, rather than validating and saving the $this->data variable.
Your second option is correct. I had encountered this problem before and wrote an article about it at the Bakery: Multiple Forms per page for the same model
The basic idea is to create separate models for each form extending the original model:
class RegisterForm extends User {
}
Then, load these forms in your controller however you please:
$this->loadModel('RegisterForm');
Then call validation as usual:
$this->RegisterForm->save($this->data);
For your particular case, you might not want to create the LoginForm model, and have only the RegisterForm model. This will let you take advantage of whatever magic the AuthComponent has.
HTH.
I haven't tried two forms with the same inputs, but this works for two forms with different inputs. I don't see why it shouldn't work for your needs.
View:
Make sure each submit button has a name value so that $this->params can identify it.
//first form ...
<?php
$profile_options = array('label' => 'edit profile',
'name' => 'form1');
echo $this->Form->end($profile_options);
?>
//second form ...
<?php
$password_options = array('label' => 'edit password',
'name' => 'form2');
echo $this->Form->end($password_options);
?>
Controller action:
Use $this->params to test for each form submission
if(isset($this->params['form']['form1'])){
$this->User->set($this->data); //necessary to specify validation rules
if($this->User->validates(array('fieldList' => array('email')))){
$this->User->saveField('email', $this->data['User']['email']);
}
}
elseif(isset($this->params['form']['form2'])){
//same deal for second form
}
It may be desirable to validate your model only using a subset of the validations specified in your model. For example say you had a User model with fields for first_name, last_name, email and password. In this instance when creating or editing a user you would want to validate all 4 field rules. Yet when a user logs in you would validate just email and password rules. To do this you can pass an options array specifying the fields to validate:
if ($this->User->validates(array('fieldList' => array('email', 'password')))) {
// valid
} else {
// invalid
}

Resources