Я использую вложенный набор поведение в Symfony2 с StofDoctrineExtension.
Категория и модель поста хорошо настроены, а дерево категорий работает нормально.
Чтобы показать сообщения категории, я использую этот запрос из своего хранилища:
public function findAllPosts($category)
{
return $this->queryAllPosts($category)->getResult();
}
public function queryAllPosts($category)
{
$em = $this->getEntityManager();
$query = $em->createQuery('
SELECT p, c FROM AppBundle:Post p JOIN p.category c
WHERE c.slug = :category
ORDER BY p.created DESC
');
$query->setParameter('category', $category);
return $query;
}
Но как я могу показать посты детей из категорий тоже?
Вы должны быть в состоянии сделать это в одном запросе, который будет близок к этому, так как я не являюсь профессионалом SQL, обычно у меня уходит время и тесты, прежде чем я понимаю это правильно, но это то, с чего я бы начал:
SELECT parent.* , children.* FROM
(SELECT p, c FROM AppBundle:Post p JOIN p.category c WHERE c.slug = :category) AS parent
INNER JOIN
(SELECT p1 FROM AppBundle:Post p1 JOIN p.category c1 ON c1.parent = parent.id ) AS children
не уверен, если вам нужно сделать ON внутри внутреннего выбора или обертки выбора для объединения, но вы можете попробовать 🙂
Если твой CategoryRepository
наследуется от NestedTreeRepository
Вы могли бы сделать что-то вроде этого:
$categories = $em->getRepository('XBundle:Category')
->childrenQueryBuilder($category)
->addSelect('posts')
->join('node.posts', 'posts')
->getQuery()
->getResult();
foreach ($categories as $category) {
$category->getPosts();
// do stuff
}
Я нашел способ. Запрос будет выглядеть так:
/*
* GET POSTS FROM PARENT AND CHILDREN
*/
public function getPostsParentAndChildren($children)
{
$em = $this->getEntityManager();
$posts = $em->createQueryBuilder()
->select(array('p', 'c'))
->from('AppBundle:Post', 'p')
->join('p.category', 'c')
->where('c.id IN (:children)')
->orderBy('p.created', 'DESC')
->getQuery();
$posts->setParameter('children', $children);
return $posts->getResult();
}
Мы передаем массив с дочерними элементами в запрос, который мы получаем с помощью функции getChildren ($ categoryId). Помните, что вы должны передать идентификатор (с этим запросом), чтобы вы могли получить идентификаторы, как это:
$category = $repo->findOneBy(array('slug' => $slug1));
$children = $repo->getChildren($category);
$childrenIds[] = $category->getId();
foreach ($children as $child){
$id = $child->getId();
$childrenIds[] = $id;
}
$posts = $em->getRepository('AppBundle:Category')->getPostsParentAndChildren($childrenIds);