app/Customize/Repository/ProductRepository.php line 60

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Customize\Repository;
  13. use Doctrine\Common\Collections\ArrayCollection;
  14. use Doctrine\Persistence\ManagerRegistry as RegistryInterface;
  15. use Eccube\Common\EccubeConfig;
  16. use Eccube\Doctrine\Query\Queries;
  17. use Eccube\Entity\Category;
  18. use Eccube\Entity\Master\ProductListMax;
  19. use Eccube\Entity\Master\ProductListOrderBy;
  20. use Eccube\Entity\Master\ProductStatus;
  21. use Eccube\Entity\Product;
  22. use Eccube\Entity\ProductStock;
  23. use Eccube\Entity\Tag;
  24. use Eccube\Repository\AbstractRepository;
  25. use Eccube\Repository\QueryKey;
  26. use Eccube\Util\StringUtil;
  27. /**
  28.  * ProductRepository
  29.  *
  30.  * This class was generated by the Doctrine ORM. Add your own custom
  31.  * repository methods below.
  32.  */
  33. class ProductRepository extends \Eccube\Repository\ProductRepository
  34. {
  35.     /**
  36.      * @var Queries
  37.      */
  38.     protected $queries;
  39.     /**
  40.      * @var EccubeConfig
  41.      */
  42.     protected $eccubeConfig;
  43.     public const COLUMNS = [
  44.         'product_id' => 'p.id''name' => 'p.name''product_code' => 'pc.code''stock' => 'pc.stock''status' => 'p.Status''create_date' => 'p.create_date''update_date' => 'p.update_date',
  45.     ];
  46.     /**
  47.      * ProductRepository constructor.
  48.      *
  49.      * @param RegistryInterface $registry
  50.      * @param Queries $queries
  51.      * @param EccubeConfig $eccubeConfig
  52.      */
  53.     public function __construct(
  54.         RegistryInterface $registry,
  55.         Queries $queries,
  56.         EccubeConfig $eccubeConfig
  57.     ) {
  58.         parent::__construct($registry$queries$eccubeConfig);
  59.         $this->queries $queries;
  60.         $this->eccubeConfig $eccubeConfig;
  61.     }
  62.     /**
  63.      * get query builder.
  64.      *
  65.      * @param array{
  66.      *         id?:string|int|null,
  67.      *         category_id?:Category,
  68.      *         status?:ProductStatus[],
  69.      *         link_status?:ProductStatus[],
  70.      *         stock_status?:int,
  71.      *         stock?:ProductStock::IN_STOCK|ProductStock::OUT_OF_STOCK,
  72.      *         tag_id?:Tag,
  73.      *         create_datetime_start?:\DateTime,
  74.      *         create_datetime_end?:\DateTime,
  75.      *         create_date_start?:\DateTime,
  76.      *         create_date_end?:\DateTime,
  77.      *         update_datetime_start?:\DateTime,
  78.      *         update_datetime_end?:\DateTime,
  79.      *         update_date_start?:\DateTime,
  80.      *         update_date_end?:\DateTime,
  81.      *         sortkey?:string,
  82.      *         sorttype?:string
  83.      *     } $searchData
  84.      *
  85.      * @return \Doctrine\ORM\QueryBuilder
  86.      */
  87.     public function getQueryBuilderBySearchDataForAdmin($searchData)
  88.     {
  89.         $qb $this->createQueryBuilder('p')
  90.             ->addSelect('pc''pi''tr''ps')
  91.             ->innerJoin('p.ProductClasses''pc')
  92.             ->leftJoin('p.ProductImage''pi')
  93.             ->leftJoin('pc.TaxRule''tr')
  94.             ->leftJoin('pc.ProductStock''ps')
  95.             ->andWhere('pc.visible = :visible')
  96.             ->setParameter('visible'true);
  97.         // id
  98.         if (isset($searchData['id']) && StringUtil::isNotBlank($searchData['id'])) {
  99.             $id preg_match('/^\d{0,10}$/'$searchData['id']) ? $searchData['id'] : null;
  100.             if ($id && $id '2147483647' && $this->isPostgreSQL()) {
  101.                 $id null;
  102.             }
  103.             $qb
  104.                 ->andWhere('p.id = :id OR p.name LIKE :likeid OR pc.code LIKE :likeid OR p.product_control_number LIKE :likeid')
  105.                 ->setParameter('id'$id)
  106.                 ->setParameter('likeid''%'.str_replace(['%''_'], ['\\%''\\_'], $searchData['id']).'%');
  107.         }
  108.         // code
  109.         /*
  110.         if (!empty($searchData['code']) && $searchData['code']) {
  111.             $qb
  112.                 ->innerJoin('p.ProductClasses', 'pc')
  113.                 ->andWhere('pc.code LIKE :code')
  114.                 ->setParameter('code', '%' . $searchData['code'] . '%');
  115.         }
  116.         // name
  117.         if (!empty($searchData['name']) && $searchData['name']) {
  118.             $keywords = preg_split('/[\s ]+/u', $searchData['name'], -1, PREG_SPLIT_NO_EMPTY);
  119.             foreach ($keywords as $keyword) {
  120.                 $qb
  121.                     ->andWhere('p.name LIKE :name')
  122.                     ->setParameter('name', '%' . $keyword . '%');
  123.             }
  124.         }
  125.        */
  126.         // category
  127.         if (!empty($searchData['category_id']) && $searchData['category_id']) {
  128.             $Categories $searchData['category_id']->getSelfAndDescendants();
  129.             if ($Categories) {
  130.                 $qb
  131.                     ->innerJoin('p.ProductCategories''pct')
  132.                     ->innerJoin('pct.Category''c')
  133.                     ->andWhere($qb->expr()->in('pct.Category'':Categories'))
  134.                     ->setParameter('Categories'$Categories);
  135.             }
  136.         }
  137.         // status
  138.         if (!empty($searchData['status']) && $searchData['status']) {
  139.             $qb
  140.                 ->andWhere($qb->expr()->in('p.Status'':Status'))
  141.                 ->setParameter('Status'$searchData['status']);
  142.         }
  143.         // link_status
  144.         if (isset($searchData['link_status']) && !empty($searchData['link_status'])) {
  145.             $qb
  146.                 ->andWhere($qb->expr()->in('p.Status'':Status'))
  147.                 ->setParameter('Status'$searchData['link_status']);
  148.         }
  149.         // stock status
  150.         if (isset($searchData['stock_status'])) {
  151.             $qb
  152.                 ->andWhere('pc.stock_unlimited = :StockUnlimited AND pc.stock = 0')
  153.                 ->setParameter('StockUnlimited'$searchData['stock_status']);
  154.         }
  155.         // stock status
  156.         if (isset($searchData['stock']) && !empty($searchData['stock'])) {
  157.             switch ($searchData['stock']) {
  158.                 case [ProductStock::IN_STOCK]:
  159.                     $qb->andWhere('pc.stock_unlimited = true OR pc.stock > 0');
  160.                     break;
  161.                 case [ProductStock::OUT_OF_STOCK]:
  162.                     $qb->andWhere('pc.stock_unlimited = false AND pc.stock <= 0');
  163.                     break;
  164.                 default:
  165.                     // 共に選択された場合は全権該当するので検索条件に含めない
  166.             }
  167.         }
  168.         // tag
  169.         if (!empty($searchData['tag_id']) && $searchData['tag_id']) {
  170.             $qb
  171.                 ->innerJoin('p.ProductTag''pt')
  172.                 ->andWhere('pt.Tag = :tag_id')
  173.                 ->setParameter('tag_id'$searchData['tag_id']);
  174.         }
  175.         // crate_date
  176.         if (!empty($searchData['create_datetime_start']) && $searchData['create_datetime_start']) {
  177.             $date $searchData['create_datetime_start'];
  178.             $qb
  179.                 ->andWhere('p.create_date >= :create_date_start')
  180.                 ->setParameter('create_date_start'$date);
  181.         } elseif (!empty($searchData['create_date_start']) && $searchData['create_date_start']) {
  182.             $date $searchData['create_date_start'];
  183.             $qb
  184.                 ->andWhere('p.create_date >= :create_date_start')
  185.                 ->setParameter('create_date_start'$date);
  186.         }
  187.         if (!empty($searchData['create_datetime_end']) && $searchData['create_datetime_end']) {
  188.             $date $searchData['create_datetime_end'];
  189.             $qb
  190.                 ->andWhere('p.create_date < :create_date_end')
  191.                 ->setParameter('create_date_end'$date);
  192.         } elseif (!empty($searchData['create_date_end']) && $searchData['create_date_end']) {
  193.             $date = clone $searchData['create_date_end'];
  194.             $date $date
  195.                 ->modify('+1 days');
  196.             $qb
  197.                 ->andWhere('p.create_date < :create_date_end')
  198.                 ->setParameter('create_date_end'$date);
  199.         }
  200.         // update_date
  201.         if (!empty($searchData['update_datetime_start']) && $searchData['update_datetime_start']) {
  202.             $date $searchData['update_datetime_start'];
  203.             $qb
  204.                 ->andWhere('p.update_date >= :update_date_start')
  205.                 ->setParameter('update_date_start'$date);
  206.         } elseif (!empty($searchData['update_date_start']) && $searchData['update_date_start']) {
  207.             $date $searchData['update_date_start'];
  208.             $qb
  209.                 ->andWhere('p.update_date >= :update_date_start')
  210.                 ->setParameter('update_date_start'$date);
  211.         }
  212.         if (!empty($searchData['update_datetime_end']) && $searchData['update_datetime_end']) {
  213.             $date $searchData['update_datetime_end'];
  214.             $qb
  215.                 ->andWhere('p.update_date < :update_date_end')
  216.                 ->setParameter('update_date_end'$date);
  217.         } elseif (!empty($searchData['update_date_end']) && $searchData['update_date_end']) {
  218.             $date = clone $searchData['update_date_end'];
  219.             $date $date
  220.                 ->modify('+1 days');
  221.             $qb
  222.                 ->andWhere('p.update_date < :update_date_end')
  223.                 ->setParameter('update_date_end'$date);
  224.         }
  225.         // Order By
  226.         if (isset($searchData['sortkey']) && !empty($searchData['sortkey'])) {
  227.             $sortOrder = (isset($searchData['sorttype']) && $searchData['sorttype'] == 'a') ? 'ASC' 'DESC';
  228.             $qb->orderBy(self::COLUMNS[$searchData['sortkey']], $sortOrder);
  229.             $qb->addOrderBy('p.update_date''DESC');
  230.             $qb->addOrderBy('p.id''DESC');
  231.         } else {
  232.             $qb->orderBy('p.update_date''DESC');
  233.             $qb->addOrderBy('p.id''DESC');
  234.         }
  235.         return $this->queries->customize(QueryKey::PRODUCT_SEARCH_ADMIN$qb$searchData);
  236.     }
  237.     
  238.     /**
  239.      * get query builder.
  240.      *
  241.      * @param array{
  242.      *         category_id?:Category,
  243.      *         name?:string,
  244.      *         pageno?:string,
  245.      *         disp_number?:ProductListMax,
  246.      *         orderby?:ProductListOrderBy
  247.      *     } $searchData
  248.      *
  249.      * @return \Doctrine\ORM\QueryBuilder
  250.      */
  251.     public function getQueryBuilderBySearchData($searchData)
  252.     {
  253.         $qb $this->createQueryBuilder('p')
  254.             ->andWhere('p.Status = 1');
  255.         // category
  256.         $categoryJoin false;
  257.         if (!empty($searchData['category_id']) && $searchData['category_id']) {
  258.             $Categories $searchData['category_id']->getSelfAndDescendants();
  259.             if ($Categories) {
  260.                 $qb
  261.                     ->innerJoin('p.ProductCategories''pct')
  262.                     ->innerJoin('pct.Category''c')
  263.                     ->andWhere($qb->expr()->in('pct.Category'':Categories'))
  264.                     ->setParameter('Categories'$Categories);
  265.                 $categoryJoin true;
  266.             }
  267.         }
  268.         // name
  269.         if (isset($searchData['name']) && StringUtil::isNotBlank($searchData['name'])) {
  270.             $keywords preg_split('/[\s ]+/u'str_replace(['%''_'], ['\\%''\\_'], $searchData['name']), -1PREG_SPLIT_NO_EMPTY);
  271.             foreach ($keywords as $index => $keyword) {
  272.                 $key sprintf('keyword%s'$index);
  273.                 $qb
  274.                     ->andWhere(sprintf('NORMALIZE(p.name) LIKE NORMALIZE(:%s) OR
  275.                         NORMALIZE(p.search_word) LIKE NORMALIZE(:%s) OR
  276.                         EXISTS (SELECT wpc%d FROM \Eccube\Entity\ProductClass wpc%d WHERE p = wpc%d.Product AND NORMALIZE(wpc%d.code) LIKE NORMALIZE(:%s))',
  277.                         $key$key$index$index$index$index$key))
  278.                     ->setParameter($key'%'.$keyword.'%');
  279.             }
  280.         }
  281.         // Order By
  282.         // 価格低い順
  283.         $config $this->eccubeConfig;
  284.         $qb->innerJoin('p.ProductClasses''pc');
  285.         $qb->andWhere('pc.visible = true');
  286.         $qb->groupBy('p.id');
  287.         $qb->addSelect(
  288.             '(CASE 
  289.                 WHEN pc.stock > 0 THEN 1 
  290.                 WHEN pc.stock IS NULL THEN 2 
  291.                 WHEN pc.stock = 0 THEN 3
  292.              ELSE 1
  293.              END) AS HIDDEN sort_order'
  294.         )
  295.         ->orderBy('sort_order''ASC')
  296.             ->addOrderBy('pc.stock_unlimited''DESC');
  297.             
  298.         if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_lower']) {
  299.             // @see http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
  300.             $qb->addSelect('MIN(pc.price02) as HIDDEN price02_min');
  301.             // $qb->innerJoin('p.ProductClasses', 'pc');
  302.             // $qb->andWhere('pc.visible = true');
  303.             $qb->groupBy('p.id');
  304.             $qb->addOrderBy('price02_min''ASC');
  305.             $qb->addOrderBy('p.id''DESC');
  306.         // 価格高い順
  307.         } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_higher']) {
  308.             $qb->addSelect('MAX(pc.price02) as HIDDEN price02_max');
  309.             // $qb->innerJoin('p.ProductClasses', 'pc');
  310.             // $qb->andWhere('pc.visible = true');
  311.             $qb->groupBy('p.id');
  312.             $qb->addOrderBy('price02_max''DESC');
  313.             $qb->addOrderBy('p.id''DESC');
  314.         // 新着順
  315.         } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_newer']) {
  316.             // 在庫切れ商品非表示の設定が有効時対応
  317.             // @see https://github.com/EC-CUBE/ec-cube/issues/1998
  318.             // if ($this->getEntityManager()->getFilters()->isEnabled('option_nostock_hidden') == true) {
  319.             //     $qb->innerJoin('p.ProductClasses', 'pc');
  320.             //     $qb->andWhere('pc.visible = true');
  321.             // }
  322.             $qb->addOrderBy('p.create_date''DESC');
  323.             $qb->addOrderBy('p.id''DESC');
  324.         } else {
  325.             if ($categoryJoin === false) {
  326.                 $qb
  327.                     ->leftJoin('p.ProductCategories''pct')
  328.                     ->leftJoin('pct.Category''c');
  329.             }
  330.             $qb
  331.                 ->addOrderBy('p.id''DESC');
  332.         }
  333.         return $this->queries->customize(QueryKey::PRODUCT_SEARCH$qb$searchData);
  334.     }
  335. }