Symfony: No route found for "GET/content/articles/changeArt......" - symfony

I have a button that contains a link to another page, and pass some variables from the twig template to the controller action of that page :
<button class="btn btn-warning btn-xs" title="modifier l'article">
<i class="fa fa-pencil-square-o"></i>
</button>
The variables pass to the action successfully but I get an error :
No route found for "GET /content/articles/changeArt/3/test3/%3Ci%3E%3Cu%20style=%22background-color:%20rgb%28255,%20255,%200%29;%22%3Esdfghyujhgrertjr%22%5Ekrjthbkrkjgjgrhgiebgfjkebvkebvkezbkzbkdzbdkzbckdszb%20sdnckdzb%20nc,de%3C/u%3E%3C/i%3E/11/04/2017" (from "http://127.0.0.1/PFE_CNAM/web/content/articles")
(the variable 'content' its of type BLOB, and I start geting this error when i changed its type, because before when it was of type text,this action was working pretty good).
Here is the action code :
/**
* #Route("/content/articles/changeArt/{id}/{title}/{content}/{date}",defaults={"id": 0,"title": 0,"content": 0,"date": 0},name="changeArticle")
* #Template()
*/
public function changeArticleAction($id,$title,$content,$date)
{
$session = new Session();
$session->start();
$search = $session->get('user');
$gestAcces = $session->get('acces');
$gestEtat = $session->get('etatUser');
$gestCont = $session->get('contenu');
$repMsg = $session->get('repMsg');
$gestRec = $session->get('Reclam');
$gestMess = $session->get('gestMess');
$gestMp = $session->get('gestMp');
return $this->render('CNAMCMSBundle:Default:changeArticle.html.twig', array('search' => $search,
'contenu' => $gestCont,
'gestAcces' => $gestAcces,
'gestEtat' => $gestEtat,
'repMsg' => $repMsg,
'gestRec' => $gestRec,
'gestMess' => $gestMess,
'gestMp' => $gestMp,
'date'=>$date,
'id'=>$id,
'title'=>$title,
'content'=>$content,
));
}

Look at your route definition /content/articles/changeArt/{id}/{title}/{content}/{date} you can see this route expected exactly 4 params. Then, look at the generated path /content/articles/changeArt/3/test3/%3Ci%3E%3Cu%20style=%22background-color:%20rgb%28255,%20255,%200%29;%22%3Esdfghyujhgrertjr%22%5Ekrjthbkrkjgjgrhgiebgfjkebvkebvkezbkzbkdzbdkzbckdszb%20sdnckdzb%20nc,de%3C/u%3E%3C/i%3E/11/04/2017, it has alot of params separated by / because your params contains slashes.
When matching the URI with route path, it look like:
id: 3
title: test3
content: %3Ci%3E%3Cu%20style=%22background-color:%20rgb%28255,%20255,%200%29;%22%3Esdfghyujhgrertjr%22%5Ekrjthbkrkjgjgrhgiebgfjkebvkebvkezbkzbkdzbdkzbckdszb%20sdnckdzb%20nc,de%3C
date: u%3E%3C
i%3E // how about these extra params?
11 //
04 //
2017 //
I don't known which Symfony version you're using, it should throw exeption if your params contains /. You can solve your problem by encode your params before generate the url.
{{ path('changeArticle', {
id: id,
title: titre|url_encode,
content: corps|url_encode,
date: pub|date('d/m/Y')|url_encode
}) }}

Is 'date':pub|date('d/m/Y') a Typo?
Try this:
<button class="btn btn-warning btn-xs" title="modifier l'article">
<a
href="{{ path('changeArticle',{
'id' : id,
'title' : titre,
'content' : corps,
'date' : date|date('d/m/Y')
}) }}"
style="color: #ffffee;text-decoration: none;"><i class="fa fa-pencil-square-o"></i>
</a>
</button>

Related

Laravel Livewire errors are not cleared

I am experimenting with Laravel Livewire and I came across a situation where the previous errors are displayed even though the form is successfully submitted.
Before hit Save
After hitting Save
Html segment of name in blade file customer-new.blade.php.
<div class="form-group">
<div class="border rounded-0 px-1">
<label class="mb-0" for="name">Name</label>
<input wire:model="name" type="text" class="form-control form-control-sm " id="customer-name" aria-describedby="customer-nameHelp">
</div>
#error('name') <span class="err-message">{{ $message }}</span> #enderror
</div>
and the Save button code:
<button
wire:click="store"
wire:loading.attr="disabled"
wire:target="store"
type="submit"
class="btn btn-sm btn-light">Save
</button>
store method of CustomerNew.php:
public function store()
{
$this->validate([
'name' => 'required|max:80',
'street' => 'required|max:100',
'city' => 'required|max:40',
'dueAmount' => 'numeric|min:0'
]);
Customer::create([
'name' => $this->name,
'street' => $this->street,
'city' => $this->city,
'due_amount' => $this->dueAmount,
]);
session()->flash('message', 'Customer was saved');
$this->clear();
}
and the clear() method is like:
public function clear() {
$this - > name = '';
$this - > street = '';
$this - > city = '';
$this - > dueAmount = 0;
}
According to docs https://laravel-livewire.com/docs/input-validation,
You need to reset the validations whenever you want
Direct Error Message Manipulation The validate() and validateOnly()
method should handle most cases, but sometimes you may want direct
control over Livewire's internal ErrorBag.
Livewire provides a handful of methods for you to directly manipulate
the ErrorBag.
From anywhere inside a Livewire component class, you can call the
following methods:
$this->addError('email', 'The email field is invalid.');
// Quickly add a validation message to the error bag.
$this->resetErrorBag();
$this->resetValidation();
// These two methods do the same thing. The clear the error bag.
// If you only want to clear errors for one key, you can use:
$this->resetValidation('email');
$this->resetErrorBag('email');
$errors = $this->getErrorBag();
// This will give you full access to the error bag,
// allowing you to do things like this:
$errors->add('some-key', 'Some message');
HINT
I am using the reset methods on hydrate function like following
...
public function hydrate()
{
$this->resetErrorBag();
$this->resetValidation();
}
...
You should reset the public properties by using the livewire's reset method. Delete your $this->clear() method definition and replace it with the following:
$this->reset('name', 'street', 'city', 'dueAmount');
add id's to the error message div
#error('name') <span class="err-message" id="name-error">{{ $message }}</span> #enderror
#error('street') <span class="err-message" id="street-error">{{ $message }}</span> #enderror
#error('city') <span class="err-message" id="city-error">{{ $message }}</span> #enderror
#error('due_amount') <span class="err-message" id="due_amount-error">{{ $message }}</span> #enderror
$this->resetErrorBag();
Just add this in your clear() method. This will reset the error bag after each save.
It is better to send $name to the resetValidation and resetErrorBug. In this way you reset validation for the updating fields only. Here is my example:
public function updated($name, $value)
{
$this->resetValidation($name);
$this->resetErrorBag($name);
}

Laravel 5.7 Controller check which button has been clicked

I am current using laravel 5.7 I have a form in a bootstrap modal that has 2 tabs and each tab will display its submit button respectively. I am trying to capture which submit button has been click from my controller. I have already tried using Input::get('btn-name'); and $request->submit == 'btn-name' but neither of the methods are working for me. I tried dd(Input::all()) but it did not even capture the clicked button
Update
i have tried changing both my button name to create-btn and added these in my controller and it displays "none" in the dd($action);
$action = Input::get('create-btn','none');
if($action == 'create-team'){
$project->type = 'Team';
dd($action);
}else if($action == 'create-personal'){
$project->type = 'personal';
dd($action);
}else{
dd($action);
}
HTML
The <a> tag is not inside the <form> tag is because it is located at the modal's footer hence i use an on-event function
<!--Team Tab Button-->
<button action="{{route('project.store')}}"
method="POST"
class="btn btn-primary"
name="create-btn"
value="create-team"
onclick="event.preventDefault(); document.getElementById('submit-form
personal').submit();">Createdd changes
</button>`
<!--Personal Tab Button-->
<button action="{{route('project.store')}}"
method="POST"
class="btn btn-primary"
name="create-btn"
value="create-personal"
onclick="event.preventDefault(); document.getElementById('submit-form-
personal').submit();">Createdd changes
</button>`
Controller
public function store(Request $request)
{
$this->validate($request, [
'p_name' => 'required|min:6|max:50',
'start_date' => 'required',
'end_date' => 'required',
]);
$project = new Project;
$project->p_name = $request->input('p_name');
$project->start_date = $request->input('start_date');
$project->end_date = $request->input('end_date');
$project->colab = $request->input('colab');
dd(Input::all());
if($request->submit == 'create-team'){
$project->type = 'team ';
$project->save();
}
return 123;
}

Symfony2 InvalidArgumentException: The current node list is empty

I'm doing functional testing and I am getting the error
InvalidArgumentException: The current node list is empty
This is my code
public function testThis(){
$requestContent = [
'val1' => '324343',
'valname' => '"Benjamin"',
'valLast' => '"A"',
'valnum' => '44343',
'hndval1' => '0000',
'hdnval2' => '0000',
'hndval3' => '1111',
'hndref' => '"ThisIsAtest"',
'hdnMessage' => '"I am a message"'
];
$crawler = $this->client->request('GET', '/');
$submitButton = $crawler->selectButton('btnSubmit');
$form = $submitButton->form($requestContent);
print_r($form);
$this->client->followRedirects(true);
$crawler = $this->client->submit($form);
$response = $this->client->getResponse();
$request = $this->client->getRequest();
print_r($crawler->html());
$this->assertRegExp('/\/nextPage', $request->getUri());
print_r($request->getUri());
$a = $crawler->filter('input[name="pageName"]');
$this->assertContains(
"True",
$a->attr('value')
);
}
I think it is getting error in this :
$form = $submitButton->form($requestContent);
Note that $requestContent values are coming from a hidden input type which are all inside the form tag.
You have not posted your HTML so now i assumed your HTML such as :
<html>
<form method='GET' action='your action here'>
/*
* all other html here
*/
<input type='submit' value='Submit' id='btnSubmit' name='btnSubmit'>
</form>
</html>
$submitButton = $crawler->selectButton('btnSubmit');
to change
$submitButton = $crawler->selectButton('Submit');
Because selectButton() accept the button value instead of id or name.
Make sure this is a helpful to you.
You have to provide the text of the button to $crawler->selectButton().
// For a given HTML button:
// <input type="button" value="Upload File" />
// or
// <button type="button">Upload File</button>
$crawler->selectButton("Upload File");
Side note, your regex pattern '/\/nextPage' is invalid. You need to add a closing / --> '/\/nextPage/' // This will match the exact string: "/nextPage"

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

Handle two forms in one Controller with Symfony2

Hey I am saving every page in two different languages on my website. I want to manage my pages with an admin area that I am developing with symfony2 at the moment.
Following controller code is able to display two forms on the same page containing the right data from the database. One form to manage the DE language and another for EN:
View:
<form action="{{ path('admin_about') }}" method="post" {{ form_enctype(formEN) }}>
{{ form_widget(formEN) }}
<button type="submit" class="btn btn btn-warning" naem="EN">Save</button>
</form>
<form action="{{ path('admin_about') }}" method="post" {{ form_enctype(formDE) }}>
{{ form_widget(formDE) }}
<button type="submit" class="btn btn btn-warning" name="DE">Save</button>
</form>
Controller:
public function aboutAction(Request $request)
{
$pageEN = $this->getDoctrine()
->getRepository('MySitePublicBundle:Page')
->findOneBy(array('idName' => 'about', 'lang' => 'EN'));
$pageDE = $this->getDoctrine()
->getRepository('MySitePublicBundle:Page')
->findOneBy(array('idName' => 'about', 'lang' => 'DE'));
if (!$pageDE) {
throw $this->createNotFoundException('About page (DE) not found.');
}
if (!$pageEN) {
throw $this->createNotFoundException('About page (EN) not found.');
}
$formDE = $this->createFormBuilder($pageDE)
->add('title', 'text')
->add('content', 'text')
->getForm();
$formEN = $this->createFormBuilder($pageEN)
->add('title', 'text')
->add('content', 'text')
->getForm();
//Save Form here
return $this->render('MySitePublicBundle:Admin:about.html.twig', array(
'aboutPageDE' => $pageDE, 'aboutPageEN' => $pageEN, 'formDE' => $formDE->createView(), 'formEN' => $formEN->createView(),
));
}
My Question is: How to save the form that has been used out of one controller?
Based on the Forms and Doctrine section of the Symfony2 Docs (or in your case, since you're not using a Form class) --
So where you have //save form here assuming you've set up MySitePublicBundle:Page to save the Title and Content (and has the normal getters/setters).
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
// data is an array with "title" and "content" keys
$data = $form->getData();
// You'll need to have some switch depending on which language you're dealing
// with... (unless its both, then just repeat for $pageDE)
$pageEn->setTitle($data['title']);
$pageEn->setContent($data['content']);
$em = $this->getDoctrine()->getEntityManager();
$em->persist($pageEn);
$em->flush();
}
In your controller you could test if the request contains the forms, such as:
if($this->getRequest()->get('form1')) {
//
} elseif($this->getRequest()->get('form2')) {
//
}

Resources