I am trying to query a dynamic category sidebar and I am using the Sonata ClassificationBundle. I Have created a few categories(parent) and some subcategories(child). I am able to show the categories, however I cant understand how to query the subcategories under a specific category. I think i need to check if the category has children and display it? I have no idea how to do that without proper documentation..
This is the sidebar controller:
<?php
namespace Mp\ShopBundle\Controller;
use Sonata\ClassificationBundle\Entity\Category;
use Sonata\ClassificationBundle\Model\CategoryInterface;
use Sonata\Component\Currency\CurrencyDetector;
use Sonata\Component\Product\Pool;
use Sonata\ProductBundle\Entity\ProductSetManager;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SidebarController extends Controller
{
/**
* @ Route("/hello/{name}")
* @ Template()
*/
public function sidebarAction()
{
$page = $this->getRequest()->get('page', 1);
$displayMax = $this->getRequest()->get('max', 9);
$displayMode = $this->getRequest()->get('mode', 'grid');
$filter = $this->getRequest()->get('filter');
$option = $this->getRequest()->get('option');
if (!in_array($displayMode, array('grid'))) { // "list" mode will be added later
throw new NotFoundHttpException(sprintf('Given display_mode "%s" doesn\'t exist.', $displayMode));
}
$category = $this->retrieveCategoryFromQueryString();
return $this->render('sidebar.html.twig', array(
'display_mode' => $displayMode,
'category' => $this->getCategoryManager()->findBy(
array('parent' => 1 )),
'subcategory' => $this->getCategoryManager()->findBy(
array('children' => true )), ////// ERROR You cannot search for the association field 'Application\Sonata\ClassificationBundle\Entity\Category#children', because it is the inverse side of an association. Find methods only work on owning side associations."
'provider' => $this->getProviderFromCategory($category),
));
}
/* $em = $this->getDoctrine()->getManager();
$products = $em->getRepository('MpShopBundle:Product')->findAll();
return $this->render('sidebar.html.twig', array(
'products'=>$products
)); */
/**
* Retrieve Category from its id and slug, if any.
*
* @return CategoryInterface|null
*/
protected function retrieveCategoryFromQueryString()
{
$categoryId = $this->getRequest()->get('category_id');
$categorySlug = $this->getRequest()->get('category_slug');
if (!$categoryId || !$categorySlug ) {
return null;
}
return $this->getCategoryManager()->findOneBy(array(
'id' => $categoryId,
'enabled' => true,
));
}
This is how I try to display the sidebar:
{% for categories in category %}
{% for subcategories in subcategory %}
<li class="subMenu"><a> {{ categories.name }} [{{ categories|length }}]</a>
<ul>
<li><a href="{{ path('products') }}">{{ subcategories.name }} ({{ categories|length }})</a></li>
</ul>
</li>
{% endfor %}
{% endfor %}
The Category entity:
<?php
/*
* This file is part of the Sonata project.
*
* (c) Sonata Project <https://github.com/sonata-project/SonataClassificationBundle/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sonata\ClassificationBundle\Model;
use Sonata\MediaBundle\Model\MediaInterface;
interface CategoryInterface
{
/**
* @param $name
*
* @return mixed
*/
public function setName($name);
/**
* Get name
*
* @return string $name
*/
public function getName();
/**
* Set enabled
*
* @param boolean $enabled
*/
public function setEnabled($enabled);
/**
* Get enabled
*
* @return boolean $enabled
*/
public function getEnabled();
/**
* Set slug
*
* @param integer $slug
*/
public function setSlug($slug);
/**
* Get slug
*
* @return integer $slug
*/
public function getSlug();
/**
* Set description
*
* @param string $description
*/
public function setDescription($description);
/**
* Get description
*
* @return string $description
*/
public function getDescription();
/**
* @param integer $position
*/
public function setPosition($position);
/**
* @return integer
*/
public function getPosition();
/**
* Add Children
*
* @param CategoryInterface $children
* @param boolean $nested
*/
public function addChild(CategoryInterface $children, $nested = false);
/**
* Get Children
*
* @return \Doctrine\Common\Collections\Collection $children
*/
public function getChildren();
/**
* Set children
*
* @param $children
*/
public function setChildren($children);
/**
* Return true if category has children
*
* @return boolean
*/
public function hasChildren();
/**
* Set Parent
*
* @param CategoryInterface $parent
* @param boolean $nested
*/
public function setParent(CategoryInterface $parent = null, $nested = false);
/**
* Get Parent
*
* @return CategoryInterface $parent
*/
public function getParent();
/**
* @param MediaInterface $media
*/
public function setMedia(MediaInterface $media = null);
/**
* @return MediaInterface
*/
public function getMedia();
/**
* @param ContextInterface $context
*/
public function setContext(ContextInterface $context);
/**
* @return ContextInterface
*/
public function getContext();
}
MY IDEA Okay since all the parent categories have a parent_id of 1, i display them easily. The child categories have parent_id that is the same as the id of the parent category. Is it possible to somehow query this condition? Like parent_id = id?