-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
BlogController.php
181 lines (155 loc) · 6.57 KB
/
BlogController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Controller\Admin;
use App\Entity\Post;
use App\Form\PostType;
use App\Repository\PostRepository;
use App\Security\PostVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
/**
* Controller used to manage blog contents in the backend.
*
* Please note that the application backend is developed manually for learning
* purposes. However, in your real Symfony application you should use any of the
* existing bundles that let you generate ready-to-use backends without effort.
*
* See http://knpbundles.com/keyword/admin
*
* @Route("/admin/post")
* @IsGranted("ROLE_ADMIN")
*
* @author Ryan Weaver <weaverryan@gmail.com>
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
*/
class BlogController extends AbstractController
{
/**
* Lists all Post entities.
*
* This controller responds to two different routes with the same URL:
* * 'admin_post_index' is the route with a name that follows the same
* structure as the rest of the controllers of this class.
* * 'admin_index' is a nice shortcut to the backend homepage. This allows
* to create simpler links in the templates. Moreover, in the future we
* could move this annotation to any other controller while maintaining
* the route name and therefore, without breaking any existing link.
*
* @Route("/", methods={"GET"}, name="admin_index")
* @Route("/", methods={"GET"}, name="admin_post_index")
*/
public function index(PostRepository $posts): Response
{
$authorPosts = $posts->findBy(['author' => $this->getUser()], ['publishedAt' => 'DESC']);
return $this->render('admin/blog/index.html.twig', ['posts' => $authorPosts]);
}
/**
* Creates a new Post entity.
*
* @Route("/new", methods={"GET", "POST"}, name="admin_post_new")
*
* NOTE: the Method annotation is optional, but it's a recommended practice
* to constraint the HTTP methods each controller responds to (by default
* it responds to all methods).
*/
public function new(Request $request, SluggerInterface $slugger): Response
{
$post = new Post();
$post->setAuthor($this->getUser());
// See https://symfony.com/doc/current/form/multiple_buttons.html
$form = $this->createForm(PostType::class, $post)
->add('saveAndCreateNew', SubmitType::class);
$form->handleRequest($request);
// the isSubmitted() method is completely optional because the other
// isValid() method already checks whether the form is submitted.
// However, we explicitly add it to improve code readability.
// See https://symfony.com/doc/current/forms.html#processing-forms
if ($form->isSubmitted() && $form->isValid()) {
$post->setSlug($slugger->slug($post->getTitle())->lower());
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$em->flush();
// Flash messages are used to notify the user about the result of the
// actions. They are deleted automatically from the session as soon
// as they are accessed.
// See https://symfony.com/doc/current/controller.html#flash-messages
$this->addFlash('success', 'post.created_successfully');
if ($form->get('saveAndCreateNew')->isClicked()) {
return $this->redirectToRoute('admin_post_new');
}
return $this->redirectToRoute('admin_post_index');
}
return $this->render('admin/blog/new.html.twig', [
'post' => $post,
'form' => $form->createView(),
]);
}
/**
* Finds and displays a Post entity.
*
* @Route("/{id<\d+>}", methods={"GET"}, name="admin_post_show")
*/
public function show(Post $post): Response
{
// This security check can also be performed
// using an annotation: @IsGranted("show", subject="post", message="Posts can only be shown to their authors.")
$this->denyAccessUnlessGranted(PostVoter::SHOW, $post, 'Posts can only be shown to their authors.');
return $this->render('admin/blog/show.html.twig', [
'post' => $post,
]);
}
/**
* Displays a form to edit an existing Post entity.
*
* @Route("/{id<\d+>}/edit",methods={"GET", "POST"}, name="admin_post_edit")
* @IsGranted("edit", subject="post", message="Posts can only be edited by their authors.")
*/
public function edit(Request $request, Post $post, SluggerInterface $slugger): Response
{
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$post->setSlug($slugger->slug($post->getTitle())->lower());
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', 'post.updated_successfully');
return $this->redirectToRoute('admin_post_edit', ['id' => $post->getId()]);
}
return $this->render('admin/blog/edit.html.twig', [
'post' => $post,
'form' => $form->createView(),
]);
}
/**
* Deletes a Post entity.
*
* @Route("/{id}/delete", methods={"POST"}, name="admin_post_delete")
* @IsGranted("delete", subject="post")
*/
public function delete(Request $request, Post $post): Response
{
if (!$this->isCsrfTokenValid('delete', $request->request->get('token'))) {
return $this->redirectToRoute('admin_post_index');
}
// Delete the tags associated with this blog post. This is done automatically
// by Doctrine, except for SQLite (the database used in this application)
// because foreign key support is not enabled by default in SQLite
$post->getTags()->clear();
$em = $this->getDoctrine()->getManager();
$em->remove($post);
$em->flush();
$this->addFlash('success', 'post.deleted_successfully');
return $this->redirectToRoute('admin_post_index');
}
}