diff --git a/app/Resources/views/category/detail.html.twig b/app/Resources/views/category/detail.html.twig index 13b9283..8cf3245 100644 --- a/app/Resources/views/category/detail.html.twig +++ b/app/Resources/views/category/detail.html.twig @@ -1,8 +1,13 @@ {% extends 'base.html.twig' %} {% block body %} + {% include 'components/breadcrumb.html.twig' %} +
{% include 'components/list.html.twig' %}
+ + + {% include ':components:paginator.html.twig' %} {% endblock %} diff --git a/app/Resources/views/components/breadcrumb.html.twig b/app/Resources/views/components/breadcrumb.html.twig new file mode 100644 index 0000000..c61b41f --- /dev/null +++ b/app/Resources/views/components/breadcrumb.html.twig @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/app/Resources/views/components/paginator.html.twig b/app/Resources/views/components/paginator.html.twig new file mode 100644 index 0000000..0e97218 --- /dev/null +++ b/app/Resources/views/components/paginator.html.twig @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/src/AppBundle/Controller/CategoryController.php b/src/AppBundle/Controller/CategoryController.php index 6e6a457..90017dd 100644 --- a/src/AppBundle/Controller/CategoryController.php +++ b/src/AppBundle/Controller/CategoryController.php @@ -3,6 +3,7 @@ use AppBundle\Entity\Category; use AppBundle\Entity\Product; +use AppBundle\Repository\ProductRepository; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -14,25 +15,52 @@ */ class CategoryController extends Controller { - /** - * @Route("/vyber/{slug}", name="category_detail") - * @Template("category/detail.html.twig") - * - * @param Request $request - * @return array - */ - public function categoryDetail(Request $request) + const DIRECTION_NEXT = 'next'; + const DIRECTION_PREV = 'prev'; + + /** + * @Route("/vyber/{slug}/{last}/{direction}", name="category_detail", requirements={"last": "\d+"}) + * @Template("category/detail.html.twig") + * + * @param string $slug + * @param int $last + * @param string $direction + * @return array + * @internal param Request $request + */ + public function categoryDetail($slug, $last = 0, $direction = self::DIRECTION_NEXT) { $category = $this->getDoctrine()->getRepository(Category::class)->findOneBy([ - "slug" => $request->attributes->get("slug"), + "slug" => $slug, ]); if (!$category) { throw new NotFoundHttpException("Kategorie neexistuje"); } + if ($direction === self::DIRECTION_NEXT) { + $products = $this->getDoctrine()->getRepository(Product::class)->findNextByCategory($category, $last); + } else { + $products = $this->getDoctrine()->getRepository(Product::class)->findPrevByCategory($category, $last); + } + + if (current($products)->getId() !== 1) { + $prev = current($products)->getId(); + } else { + $prev = null; + } + + if (isset($products[ProductRepository::PAGE_SIZE])) { + unset($products[ProductRepository::PAGE_SIZE]); + $next = end($products)->getId(); + } else { + $next = null; + } + return [ - "products" => $this->getDoctrine()->getRepository(Product::class)->findByCategory($category), + "products" => $products, + "prev" => $prev, + "next" => $next, "categories" => $this->getDoctrine()->getRepository(Category::class)->findBy( [ "parentCategory" => $category, @@ -42,7 +70,7 @@ public function categoryDetail(Request $request) ] ), "category" => $category, + "breadcrumb" => $this->getDoctrine()->getRepository(Category::class)->getParents($category) ]; } - } diff --git a/src/AppBundle/Repository/CategoryRepository.php b/src/AppBundle/Repository/CategoryRepository.php index f9b2633..edbcd73 100644 --- a/src/AppBundle/Repository/CategoryRepository.php +++ b/src/AppBundle/Repository/CategoryRepository.php @@ -3,6 +3,7 @@ namespace AppBundle\Repository; use Doctrine\ORM\EntityRepository; +use AppBundle\Entity\Category; /** * CategoryRepository @@ -12,4 +13,16 @@ */ class CategoryRepository extends EntityRepository { + public function getParents(Category $category) + { + return $this->_em->createQuery(" + SELECT ancestor + FROM AppBundle\Entity\Category child, AppBundle\Entity\Category ancestor + WHERE child.left >= ancestor.left + AND child.left <= ancestor.right + AND child.id = :current + ORDER BY ancestor.left") + ->setParameter("current", $category->getId()) + ->getResult(); + } } diff --git a/src/AppBundle/Repository/ProductRepository.php b/src/AppBundle/Repository/ProductRepository.php index ac70f55..4004b43 100644 --- a/src/AppBundle/Repository/ProductRepository.php +++ b/src/AppBundle/Repository/ProductRepository.php @@ -8,23 +8,70 @@ class ProductRepository extends EntityRepository { + const PAGE_SIZE = 3; - /** - * @param Category $category - * @return Product[] - */ - public function findByCategory(Category $category) + /** + * @param Category $category + * @param int $last + * @return Product[] + */ + public function findPrevByCategory(Category $category, $last = 0) + { + return $this->inverseResult($this->_em->createQuery('SELECT p + FROM AppBundle\Entity\Product p + JOIN AppBundle\Entity\ProductCategory pc WITH p = pc.product + JOIN AppBundle\Entity\Category c WITH pc.category = c + WHERE c.left >= :lft and c.right <= :rgt + AND p.id <= :last + GROUP BY p + ORDER BY p.id DESC + ') + ->setParameter("lft", $category->getLeft()) + ->setParameter("rgt", $category->getRight()) + ->setParameter("last", $last) + ->setMaxResults(self::PAGE_SIZE + 1) + ->getResult()); + } + + + /** + * @param array $entities + * @return array + */ + protected function inverseResult(array $entities) + { + $result = []; + + $max = count($entities) - 1; + $min = 0; + for ($i = $max; $i >= $min; $i--) { + $result[] = $entities[$i]; + } + + return $result; + } + + /** + * @param Category $category + * @param int $last + * @return Product[] + */ + public function findNextByCategory(Category $category, $last = 0) { return $this->_em->createQuery('SELECT p FROM AppBundle\Entity\Product p JOIN AppBundle\Entity\ProductCategory pc WITH p = pc.product JOIN AppBundle\Entity\Category c WITH pc.category = c WHERE c.left >= :lft and c.right <= :rgt + AND p.id > :last GROUP BY p + ORDER BY p.id ASC ') ->setParameter("lft", $category->getLeft()) ->setParameter("rgt", $category->getRight()) - ->getResult(); + ->setParameter("last", $last) + ->setMaxResults(self::PAGE_SIZE + 1) + ->getResult(); } }