<?php
namespace Plugin\tbsFeaturePage\Controller\Admin;
use Eccube\Application;
use Eccube\Common\Constant;
use Eccube\Controller\AbstractController;
use Eccube\Form\Type\Admin\SearchProductType;
use Eccube\Repository\CategoryRepository;
use Eccube\Repository\ProductRepository;
use Eccube\Util\CacheUtil;
use Knp\Component\Pager\Paginator;
use Plugin\tbsFeaturePage\Entity\Feature;
use Plugin\tbsFeaturePage\Entity\FeatureProduct;
use Plugin\tbsFeaturePage\Entity\FeatureStatus;
use Plugin\tbsFeaturePage\Form\Type\Admin\FeatureType;
use Plugin\tbsFeaturePage\Repository\FeatureProductRepository;
use Plugin\tbsFeaturePage\Repository\FeatureRepository;
use Plugin\tbsFeaturePage\Repository\FeatureStatusRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
use Symfony\Component\Routing\RouterInterface;
class FeatureController extends AbstractController
{
/** @var ProductRepository */
private $productRepository;
/** @var CategoryRepository */
private $categoryRepository;
/** @var FeatureRepository */
private $featureRepository;
/** @var FeatureStatusRepository */
private $featureStatusRepository;
/** @var FeatureProductRepository */
private $featureProductRepository;
/**
* FeatureController constructor.
*
* @param ProductRepository $productRepository
* @param CategoryRepository $categoryRepository
* @param FeatureRepository $featureRepository
* @param FeatureStatusRepository $featureStatusRepository
* @param FeatureProductRepository $featureProductRepository
*/
public function __construct(
ProductRepository $productRepository,
CategoryRepository $categoryRepository,
FeatureRepository $featureRepository,
FeatureStatusRepository $featureStatusRepository,
FeatureProductRepository $featureProductRepository
) {
$this->productRepository = $productRepository;
$this->categoryRepository = $categoryRepository;
$this->featureRepository = $featureRepository;
$this->featureStatusRepository = $featureStatusRepository;
$this->featureProductRepository = $featureProductRepository;
}
/**
* 管理.
*
* @Route("%eccube_admin_route%/tbs_feature_page/", name="tbs_feature_page_admin_feature")
* @Template("@tbsFeaturePage/admin/index.twig")
*
* @return array|RedirectResponse
*/
public function index()
{
$Features = $this->featureRepository->findBy(array(), array('rank' => 'DESC'));
return [
'Features' => $Features,
];
}
/**
* 登録・編集.
*
* @Route("%eccube_admin_route%/tbs_feature_page/new", name="tbs_feature_page_admin_feature_new")
* @Route("%eccube_admin_route%/tbs_feature_page/{id}/edit", name="tbs_feature_page_admin_feature_edit")
* @Template("@tbsFeaturePage/admin/edit.twig")
*
* @param Request $request
* @param $id
*
* @return array|RedirectResponse
*/
public function edit(Request $request, $id = null, RouterInterface $router, CacheUtil $cacheUtil)
{
$Feature = null;
$arrFeatureProducts = array('1' => null, '2' => null, '3' => null, '4' => null, '5' => null);
if (is_null($id)) {
$rank = 1;
$Feature = $this->featureRepository->findOneBy(array(), array('rank' => 'DESC'));
if ($Feature) {
$rank = $Feature->getRank() + 1;
}
$Feature = new Feature();
$Feature
->setRank($rank)
->setStatus($this->featureStatusRepository->find(FeatureStatus::HIDE));
} else {
$Feature = $this->featureRepository->find(array('id' => $id));
if (!$Feature) {
throw new NotFoundHttpException();
}
$FeatureProducts = $this->featureProductRepository->findBy(array('Feature' => $Feature), array('rank' => 'DESC'));
foreach ($FeatureProducts as $FeatureProduct) {
$arrFeatureProducts[$FeatureProduct->getPosition()][] = $FeatureProduct;
}
}
$form = $this->createForm(FeatureType::class, $Feature);
if ('POST' === $request->getMethod()) {
$form->handleRequest($request);
// 登録ボタン押下
switch ($request->get('mode')) {
case 'register':
if ($form->isValid()) {
$Feature = $form->getData();
// ファイルアップロード
$file = $form['banner_file_name']->getData();
$fs = new Filesystem();
if ($file && $fs->exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' . $file)) {
$fs->rename(
$this->eccubeConfig['eccube_temp_image_dir'] . '/' . $file,
$this->eccubeConfig['plugin_html_realdir'] . 'tbsFeaturePage/save_image/' . $file
);
}
$Feature->setUpdateDate(new \DateTime());
$this->entityManager->persist($Feature);
$this->entityManager->flush();
log_info('Feature page edit ID:' . $Feature->getId());
$this->addSuccess('tbs_feature_page.admin.save.complete', 'admin');
if ($returnLink = $form['return_link']->getData()) {
try {
// $returnLinkはpathの形式で渡される. pathが存在するかをルータでチェックする.
$pattern = '/^'.preg_quote($request->getBasePath(), '/').'/';
$returnLink = preg_replace($pattern, '', $returnLink);
$result = $router->match($returnLink);
// パラメータのみ抽出
$params = array_filter($result, function ($key) {
return 0 !== \strpos($key, '_');
}, ARRAY_FILTER_USE_KEY);
// pathからurlを再構築してリダイレクト.
return $this->redirectToRoute($result['_route'], $params);
} catch (\Exception $e) {
// マッチしない場合はログ出力してスキップ.
log_warning('URLの形式が不正です。');
}
}
$cacheUtil->clearDoctrineCache();
return $this->redirectToRoute(
'tbs_feature_page_admin_feature_edit',
['id' => $Feature->getId()]
);
} else {
$this->addError('tbs_feature_page.admin.save.error', 'admin');
}
break;
default:
break;
}
}
// 商品検索フォーム
$builder = $this->formFactory
->createBuilder(SearchProductType::class);
$searchProductModalForm = $builder->getForm();
return [
'form' => $form->createView(),
'Feature' => $Feature,
'FeatureProducts' => $arrFeatureProducts,
'searchProductModalForm' => $searchProductModalForm->createView(),
'id' => $id,
];
}
/**
* 削除.
*
* @Method("DELETE")
* @Route("%eccube_admin_route%/tbs_feature_page/{id}/delete", name="tbs_feature_page_admin_feature_delete")
*
* @param Feature $Feature
*
* @return RedirectResponse
*/
public function delete(Feature $Feature)
{
$this->isTokenValid();
$this->entityManager->remove($Feature);
$this->entityManager->flush($Feature);
$this->addSuccess('tbs_feature_page.admin.delete.complete', 'admin');
log_info('Feature page delete', ['id' => $Feature->getId()]);
return $this->redirect($this->generateUrl('tbs_feature_page_admin_feature'));
}
/**
* @Route("/%eccube_admin_route%/tbs_feature_page/{url}/display", name="tbs_feature_page_admin_feature_display")
*/
public function display(Request $request, $url = null)
{
if (!is_null($url)) {
return $this->redirectToRoute('feature_detail', ['url' => $url, 'admin' => '1']);
}
return $this->redirectToRoute(
'tbs_feature_page_admin_feature'
);
}
/**
* @Route("/%eccube_admin_route%/tbs_feature_page/image/add", name="tbs_feature_page_admin_feature_image_add", methods={"POST"})
*/
public function addImage(Request $request)
{
if (!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException();
}
$images = $request->files->get('feature');
$allowExtensions = ['gif', 'jpg', 'jpeg', 'png'];
$filename = null;
if (isset($images['banner_file'])) {
$image = $images['banner_file'];
//ファイルフォーマット検証
$mimeType = $image->getMimeType();
if (0 !== strpos($mimeType, 'image')) {
throw new UnsupportedMediaTypeHttpException();
}
// 拡張子
$extension = $image->getClientOriginalExtension();
if (!in_array($extension, $allowExtensions)) {
throw new UnsupportedMediaTypeHttpException();
}
$filename = date('mdHis') . uniqid('_') . '.' . $extension;
$image->move($this->eccubeConfig['eccube_temp_image_dir'], $filename);
}
return $this->json(['filename' => $filename], 200);
}
/**
* @Route("/%eccube_admin_route%/tbs_feature_page/search/product", name="tbs_feature_page_admin_feature_search_product")
* @Route("/%eccube_admin_route%/tbs_feature_page/search/product/page/{page_no}", requirements={"page_no" = "\d+"}, name="tbs_feature_page_admin_feature_search_product_page")
* @Template("@tbsFeaturePage/admin/search_product.twig")
*/
public function searchProduct(Request $request, $page_no = null, Paginator $paginator)
{
if ($request->isXmlHttpRequest() && $this->isTokenValid()) {
log_debug('search product start.');
$page_count = $this->eccubeConfig['eccube_default_page_count'];
$session = $this->session;
if ('POST' === $request->getMethod()) {
$page_no = 1;
$searchData = array(
'id' => $request->get('id'),
);
if ($categoryId = $request->get('category_id')) {
$Category = $this->categoryRepository->find($categoryId);
$searchData['category_id'] = $Category;
}
$session->set('eccube.admin.feature.product.search', $searchData);
$session->set('eccube.admin.feature.product.search.page_no', $page_no);
} else {
$searchData = (array)$session->get('eccube.admin.feature.product.search');
if (is_null($page_no)) {
$page_no = intval($session->get('eccube.admin.feature.product.search.page_no'));
} else {
$session->set('eccube.admin.feature.product.search.page_no', $page_no);
}
}
$qb = $this->productRepository
->getQueryBuilderBySearchDataForAdmin($searchData);
/** @var \Knp\Component\Pager\Pagination\SlidingPagination $pagination */
$pagination = $paginator->paginate(
$qb,
$page_no,
$page_count,
['wrap-queries' => true]
);
/** @var $Products \Eccube\Entity\Product[] */
$Products = $pagination->getItems();
if (empty($Products)) {
log_debug('search product not found.');
}
return [
'Products' => $Products,
'pagination' => $pagination,
];
}
}
/**
* @Route("/%eccube_admin_route%/tbs_feature_page/product/register", name="tbs_feature_page_admin_feature_product_register")
*
* @return JsonResponse
*/
public function registerProduct(Request $request)
{
if (!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException();
}
$productIds = $request->get('productIds');
$featureId = $request->get('featureId');
$Feature = $this->featureRepository->find($featureId);
$position = $request->get('position');
foreach ($productIds as $productId) {
$rank = 1;
$FeatureProduct = $this->featureProductRepository->findOneBy(array(
'Feature' => $Feature,
'position' => $position
), array('rank' => 'DESC'));
if ($FeatureProduct) {
$rank = $FeatureProduct->getRank() + 1;
}
$Product = $this->productRepository->find($productId);
$FeatureProduct = new FeatureProduct();
$FeatureProduct
->setRank($rank)
->setProduct($Product)
->setFeature($Feature)
->setPosition($position);
$this->entityManager->persist($FeatureProduct);
$this->entityManager->flush($FeatureProduct);
}
$this->addSuccess('admin.common.save_complete', 'admin');
return $this->json(['success' => true]);
}
/**
* @Route("/%eccube_admin_route%/tbs_feature_page/product/{id}/delete", requirements={"id" = "\d+"}, name="tbs_feature_page_admin_feature_product_delete", methods={"DELETE"})
*/
public function deleteProduct(Request $request, $id, CacheUtil $cacheUtil)
{
$this->isTokenValid();
$FeatureProduct = $this->featureProductRepository->find($id);
if (!$FeatureProduct) {
$this->deleteMessage();
return $this->redirectToRoute('tbs_feature_page_admin_feature_edit', ['id' => $feature_id]);
}
$feature_id = $FeatureProduct->getFeature()->getId();
$this->entityManager->remove($FeatureProduct);
$this->entityManager->flush($FeatureProduct);
$this->addSuccess('tbs_feature_page.admin.feature_edit.product_delete.complete', 'admin');
$cacheUtil->clearDoctrineCache();
return $this->redirectToRoute('tbs_feature_page_admin_feature_edit', ['id' => $feature_id]);
}
/**
* @Route("/%eccube_admin_route%/tbs_feature_page/move", name="tbs_feature_page_admin_feature_move", methods={"POST"})
*/
public function moveRank(Request $request, CacheUtil $cacheUtil)
{
if (!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException();
}
if ($this->isTokenValid()) {
$ranks = $request->request->all();
foreach ($ranks as $featureId => $rank) {
$Feature = $this->featureRepository->find($featureId);
$Feature->setRank($rank);
$this->entityManager->persist($Feature);
}
$this->entityManager->flush();
}
$cacheUtil->clearDoctrineCache();
return new Response('Successful');
}
/**
* @Route("/%eccube_admin_route%/tbs_feature_page/product/move", name="tbs_feature_page_admin_feature_product_move", methods={"POST"})
*/
public function moveRankProduct(Request $request, CacheUtil $cacheUtil)
{
if (!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException();
}
if ($this->isTokenValid()) {
$ranks = $request->request->all();
foreach ($ranks as $id => $rank) {
$FeatureProduct = $this->featureProductRepository->find($id);
$FeatureProduct->setRank($rank);
$this->entityManager->persist($FeatureProduct);
}
$this->entityManager->flush();
$cacheUtil->clearDoctrineCache();
return new Response('Successful');
}
}
}