I'm currently working on a basic Symfony project to discover this Framework, my website identifies some French rap albums and gives infos about it, then I created 2 Controllers : "DefaultController" and "AlbumsController". In the fist one, I implements some functions to displays some music lyrics and I use path names for the links and it's well work but with the second Controller I do the exact same things and it's not working. (Sorry for bad English).
Attached -> The problematic code
DefaultController :
<?php
namespace App\Controller;
use App\Entity\Musique;
use App\Form\AlbumsType;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Controller\AlbumsController;
use App\Repository\AlbumsRepository;
use App\Repository\MusiqueRepository;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\Albums;
class DefaultController extends AbstractController
{
/**
* #Route("/", name="index")
*/
public function index()
{
return $this->render('index.html.twig', [
'title' => 'Accueil',
]);
}
/**
* #Route("/albums", name="albums")
*/
public function albums()
{
$repo = $this->getDoctrine()->getRepository(Albums::class);
$albums = $repo->findAll();
return $this->render('albums/index.html.twig', [
'albums' => $albums,
]);
}
/**
* #Route("/musiques", name="musiques")
*/
public function musiques()
{
$repo = $this->getDoctrine()->getRepository(Musique::class);
$musiques = $repo->findAll();
return $this->render('musiques.html.twig', [
'title' => 'Liste des Musiques',
'$musiques' => $musiques,
]);
}
/**
* #Route("/musiques/{id}", requirements={"id": "[1-9]\d*"}, name="randMusique")
* #throws \Exception
*/
public function randomMusique()
{
$random = random_int(1, 100);
$repo = $this->getDoctrine()->getRepository(Musique::class);
$musique = $repo->find($random);
return $this->render('randomMusique.html.twig', [
'musique' => $musique,
]);
}
}
AlbumsController :
<?php
namespace App\Controller;
use App\Entity\Albums;
use App\Form\AlbumsType;
use App\Repository\AlbumsRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* #Route("/albums")
*/
class AlbumsController extends AbstractController
{
/**
* #Route("/", name="albums_index", methods={"GET"})
*/
public function index(AlbumsRepository $albumsRepository): Response
{
return $this->render('albums/index.html.twig', [
'albums' => $albumsRepository->findAll(),
]);
}
/**
* #Route("/new", name="album_new", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$album = new Albums();
$form = $this->createForm(AlbumsType::class, $album);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($album);
$entityManager->flush();
return $this->redirectToRoute('albums_index');
}
return $this->render('albums/new.html.twig', [
'album' => $album,
'formAlbum' => $form->createView(),
]);
}
/**
* #Route("/{id}", name="albums_show", methods={"GET"})
*/
public function show(Albums $album): Response
{
return $this->render('albums/show.html.twig', [
'album' => $album,
]);
}
/**
* #Route("/{id}/edit", name="albums_edit", methods={"GET","POST"})
*/
public function edit(Request $request, Albums $album): Response
{
$form = $this->createForm(AlbumsType::class, $album);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('albums_index');
}
return $this->render('albums/edit.html.twig', [
'album' => $album,
'form' => $form->createView(),
]);
}
/**
* #Route("/{id}", name="albums_delete", methods={"DELETE"})
*/
public function delete(Request $request, Albums $album): Response
{
if ($this->isCsrfTokenValid('delete'.$album->getId(), $request->request->get('_token'))) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($album);
$entityManager->flush();
}
return $this->redirectToRoute('albums_index');
}
}
base.html.twig :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Projet — PHP{% endblock %}</title>
<link rel="stylesheet" href="https://bootswatch.com/4/darkly/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="{{ asset('css/style.css')}}">
{% block stylesheets %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light">
<a class="navbar-brand" href="/">France-Rap</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor03"
aria-controls="navbarColor03" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor03">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{{ path('index') }}">Accueil</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ path('albums') }}">Liste des Albums</a>
</li>
{#
<li class="nav-item">
<a class="nav-link" href="{{ path('musiques') }}">Liste des Musiques</a> // The path isn't working
</li>
<li class="nav-item">
<a class="nav-link" href="{{ path('randMusique') }}">Musique Aléatoire</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ path('album_new') }}">Créer un Album</a>
</li>
#}
<li class="nav-item">
<a class="nav-link" href="#">Contact</a>
</li>
</ul>
{% block search %}{% endblock %}
</div>
</nav>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
This is the error :
Render error
Resultat of the command :
php bin/console debug:router musiques
In the secreen shot of the error i can see that your view is picked up from cache try runing follwing comand:
php bin/console cache:clear
Related
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.
I'm currently working on translations for my laravel project. It's all working fine, but only when I'm working with just one translation file.
I'm trying to keep things organised, and for that purpose I had the idea to have one translation file for the side-wide components (login/logout links, back buttons, stuff like that) and then introduce other translation files for more specific things, such as translating components found on your profile's dashboard.
Here are, for example, my English translation files:
general.php
return [
"login" => "Login",
"register" => "Register",
"logout" => "Logout",
"back" => "Back",
"postBy" => "Posted by",
"name" => "Name",
"email" => "E-Mail Address",
"pass" => "Password",
"confirmPass" => "Confirm Password",
"rememberMe" => "Remember Me",
"forgotPass" => "Forgot Your Password?",
];
dashboard.php
<?php
return [
"title" => "Your Messages",
"header" => "Message",
"create" => "Add Message",
"edit" => "Edit",
"delete" => "Delete",
];
I'm already getting errors by doing this, without even using it in my dashboard.blade.php file. The error I get is:
ErrorException (E_ERROR) htmlspecialchars() expects parameter 1 to be
string, array given (View:
C:\xampp\htdocs\messageboard\resources\views\layouts\app.blade.php)
(View:
C:\xampp\htdocs\messageboard\resources\views\layouts\app.blade.php)
while I haven't even attempted to call it with something like {{ __('dashboard.title') }}. I'm at a loss as to what's causing this error.
As requested, here is the view causing the error. I'm getting the same error no matter what page is loaded, so I'm assuming that it'll be this very view as it's basically included and expanded upon in every other view.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
</head>
<body>
<div id="app">
<nav class="navbar navbar-expand-md navbar-light navbar-laravel">
<div class="container">
<a class="navbar-brand" href="{{ url('/') }}">
<i class="far fa-envelope"></i>
{{ config('app.name', 'Messageboard') }}
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar -->
<ul class="navbar-nav mr-auto">
</ul>
<!-- Right Side Of Navbar -->
<ul class="navbar-nav ml-auto">
<!-- Authentication Links -->
#guest
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">{{ __('general.login') }}</a>
</li>
#if (Route::has('register'))
<li class="nav-item">
<a class="nav-link" href="{{ route('register') }}">{{ __('general.register') }}</a>
</li>
#endif
#else
<li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }} <span class="caret"></span>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/dashboard">{{ __('Dashboard') }}</a>
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('general.logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
#csrf
</form>
</div>
</li>
#endguest
</ul>
</div>
</div>
</nav>
<div class="container">
<main class="py-4">
#include('inc.statusmessages')
#yield('content')
</main>
</div>
</div>
</body>
</html>
The controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Message;
use App\User;
use Auth;
class MessagesController extends Controller
{
public function __construct(){
$this->middleware('auth', [
'except' => [
'index',
'show'
]
]);
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$messages = Message::orderBy('created_at', 'desc')->get();
return view('messages')->with('messages', $messages);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('createmessage');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required',
'body' => 'required|min:15|max:500'
]);
// Create Message
$message = new Message;
$message->title = $request->input('title');
$message->body = $request->input('body');
$message->status = 100;
$message->user_id = auth()->user()->id;
$message->save();
return redirect('/dashboard')->with('success', 'Message Created');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$message = Message::findOrFail($id);
$user = User::findOrFail($message->user_id);
$messageData = [
'message' => $message,
'user' => $user
];
return view('showmessage')->with($messageData);
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
$userId = 0;
$message = Message::findOrFail($id);
if (Auth::check())
{
// The user is logged in...
$userId = Auth::user()->id;
}
if((int)$userId !== (int)$message->user_id) {
return "Poster ID: ".$message->user_id.", User ID: ".$userId;
}
return view('editmessage')->with('message', $message);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'title' => 'required',
'body' => 'required|min:15|max:500'
]);
$message = Message::find($id);
$message->title = $request->input('title');
$message->body = $request->input('body');
$message->status = 100;
$message->user_id = auth()->user()->id;
$message->save();
return redirect('/dashboard')->with('success', 'Message Updated');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$message = Message::find($id);
$message->delete();
return redirect('/dashboard')->with('success', 'Message Removed');
}
}
Any help would be appreciated. I hope I'm clear enough, and if not please let me know.
As #Magnus Eriksson pointed out, this is because you're using {{ __('Dashboard') }} in your blade view and have a dashboard.php translation file.
The __() translation helper will normally fall back to returning the string it's given when there are no matching translation keys, but in this case it does find the translation file. Since you're not using a specific key from the file such as dashboard.title, it's returning the full translation array from the file, which is then given to htmlentities() when the blade view is rendered.
I create two entity. first Posts and second categories. this to entity have many to many relation.
I make a form from posts and add an embed form categories that use ChoiceType.
the form work correctly an I can add as many as categories to each post.
but in database orm create an posts_categories when I look to its data the posts_id is correct and from posts table but I don't know where the categories_id come from ?
I means the real id of categories not save on posts_categories table. where does this id come? and how I can config that real id save on table?
App\Entity\Posts.php
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\PostsRepository")
*/
class Posts
{
public $newFormTitle = 'Add New Post';
public $editFormTitle = 'Edit Post';
public $listFormTitle = 'Posts List';
public $adminList = 'postList';
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=200)
*/
private $title;
/**
* #ORM\Column(type="text")
*/
private $content;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Categories" , orphanRemoval=true, cascade={"persist"})
*/
private $categories;
public function __construct()
{
$this->categories = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getContent(): ?string
{
return $this->content;
}
public function setContent(?string $content): self
{
$this->content = $content;
return $this;
}
/**
* #return Collection|Categories[]
*/
public function getCategories(): Collection
{
return $this->categories;
}
public function addCategory(Categories $category): self
{
if (!$this->categories->contains($category)) {
$this->categories[] = $category;
}
return $this;
}
public function removeCategory(Categories $category): self
{
if ($this->categories->contains($category)) {
$this->categories->removeElement($category);
}
return $this;
}
}
App\Entity\Categories.php
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\CategoriesRepository")
*/
class Categories
{
public $newFormTitle = 'Add New Post';
public $editFormTitle = 'Edit Post';
public $listFormTitle = 'Categories List';
public $adminList = 'categoriesList';
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=100)
*/
private $name;
public function __construct()
{
}
public function getId()
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
App\Form\PostsType.php
<?php
namespace App\Form;
use App\Entity\Posts;
use App\Form\CategoriesPostsType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class PostsType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', null, [
'attr' => ['autofocus' => true ,'class'=>'form-control'],
'label' => 'label.title',
'label_attr' => ['class'=>'label-control'],
])
->add('content', null, [
'attr' => ['rows' => 8 ,'class'=>'form-control'],
'label' => 'label.content',
'label_attr' => ['class'=>'label-control'],
])
;
/*
$builder->add('categories', CollectionType::class, array(
'entry_type' => CategoryType::class,
'entry_options' => array('label' => false),
'allow_add' => true,
));
*/
$builder->add('categories', CollectionType::class, array(
'entry_type' => CategoriesPostsType::class,
'entry_options' => array('label' => false),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => true,
'label' => false,
));
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Posts::class,
]);
}
}
App\Form\CategoriesPostsType.php
<?php
namespace App\Form;
use App\Entity\Categories;
use App\Form\Type\CategoryInputType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use App\Repository\CategoriesRepository;
class CategoriesPostsType extends AbstractType
{
private $categories;
public function __construct(CategoriesRepository $category)
{
$categories = $category->findAll();
$choise = array();
foreach ($categories as $key => $value)
//$choise[] = new Categories($categories[$key]->getId();
$choise[$categories[$key]->getName()] = $categories[$key]->getId();
$this->categories = $choise;
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', ChoiceType::class, [
'attr' => ['autofocus' => true ,'class'=>'form-detail-control formChoiceType'],
'label' => false,
'label_attr' => ['class'=>'label-control'],
'choices' => $this->categories,
])
/* ->add('category', CategoryInputType::class, [
'label' => 'label.category',
'required' => false,
])*/
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Categories::class,
]);
}
}
twig form
{% extends 'theme/basickTheme/form.html.twig' %}
{% block body_id 'content_new_posts' %}
{% block defaultFormHeader entity.newFormTitle %}
{% block defaultFormBody %}
<div class="row">
<div class="col-12">
{{ form_start(form) }}
<div class="col-12">
{{ form_errors(form) }}
</div>
<div class="col-12">
{{ form_row(form.title) }}
</div>
<div class="col-12">
{{ form_row(form.content) }}
</div>
<div class="col-12 form-group">
<h3>Categories</h3>
</div>
<div class="col-12">
<button type="button" class="btn add-detail-botton" onclick="addCategoriesForm(1)">
<img src="{{ asset('img/custum-icon/add-small.png') }}">
<i class="fa fa-save" aria-hidden="true"></i> {{ button_label|default('categories.label.add.category'|trans) }}
</button>
<ol class="detail-list" data-prototype="{{ form_widget(form.categories.vars.prototype)|e('html_attr') }}">
{# iterate over each existing tag and render its only field: name #}
{% for Category in form.categories %}
<li>{{ form_widget(Category.name) }}</li>
{% endfor %}
</ol>
<button type="button" class="btn add-detail-botton" onclick="addCategoriesForm(2)">
<img src="{{ asset('img/custum-icon/add-small.png') }}">
<i class="fa fa-save" aria-hidden="true"></i> {{ button_label|default('categories.label.add.category'|trans) }}
</button>
</div>
<div class="col-12 form-footer-botton">
<button type="submit" class="btn btn-primary">
<i class="fa fa-save" aria-hidden="true"></i> {{ button_label|default('Label.save'|trans) }}
</button>
<a href="{{ backUrl }}" class="btn btn-primary">
<i class="fa fa-list-alt" aria-hidden="true"></i> {{ 'Label.back.to.list'|trans }}
</a>
</div>
{{ form_end(form) }}
</div>
</div>
{% endblock %}
{% block javascripts %}`
<script>
var $collectionHolder;
jQuery(document).ready(function() {
// Get the ul that holds the collection of tags
$collectionHolder = $('ol.detail-list');
$collectionHolder.find('li').each(function() {
addCategoriesFormDeleteLink($(this));
});
// count the current form inputs we have (e.g. 2), use that as the new
// index when inserting a new item (e.g. 2)
$collectionHolder.data('index', $collectionHolder.find(':input').length);
});
function addCategoriesForm( $appendType = 1) {
var $collectionHolder = $('ol.detail-list');
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
var newForm = prototype;
// You need this only if you didn't set 'label' => false in your tags field in TaskType
// Replace '__name__label__' in the prototype's HTML to
// instead be a number based on how many items we have
// newForm = newForm.replace(/__name__label__/g, index);
// Replace '__name__' in the prototype's HTML to
// instead be a number based on how many items we have
newForm = newForm.replace(/__name__/g, index);
newForm = newForm.replace(/form-detail-control/g, 'form-detail-control-new');
// increase the index with one for the next item
$collectionHolder.data('index', index + 1);
// Display the form in the page in an li, before the "Add a tag" link li
var $newFormLi = $('<li class="prototye"></li>').prepend(newForm);
if($appendType == 1)
$collectionHolder.prepend($newFormLi);
else
$collectionHolder.append($newFormLi);
//$newLinkLi.before($newFormLi);
addCategoriesFormDeleteLink($newFormLi);
}
function addCategoriesFormDeleteLink($tagFormLi) {
//var $removeFormButton = $('<button type="button" class="detailDeleteButton">Delete</button>');
var $removeFormButton = $('<button type="button" class="btn delte-detail-botton"><img src="{{ asset('img/custum-icon/delete-smal.png') }}"><i class="fa fa-save" aria-hidden="true"></i>{{ button_label|default('categories.label.delete.category'|trans) }}</button>');
$tagFormLi.append($removeFormButton);
$removeFormButton.on('click', function(e) {
// remove the li for the tag form
$tagFormLi.remove();
});
}
</script>
{% endblock %}
I'm setting up a blog and want the homepage to show the latest blog entries including links to the single entries.
I got a link to all entries showing in a list but I can't exactly figure out how to show a single entry. Plus now I always get an "object not found" exception as soon as I try to click on the link.
Here's the controller which contents the Function to show a single entry:
<?php
// src/BlogBundle/Controller/BlogController.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 BlogBundle\Form\BlogType;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class BlogController extends Controller
{
/**
* #Route("/blog", name="bloglist", requirements={"page": "\d+"})
*/
public function listAction()
{
$entry = $this->getDoctrine()->getRepository('BlogBundle:Blog')->findBy(array(), array('date' => 'DESC'));
dump($entry);
return $this->render('BlogBundle:blog:blog.html.twig', [
'bloglist' => $entry
]);
}
/**
* #Route("/blog/new", name="create")
*/
public function createAction(Request $request) {
$entry = new Blog();
$entry->setDate(new \DateTime('now'));
$entry->setAuthor($this->getUser());
$form = $this->createForm(BlogType::class, $entry);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entry = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($entry);
$em->flush();
return $this->render('BlogBundle:blog:createsubmit.html.twig', array(
'entry' => $entry,
'form' => $form->createView(),
'success' => true
));
}
return $this->render('BlogBundle:blog:new.html.twig', array(
'quote' => 'New blog entry created!',
'form' => $form->createView(),
));
}
/**
* #Route("/blog/singleentry/{id}", name="singleentry", requirements={"id" = "\d+"}, defaults={"id" = 0})
*/
public function listSingleEntryAction(Request $request, Blog $blog)
{
$em = $this->getDoctrine()->getRepository('BlogBundle:Blog')->find($blog);
$form = $this->createForm(BlogType::class, $entry);
$form->handleRequest($request);
$em->persist($entry);
$em->flush();
return $this->render('BlogBundle:singleentry:edit.html.twig', array(
'entry' =>$entry,
'form' => $form->createView()
));
}
/**
* #Route("/blog/edit/{id}", name="entryedit", requirements={"id" = "\d+"}, defaults={"id" = 0})
*
*/
public function editAction(Request $request, Blog $blog) {
$em = $this->getDoctrine()->getManager();
$entry = $em->getRepository('BlogBundle:Blog')->find($blog);
if ($this->get('security.authorization_checker')->isGranted('ROLE_ADMIN') || $entry->getAuthor() == $this->getUser()->getUsername() ) {
$form = $this->createForm(BlogType::class, $entry);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($entry);
$em->flush();
return $this->render('BlogBundle:blog:editsubmit.html.twig', array(
'entry' => $entry,
'form' => $form->createView(),
'success' => true
));
}
return $this->render('BlogBundle:blog:edit.html.twig', array(
'form' => $form->createView(),
));
}
else {
echo '<div class="alert alert-danger alert-dismissable">
<span aria-hidden="true" data-dismiss="alert" class="close">×</span>
<h4>
<i class="fa fa-exclamation-circle "></i>
Only the author of an entry is allowed to edit it!</h4></div>';
return $this->listAction();
}
}
/**
* #Route("/blog/delete/{id}", name="entrydelete", requirements={"id" = "\d+"}, defaults={"id" = 0})
*
*/
public function deleteAction(Request $request, Blog $blog) {
$em = $this->getDoctrine()->getManager();
$entry = $em->getRepository('BlogBundle:Blog')->find($blog);
if ($this->get('security.authorization_checker')->isGranted('ROLE_ADMIN') || $entry->getAuthor() == $this->getUser()->getUsername() ) {
$em->remove($entry);
$em->flush();
return $this->render('BlogBundle:blog:deletesubmit.html.twig');
}
else {
return $this->render('BlogBundle:blog:error.html.twig');
}
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => 'BlogBundle\Entity\Blog'
]);
}
}
?>
for my homepage:
<?php
namespace BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class DefaultController extends Controller {
/**
* #Route("/", name="welcome")
*/
public function indexAction() {
$entry = $this->getDoctrine()->getRepository('BlogBundle:Blog')->findBy(array(), array('date' => 'DESC'),5);
dump($entry);
return $this->render('BlogBundle:Default:index.html.twig', [
'Welcome' => 'Welcome!',
'avatar_url' => 'http://www.lufthansa.com/mediapool/jpg/45/media_789050645.jpg',
'blog' => $this->redirectToRoute('singleentry'),
'bloglist' => $entry
]);
}
}
?>
And those are the twig templates I try to render
singleentry.html.twig:
{% extends '::base.html.twig' %}
{% block body %}
<div class="container">
<div class="col-md-11">
<h1 class="page-header">{{ blog. title }}</h1>
<div class="table">
<p><span class="fa fa-clock-o"></span> Posted on {{ blog.date|date('d.M Y H:i A') }} </p>
<p><span class="fa fa-user-circle"></span> Posted by {{ blog.author }} </p>
<p>{{ blog.text }}</p>
<!-- <a class="btn btn-primary" href="#">Read More <span class="glyphicon glyphicon-chevron-right"></span></a> -->
<button type="button" class="btn btn btn-info">
Edit entry
</button>
<button type="button" class="btn btn btn-warning">
Delete entry
</button>
<hr>
</div>
</div>
</div>
{% endblock %}
for the list of blog entries on my homepage:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title text-center">My latest blog entries</h3>
</div>
<table class="table">
{% for blog in bloglist %}
<tr>
<td>{{ blog.title }}</td>
<td width="85%" style="max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;">
{{ blog.text }}
</td>
</tr>
{% endfor %}
</table>
</div>
edited version of listSingleEntryAction --> object shown as NULL
public function listSingleEntryAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entry = $em->getRepository('BlogBundle:Blog')->find($id);
if($entry == null)
{
$message='Entry does not exist';
return $this->render('BlogBundle:blog:error.html.twig');
}
return $this->render('BlogBundle:blog:singleentry.html.twig', Array(
'entry' => $entry,
'success' => true,
));
}
The problem is your arguments.
public function listSingleEntryAction(Request $request, Blog $blog)
{
First of all, it shouldn't be with a Blog type. It's int.
Second, rename it to $id.
And I think you have the same problem with edit and delete actions.
check out your action. First 2 lines are the reason of your problem.
/**
* #Route("/blog/singleentry/{id}", name="singleentry", requirements={"id" = "\d+"}, defaults={"id" = 0})
*/
public function listSingleEntryAction(Request $request, Blog $blog)
{
$em = $this->getDoctrine()->getManager();
$entry = $em->getRepository('BlogBundle:Blog')->find($blog);
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