Skip to content

Commit 52d2fa3

Browse files
committed
Add user relationship to Post and Comment entities
1 parent d579b49 commit 52d2fa3

File tree

13 files changed

+87
-59
lines changed

13 files changed

+87
-59
lines changed

app/Resources/views/admin/blog/new.html.twig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
{{ form_row(form.title) }}
1010
{{ form_row(form.summary) }}
1111
{{ form_row(form.content) }}
12-
{{ form_row(form.authorEmail) }}
1312
{{ form_row(form.publishedAt) }}
1413

1514
<input type="submit" value="{{ 'label.create_post'|trans }}" class="btn btn-primary" />

app/Resources/views/admin/blog/show.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</tr>
1818
<tr>
1919
<th scope="row">{{ 'label.author'|trans }}</th>
20-
<td><p>{{ post.authorEmail }}</p></td>
20+
<td><p>{{ post.author.email }}</p></td>
2121
</tr>
2222
<tr>
2323
<th scope="row">{{ 'label.published_at'|trans }}</th>

app/Resources/views/blog/index.xml.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<link>{{ url('blog_post', {'slug': post.slug}) }}</link>
1616
<guid>{{ url('blog_post', {'slug': post.slug}) }}</guid>
1717
<pubDate>{{ post.publishedAt|date(format='r', timezone='GMT') }}</pubDate>
18-
<author>{{ post.authorEmail }}</author>
18+
<author>{{ post.author.email }}</author>
1919
</item>
2020
{% endfor %}
2121
</channel>

app/Resources/views/blog/post_show.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<div class="row post-comment">
3333
<a name="comment_{{ comment.id }}"></a>
3434
<h4 class="col-sm-3">
35-
<strong>{{ comment.authorEmail }}</strong> {{ 'post.commented_on'|trans }}
35+
<strong>{{ comment.author.email }}</strong> {{ 'post.commented_on'|trans }}
3636
{# it's not mandatory to set the timezone in localizeddate(). This is done to
3737
avoid errors when the 'intl' PHP extension is not available and the application
3838
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
@@ -50,7 +50,7 @@
5050
{% endblock %}
5151

5252
{% block sidebar %}
53-
{% if app.user and post.isAuthor(app.user) %}
53+
{% if post.isAuthor(app.user) %}
5454
<div class="section">
5555
<a class="btn btn-lg btn-block btn-success" href="{{ path('admin_post_edit', { id: post.id }) }}">
5656
<i class="fa fa-edit" aria-hidden="true"></i> {{ 'action.edit_post'|trans }}

src/AppBundle/Controller/Admin/BlogController.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class BlogController extends Controller
5555
public function indexAction()
5656
{
5757
$entityManager = $this->getDoctrine()->getManager();
58-
$posts = $entityManager->getRepository(Post::class)->findBy(['authorEmail' => $this->getUser()->getEmail()], ['publishedAt' => 'DESC']);
58+
$posts = $entityManager->getRepository(Post::class)->findBy(['author' => $this->getUser()], ['publishedAt' => 'DESC']);
5959

6060
return $this->render('admin/blog/index.html.twig', ['posts' => $posts]);
6161
}
@@ -73,7 +73,7 @@ public function indexAction()
7373
public function newAction(Request $request)
7474
{
7575
$post = new Post();
76-
$post->setAuthorEmail($this->getUser()->getEmail());
76+
$post->setAuthor($this->getUser());
7777

7878
// See http://symfony.com/doc/current/book/forms.html#submitting-forms-with-multiple-buttons
7979
$form = $this->createForm(PostType::class, $post)
@@ -122,7 +122,7 @@ public function showAction(Post $post)
122122
// This security check can also be performed:
123123
// 1. Using an annotation: @Security("post.isAuthor(user)")
124124
// 2. Using a "voter" (see http://symfony.com/doc/current/cookbook/security/voters_data_permission.html)
125-
if (null === $this->getUser() || !$post->isAuthor($this->getUser())) {
125+
if (!$post->isAuthor($this->getUser())) {
126126
throw $this->createAccessDeniedException('Posts can only be shown to their authors.');
127127
}
128128

@@ -139,7 +139,7 @@ public function showAction(Post $post)
139139
*/
140140
public function editAction(Post $post, Request $request)
141141
{
142-
if (null === $this->getUser() || !$post->isAuthor($this->getUser())) {
142+
if (!$post->isAuthor($this->getUser())) {
143143
throw $this->createAccessDeniedException('Posts can only be edited by their authors.');
144144
}
145145

src/AppBundle/Controller/BlogController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public function commentNewAction(Request $request, Post $post)
9999
if ($form->isSubmitted() && $form->isValid()) {
100100
/** @var Comment $comment */
101101
$comment = $form->getData();
102-
$comment->setAuthorEmail($this->getUser()->getEmail());
102+
$comment->setAuthor($this->getUser());
103103
$comment->setPost($post);
104104

105105
$entityManager = $this->getDoctrine()->getManager();

src/AppBundle/DataFixtures/ORM/LoadFixtures.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use AppBundle\Entity\Comment;
1515
use AppBundle\Entity\Post;
1616
use AppBundle\Entity\User;
17-
use Doctrine\Common\DataFixtures\FixtureInterface;
17+
use Doctrine\Common\DataFixtures\AbstractFixture;
1818
use Doctrine\Common\Persistence\ObjectManager;
1919
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
2020
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
@@ -32,7 +32,7 @@
3232
* @author Ryan Weaver <[email protected]>
3333
* @author Javier Eguiluz <[email protected]>
3434
*/
35-
class LoadFixtures implements FixtureInterface, ContainerAwareInterface
35+
class LoadFixtures extends AbstractFixture implements ContainerAwareInterface
3636
{
3737
use ContainerAwareTrait;
3838

@@ -55,6 +55,7 @@ private function loadUsers(ObjectManager $manager)
5555
$encodedPassword = $passwordEncoder->encodePassword($johnUser, 'kitten');
5656
$johnUser->setPassword($encodedPassword);
5757
$manager->persist($johnUser);
58+
$this->addReference('john-user', $johnUser);
5859

5960
$annaAdmin = new User();
6061
$annaAdmin->setUsername('anna_admin');
@@ -63,6 +64,7 @@ private function loadUsers(ObjectManager $manager)
6364
$encodedPassword = $passwordEncoder->encodePassword($annaAdmin, 'kitten');
6465
$annaAdmin->setPassword($encodedPassword);
6566
$manager->persist($annaAdmin);
67+
$this->addReference('anna-admin', $annaAdmin);
6668

6769
$manager->flush();
6870
}
@@ -76,13 +78,13 @@ private function loadPosts(ObjectManager $manager)
7678
$post->setSummary($this->getRandomPostSummary());
7779
$post->setSlug($this->container->get('slugger')->slugify($post->getTitle()));
7880
$post->setContent($this->getPostContent());
79-
$post->setAuthorEmail('[email protected]');
81+
$post->setAuthor($this->getReference('anna-admin'));
8082
$post->setPublishedAt(new \DateTime('now - '.$i.'days'));
8183

8284
foreach (range(1, 5) as $j) {
8385
$comment = new Comment();
8486

85-
$comment->setAuthorEmail('[email protected]');
87+
$comment->setAuthor($this->getReference('john-user'));
8688
$comment->setPublishedAt(new \DateTime('now + '.($i + $j).'seconds'));
8789
$comment->setContent($this->getRandomCommentContent());
8890
$comment->setPost($post);

src/AppBundle/Entity/Comment.php

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,6 @@ class Comment
6060
*/
6161
private $content;
6262

63-
/**
64-
* @var string
65-
*
66-
* @ORM\Column(type="string")
67-
* @Assert\Email
68-
*/
69-
private $authorEmail;
70-
7163
/**
7264
* @var \DateTime
7365
*
@@ -76,6 +68,14 @@ class Comment
7668
*/
7769
private $publishedAt;
7870

71+
/**
72+
* @var User
73+
*
74+
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
75+
* @ORM\JoinColumn(nullable=false)
76+
*/
77+
private $author;
78+
7979
public function __construct()
8080
{
8181
$this->publishedAt = new \DateTime();
@@ -109,27 +109,30 @@ public function setContent($content)
109109
$this->content = $content;
110110
}
111111

112-
public function getAuthorEmail()
112+
public function getPublishedAt()
113113
{
114-
return $this->authorEmail;
114+
return $this->publishedAt;
115115
}
116116

117-
/**
118-
* @param string $authorEmail
119-
*/
120-
public function setAuthorEmail($authorEmail)
117+
public function setPublishedAt(\DateTime $publishedAt)
121118
{
122-
$this->authorEmail = $authorEmail;
119+
$this->publishedAt = $publishedAt;
123120
}
124121

125-
public function getPublishedAt()
122+
/**
123+
* @return User
124+
*/
125+
public function getAuthor()
126126
{
127-
return $this->publishedAt;
127+
return $this->author;
128128
}
129129

130-
public function setPublishedAt(\DateTime $publishedAt)
130+
/**
131+
* @param User $author
132+
*/
133+
public function setAuthor(User $author)
131134
{
132-
$this->publishedAt = $publishedAt;
135+
$this->author = $author;
133136
}
134137

135138
public function getPost()

src/AppBundle/Entity/Post.php

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,6 @@ class Post
7171
*/
7272
private $content;
7373

74-
/**
75-
* @var string
76-
*
77-
* @ORM\Column(type="string")
78-
* @Assert\Email
79-
*/
80-
private $authorEmail;
81-
8274
/**
8375
* @var \DateTime
8476
*
@@ -87,6 +79,14 @@ class Post
8779
*/
8880
private $publishedAt;
8981

82+
/**
83+
* @var User
84+
*
85+
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
86+
* @ORM\JoinColumn(nullable=false)
87+
*/
88+
private $author;
89+
9090
/**
9191
* @var Comment[]|ArrayCollection
9292
*
@@ -149,35 +149,38 @@ public function setContent($content)
149149
$this->content = $content;
150150
}
151151

152-
public function getAuthorEmail()
152+
public function getPublishedAt()
153153
{
154-
return $this->authorEmail;
154+
return $this->publishedAt;
155155
}
156156

157-
/**
158-
* @param string $authorEmail
159-
*/
160-
public function setAuthorEmail($authorEmail)
157+
public function setPublishedAt(\DateTime $publishedAt)
161158
{
162-
$this->authorEmail = $authorEmail;
159+
$this->publishedAt = $publishedAt;
163160
}
164161

165162
/**
166-
* Is the given User the author of this Post?
163+
* @return User
167164
*/
168-
public function isAuthor(User $user)
165+
public function getAuthor()
169166
{
170-
return $user->getEmail() === $this->getAuthorEmail();
167+
return $this->author;
171168
}
172169

173-
public function getPublishedAt()
170+
/**
171+
* @param User $author
172+
*/
173+
public function setAuthor(User $author)
174174
{
175-
return $this->publishedAt;
175+
$this->author = $author;
176176
}
177177

178-
public function setPublishedAt(\DateTime $publishedAt)
178+
/**
179+
* Is the given User the author of this Post?
180+
*/
181+
public function isAuthor(User $user = null)
179182
{
180-
$this->publishedAt = $publishedAt;
183+
return $user === $this->author;
181184
}
182185

183186
public function getComments()

src/AppBundle/EventListener/CommentNotificationListener.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace AppBundle\EventListener;
1313

14+
use AppBundle\Entity\Comment;
1415
use Symfony\Component\EventDispatcher\GenericEvent;
1516
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
1617
use Symfony\Component\Translation\TranslatorInterface;
@@ -63,6 +64,7 @@ public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $urlGen
6364
*/
6465
public function onCommentCreated(GenericEvent $event)
6566
{
67+
/** @var Comment $comment */
6668
$comment = $event->getSubject();
6769
$post = $comment->getPost();
6870

@@ -82,7 +84,7 @@ public function onCommentCreated(GenericEvent $event)
8284
// See http://symfony.com/doc/current/email.html#sending-emails
8385
$message = \Swift_Message::newInstance()
8486
->setSubject($subject)
85-
->setTo($post->getAuthorEmail())
87+
->setTo($post->getAuthor()->getEmail())
8688
->setFrom($this->sender)
8789
->setBody($body, 'text/html')
8890
;

src/AppBundle/Form/PostType.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ public function buildForm(FormBuilderInterface $builder, array $options)
5252
'attr' => ['rows' => 20],
5353
'label' => 'label.content',
5454
])
55-
->add('authorEmail', null, [
56-
'label' => 'label.author_email',
57-
])
5855
->add('publishedAt', DateTimePickerType::class, [
5956
'label' => 'label.published_at',
6057
])

tests/AppBundle/Controller/Admin/BlogControllerTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,26 @@ public function testIndex()
7070
'The backend homepage displays all the available posts.'
7171
);
7272
}
73+
74+
/**
75+
* @dataProvider getPostUrls
76+
*/
77+
public function testOnlyAuthorCanAccessToThePostInTheBackend($method, $url, $statusCode)
78+
{
79+
$client = static::createClient([], [
80+
'PHP_AUTH_USER' => 'anna_admin',
81+
'PHP_AUTH_PW' => 'kitten',
82+
]);
83+
84+
$client->request($method, $url);
85+
86+
$this->assertEquals($statusCode, $client->getResponse()->getStatusCode());
87+
}
88+
89+
public function getPostUrls()
90+
{
91+
yield ['GET', '/en/admin/post/1', Response::HTTP_OK];
92+
yield ['GET', '/en/admin/post/1/edit', Response::HTTP_OK];
93+
yield ['POST', '/en/admin/post/1/delete', Response::HTTP_FOUND];
94+
}
7395
}

var/data/blog.sqlite

1 KB
Binary file not shown.

0 commit comments

Comments
 (0)