▼テンプレート
[EC-CUBE] 4.0.3
現在EC-CUBE4でサイトを構築しています。
TOPページにてカテゴリ検索またはキーワードによる検索を実行すると、初期状態ではdtb_productテーブルからデータを取得するようになっていると思いますが、
今回のカスタマイズで、dtb_productテーブルではなく新しく新規で追加したdtb_shopというテーブルからデータを持ってくるように変更したいと考えています。
ProductController内の
$qb = $this->productRepository->getQueryBuilderBySearchData($searchData);
でEccube\Repository\ProductRepository.phpの中で定義されているgetQueryBuilderBySearchData()が呼ばれて取得の処理が行われる認識でいますので、
$qb = $this->shopRepository->getQueryBuilderBySearchData($searchData);
下記を作成し、
Customize\Repository\ShopRepository.php(Eccube\Repository\ProductRepository.phpのコピー)
Customize\Form\Type\SearchShopType.php(Eccube\Form\Type\SearchProductType.phpのコピー)
中身をいじれば対象のデータを抽出できるのではないかと考えています。
現在のCustomize\Repository\ShopRepository.phpは下記の状態になっています。
<?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 Customize\Repository;
use Customize\Entity\Shop;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Eccube\Common\EccubeConfig;
use Eccube\Doctrine\Query\Queries;
use Eccube\Entity\Product;
use Eccube\Entity\ProductStock;
use Eccube\Util\StringUtil;
use Eccube\Repository\QueryKey;
/**
* BaseInfoRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ShopRepository extends \Eccube\Repository\AbstractRepository
{
/**
* @var Queries
*/
protected $queries;
/**
* @var EccubeConfig
*/
protected $eccubeConfig;
/**
* ShopRepository constructor.
*
* @param RegistryInterface $registry
* @param Queries $queries
* @param EccubeConfig $eccubeConfig
*/
public function __construct(
RegistryInterface $registry,
Queries $queries,
EccubeConfig $eccubeConfig
) {
parent::__construct($registry, Shop::class);
$this->queries = $queries;
$this->eccubeConfig = $eccubeConfig;
}
public function getQueryBuilderBySearchData($searchData)
{
$qb = $this->createQueryBuilder('p')
->andWhere('p.authenticatedByAdmin = 2 AND p.publicStatus = 2');
// 両方のカラムが2のデータを抽出する
// category
$categoryJoin = false;
if (!empty($searchData['category_id']) && $searchData['category_id']) {
$Categories = $searchData['category_id']->getSelfAndDescendants();
if ($Categories) {
$qb->setParameter('Categories', $Categories);
$categoryJoin = true;
}
}
// name
if (isset($searchData['name']) && StringUtil::isNotBlank($searchData['name'])) {
$keywords = preg_split('/[\s ]+/u', str_replace(['%', '_'], ['\\%', '\\_'], $searchData['name']), -1, PREG_SPLIT_NO_EMPTY);
foreach ($keywords as $index => $keyword) {
$key = sprintf('keyword%s', $index);
$qb
->andWhere(sprintf('NORMALIZE(p.name) LIKE NORMALIZE(:%s) OR
NORMALIZE(p.search_word) LIKE NORMALIZE(:%s) OR
EXISTS (SELECT wpc%d FROM \Eccube\Entity\ProductClass wpc%d WHERE p = wpc%d.Product AND NORMALIZE(wpc%d.code) LIKE NORMALIZE(:%s))',
$key, $key, $index, $index, $index, $index, $key))
->setParameter($key, '%'.$keyword.'%');
}
}
// // Order By
// // 価格低い順
// $config = $this->eccubeConfig;
// if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_lower']) {
// //@see http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
// $qb->addSelect('MIN(pc.price02) as HIDDEN price02_min');
// $qb->innerJoin('p.ProductClasses', 'pc');
// $qb->andWhere('pc.visible = true');
// $qb->groupBy('p.id');
// $qb->orderBy('price02_min', 'ASC');
// $qb->addOrderBy('p.id', 'DESC');
// // 価格高い順
// } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_higher']) {
// $qb->addSelect('MAX(pc.price02) as HIDDEN price02_max');
// $qb->innerJoin('p.ProductClasses', 'pc');
// $qb->andWhere('pc.visible = true');
// $qb->groupBy('p.id');
// $qb->orderBy('price02_max', 'DESC');
// $qb->addOrderBy('p.id', 'DESC');
// // 新着順
// } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_newer']) {
// // 在庫切れ商品非表示の設定が有効時対応
// // @see https://github.com/EC-CUBE/ec-cube/issues/1998
// if ($this->getEntityManager()->getFilters()->isEnabled('option_nostock_hidden') == true) {
// $qb->innerJoin('p.ProductClasses', 'pc');
// $qb->andWhere('pc.visible = true');
// }
// $qb->orderBy('p.create_date', 'DESC');
// $qb->addOrderBy('p.id', 'DESC');
// } else {
// if ($categoryJoin === false) {
// $qb
// ->leftJoin('p.ProductCategories', 'pct')
// ->leftJoin('pct.Category', 'c');
// }
// $qb
// ->addOrderBy('p.id', 'DESC');
// }
return $this->queries->customize(QueryKey::PRODUCT_SEARCH, $qb, $searchData);
}
}
という状態になっており、ソートは現状必要ないので消してあります。(消していいものかは理解してません)
まず、
$qb = $this->createQueryBuilder('p')
->andWhere('p.authenticatedByAdmin = 2 AND p.publicStatus = 2');
// 両方のカラムが2のデータを抽出する
の記述をすると
Too many parameters: the query defines 1 parameters and you bound 2
のエラーが発生します。
こちらの改善方法がわかりません。
また、この記述は意味のないものだと思いますが、
$qb = $this->createQueryBuilder('p')
->andWhere('shop.authenticatedByAdmin = 2 AND shop.publicStatus = 2');
// 両方のカラムが2のデータを抽出する
変えると、
[Semantical Error] line 0, col 44 near 'shop.authenticatedByAdmin': Error: 'shop' is not defined.
のエラーが出ます。
log_infoでどこまで進んでいるのか追ってみたら、ProductControllerの
/** @var SlidingPagination $pagination */
$pagination = $paginator->paginate(
$query,
!empty($searchData['pageno']) ? $searchData['pageno'] : 1,
!empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId()
);
の手前までは進んでいるのが確認できたのですが、エラーが何を指しているのかがわかりません。
'shop.authenticatedByAdmin'がないということだと思うのですが、これがなんなのか・・・???
ご教授お願いいたします。