Routing in laravel to update the registry - laravel-5.3

I am trying to update a record but when passing the data, it throws me this error:
MethodNotAllowedHttpException in RouteCollection.php line 218:
I understand that there are problems with routing but I'm unable to find what is causing this.
My form:
<form action="{{route('profesorControll.update', $datosProfesor->id)}}" method="POST">
My routing:
Route::resource('profesorControll', 'profesor\ProfesorController');
My controller:
public function update(Request $request, $id){
$camposProfesor = array('nombre_profesor' => $request['nombre_profesor'], 'apellido_profesor' => $request['apellido_profesor'], 'documento_profesor' => $request['documento_profesor'], 'fecha_nacimiento_profesor' => $request['fecha_nacimiento_profesor'], 'telefono_profesor' => $request['telefono_profesor'], 'telefono_movil_profesor' => $request['telefono_movil_profesor'], 'correo_profesor' => $request['correo_profesor'], 'domicilio_profesor' => $request['domicilio_profesor'], 'institucion_id' => $request['idInstitucion']);
$update = DB::table('profesor')->where('id', $id)->update($camposProfesor);
Session::flash('mensaje_profesor', 'Profesor modificado correctamente');
return redirect('Profesores/Editar/'. $id);
}
How do I solve this problem?

in resource update method is called using the put method to use put method in your form add below
<form action="{{route('profesorControll.update', $datosProfesor->id)}}" method="POST">
{{ method_field('PUT') }}
check here
https://laravel.com/docs/5.3/routing#form-method-spoofing

Related

Laravel 5.7 , login redirectes back to login

Im using laravel 5.7, I implemented login using make-auth().
also folowing is my login funtion:
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
$validator = Validator::make($request->all(), [
'email' => 'required|unique:users|max:255',
'password' => 'required',
]);
$credentials= ['email' => $request->get('email'), 'password'=>$request->get('password')];
if (Auth::guard('web')->attempt($credentials)) {
$user = Auth::user();
return redirect(route('home'));
}
$validator->errors()->add('login', 'Invalid Credentials');
return redirect()->back()
->with('loginError','Invalid Credentials')
->withInput($request->only('email', 'remember'));
}
When I try login, the page get redirected back to the login page.
Am I missing out something or is there anything to be added in middleware or any other file
I suspect this part might be the issue?
$validator = Validator::make($request->all(), [
'email' => 'required|unique:users|max:255',
'password' => 'required',
]);
By adding a unique validation rule to the login page (as opposed to the registration page), an existing user would be redirected back with a validation error every time because their email is already in the database.
Check your login page and make sure you're displaying form validation errors. If you see an error stating that the email must be unique, then this is the cause.
Here's a snippet you can use to display errors (from https://laravel.com/docs/5.7/validation#quick-displaying-the-validation-errors)
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif

The parameter must be defined

I store the keys Stripe in the parameters.yml.dist file, I have the following error message : The parameter "public_key" must be defined.
public function paiementAction(Request $request)
{
if ($request->isMethod('POST')) {
$token = $request->get('stripeToken');
\Stripe\Stripe::setApiKey($this->getParameter("private_key"));
\Stripe\Charge::create(array(
"amount" => 1000,
"currency" => "eur",
"source" => $token,
"description" => "First test charge!"
));
$request->getSession()->getFlashBag()->add('info', 'Paiement accepté');
}
return $this->render('saya25LouvreBundle:Ticket:paiement.html.twig', array(
'public_key' => $this->getParameter("public_key"),
));
}
Vue :
<form action="{{ path('saya25_louvre_paiement') }}" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="{{ public_key }}"
data-amount="1000"
data-name="paiement"
data-description="test"
data-image="http://www.france-hotel-guide.com/fr/blog/wp-content/uploads/2014/09/musee-louvre.jpg"
data-locale="auto"
data-zip-code="true">
</script>
</form>
check if the public_key is correctly configured in the parameters.yml.dist and that you have launch the composer install command from the CLI (so the files parameters.yml will be updated):
>composer install
Hope this help

Render a choice field without form

I often need to render very simple imputs in some of my templates.
I'd like to take advantage of the twig macros & form blocks to render certain HTML inputs without involving the whole Symfony forms machinery.
For example from the controller:
$templateContext = array(
'my_input' = new FormField('my_input', 'choice', array(
'choices' => array('value1', 'value2', 'my_value'),
'value' => 'my_value',
));
);
In the template:
<div>{{ form_widget(my_input) }}</div>
would render:
<div>
<select name="my_input">
<option>value1</option>
<option>value2</option>
<option selected="selected">my_value</option>
</select>
</div>
Is there a simple way to do that ?
Eventually I would also like to be able to reuse these fields elsewhere (like we can reuse form types)
There are many ways to go about this. The easiest would be to write the plain HTML into your twig template.
<form method="post">
<div>
<select name="my_input">
<option>value1</option>
<option>value2</option>
<option selected="selected">my_value</option>
</select>
</div>
</form>
And then in your controller read the values back.
$request = $this->getRequest();
if($request->getMethod() == 'POST'){
$data = $request->get('my_input')
//Do whatever you want with $data
}
If you want you re-use the html, you can build it somewhere in your PHP and pass it into Twig whenever you need it; or you can place it in a separate twig template and read that with the {include ''} command in twig.
Here is what I finally ended up with:
Class MyInput {
public static values = array(
'value1',
'value2',
'my_value',
);
}
class MyInputType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'choices' => MyInput::$value,
));
}
public function getParent() { return 'choice'; }
public function getName() { return 'my_input_type'; }
}
Field type used from the controller (after having registered it as a service)
public function MyAction(Request $request)
{
$form = $this->createForm('my_input_type');
$form->handleRequest($request);
$templateContext['myForm'] = $form->createView();
// ...
}
Input rendered into the template
<div>{{ form(myForm) }}</div>
To conclude: I've not been able to render an input without the form machinery, but the actual form remains rather simple.
I found my own solution for it since i need to create subforms from existing forms.
create totally empty twig template,
add in it only {{form(form)}}
render this template render()->getContent()
do a preg replace on the result (i do it in js) formView = formView.replace(/<(.*?)form(.*?)>/, '');
Yes yes - i know that regex is not perfect so before someone says it - i say it on my own, change it for youself as it catches "form-group" classes etc as well.
This is just a showcase of my solution

Invalid CSRF using symfony2 form type

I'm creating 2 forms in one action and these forms are submitted by jquery ajax to other 2 actions. Now, problem is - only first form works. Edit form throws that csrf token is invalid. Why is that happening? My code:
Creating forms:
$project = new Project();
$addProjectForm = $this->createForm(new AddProjectType(), $project, [
'action' => $this->generateUrl('tfpt_portfolio_versionhistory_addproject'),
'method' => 'POST',
'attr' => ['id' => 'newProjectForm']
]);
$editProjectForm = $this->createForm(new EditProjectType(), $project, [
'action' => $this->generateUrl('tfpt_portfolio_versionhistory_editproject'),
'method' => 'POST',
'attr' => ['id' => 'editProjectForm']
]);
Handling submit edit form (but add form is pretty much identical):
$project = new Project();
$form = $this->createForm(new EditProjectType(), $project);
$form->handleRequest($request);
if($form->isValid()){
//handle form
}
}
The only diffrence between these 2 forms is that edit form have one more field - hidden id. Both are submitted by jquery like that:
var form = $("#editProjectForm")
if(form.valid()){
$("#loader").show();
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize()
}).done(function(data){
//result
}
});
And i display forms like that:
{{ form_start(editProjectForm) }}
{{ form_errors(editProjectForm) }}
{{ form_widget(editProjectForm.name) }}
{{ form_widget(editProjectForm.id) }}
{{ form_rest(editProjectForm) }}
{{ form_end(editProjectForm) }}
Can somebody point my mistake? Isn't it possible to embed 3 forms in one action? Or i have to generate CSRF other way?
#Edit: I updated symfony to the newest release and now it's working prefect. Seems like this version had a bug or i got some lack of vendors code. Anyway, problem resolved.
I think you have to create two tokens in the controller:
$token_add = $this->get('form.csrf_provider')->generateCsrfToken('add');
$token_edit = $this->get('form.csrf_provider')->generateCsrfToken('edit');
and put in the view in hidden field. And then validate in the controller action that proccess the form
# Here you can validate the 'add' or 'edit' token
if (!$this->get('form.csrf_provider')->isCsrfTokenValid('add', $token)) {
$respuesta = array('mensaje' => 'Oops! Invalid token.',
'token' => $token);
return new Response(json_encode($respuesta));
}

Why getMethod() returns "GET" instead of "POST"?

The goal is to submit a POST form with two radiobuttons (tipo) and a text field (numero) to make a query in my DB and show the data to the user.
I am trying to submit the form below, however when I submit the form, the request coming accross is a 'GET REQUEST'. The form is in "SupuestoConfig.html.twig":
<div id="cuadro">
<form id="configurador" action="{{ path('configsup') }}" method="POST">
<p class="titulo_configurador">Elija supuesto penal:</p>
{{ form_row(form.tipo) }}
{{ form_row(form.numero, { 'label' : ' ', 'attr' : { 'class' : 'rec3' }}) }}
{{ form_rest(form) }}
<input type="submit" name="cargar" value="Cargar" class="inputbt"/>
</form>
</div>
I render the previous form in "principal.html.twig":
{{ render(controller('PprsBundle:Default:SupuestoConfig'), {'strategy': 'inline'}) }}
My "Controller.php":
/**
* #Route("/pprs/principal/supuesto={numero_supuesto}", name="configsup")
* #Template("PprsBundle:Default:SupuestoConfig.html.twig")
*/
public function SupuestoConfigAction($numero_supuesto = null)
{
$form = $this->createFormBuilder(null)
->add('tipo', 'choice', array(
'choices' => array(
'aleatorio' => 'Aleatorio',
'pornumero' => 'Por número'),
'multiple' => false,
'expanded' => true,
'data' => 'aleatorio'
))
// This add may contains error
->add('numero', 'text', array('label' => ' ','disabled' => true))
->getForm();
$peticion = $this->getRequest();
echo ('<script type="text/javascript">alert ("'.$peticion->getMethod().'");</script>');// Returns 'GET'
if ($peticion->isMethod('POST')) {
// Symfony2.2
$form->bind($peticion);
**$datos = $form->getData();**
*//foreach(array_keys($datos) as $p) {
//echo ('<script type="text/javascript">alert ("'.$datos.'");</script>');
//}*
if ($form->isValid()) { ... }
In Controller.php, despite I´ve got a GET request (when I remove the line
->add('numero', 'text',..
I´ve got a POST request, why is that?), in getData I don´t get the text field.
Finally, my routing.yml:
pprs_principal:
pattern: /pprs/principal/supuesto={numero_supuesto}/
defaults: { _controller: PprsBundle:Default:principal, numero_supuesto: 1 }
_pprs_principal:
pattern: /pprs/principal/
defaults: { _controller: FrameworkBundle:Redirect:redirect, route: pprs_principal }
Sorry for my bad english, Thanks in advance
Edit:
1) Anybody knows why I obtain a GET request instead of a POST when I add the text field in my createFormBuilder?
2) Anybody knows why Don't I get the text field when I call getData?
Help me please...
Maybe this answer could help you out:
getRequest() returns "GET" when posting form
Basically, when rendering a form with a {% render %} tag, it actually creates "another" request... It doesn't pass in the locale, the method, etc.
I opened a bug about this, and it went as By Design:
https://github.com/symfony/symfony/issues/7551

Resources