CakePHP 4 FormProtector instance has not been created error - php

I am currently in the process of updating a (rather big) application from CakePHP 3 to 4.
I have this template:
<?= $this->Form->create(
$dmpLayer,
[
'url' => [
'controller' => 'DmpLayers',
'action' => 'edit',
],
]
); ?>
<div class="row">
<div class="col-4">
<?= $this->element('DataLayers/layer-table'); ?>
</div>
<div id="form-div" class="col-6">
<div class="layer-form">
<?= $this->element('DataLayers/form') ?>
</div>
</div>
<div class="col-2">
<div class="layer-form">
<h2>Form Actions</h2>
<?= $this->Form->submit('Create/Update Layer', ['class' => 'btn btn-success']); ?>
</div>
</div>
</div>
<?= $this->Form->end(); ?>
<?= $this->Html->script('data-layers'); ?>
which includes the DataLayers/form element:
<div class="row">
<div class="col-12">
<h4>Artist Layer</h4>
<?php
echo $this->Html->tag('fieldset', $this->element(
'actions/add',
[
'url' => [
'prefix' => 'Admin',
'plugin' => false,
'controller' => 'SegmentCores',
'action' => 'add',
],
]
)
. $this->Form->control('artist_layer.segment_cores[]', [
'multiple',
'options' => $segmentCores,
'label' => 'Segment Core',
'value' => $selectedValues['segment_cores'],
])
. $this->Form->control('artist_layer.segment_potentials[]', [
'multiple',
'options' => $segmentPotentials,
'label' => 'Segment Potential',
'value' => $selectedValues['segment_potentials'],
])
. $this->Form->control('artist_layer.layer_tags[]', [
'multiple',
'options' => $layerTags,
'label' => 'Artist Tag',
'value' => $selectedValues['artist_tags'],
])
. $this->Form->control('artist_layer.genres[]', [
'empty' => 'No genre set',
'options' => $genres,
'label' => 'Genre',
'value' => $selectedValues['genres'],
]);
?>
</div>
</div>
<?php
$this->Form->unlockField('artist_layer.genres');
$this->Form->unlockField('artist_layer.segment_cores');
$this->Form->unlockField('artist_layer.segment_potentials');
$this->Form->unlockField('artist_layer.layer_tags');
?>
In the initialize function of the AppController I have this:
$this->loadComponent('Security');
When I visit the page, it doesn't render and I immediately get this error:
FormProtector instance has not been created. Ensure you have loaded the FormProtectionComponent in your controller and called FormHelper::create() before calling FormHelper::unlockField()
This is the only form in my application for which this error happens. Every other form is working fine, and I am calling the Form->unlockField() function in many of them.
I am obviously calling Form->create() in my code, so is this because I am including an element to add fields to the form that is defined in the "main" template? Or is there some other explanation?
I have already attempted adding
$this->loadComponent('FormProtection');
to my AppController, but this causes a whole lot more problems in many other places in the app, and it doesn't solve the problem anyway (the page renders, but I get an error when submitting the form to save the data).

Related

yii2 kartik select2 widget doesn't show first element of the list

I am js developer, but I was given a task to solve some problems in our php Yii2 site. I am novice in yii2 and php, so I am stuck with kartik yii2 widget. The code wasn't written by me. When I choose first option from the list - it saves to db correctly but shows second item in widget itself, instead of first item. When I choose all items from the list, the widget cuts first item also. But data in db is correct.
Here is the code:
<?php
...
function sortArray($a, $b)
{
return strcmp($a, $b);
}
$projects = ArrayHelper::map($projects, 'id', 'title');
usort($projects, 'sortArray');
?>
<div class="x_title"><h3><?= Html::encode($this->title) ?></h3></div>
<div class="x_content">
<?php $form = ActiveForm::begin(); ?>
<div class="form-group">
<?= Select2::widget([
'name' => 'projects[]',
'options' => ['placeholder' => 'Выберите проект...'],
'language' => 'ru',
'value' => array_keys(ArrayHelper::map($model->projects, 'id', 'title')),
'data' => $projects,
'pluginOptions' => [
'allowClear' => true,
'multiple' => true
],
]) ?>
</div>
<div class="form-group">
<?= Html::submitButton('Обновить', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end() ?>
</div>
I check "select all" then press "update" button
but all items were saved to db:
How to overcome my problem and make select widget work correctly? I am very tired. Thanks in advance!
You should have to add 'maintainOrder' => true, for example:
<?= Select2::widget([
'name' => 'projects[]',
'maintainOrder' => true, // add here the property
'options' => ['placeholder' => 'Выберите проект...'],
'language' => 'ru',
'value' => array_keys(ArrayHelper::map($model->projects, 'id', 'title')),
'data' => $projects,
'pluginOptions' => [
'allowClear' => true,
'multiple' => true
],
]) ?>

Yii2 form validating but not submitting to send email

I have a form that is not submitting anytime the submit button is clicked but it is validating.
see the form below:
<?php
$form = ActiveForm::begin([
'id' => 'contact-form',
'action' => ['site/index'],
'options' => [
'class' => 'contact-form wow fadeInUp',
'data-row-duration' => '1s',
]
])
?>
<div class="form-validation alert">
<div class="form-group col-md-12">
<?=
$form->field($model, 'name', [
'options' => ['style' => 'margin:0;padding:0'],
'inputOptions' => [
'class' => 'form-control',
'placeholder' => 'Full Name',
'autocomplete' => 'off'
]
])->label(false)
?>
</div>
<div class="form-group col-md-6">
<?=
$form->field($model, 'email', [
'options' => ['style' => 'margin:0;padding:0'],
'inputOptions' => [
'class' => 'form-control',
'placeholder' => 'Email',
'autocomplete' => 'off'
]
])->label(false)
?>
</div>
<div class="form-group col-md-6">
<?=
$form->field($model, 'phone', [
'options' => ['style' => 'margin:0;padding:0'],
'inputOptions' => [
'class' => 'form-control',
'placeholder' => 'Phone',
'autocomplete' => 'off'
]
])->label(false)
?>
</div>
<div class="form-group col-md-12">
<?=
$form->field($model, 'name', [
'options' => ['style' => 'margin:0;padding:0'],
'inputOptions' => [
'class' => 'form-control',
'placeholder' => 'Message',
'autocomplete' => 'off',
'rows' => '5'
]
])->textarea()->label(false)
?>
</div>
<div class="form-group col-md-4 col-md-offset-8">
<?=Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
</div>
<?php ActiveForm::end(); ?>
SiteController/actionIndex:
public function actionIndex() {
$model = new ContactForm;
if( $model->load(Yii::$app->request->post()) && $model->validate() ){
if( $model->sendEmail(Yii::$app->params['adminEmail']) ){
Yii::$app->session->setFlash('success', 'Thank you for reaching us. We will respond to you shortly');
} else{
Yii::$app->session->setFlash('error', 'Something went wrong. Message not send successfuly');
}
return $this->refresh();
} else{
return $this->render('index', ['model' => $model]);
}
}
NOTE: I'm not getting any error. it's validating but after filling the form to click on submit, the button doesn't work I even used die() in place of the Yii::$app->session->setFlash() still nothing happened. it is just not responding.
Apparently, you have an error but you are not noticing it because you are rendering the name field instead of the message field inside your ActiveForm, I am talking about the very last field before the submit button.
<div class="form-group col-md-12">
<?=
$form->field($model, 'name', [
'options' => ['style' => 'margin:0;padding:0'],
'inputOptions' => [
'class' => 'form-control',
'placeholder' => 'Message',
'autocomplete' => 'off',
'rows' => '5'
]
])->textarea()->label(false)
?>
</div>
and although you have a validation error when you call the $model->validate() against the message field but it is unable to display because it assigns the error to the attribute field that is used in the form but apparently there isn't any field with the name message in the form, so it does not display anything. If you add this line after the form declaration you will immediately see the error
<?= $form->errorSummary($model); ?>
So, change the last field to below and everything will work now.
<div class="form-group col-md-12">
<?=
$form->field($model, 'message', [
'options' => ['style' => 'margin:0;padding:0'],
'inputOptions' => [
'class' => 'form-control',
'placeholder' => 'Message',
'autocomplete' => 'off',
'rows' => '5'
]
])->textarea()->label(false)
?>
</div>

How to add css class to form-group div of ActiveField in Yii2?

I have a following code below:
<?= $form->field($model, 'date') ->widget(yii\jui\DatePicker::className(),['clientOptions' => [ 'placeholder' => 'dd/mm/yyyy',
'id' => 'form',
'autocomplete' => 'off',
'value' => date('m/d/Y'),
'autoclose'=>true,
]]) ?>
That will result in HTML in following way:
<div class="form-group has-icon has-label">
<label for="formSearchUpLocation">Picking Up Location</label>
<input type="text" class="form-control" id="formSearchUpLocation" placeholder="Airport or Anywhere">
<span class="form-control-icon"><i class="fa fa-map-marker"></i></span>
</div>
My question is as following:
How can I integrate the css and bootstrap classes in HTML below into yii2 active form above?
Thank you for your help.
if you are looking to add the class to all the group divs mean all the div that have the class form-group then you can use the fieldConfig option of the ActiveForm or if you want it for one specific field then you can use the options option of the $form->field() as the 3rd parameter
For the whole Form
$form = yii\widgets\ActiveForm::begin([
'fieldConfig' => [
'options' => [
'class' => 'my-group'
]
]
]);
For Single Field
echo $form->field($model, 'name', ['options' => ['class' => 'my-class']])->textInput();
Conversion
About converting your above HTML using ActiveForm the following should work you can use template option of the $form->field() 3rd parameter to add your custom icon after the input, along with other, see below will create your desired HTML
echo $form->field($model, 'date', [
'options' => [
'class' => 'form-group has-icon has-label'
],
'inputOptions' => [
'class' => 'form-control'
],
'template' => '{label}{input}<span class="form-control-icon"><i class="fa fa-map-marker"></i></span>{error}'
])->widget(yii\jui\DatePicker::class, [
'id' => 'created_at',
'options' => [
'placeholder' => 'Airport or Anywhere'
]
]);
You will have something like below
<?= $form->field($model, 'date') ->widget(yii\jui\DatePicker::className(),['clientOptions' => [ 'placeholder' => 'dd/mm/yyyy',
'id' => 'form',
'class' => 'WRITE-YOUR-CLASS'
'autocomplete' => 'off',
'value' => date('m/d/Y'),
'autoclose'=>true,
]]) ?>
just input your class name in 'class' section it will work.
example : 'class' => 'fa fa-map-marker'
You could try something like the code bellow to concat your calendar icon with the widget:
<?php
$addon = '<span class="input-group-addon">
<i class="fa fa-calendar-alt"></i>
</span>';
echo $addon.$form->field($model, 'date')->widget(yii\jui\DatePicker::className(),['clientOptions' => [ 'placeholder' => 'dd/mm/yyyy',
'id' => 'form',
'autocomplete' => 'off',
'value' => date('m/d/Y'),
'autoclose'=>true,
]]);
?>
Or you can try search more on the plugin you are using, some widgets have his own attribute to render the calendar icon.

action create not working Yii2 frontend

i want to execute action create in my view frontend, the code of actionCreate in site controller is correct , but it redirect me to index.php with this url "http://localhost/advanced/frontend/web/index.php?Subsidize%5Bname%5D..........."
knowing that i want to redirect to view.php after creating a new item in table "subsidize"
action create in siteController.php
public function actionView($id) {
$model = Subsidize::findOne($id);
if ($model === null) {
throw new NotFoundHttpException;
}
return $this->render('view', [
'model' => $model,
]);
}
public function actionCreate() {
$model = new Subsidize();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->subsidize_id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
code of submitButton in view "create.php"
<?= Html::submitButton($model->isNewRecord ? 'إرسال ' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
also , function behaviors in siteController
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['create'],
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['create', 'view'],
'allow' => true,
'roles' => ['#'],
],
[
//see captcha and error added here, this fixes the issue
'actions' => ['support', 'test', 'delete', 'update', 'create', 'view'],
'allow' => true,
'roles' => ['?', '#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'create' => ['get', 'post'],
'update' => ['get', 'put', 'post'],
'delete' => ['post', 'delete'],
],
],
];
}
code of my view : create.php
<?php use yii\helpers\Html; use yii\widgets\ActiveForm; $model = new app\models\Subsidize; ?> <section class="support">
<div class="container">
<form class="dialog-form row">
<?php $form = ActiveForm::begin() ?>
<div class="col-md-12">
<div class="form-group">
<?php echo $form->field($model, 'name', [
'inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control transparent']
])->textInput()->input('name', ['placeholder' => "الإسم الكريم"])->label(false); ?>
</div><!--End Form-group-->
</div><!-- col -->
<div class="col-md-12">
<div class="form-group">
<?php echo $form->field($model, 'montant', [
'inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control transparent']
])->textInput()->input('montant', ['placeholder' => "المبلغ "])->label(false); ?>
</div><!--End Form-group-->
</div><!-- col -->
<div class="col-md-12">
<div class="form-group">
<?php echo $form->field($model, 'date', [
'inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control transparent']
])->textInput()->input('date', ['placeholder' => "تاريخ التذكير "])->label(false); ?>
</div><!--End Form-group-->
</div><!-- col -->
<div class="col-md-12">
<div class="form-group">
<?php echo $form->field($model, 'phone', [
'inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control transparent']
])->textInput()->input('phone', ['placeholder' => "رقم الجوال"])->label(false); ?>
</div><!--End Form-group-->
</div><!-- col -->
<div class="col-md-12">
<div class="form-group">
<?php echo $form->field($model, 'remarks', [
'inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control transparent']
])->textInput(['rows' =>6])->input('remarks', ['placeholder' => "ملاحظات"])->label(false); ?>
</div><!-- form-group -->
</div><!-- col -->
<div class="col-md-12">
<div class="form-group" style="text-align:center ">
<?= Html::submitButton($model->isNewRecord ? 'إرسال ' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div><!-- form-group -->
</div><!-- col -->
<?php ActiveForm::end(); ?>
</form><!--End-->
</div><!-- container -->
Did you forget to specify method attribute of your HTML form?
<form method="POST" ...>
Looks like form just being submitted as GET request
Sorry for my english before. Can you edit your post and add your complete ActiveForm::begin() code. for alternate fix, you can try to remove the create action on your verb behavior like this :
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'update' => ['get', 'put', 'post'],
'delete' => ['post', 'delete'],
],
],

Multiple forms inside a foreach

I have a foreach that show many forms with the same action ending with diferente id's.
But, the tag <form> just appears in the first form. All others, the fields appears, but don't the <form>
I tried to put the id for the form different in the loop. But doesn't work.
The code:
<?php echo $this->Form->create(null, array(
'url' => array('controller' => 'menus', 'action' => 'aprovar', $procuracao['Attorney']['id']), 'id' => $procuracao['Attorney']['id']
)); ?>
<div class="control-group">
<label class="control-label">Alçada:</label>
<div class="controls">
<?php echo $this->Form->input ('alcada', array('type' => 'select', 'label' => FALSE, 'options' => array(
'Até 10.000' => 'Até 10.000',
'Até 50.000' => 'Até 50.000',
'Acima de 100.000' => 'Acima de 100.000',
'Acima de 500.000' => 'Até 500.000',),
'empty' => 'Selecione')); ?>
</div>
</div>
<div class="control-group">
<label class="control-label">Validade:</label>
<div class="controls">
<?php echo $this->Form->input('validade', array('label' => FALSE, 'type' => 'text')); ?>
</div>
</div>
<?php echo $this->Form->submit('Ok', array('class' =>'btn btn-success pull-left', 'div' => false)); ?>
</div>
The field "Alçada" and "Validade" appears correctly. But the tag <form> just appears in the first element.
You are not ending the form.
echo $this->Form->create(null, array(
'id' => 'your-form-'.$i, //that $i is the index of the foreach, for example
'url' => array('controller' => 'menus', 'action' => 'aprovar', $procuracao['Attorney']['id']), 'id' => $procuracao['Attorney']['id']
));
//all inputs and other stuff
echo $this->Form->end(array('label'=>'Ok', 'class' =>'btn btn-success pull-left', 'div' => false));
all that inside the foreach you're using.
Here is the reference of that function in the docs. But basically, it does this
Closes an HTML form, cleans up values set by FormHelper::create(), and
writes hidden input fields where appropriate

Categories