A Symfony 5 Cheatsheet
An incomplete Symfony 5 Snippet-Collection
21. Jul. 2020
Here are some snippets of code that I regularly need in some way when I'm dealing with Symfony. Since I'm super forgetful this post hopefully helps me not having to Search all possible projects and files when I want to implement something :)
This code snippets are based on Symfony 5
Controller
Routes
Named route returning (or rendering) a twig template:
/**
* @Route("/project", name="index")
*/
public function index()
{
return $this->render('project/index.html.twig', [
'controller_name' => 'ProjectController',
]);
}
An API-route returning JSON. The route is restricted to POST requests:
/**
* @Route("/project/toggle", name="project_toggle", methods={"POST"})
*/
public function index()
{
return $this->json(['value' => rand(0, 10)]);
// or:
// return new JsonResponse(['value' => rand(0, 10)]);
}
Route with parameters having requirements
/**
* @Route("/project/{id}", requirements={"id"="\d+"}, name="project_show")
*/
public function show($id)
{
return new Response("Test $id");
}
It's also possible to write the requirements directly after the parameter in the
route string enclosed in < >
/**
* @Route("/project/{id<\d+>}", name="project_show")
*/
Parameter-Converter
The parameter converter automatically fetches entity objects rom the database
from route parameters.
In this example a BlogPost object is automatically created if the Parameter slug
can be associated with a post:
/**
* @Route("/blog/{slug}", name="blog_show")
*/
public function show(BlogPost $post)
{
// $post is the object whose slug matches the routing parameter
// ...
}
It is sufficient to specify a type hint for the parameter. If a post cannot be found, a 404 page is generated automatically.
Here is an example if you have several parameters that are to be converted. The comment entity has to be specially 'mentioned' since we're in the blog controller:
/**
* @Route("/blog/{id}/comments/{comment_id}")
* @Entity("comment", expr="repository.find(comment_id)")
*/
public function show(Post $post, Comment $comment)
{
// ...
}
More info on the parameter converter can be found here.
Redirects
// ...
public function index()
{
// redirects to the "homepage" route
return $this->redirectToRoute('homepage');
// redirectToRoute is a shortcut for:
// return new RedirectResponse($this->generateUrl('homepage'));
// does a permanent - 301 redirect
return $this->redirectToRoute('homepage', [], 301);
// redirect to a route with parameters
return $this->redirectToRoute('app_lucky_number', ['max' => 10]);
// redirects to a route and maintains the original query string parameters
return $this->redirectToRoute('blog_show', $request->query->all());
// redirects externally
return $this->redirect('http://symfony.com/doc');
}
Flash messages
Official documentation regarding flash messages
Flash messages are used to display messages to users once.
Create messages
use Symfony\Component\HttpFoundation\Request;
public function update(Request $request)
{
$this->addFlash('notice', 'Your changes were saved!');
// $this->addFlash() is equivalent to $request->getSession()->getFlashBag()->add()
}
Show messages
{# read and display just one flash message type #}
{% for message in app.flashes('notice') %}
<div class="flash-notice">
{{ message }}
</div>
{% endfor %}
{# read and display several types of flash messages #}
{% for label, messages in app.flashes(['success', 'warning']) %}
{% for message in messages %}
<div class="flash-{{ label }}">
{{ message }}
</div>
{% endfor %}
{% endfor %}
{# read and display all flash messages #}
{% for label, messages in app.flashes %}
{% for message in messages %}
<div class="flash-{{ label }}">
{{ message }}
</div>
{% endfor %}
{% endfor %}
Assets
Referencing files from the public
folder
The following snippet references <symfony_root>/public/css/app.css
.
<link rel="stylesheet" type="text/css" href="{{ asset('css/app.css') }}">
Reference files created with webpack-encore
Official webpack-encore documentation
The webpack.config.js
should contain lines like this:
.addEntry('app', './assets/js/app.js')
.addEntry('plot', './assets/js/plot.js')
.addEntry('scene', './assets/js/scene.js')
The assets can be included in your Twig template using the following code:
{{ encore_entry_script_tags('app') }} {# Creates script tags #}
{{ encore_entry_link_tags('app') }} {# Creates CSS (link) tags #}
URLs
<a href="{{ path('index') }}">Index</a>
<a href="{{ path('project_show', {id: 2}) }}">Show project</a>
Twig
Extend blocks from the father element:
{% block javascripts %}
{{ parent() }}
<script>
...
</sctipt>
{% endblock %}
Database and Doctrine
Fetch objects
$repository = $this->getDoctrine()->getRepository(Product::class);
// look for a single Product by its primary key (usually "id")
$product = $repository->find($id);
// look for a single Product by name
$product = $repository->findOneBy(['name' => 'Keyboard']);
// or find by name and price
$product = $repository->findOneBy([
'name' => 'Keyboard',
'price' => 1999,
]);
// look for multiple Product objects matching the name, ordered by price
$products = $repository->findBy(
['name' => 'Keyboard'],
['price' => 'ASC']
);
// look for *all* Product objects
$products = $repository->findAll();
Store objects
/**
* @Route("/project/store", name="project_store", methods={"POST"})
*/
public function store()
{
$project = new Project();
$project->setName('test');
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($project);
$entityManager->flush();
return $this->render('project/index.html.twig', [
'controller_name' => 'ProjectController',
]);
}
Change objects
/**
* @Route("/product/edit/{id}")
*/
public function update($id)
{
$product = $entityManager->getRepository(Product::class)->find($id);
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$id
);
}
$entityManager = $this->getDoctrine()->getManager();
$product->setName('New product name!');
$entityManager->flush();
return $this->redirectToRoute('product_show', [
'id' => $product->getId()
]);
}
Delete objects
$entityManager->remove($product);
$entityManager->flush();