<?php
/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Eccube\Controller;
use Eccube\Entity\BaseInfo;
use Eccube\Entity\Page;
use Eccube\Repository\BaseInfoRepository;
use Eccube\Repository\CategoryRepository;
use Eccube\Repository\Master\ProductListOrderByRepository;
use Eccube\Repository\PageRepository;
use Eccube\Repository\ProductRepository;
use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
class SitemapController extends AbstractController
{
/**
* @var CategoryRepository
*/
private $categoryRepository;
/**
* @var PageRepository
*/
private $pageRepository;
/**
* @var ProductListOrderByRepository
*/
private $productListOrderByRepository;
/**
* @var ProductRepository
*/
private $productRepository;
/**
* @var RouterInterface
*/
private $router;
/**
* @var BaseInfo
*/
protected $BaseInfo;
/**
* SitemapController constructor.
*/
public function __construct(
CategoryRepository $categoryRepository,
PageRepository $pageRepository,
ProductListOrderByRepository $productListOrderByRepository,
ProductRepository $productRepository,
RouterInterface $router,
BaseInfoRepository $baseInfoRepository
) {
$this->categoryRepository = $categoryRepository;
$this->pageRepository = $pageRepository;
$this->productListOrderByRepository = $productListOrderByRepository;
$this->productRepository = $productRepository;
$this->router = $router;
$this->BaseInfo = $baseInfoRepository->get();
}
/**
* Output sitemap index
*
* @Route("/sitemap.xml", name="sitemap_xml", methods={"GET"})
*/
public function index(PaginatorInterface $paginator)
{
$pageQueryBuilder = $this->pageRepository->createQueryBuilder('p');
$Page = $pageQueryBuilder->select('p')
->where("((p.meta_robots not like '%noindex%' and p.meta_robots not like '%none%') or p.meta_robots IS NULL)")
->andWhere('p.id <> 0')
->andWhere('p.MasterPage is null')
->orderBy('p.update_date', 'DESC')
->setMaxResults(1)
->getQuery()
->getSingleResult();
$Product = $this->productRepository->findOneBy(['Status' => 1], ['update_date' => 'DESC']);
// フロントの商品一覧の条件で商品情報を取得
$ProductListOrder = $this->productListOrderByRepository->find($this->eccubeConfig['eccube_product_order_newer']);
$productQueryBuilder = $this->productRepository->getQueryBuilderBySearchData(['orderby' => $ProductListOrder]);
/** @var SlidingPagination $pagination */
$pagination = $paginator->paginate(
$productQueryBuilder,
1,
$this->eccubeConfig['eccube_sitemap_products_per_page']
);
$paginationData = $pagination->getPaginationData();
$Category = $this->categoryRepository->findOneBy([], ['update_date' => 'DESC']);
return $this->outputXml(
[
'Category' => $Category,
'Product' => $Product,
'productPageCount' => $paginationData['pageCount'],
'Page' => $Page,
],
'sitemap_index.xml.twig'
);
}
/**
* Output sitemap of product categories
*
* @Route("/sitemap_category.xml", name="sitemap_category_xml", methods={"GET"})
*/
public function category()
{
$Categories = $this->categoryRepository->getList(null, true);
return $this->outputXml(['Categories' => $Categories]);
}
/**
* Output sitemap of products
*
* Output sitemap of products as status is 1
*
* @Route("/sitemap_product_{page}.xml", name="sitemap_product_xml", requirements={"page" = "\d+"}, methods={"GET"})
*
* @return Response
*/
public function product(Request $request, PaginatorInterface $paginator)
{
// Doctrine SQLFilter
if ($this->BaseInfo->isOptionNostockHidden()) {
$this->entityManager->getFilters()->enable('option_nostock_hidden');
}
// フロントの商品一覧の条件で商品情報を取得
$ProductListOrder = $this->productListOrderByRepository->find($this->eccubeConfig['eccube_product_order_newer']);
$productQueryBuilder = $this->productRepository->getQueryBuilderBySearchData(['orderby' => $ProductListOrder]);
/** @var SlidingPagination $pagination */
$pagination = $paginator->paginate(
$productQueryBuilder,
$request->get('page'),
$this->eccubeConfig['eccube_sitemap_products_per_page']
);
$paginationData = $pagination->getPaginationData();
if ($paginationData['currentItemCount'] === 0) {
throw new NotFoundHttpException();
}
return $this->outputXml(['Products' => $pagination]);
}
/**
* Output sitemap of pages
*
* Output sitemap of pages without 'noindex' in meta robots.
*
* @Route("/sitemap_page.xml", name="sitemap_page_xml", methods={"GET"})
*/
public function page()
{
$Pages = $this->pageRepository->getPageList("((p.meta_robots not like '%noindex%' and p.meta_robots not like '%none%') or p.meta_robots IS NULL)");
// URL に変数が含まれる場合は URL の生成ができないためここで除外する
$DefaultPages = array_filter($Pages, function (Page $Page) {
// 管理画面から作成されたページは除外
if ($Page->getEditType() === Page::EDIT_TYPE_USER) {
return false;
}
$route = $this->router->getRouteCollection()->get($Page->getUrl());
if (is_null($route)) {
return false;
}
return count($route->compile()->getPathVariables()) < 1;
});
// 管理画面から作成されたページ
$UserPages = array_filter($Pages, function (Page $Page) {
return $Page->getEditType() === Page::EDIT_TYPE_USER;
});
return $this->outputXml([
'DefaultPages' => $DefaultPages,
'UserPages' => $UserPages,
]);
}
/**
* Output XML response by data.
*
* @param array $data
* @param string $template_name
*
* @return Response
*/
private function outputXml(array $data, $template_name = 'sitemap.xml.twig')
{
$response = new Response();
$response->headers->set('Content-Type', 'application/xml'); // Content-Typeを設定
return $this->render(
$template_name,
$data,
$response
);
}
}