I'm creating second route for display all articles by category in the URL. There is my route for that:
default_blog_category:
path: /category/{slug}/{page}
defaults: { _controller: AcmeBlogBundle:Default:indexByCategory, page: 1 }
And here is my try, to get items by category, but it does not works (I'll get this error message:
[Semantical Error] line 0, col 47 near 'categories =': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
):
public function indexByCategoryAction($slug, $page)
{
$em = $this->getDoctrine()->getManager();
$dql = "SELECT a FROM AcmeBlogBundle:Article a WHERE a.categories = :category ORDER BY a.published DESC";
$query = $em->createQuery($dql)->setParameter('category', $slug);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$query,
$this->get('request')->query->get('page', $page),
10
);
return $this->render('AcmeBlogBundle:Default:index.html.twig', array('pagination' => $pagination));
}
I'm not sure, how to use WHERE in my query for now, here is also my Article.php entity:
<?php
namespace Acme\BlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Entity(repositoryClass="Acme\BlogBundle\Entity\ArticleRepository")
* @ORM\Table(name="articles")
*/
class Article
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=200)
* @Assert\NotBlank(
* message = "Title cannot be blank"
* )
* @Assert\Length(
* min = "3",
* minMessage = "Title is too short"
* )
*/
private $title;
/**
* @Gedmo\Slug(fields={"title"}, updatable=true, separator="-")
*
* @ORM\Column(name="slug", type="string", length=200, nullable=false, unique=true)
*/
private $slug;
/**
* @ORM\Column(type="datetime")
* @Assert\NotBlank(
* message = "DateTime cannot be blank"
* )
* @Assert\DateTime(
* message = "DateTime is not valid"
* )
*/
protected $published;
/**
* @ORM\ManyToMany(targetEntity="Category", inversedBy="articles")
* @Assert\Count(min = 1, minMessage = "Choose any category")
*/
private $categories;
/**
* @ORM\OneToMany(targetEntity="Comment", mappedBy="article")
* @ORM\OrderBy({"published" = "ASC"})
*/
private $comments;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank(
* message = "Perex cannot be blank"
* )
* @Assert\Length(
* min = "5",
* minMessage = "Perex is too short"
* )
*/
private $perex;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank(
* message = "Content cannot be blank"
* )
* @Assert\Length(
* min = "10",
* minMessage = "Content must have min. 10 characters"
* )
*/
private $content;
/**
* @ORM\Column(type="string", length=200)
*/
private $description;
/**
* @ORM\Column(type="string", length=200)
*/
private $keywords;
/**
* Constructor
*/
public function __construct()
{
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
$this->comments = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* @param string $title
* @return Article
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set slug
*
* @param string $slug
* @return Article
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set content
*
* @param string $content
* @return Article
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* Add categories
*
* @param \Acme\BlogBundle\Entity\Category $categories
* @return Article
*/
public function addCategory(\Acme\BlogBundle\Entity\Category $categories)
{
//$this->categories[] = $categories;
//return $this;
if (!$this->categories->contains($categories)) {
$this->categories->add($categories);
$categories->addArticle($this);
}
}
/**
* Remove categories
*
* @param \Acme\BlogBundle\Entity\Category $categories
*/
public function removeCategory(\Acme\BlogBundle\Entity\Category $categories)
{
$this->categories->removeElement($categories);
}
/**
* Get categories
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCategories()
{
return $this->categories;
}
/**
* Add comments
*
* @param \Acme\BlogBundle\Entity\Comment $comments
* @return Article
*/
public function addComment(\Acme\BlogBundle\Entity\Comment $comments)
{
$this->comments[] = $comments;
return $this;
}
/**
* Remove comments
*
* @param \Acme\BlogBundle\Entity\Comment $comments
*/
public function removeComment(\Acme\BlogBundle\Entity\Comment $comments)
{
$this->comments->removeElement($comments);
}
/**
* Get comments
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getComments()
{
return $this->comments;
}
/**
* Set published
*
* @param \DateTime $published
* @return Article
*/
public function setPublished($published)
{
$this->published = $published;
return $this;
}
/**
* Get published
*
* @return \DateTime
*/
public function getPublished()
{
return $this->published;
}
/**
* Set description
*
* @param string $description
* @return Article
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set keywords
*
* @param string $keywords
* @return Article
*/
public function setKeywords($keywords)
{
$this->keywords = $keywords;
return $this;
}
/**
* Get keywords
*
* @return string
*/
public function getKeywords()
{
return $this->keywords;
}
/**
* Set perex
*
* @param string $perex
* @return Article
*/
public function setPerex($perex)
{
$this->perex = $perex;
return $this;
}
/**
* Get perex
*
* @return string
*/
public function getPerex()
{
return $this->perex;
}
}
Any idea?
You have to join the categories. This code should be placed in the ArticleRepository.
See doctrine query builder and symfony custom repository classes for an tutorial.