Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/Resources/views/blog/index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
{{ post.title }}
</a>
</h2>
{% if 0 < post.tags | length %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about updating the repository to load with tags? To avoid lazy loading
And btw, inform what is lazy loading :)

<p>
{% for tag in post.tags %}
<span class="label label-default">{{ tag.name }}</span>
{% endfor %}
</p>
{% endif %}

{{ post.summary|md2html }}
</article>
Expand Down
8 changes: 8 additions & 0 deletions app/Resources/views/blog/post_show.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
{% block main %}
<h1>{{ post.title }}</h1>

{% if 0 < post.tags | length %}
<p> Tags:
{% for tag in post.tags %}
<span class="label label-default">{{ tag.name }}</span>
{% endfor %}
</p>
{% endif %}

{{ post.content|md2html }}

<div id="post-add-comment" class="well">
Expand Down
101 changes: 100 additions & 1 deletion src/AppBundle/DataFixtures/ORM/LoadFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

namespace AppBundle\DataFixtures\ORM;

use AppBundle\Entity\Tag;
use AppBundle\Entity\User;
use AppBundle\Entity\Post;
use AppBundle\Entity\Comment;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
Expand All @@ -29,6 +31,7 @@
*
* @author Ryan Weaver <[email protected]>
* @author Javier Eguiluz <[email protected]>
* @author Rasanga Perera <[email protected]>
*/
class LoadFixtures implements FixtureInterface, ContainerAwareInterface
{
Expand All @@ -41,7 +44,11 @@ class LoadFixtures implements FixtureInterface, ContainerAwareInterface
public function load(ObjectManager $manager)
{
$this->loadUsers($manager);
$this->loadPosts($manager);
$this->loadPostsTags(
$manager,
$this->loadPosts($manager),
$this->loadTags($manager)
);
}

private function loadUsers(ObjectManager $manager)
Expand All @@ -66,8 +73,15 @@ private function loadUsers(ObjectManager $manager)
$manager->flush();
}

/**
* @param ObjectManager $manager
*
* @return array
*/
private function loadPosts(ObjectManager $manager)
{
$posts = array();

foreach (range(1, 30) as $i) {
$post = new Post();

Expand All @@ -91,9 +105,94 @@ private function loadPosts(ObjectManager $manager)
}

$manager->persist($post);

$posts[] = $post;
}

$manager->flush();

return $posts;
}

/**
* @param ObjectManager $manager
*
* @return array
*/
private function loadTags(ObjectManager $manager)
{
$tags = array();
$tagNames = array(
'Lorem',
'ipsum',
'consectetur',
'adipiscing',
'incididunt',
'labore',
'voluptate'
);

foreach ($tagNames as $key => $name) {
$tag = new Tag();
$tag->setName($name);

$manager->persist($tag);

$tags[] = $tag;
}

$manager->flush();

return $tags;
}

/**
* @param ObjectManager $manager
* @param array|Post[] $posts
* @param array|Tag[] $tags
*/
private function loadPostsTags(
ObjectManager $manager,
array $posts,
array $tags
) {
$posts[0]->addTag($tags[0]);
$posts[0]->addTag($tags[2]);
$manager->persist($posts[0]);

$posts[1]->addTag($tags[1]);
$manager->persist($posts[1]);

$posts[2]->addTag($tags[2]);
$posts[2]->addTag($tags[3]);
$posts[2]->addTag($tags[4]);
$manager->persist($posts[2]);

$posts[3]->addTag($tags[5]);
$posts[3]->addTag($tags[6]);
$manager->persist($posts[3]);

$posts[4]->addTag($tags[0]);
$manager->persist($posts[4]);

$posts[5]->addTag($tags[0]);
$manager->persist($posts[5]);

$posts[6]->addTag($tags[2]);
$manager->persist($posts[6]);

$posts[7]->addTag($tags[4]);
$posts[7]->addTag($tags[6]);
$manager->persist($posts[7]);

$posts[8]->addTag($tags[0]);
$manager->persist($posts[8]);

$posts[9]->addTag($tags[3]);
$posts[9]->addTag($tags[5]);
$manager->persist($posts[9]);

$manager->flush();
}

/**
Expand Down
65 changes: 65 additions & 0 deletions src/AppBundle/Entity/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace AppBundle\Entity;

use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
Expand All @@ -18,6 +19,7 @@
*
* @author Ryan Weaver <[email protected]>
* @author Javier Eguiluz <[email protected]>
* @author Rasanga Perera <[email protected]>
*/
class Post
{
Expand Down Expand Up @@ -81,10 +83,21 @@ class Post
*/
private $comments;

/**
* @var Collection|Tag[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't use the Collection type here. Client code shouldn't need to care about the actual type (it's sufficient to know that there are traversable tags).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xabbuh, but collections support many useful methods: each, map, filter and partition

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but you then tie code using the entities to your internal implementation and I don't think we should encourage that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell the default is ArrayCollection. You should either consider it as a bad practice and do it with just array or what you consider better; or use the default and show how to do it right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, what's the verdict?

I suggest that we should keep the Collection type hint as examples given by @voronkovich

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rasanga yes, let's keep them as is

*
* @ORM\ManyToMany(
* targetEntity="Tag"
* )
* @ORM\JoinTable(name="posts_tags")
*/
private $tags;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to initialize the collection in the constructor


public function __construct()
{
$this->publishedAt = new \DateTime();
$this->comments = new ArrayCollection();
$this->tags = new ArrayCollection();
}

public function getId()
Expand Down Expand Up @@ -179,4 +192,56 @@ public function setSummary($summary)
{
$this->summary = $summary;
}

/**
* Get tags
*
* @return Tag[]|Collection
*/
public function getTags()
{
return $this->tags;
}

/**
* Add tag
*
* @param Tag $tag
*
* @return Post
*/
public function addTag(Tag $tag)
{
if (!$this->hasTag($tag)) {
$this->tags->add($tag);
}

return $this;
}

/**
* Remove tag
*
* @param Tag $tag
*
* @return Post
*/
public function removeTag(Tag $tag)
{
if (!$this->hasTag($tag)) {
$this->tags->removeElement($tag);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it correct condition?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@versh23, no. It should be just $this->tags->removeElement($tag);, without any checkings because the removeElement function doesn't throw an exception when the element doesn't exist.

}

return $this;
}

/**
* @param Tag $tag
*
* @return bool
*/
public function hasTag(Tag $tag)
{
return $this->tags->contains($tag);
}
}
70 changes: 70 additions & 0 deletions src/AppBundle/Entity/Tag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
* Tag
*
* @ORM\Entity(repositoryClass="AppBundle\Repository\TagRepository")
*
* Defines the properties of the Tag entity to represent the blog post tag.
* See http://symfony.com/doc/current/book/doctrine.html#creating-an-entity-class
*
* @author Rasanga Perera <[email protected]>
*/
class Tag
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @var string
*
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank()
*/
private $name;

/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Set name
*
* @param string $name
*
* @return Tag
*/
public function setName($name)
{
$this->name = $name;

return $this;
}

/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
}