I get the variable does not exist error everytime I try to access a site on my blog.
the twig template:
{% extends '::base.html.twig' %}
{% block body %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title text-center">All Users</h3>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Username</th>
<th>Email Address</th>
<th>Password</th>
</tr>
</thead>
<tbody>
{% for user in userlist %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.email }}</td>
<td>{{ user.password }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<button type="button" class="btn btn btn-info">
Edit profile
</button>
{% endblock %}
the Controller :
<?php
// src/BlogBundle/Controller/UserController.php
namespace BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use BlogBundle\Entity\Blog;
use BlogBundle\Entity\User;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class UserController extends Controller
{
/**
*#Security("has_role('ROLE_ADMIN')")
* #Route("/users", name="users", requirements={"page": "\d+"})
*/
public function listAction()
{
$user = $this->getDoctrine()->getRepository('BlogBundle:User')->findBy(array(), array('username' => 'DESC'));
dump($user);
return $this->render('BlogBundle:user:userlist.html.twig', [
'userlist' => $user
]);
}
/**
* #Route("/users/edit/{id}", name="edit", requirements={"id" = "\d+"}, defaults={"id" = 0})
*#Security("has_role('ROLE_ADMIN')")
*/
public function editAction(Request $request, User $user) {
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('BlogBundle:User')->find($username);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($user);
$em->flush();
return $this->render('BlogBundle:user:userlist.html.twig', array(
'user' => $user,
'form' => $form->createView(),
'success' => true
));
}
return $this->render('FOSUserBundle:Profile:edit.html.twig');
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => 'BlogBundle\Entity\User'
]);
}
}
?>
and finally the User Entity:
<?php
// src/BlogBundle/Entity/User.php
namespace BlogBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
}
/**
* Get the value of Id
* #return mixed
*/
public function getId() {
return $this->id;
}
}
What I'm trying to do is, create a page that only the admin can access which displays a list of all users from my doctrine database. --> listAction()
next to that I would like to have the possibility to edit all the users information --> editAction()
any ideas?
the error occurs in the twig template line: "{{ path('edit', {'id':user.id}) }} ...
You put the button outside your loop, so yes, the variable user doesn't exist, simply put put
<button type="button" class="btn btn btn-info">
Edit profile
</button>
in the for loop
Related
I need to persist my form to the database. I am using Symfony to do this and I have built a response entity:
<?php
namespace App\Entity;
use App\Repository\ResponseRepository;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
* )
* #ORM\Entity(repositoryClass=ResponseRepository::class)
*/
class Response
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id", type="integer")
* #Groups({"response:read"})
*
*/
private $id;
/**
* #ORM\Column(name="answer", type="string", length=255)
* #Groups({"response:write", "response:read", "session:read"})
* #Assert\NotBlank()
*/
private $answer;
/**
* #ORM\ManyToOne(targetEntity=Session::class, inversedBy="responses")
* #ORM\JoinColumn(nullable=false)
* #Assert\Valid
*/
private $session;
/**
* #ORM\ManyToOne(targetEntity=Question::class, inversedBy="responses")
* #ORM\JoinColumn(nullable=false)
* #Groups({"response:read", "response:write"})
*/
private $question;
// /**
// * #ORM\OneToMany(targetEntity=QuestionsQuestionType::class, mappedBy="response")
// */
// private $questionsQuestionType;
public function __construct()
{
$this->questionsQuestionType = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getAnswer(): ?string
{
return $this->answer;
}
public function setAnswer(string $answer): self
{
$this->answer = $answer;
return $this;
}
public function getSession(): ?Session
{
return $this->session;
}
public function setSession(?Session $session): self
{
$this->session = $session;
return $this;
}
public function getQuestion(): ?Question
{
return $this->question;
}
public function setQuestion(?Question $question): self
{
$this->question = $question;
return $this;
}
A new response function in the ResponseController (please note QuizResponse is an alias of Response entity. This is to not confuse my response entity with Symfony Response) :
/**
* #Route("/new", name="response_new", methods={"GET", "POST"})
*/
public function new(Request $request, EntityManagerInterface $entityManager, QuestionRepository $questionRepository): Response
{
$questions = $questionRepository->findAll();
// dd($questions);
$response = new QuizResponse();
$form = $this->createForm(ResponseType::class, $response); // problem exists
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($response);
$entityManager->flush();
// $formData = $form->getData();
// dd($formData);
// echo 'this should work';exit;
return $this->redirectToRoute('response_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('response/new.html.twig', [
'response' => $response,
'question' => $questions,
'form' => $form,
]);
}
A ResponseType form:
<?php
namespace App\Form;
use App\Entity\Response;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
class ResponseType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Response::class,
]);
}
}
And here is my twig template (_form.html.twig):
{{ form_start(form) }}
<div class="mt-3">
{% for question in question %}
<input type="hidden" name="response[question][]" value="{{ question.id }}">
{% set name = 'response[answer]['~ question.id ~']' %}
{% if question.type == 'checkbox' %}
{% set name = name ~ '[]' %}
{% endif %}
{# {% if question.replies is defined %}#}
<div class="mb-3 mt-3 border">
<h3 class="mb-0" id="question-{{ question.id }}">{{ loop.index }}. {{ question.label }}</h3>
</div>
{% if question.type == 'checkbox' or question.type == 'radio' %}
<div class="answers p-1">
{% for answer in question.replies %}
{% set id = 'answer-' ~ answer.id %}
<label for="{{ id }}">{{ answer.answer }}</label>
<input type="{{ question.type }}" name="{{ name }}" id="{{ id }}">
{% endfor %}
</div>
{% elseif question.type == 'textarea' %}
<textarea name="{{ name }}" aria-labelledby="question-{{ question.id }}" cols="30" rows="5" class="form-control"></textarea>
{% elseif question.type == 'number' %}
<input type="number" name="{{ name }}" aria-labelledby="question-{{ question.id }}">
{% else %}
<input type="text" name="{{ name }}" aria-labelledby="question-{{ question.id }}" class="form-control">
{% endif %}
{# {% endif %}#}
{% endfor %}
</div>
<button class="btn btn-primary">{{ button_label|default('Submit') }}</button>
{#{{ form_end(form, {render_rest: false }) }}#}
{{ form_end(form) }}
It's completely detached from the responseType form which is why I believe it doesn't submit to the database... But I am not sure how to map the ResponseType form to the _form.html.twig
you dont use the form component - you have the class and the correct controller code, but in your template you print the form fields yourself.
Just define the fields in your formType, remove the formfields from your twig and use the supposed {{ form_*() }} methods.
To make this conditional rendering of your CollectionType work - you will have to write some twig code in your form theme. (but to explain this is outside of my time and scope of the question)
I'm creating an app and I want to enable users to change their data and password. I've created an email changing form and it works, but I've got a problem with password.
I've got a page localhost:8000/user/{id} and here the buttons: edit email and edit password. Edit email is working and when I click on editing password - I got a blank page on localhost:8000/user/{id}/change_password
(enter image description here enter image description here). Th PassType doesn't show there.
There are no syntax error on localhost:8000/user/{id} and localhost:8000/user/{id}/change_password.
I've added a function edit_pass to UserController, crated PassType (where is the form to change password) and make a template edit_password.html.twig.
I don't know where is the problem. I did the same thing as with other Forms which work. I've tried to clear the edit_password template (I've just left the base_html there and put some text) cause I've thought there is a problem in it, but it was still a blank page on localhost:8000/user/{id}/change_password.
PassType:
<?php
/*
* Password type.
*/
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Class PassType.
*/
class PassType extends AbstractType
{
/**
* Builds the form.
*
* This method is called for each type in the hierarchy starting from the
* top most type. Type extensions can further modify the form.
*
* #see FormTypeExtensionInterface::buildForm()
*
* #param FormBuilderInterface $builder The form builder
* #param array $options The options
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'password',
RepeatedType::class,
[
'type' => PassType::class,
'required' => true,
'attr' => ['max_length' => 40],
'first_options' => ['label' => 'label.password'],
'second_options' => ['label' => 'label.repeat_password'],
]
);
}
/**
* Configures the options for this type.
*
* #param OptionsResolver $resolver The resolver for the options
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => User::class]);
}
/**
* Returns the prefix of the template block name for this type.
*
* The block prefix defaults to the underscored short class name with
* the "Type" suffix removed (e.g. "UserProfileType" => "user_profile").
*
* #return string The prefix of the template block name
*/
public function getBlockPrefix(): string
{
return 'user';
}
}
edit_password.html.twig
{% extends 'base.html.twig' %}
{% block title %}
{{ 'title_password_edit'|trans({'%id%': user.id|default('')}) }}
{% endblock %}
{% block body %}
<h1 class="display-4 d-flex justify-content-center">{{ 'title_password_edit'|trans({'%id%': user.id|default('')}) }}</h1>
{{ form_start(form, { method: 'PUT', action: url('password_edit', {id: user.id}) }) }}
{{ form_widget(form) }}
<div class="form-group row float-sm-right">
<input type="submit" value="{{ 'action_save'|trans }}" class="btn btn-primary" />
</div>
<div class="form-group row float-sm-left">
<a href="{{ url('user_index') }}" class="btn btn-link">
{{ 'action_back_to_list'|trans }}
</a>
</div>
{{ form_end(form) }}
{% endblock %}
and part of UserController whith edit_pass function
/**
* Edit Password.
*
* #param \Symfony\Component\HttpFoundation\Request $request HTTP request
* #param \App\Entity\User $user User entity
* #param \App\Repository\UserRepository $repository User repository
*
* #return \Symfony\Component\HttpFoundation\Response HTTP response
*
* #throws \Doctrine\ORM\ORMException
* #throws \Doctrine\ORM\OptimisticLockException
*
* #Route(
* "/{id}/change_password",
* methods={"GET", "PUT"},
* requirements={"id": "[1-9]\d*"},
* name="password_edit",
* )
*/
public function edit_pass(Request $request, User $user, UserPasswordEncoderInterface $passwordEncoder, UserRepository $repository): Response
{
$form = $this->createForm(PassType::class, $user, ['method' => 'PUT']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
$repository->save($user);
$this->addFlash('success', 'message.updated_successfully');
return $this->redirectToRoute('user_show', array('id' => $this->getUser()->getId()));
}
return $this->render(
'user/edit_password.html.twig',
[
'form' => $form->createView(),
'user' => $user,
]
);
}
I'm also adding the user/show.html.twig
{% extends 'base.html.twig' %}
{% block title %}
{{ 'label_detail_users'|trans({'%id%': user.id|default('')}) }}
{% endblock %}
{% block body %}
<h1 class="display-4 d-flex justify-content-center">{{ 'label_detail_users'|trans({'%id%': user.id|default('')}) }}</h1>
{% if users is defined and users|length %}
<table class="table table-striped">
<thead>
<tr>
<th>{{ 'label_user_id'|trans }}</th>
<th>{{ 'label_email'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ users.id }}</td>
<td>{{ users.email }}</td>
</tr>
</tbody>
</table>
<p>
<a class="btn btn-info" href="{{ url('user_edit', {id: users.id}) }}" title="{{ 'edit_email'|trans }}">
{{ 'edit_email'|trans }}
</a>
</p>
<p>
<a class="btn btn-info" href="{{ url('password_edit', {id: users.id}) }}" title="{{ 'edit_password'|trans }}">
{{ 'edit_password'|trans }}
</a>
</p>
<p>
<a class="btn btn-info" href="{{ url('user_index') }}" title="{{ 'action_back_to_list'|trans }}">
{{ 'action_back_to_list'|trans }}
</a>
</p>
{% else %}
<p>
{{ 'message_item_not_found'|trans }}
</p>
{% endif %}
{% endblock %}
You produced an endless loop - its PasswordType in your RepeatedType. PassType is the name of your whole Form - you see the problem?
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'password',
RepeatedType::class,
[
'type' => PasswordType::class,
'required' => true,
'attr' => ['max_length' => 40],
'first_options' => ['label' => 'label.password'],
'second_options' => ['label' => 'label.repeat_password'],
]
);
}
And may I ask why you limit the length of a password?
I am trying to build a list filter in Symfony. I'm still new to PHP, MySQL, and twig. The official documentation doesn't help a lot. It is required that I have a page with a list of all classes and next to that a search bar where the user inputs the class they want and it will show on the page without the others. I'll post my code but I think it is missing a lot of code. I only need little help and maybe sources for documentation on how to do it the official documents aren't very clear for someone with zero experience.
My ClassesRepository.php
<?php
namespace App\Repository;
use App\Entity\Classes;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* #method Classes|null find($id, $lockMode = null, $lockVersion = null)
* #method Classes|null findOneBy(array $criteria, array $orderBy = null)
* #method Classes[] findAll()
* #method Classes[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ClassesRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Classes::class);
}
public function findbyName()
{
return $this->createQueryBuilder('c')
->getQuery()->getResult();
}
public function getSearchClasses($class){
$qb = $this->createQueryBuilder('c')
->where('c.Title LIKE :Title')
->setParameter('Title', '%' . $class->getTitle() . '%')
->orderBy('c.Title', 'DESC')
->getQuery();
}
}
classesController:
<?php
namespace App\Controller;
use App\Entity\Classes;
use App\Entity\Students;
use App\Entity\Courses;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class ClassesController extends AbstractController
{
/**
* #Route("custom/classes", name="classes_list")
*/
public function index()
{
$classes = $this->getDoctrine()->getRepository(classes::class)->findAll();
return $this->render('classes/index.html.twig', [
'classes' => $classes
]);
}
/**
* #Route("/classes/new", name="new_class")
* #Method({"GET","POST"})
*/
public function new(Request $request)
{
$class = new Classes();
$form = $this->createFormBuilder($class)
->add('Title', TextType::class, array('attr' =>
array('class' => 'form-control')))
->add('save', SubmitType::class,array('label' => 'Create',
'attr' => array('class' => 'btn btn-primary mt-3')))
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$class = $form->getData();
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($class);
$entityManager->flush();
return $this->redirectToRoute('classes_list');
}
return $this->render('classes/new.html.twig', array(
'form' => $form->createView()
));
}
/**
* #Route("/classes/edit/{id}", name="edit_class")
* #Method({"GET","POST"})
*/
public function edit(Request $request, $id)
{
$class = new Classes();
$class = $this->getDoctrine()->getRepository(classes::class)->find($id);
$form = $this->createFormBuilder($class)
->add('Title', TextType::class, array('attr' =>
array('class' => 'form-control')))
->add('save', SubmitType::class,array('label' => 'Create',
'attr' => array('class' => 'btn btn-primary mt-3')))
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->flush();
return $this->redirectToRoute('classes_list');
}
return $this->render('classes/edit.html.twig', array(
'form' => $form->createView()
));
}
/**
* #Route("/classes/delete/{id}")
* #Method({"DELETE"})
*/
public function delete(Request $request, $id){
$class = $this->getDoctrine()->getRepository(Classes::class)->find($id);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($class);
$entityManager->flush();
$response = new Response();
$response->send();
}
/**
* #Route("/classes/{id}", name="classes_show")
* #Method({"GET"})
*/
public function show($id){
$_class = $this->getDoctrine()->getRepository(Classes::class)->find($id);
return $this->render('classes/show.html.twig', array('classes' => $_class));
}
// /**
// * #Route("custom/classes/save")
// */
// public function save() {
// $entityManager = $this->getDoctrine()->getManager();
// $classes = new Classes();
// $classes->setTitle('Grade 2');
// $entityManager->persist($classes);
// $entityManager->flush();
// return new Response('Saved an classes with the id of '.$classes->getId());
// }
}
Index.html.twig is Location where I will need to locate the list filter
{% extends 'base.html.twig' %}
{% block title %}Classes{% endblock %}
{% block body %}
<br>
<h1>Classes:</h1>
Create
<br>
{% if classes %}
<div class="alignleft">
<table id="classes" class="table table-striped" style="width:70%">
<thead>
<tr>
<th>Class</th>
<th>Details </th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for classes in classes %}
<tr>
<td> {{ classes.title }}</td>
<td>
Show Class Details
</td>
<td>
Edit
</td>
<td>
X
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div>
<form method="GET" action="search" style = "position:absolute; left:1100px; top:150px; height:100px; width:100px">
<input type="text" name="q" placeholder="Search Query...">
<select name="column" style = "position:absolute; left:40px; top:30px; width:100px ">
<option value="classes.Title" >Class</option>
</select>
<input type="submit" class="btn btn-warning" value="Find" style = "position:absolute; left:40px; top:56px; width:100px ">
</form>
</div>
{% else %}
<p>No Classes Available</p>
{% endif %}
{% endblock %}
{% block javascripts %}
<script src="/js/classmain.js"></script>
{% endblock %}
I don't understand the behavior you expect from the filter but I hope it will help you..
In your ClassesRepository.php
// if has not $classTitle and $query it will find all
public function getSearchClasses($classTitle = null , $query=null){
$qb = $this->createQueryBuilder('c')
->orderBy('c.Title', 'DESC');
if($classTitle && $classTitle !== '') {
$qb->andWhere('c.Title LIKE :classTitle')
->setParameter('classTitle', '%' . classTitle . '%');
}
if($query && $query !== '') {
// doSomethings with query input
}
return $qb->getQuery()->getResult();
}
In your classesController:
/**
* #Route("custom/classes", name="classes_list")
*/
public function index(Request $request)
{
$classTitle = $request->query->get('classTitle',null);
$query = $request->query->get('query',null);
// if has not $classTitle and $query it will find all
$classes = $this->getDoctrine()->getRepository(classes::class)->getSearchClasses($classTitle,$query);
return $this->render('classes/index.html.twig', [
'classes' => $classes
]);
}
In your index.html.twig
// redirect to the same route that render this template ..
<form method="GET" action="{{ path('classes_list') }}">
<input type="text" name="query" placeholder="Search Query...">
<select name="classTitle">
{% for class in classes%}
<option value="{{class.title}" >{{class.title}}</option>
{% endfor %}
</select>
<input type="submit" class="btn btn-warning" value="Find">
</form>
I'm learning how yo use symfony, and my problem is, when I want to use the handleRequest function, it did not validate my email en message field, but it's good for name field.
Look the code:
Contact.php entity
<?php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Contact
{
/**
* #Assert\NotBlank
*/
private $name;
/**
* #Assert\NotBlank
*/
private $email;
/**
* #Assert\NotBlank
*/
private $message;
public function getName()
{
return $this->name;
}
public function getEmail()
{
return $this->email;
}
public function getMessage()
{
return $this->message;
}
public function setName($name)
{
$this->name = $name;
}
public function setEmail($email)
{
$this->name = $email;
}
public function setMessage($message)
{
$this->name = $message;
}
}
?>
BlogController.php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\Article;
use App\Entity\Contact;
use App\Repository\ArticleRepository;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\HttpFoundation\Request;
class BlogController extends Controller
{
/**
* #Route("/blog", name="blog")
*/
public function blog(ArticleRepository $repo)
{
$articles = $repo->findAll();
return $this->render('blog/index.html.twig', [
'controller_name' => 'BlogController',
'articles' => $articles
]);
}
/**
* #Route("/", name="blog_home")
*/
public function home()
{
return $this->render('blog/home.html.twig');
}
/**
* #Route("/blog/articles/{id}", name="blog_show")
*/
public function show(Article $article)
{
return $this->render('blog/show.html.twig',[
'article' => $article
]);
}
/**
* #Route("/contact", name="blog_contact")
*/
public function contact(Request $request)
{
$contact = new Contact; /* Create the new contact object */
$form = $this->createFormBuilder($contact) /* Creating the form */
->add('name', TextType::class)
->add('email', TextType::class)
->add('message', TextareaType::class)
->getForm();
dump($contact);
$form->handleRequest($request);
dump($contact);
if($form->isSubmitted() && $form->isValid())
{
return $this->redirectToRoute('blog_home');
}
dump($request);
return $this->render('blog/contact.html.twig',[
'form' => $form->createView()
]);
}
}
contact.html.twig
{% extends 'base.html.twig' %}
{% block title %}BLOG - Contact{% endblock %}
{% block body %}
<h2>Me contacter !</h1>
<div class="row">
<div class="col-md-5">
{{ form_start(form) }}
<label>Nom:</label>
{{ form_widget(form.name) }}
<label>Email:</label>
{{ form_widget(form.email) }}
<label>Message:</label>
{{ form_widget(form.message) }}
<br>
<button type="submit" class="btn btn-info">Envoie</button>
{{ form_end(form) }}
</div>
<div class="col-md-1">
</div>
<div class="col-md-6">
<div class="card border-info mb-1" style="max-width: 20rem;">
<div class="card-header">Twitter: #Fergvae</div>
</div>
<div class="card border-dark mb-1" style="max-width: 20rem;">
<div class="card-header">Discord: Fergvae#0730</div>
</div>
<div class="card border-danger mb-1" style="max-width: 20rem;">
<div class="card-header">Youtube: Fergvae</div>
</div>
</div>
</div>
{% endblock %}
The only things that didn't work is the handleRequest it's why I made multiple dump.
you also can look the dumped content, the first is before handle and second after.
Dumped symfony content
Thanks to all people who answer this question !
Ok my bad, I just forget when I copy past to change the ^this->name in de setters ! Excuse me for the disturb
It's great that you have found your solution, but just in case:
If usage for classes, a better practice is to use a FormType, in there you can declare your class on which fields the form should be automatically created. Which Symfony will automatically catch all of the needed fields and will create the form for you, less code written and etc. Or you can create a custom form, and define all of your needed fields, including restrictions as not empty and etc..
To sum it up, if possible keep as less logic in the controllers as possible and move them deeper.
As the title suggests, I can't get the delete() option to work. I've struggled through a lot of posts online but the right answer just isn't there.
I'm using Laravel 5.5 with Homestead (installed a week ago, newest versions or so).
Let me give you some code and I really hope somebody is able to help me out.
This gives me a headache and the olanzapine is running out. Please tell me what I am doing wrong, and if there is something that's missing, please let me know!
I want to delete a page as a admin, but I Laravel doesn't seem to authorize me and gives me this error:
protected function methodNotAllowed(array $others)
{
throw new MethodNotAllowedHttpException($others);
}
This is my controller:
<?php
namespace App\Http\Controllers\Admin;
use Auth;
use App\Page;
use App\Http\Requests\WorkWithPage;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PagesController extends Controller
{
public function __construct() {
$this->middleware('admin');
$this->middleware('can:manageUsers,App\User');
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
if (Auth::user()->isAdmin()) {
$pages = Page::paginate(20);
} else {
$page = Auth::user()->pages()->paginate(5);
}
return view('admin.pages.index', ['pages' => $pages]);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('admin.pages.create')->with(['model' => new Page()]);
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(WorkWithPage $request)
{
Auth::user()->pages()->save(new Page($request->only([
'title','url','content'])));
return redirect()->route('pages.index')->with('status', 'Pagina succesvol aangemaakt');
}
/**
* Show the form for editing the specified resource.
*
* #param \App\Page $page
* #return \Illuminate\Http\Response
*/
public function edit(Page $page)
{
if(Auth::user()->cant('update', $page)){
return redirect()->route('pages.index')->with('status', 'Pagina succesvol aangepast');
}
return view('admin.pages.edit', ['model' => $page]);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Page $page
* #return \Illuminate\Http\Response
*/
public function update(WorkWithPage $request, Page $page)
{
if(Auth::user()->cant('update', $page)){
return redirect()->route('pages.index')->with('status', 'Dat mag jij niet');
}
$page->fill($request->only([
'title','url','content'
]));
$page->save();
return redirect()->route('pages.index')->with('status', 'Pagina succesvol aangepast');
}
/**
* Remove the specified resource from storage.
*
* #param \App\Page $page
* #return \Illuminate\Http\Response
*/
public function destroy(Page $page)
{
if(Auth::user()->cant('delete', $page)){
return redirect()->route('pages.index')->with('status', 'Hey knul! Pssst! Wegwezen!');
}
$page->id->delete();
return redirect()->route('pages.index')->with('status', 'Page has been deleted.');
}
}
And this is my index page (index as in admin index for backend :
#extends('layouts.app') #section('content')
<div class="container">
#if (session('status'))
<div class="alert alert-info">
{{ session('status') }}
</div>
#endif
Nieuwe pagina
<br>
<br>
<table class="table">
<thead>
<tr>
<th>Naam</th>
<th>URL</th>
<th>Opties</th>
</tr>
</thead>
#foreach($pages as $page)
<tr>
<td>
{{ $page->title }}
</td>
<td>{{ $page->url }}</td>
<td class="text-right">
<a href="{{ route('pages.destroy', ['page' => $page->id])}}" class="btn btn-danger delete-link" data-message="Are you sure you want to delete this page?"
data-form="delete-form">
Delete
</a>
</td>
</tr>
#endforeach
</table>
{{$pages->links()}}
</div>
<form id="delete-form" action="" methode="POST">
{{method_field('DELETE')}}
{!! csrf_field() !!}
</form>
#endsection
Then there the routes:
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/admin', function() {
return view('admin.index');
})->middleware('admin');
Route::resource('/admin/pages', 'Admin\PagesController', ['except' => ['show']]);
Route::resource('/admin/blog', 'Admin\BlogController', ['except' => ['show']]);
Route::resource('/admin/users', 'Admin\UsersController', ['except' => ['create', 'store', '']]);
Route::get('/home', 'HomeController#index')->name('home');
Then the policy:
<?php
namespace App\Policies;
use App\User;
use App\Page;
use Illuminate\Auth\Access\HandlesAuthorization;
class PagePolicy
{
use HandlesAuthorization;
public function before($user, $ability) {
if ($user->isAdmin()) {
return true;
}
}
/**
* Determine whether the user can update the page.
*
* #param \App\User $user
* #param \App\Page $page
* #return mixed
*/
public function update(User $user, Page $page)
{
return $user->id = $page->user_id;
}
/**
* Determine whether the user can delete the page.
*
* #param \App\User $user
* #param \App\Page $page
* #return mixed
*/
public function delete(User $user, Page $page)
{
return $user->id = $page->user_id;
}
}
And finally the middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class AccessAdmin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check() && Auth::user()->hasAnyRole(['Super Admin','Admin'])) {
return $next($request);
}
return redirect('login');
}
}
Update: fixed!
In the view I changed:
#foreach($model as $post)
<tr>
<td>
{{ $post->title }}
</td>
<td>{{ $post->user()->first()->name }}</td>
<td>{{ $post->slug }}</td>
<td class="text-right">
<a href="{{ route('blog.destroy', ['blog' => $post->id])}}" class="btn btn-danger delete-link" data-message="Are you sure you want to delete this page?"
data-form="delete-form">
Delete
</a>
</td>
</tr>
#endforeach
</table>
{{$model->links()}}
</div>
<form id="delete-form" action="#" methode="POST">
{{ method_field('DELETE') }}
{!! csrf_field() !!}
</form>
To:
#foreach($pages as $page)
<tr>
<td>
{{ $page->title }}
</td>
<td>{{ $page->url }}</td>
<td class="text-right">
<form action="{{ route('pages.destroy', ['page' => $page->id]) }}" method="POST" class="btn btn-danger delete-link" >
<input type="submit" value="delete"/>
{{method_field('DELETE')}}
{!! csrf_field() !!}
</form>
</td>
</tr>
#endforeach
</table>
{{$pages->links()}}
Not sure where to start...
First the exception you are receiving is because you are sending wrong method to the url. (I never do it that way) but probably you are sending GET when you are expecting POST (with DELETE overwrite). You have wrong named "methode", it should be "method".
Next... not sure if this is gone work $page->id->delete();... maybe $page->delete().
As suggestion - maybe it will be better to use !can() instead of cant(). There is no difference, but cant() may confuse you in some point.
And I am glad to see someone using ->fill() method but you may come up on a small problem when dealing with checkboxes. Check this: https://github.com/LaraModulus/admin-core/blob/master/src/traits/HelpersTrait.php