Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Úkol 2 - Vojtěch Bartoš #24

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions app/Resources/views/category/detail.html.twig
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
{% extends 'base.html.twig' %}

{% block body %}
{% include 'components/breadcrumb.html.twig' %}

<div class="row">
{% include 'components/list.html.twig' %}
</div>


{% include ':components:paginator.html.twig' %}
Copy link
Member

Choose a reason for hiding this comment

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

Kód by měl být vždy konzistentní napříč celým projektem, zde máš dva způsoby zápisu odkazu na šablonu: components/ a :components:

{% endblock %}

12 changes: 12 additions & 0 deletions app/Resources/views/components/breadcrumb.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<ol class="breadcrumb">
{% for current in breadcrumb %}
{% if current == category and product is not defined %}
<li class="active">{{ current.title }}</li>
{% else %}
<li><a href="{{ path("category_detail", {"slug": current.slug }) }}">{{ current.title }}</a></li>
{% endif %}
{% endfor %}
{% if product is defined %}
<li class="active">{{ product.title }}</li>
{% endif %}
</ol>
18 changes: 18 additions & 0 deletions app/Resources/views/components/paginator.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
{% if prev %}
<a href="{{ path("category_detail", {"slug": category.slug, 'last': prev, 'direction': 'prev'}) }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
{% endif %}
</li>
<li>
{% if next %}
<a href="{{ path("category_detail", {"slug": category.slug, 'last': next, 'direction': 'next'}) }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
{% endif %}
</li>
</ul>
</nav>
50 changes: 39 additions & 11 deletions src/AppBundle/Controller/CategoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -42,7 +70,7 @@ public function categoryDetail(Request $request)
]
),
"category" => $category,
"breadcrumb" => $this->getDoctrine()->getRepository(Category::class)->getParents($category)
];
}

}
13 changes: 13 additions & 0 deletions src/AppBundle/Repository/CategoryRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;
use AppBundle\Entity\Category;

/**
* CategoryRepository
Expand All @@ -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();
}
}
59 changes: 53 additions & 6 deletions src/AppBundle/Repository/ProductRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

}