Permalink
Browse files

feature #434 Add user relationship to Post and Comment entities (ycer…

…uto)

This PR was merged into the master branch.

Discussion
----------

Add user relationship to Post and Comment entities

Actually, we are related Post/User and Comment/User indirectly throught `authorEmail` field which IMHO makes things more complicated to understand for the beginner, because really we need this relationship.

Related discussion in #429.

Commits
-------

52d2fa3 Add user relationship to Post and Comment entities
  • Loading branch information...
2 parents d579b49 + 52d2fa3 commit e70285155c50dd9ba837106922df18c39769408d @javiereguiluz javiereguiluz committed Jan 19, 2017
@@ -9,7 +9,6 @@
{{ form_row(form.title) }}
{{ form_row(form.summary) }}
{{ form_row(form.content) }}
- {{ form_row(form.authorEmail) }}
{{ form_row(form.publishedAt) }}
<input type="submit" value="{{ 'label.create_post'|trans }}" class="btn btn-primary" />
@@ -17,7 +17,7 @@
</tr>
<tr>
<th scope="row">{{ 'label.author'|trans }}</th>
- <td><p>{{ post.authorEmail }}</p></td>
+ <td><p>{{ post.author.email }}</p></td>
</tr>
<tr>
<th scope="row">{{ 'label.published_at'|trans }}</th>
@@ -15,7 +15,7 @@
<link>{{ url('blog_post', {'slug': post.slug}) }}</link>
<guid>{{ url('blog_post', {'slug': post.slug}) }}</guid>
<pubDate>{{ post.publishedAt|date(format='r', timezone='GMT') }}</pubDate>
- <author>{{ post.authorEmail }}</author>
+ <author>{{ post.author.email }}</author>
</item>
{% endfor %}
</channel>
@@ -32,7 +32,7 @@
<div class="row post-comment">
<a name="comment_{{ comment.id }}"></a>
<h4 class="col-sm-3">
- <strong>{{ comment.authorEmail }}</strong> {{ 'post.commented_on'|trans }}
+ <strong>{{ comment.author.email }}</strong> {{ 'post.commented_on'|trans }}
{# it's not mandatory to set the timezone in localizeddate(). This is done to
avoid errors when the 'intl' PHP extension is not available and the application
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
@@ -50,7 +50,7 @@
{% endblock %}
{% block sidebar %}
- {% if app.user and post.isAuthor(app.user) %}
+ {% if post.isAuthor(app.user) %}
<div class="section">
<a class="btn btn-lg btn-block btn-success" href="{{ path('admin_post_edit', { id: post.id }) }}">
<i class="fa fa-edit" aria-hidden="true"></i> {{ 'action.edit_post'|trans }}
@@ -55,7 +55,7 @@ class BlogController extends Controller
public function indexAction()
{
$entityManager = $this->getDoctrine()->getManager();
- $posts = $entityManager->getRepository(Post::class)->findBy(['authorEmail' => $this->getUser()->getEmail()], ['publishedAt' => 'DESC']);
+ $posts = $entityManager->getRepository(Post::class)->findBy(['author' => $this->getUser()], ['publishedAt' => 'DESC']);
return $this->render('admin/blog/index.html.twig', ['posts' => $posts]);
}
@@ -73,7 +73,7 @@ public function indexAction()
public function newAction(Request $request)
{
$post = new Post();
- $post->setAuthorEmail($this->getUser()->getEmail());
+ $post->setAuthor($this->getUser());
// See http://symfony.com/doc/current/book/forms.html#submitting-forms-with-multiple-buttons
$form = $this->createForm(PostType::class, $post)
@@ -122,7 +122,7 @@ public function showAction(Post $post)
// This security check can also be performed:
// 1. Using an annotation: @Security("post.isAuthor(user)")
// 2. Using a "voter" (see http://symfony.com/doc/current/cookbook/security/voters_data_permission.html)
- if (null === $this->getUser() || !$post->isAuthor($this->getUser())) {
+ if (!$post->isAuthor($this->getUser())) {
throw $this->createAccessDeniedException('Posts can only be shown to their authors.');
}
@@ -139,7 +139,7 @@ public function showAction(Post $post)
*/
public function editAction(Post $post, Request $request)
{
- if (null === $this->getUser() || !$post->isAuthor($this->getUser())) {
+ if (!$post->isAuthor($this->getUser())) {
throw $this->createAccessDeniedException('Posts can only be edited by their authors.');
}
@@ -99,7 +99,7 @@ public function commentNewAction(Request $request, Post $post)
if ($form->isSubmitted() && $form->isValid()) {
/** @var Comment $comment */
$comment = $form->getData();
- $comment->setAuthorEmail($this->getUser()->getEmail());
+ $comment->setAuthor($this->getUser());
$comment->setPost($post);
$entityManager = $this->getDoctrine()->getManager();
@@ -14,7 +14,7 @@
use AppBundle\Entity\Comment;
use AppBundle\Entity\Post;
use AppBundle\Entity\User;
-use Doctrine\Common\DataFixtures\FixtureInterface;
+use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
@@ -32,7 +32,7 @@
* @author Ryan Weaver <weaverryan@gmail.com>
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
*/
-class LoadFixtures implements FixtureInterface, ContainerAwareInterface
+class LoadFixtures extends AbstractFixture implements ContainerAwareInterface
{
use ContainerAwareTrait;
@@ -55,6 +55,7 @@ private function loadUsers(ObjectManager $manager)
$encodedPassword = $passwordEncoder->encodePassword($johnUser, 'kitten');
$johnUser->setPassword($encodedPassword);
$manager->persist($johnUser);
+ $this->addReference('john-user', $johnUser);
$annaAdmin = new User();
$annaAdmin->setUsername('anna_admin');
@@ -63,6 +64,7 @@ private function loadUsers(ObjectManager $manager)
$encodedPassword = $passwordEncoder->encodePassword($annaAdmin, 'kitten');
$annaAdmin->setPassword($encodedPassword);
$manager->persist($annaAdmin);
+ $this->addReference('anna-admin', $annaAdmin);
$manager->flush();
}
@@ -76,13 +78,13 @@ private function loadPosts(ObjectManager $manager)
$post->setSummary($this->getRandomPostSummary());
$post->setSlug($this->container->get('slugger')->slugify($post->getTitle()));
$post->setContent($this->getPostContent());
- $post->setAuthorEmail('anna_admin@symfony.com');
+ $post->setAuthor($this->getReference('anna-admin'));
$post->setPublishedAt(new \DateTime('now - '.$i.'days'));
foreach (range(1, 5) as $j) {
$comment = new Comment();
- $comment->setAuthorEmail('john_user@symfony.com');
+ $comment->setAuthor($this->getReference('john-user'));
$comment->setPublishedAt(new \DateTime('now + '.($i + $j).'seconds'));
$comment->setContent($this->getRandomCommentContent());
$comment->setPost($post);
@@ -61,21 +61,21 @@ class Comment
private $content;
/**
- * @var string
- *
- * @ORM\Column(type="string")
- * @Assert\Email
- */
- private $authorEmail;
-
- /**
* @var \DateTime
*
* @ORM\Column(type="datetime")
* @Assert\DateTime
*/
private $publishedAt;
+ /**
+ * @var User
+ *
+ * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
+ * @ORM\JoinColumn(nullable=false)
+ */
+ private $author;
+
public function __construct()
{
$this->publishedAt = new \DateTime();
@@ -109,27 +109,30 @@ public function setContent($content)
$this->content = $content;
}
- public function getAuthorEmail()
+ public function getPublishedAt()
{
- return $this->authorEmail;
+ return $this->publishedAt;
}
- /**
- * @param string $authorEmail
- */
- public function setAuthorEmail($authorEmail)
+ public function setPublishedAt(\DateTime $publishedAt)
{
- $this->authorEmail = $authorEmail;
+ $this->publishedAt = $publishedAt;
}
- public function getPublishedAt()
+ /**
+ * @return User
+ */
+ public function getAuthor()
{
- return $this->publishedAt;
+ return $this->author;
}
- public function setPublishedAt(\DateTime $publishedAt)
+ /**
+ * @param User $author
+ */
+ public function setAuthor(User $author)
{
- $this->publishedAt = $publishedAt;
+ $this->author = $author;
}
public function getPost()
@@ -72,14 +72,6 @@ class Post
private $content;
/**
- * @var string
- *
- * @ORM\Column(type="string")
- * @Assert\Email
- */
- private $authorEmail;
-
- /**
* @var \DateTime
*
* @ORM\Column(type="datetime")
@@ -88,6 +80,14 @@ class Post
private $publishedAt;
/**
+ * @var User
+ *
+ * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
+ * @ORM\JoinColumn(nullable=false)
+ */
+ private $author;
+
+ /**
* @var Comment[]|ArrayCollection
*
* @ORM\OneToMany(
@@ -149,35 +149,38 @@ public function setContent($content)
$this->content = $content;
}
- public function getAuthorEmail()
+ public function getPublishedAt()
{
- return $this->authorEmail;
+ return $this->publishedAt;
}
- /**
- * @param string $authorEmail
- */
- public function setAuthorEmail($authorEmail)
+ public function setPublishedAt(\DateTime $publishedAt)
{
- $this->authorEmail = $authorEmail;
+ $this->publishedAt = $publishedAt;
}
/**
- * Is the given User the author of this Post?
+ * @return User
*/
- public function isAuthor(User $user)
+ public function getAuthor()
{
- return $user->getEmail() === $this->getAuthorEmail();
+ return $this->author;
}
- public function getPublishedAt()
+ /**
+ * @param User $author
+ */
+ public function setAuthor(User $author)
{
- return $this->publishedAt;
+ $this->author = $author;
}
- public function setPublishedAt(\DateTime $publishedAt)
+ /**
+ * Is the given User the author of this Post?
+ */
+ public function isAuthor(User $user = null)
{
- $this->publishedAt = $publishedAt;
+ return $user === $this->author;
}
public function getComments()
@@ -11,6 +11,7 @@
namespace AppBundle\EventListener;
+use AppBundle\Entity\Comment;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Translation\TranslatorInterface;
@@ -63,6 +64,7 @@ public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $urlGen
*/
public function onCommentCreated(GenericEvent $event)
{
+ /** @var Comment $comment */
$comment = $event->getSubject();
$post = $comment->getPost();
@@ -82,7 +84,7 @@ public function onCommentCreated(GenericEvent $event)
// See http://symfony.com/doc/current/email.html#sending-emails
$message = \Swift_Message::newInstance()
->setSubject($subject)
- ->setTo($post->getAuthorEmail())
+ ->setTo($post->getAuthor()->getEmail())
->setFrom($this->sender)
->setBody($body, 'text/html')
;
@@ -52,9 +52,6 @@ public function buildForm(FormBuilderInterface $builder, array $options)
'attr' => ['rows' => 20],
'label' => 'label.content',
])
- ->add('authorEmail', null, [
- 'label' => 'label.author_email',
- ])
->add('publishedAt', DateTimePickerType::class, [
'label' => 'label.published_at',
])
@@ -70,4 +70,26 @@ public function testIndex()
'The backend homepage displays all the available posts.'
);
}
+
+ /**
+ * @dataProvider getPostUrls
+ */
+ public function testOnlyAuthorCanAccessToThePostInTheBackend($method, $url, $statusCode)
+ {
+ $client = static::createClient([], [
+ 'PHP_AUTH_USER' => 'anna_admin',
+ 'PHP_AUTH_PW' => 'kitten',
+ ]);
+
+ $client->request($method, $url);
+
+ $this->assertEquals($statusCode, $client->getResponse()->getStatusCode());
+ }
+
+ public function getPostUrls()
+ {
+ yield ['GET', '/en/admin/post/1', Response::HTTP_OK];
+ yield ['GET', '/en/admin/post/1/edit', Response::HTTP_OK];
+ yield ['POST', '/en/admin/post/1/delete', Response::HTTP_FOUND];
+ }
}
View
Binary file not shown.

0 comments on commit e702851

Please sign in to comment.