Completed
Pull Request — 4.0 (#3658)
by Kentaro
06:26
created

ProductRepository::getFavoriteProductQueryBuilderByCustomer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 13
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 13
loc 13
ccs 0
cts 3
cp 0
crap 2
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Repository;
15
16
use Eccube\Common\EccubeConfig;
17
use Eccube\Doctrine\Query\Queries;
18
use Eccube\Entity\Product;
19
use Eccube\Entity\ProductStock;
20
use Eccube\Util\StringUtil;
21
use Symfony\Bridge\Doctrine\RegistryInterface;
22
23
/**
24
 * ProductRepository
25
 *
26
 * This class was generated by the Doctrine ORM. Add your own custom
27
 * repository methods below.
28
 */
29
class ProductRepository extends AbstractRepository
30
{
31
    /**
32
     * @var Queries
33
     */
34
    protected $queries;
35
36
    /**
37
     * @var EccubeConfig
38
     */
39
    protected $eccubeConfig;
40
41
    /**
42
     * ProductRepository constructor.
43
     *
44
     * @param RegistryInterface $registry
45
     * @param Queries $queries
46
     * @param EccubeConfig $eccubeConfig
47
     */
48 204
    public function __construct(
49
        RegistryInterface $registry,
50
        Queries $queries,
51
        EccubeConfig $eccubeConfig
52
    ) {
53 204
        parent::__construct($registry, Product::class);
54 204
        $this->queries = $queries;
55 204
        $this->eccubeConfig = $eccubeConfig;
56
    }
57
58
    /**
59
     * Find the Product with sorted ClassCategories.
60
     *
61
     * @param integer $productId
62
     *
63
     * @return Product
64
     */
65 15
    public function findWithSortedClassCategories($productId)
66
    {
67 15
        $qb = $this->createQueryBuilder('p');
68 15
        $qb->addSelect(['pc', 'cc1', 'cc2', 'pi', 'ps', 'pt'])
69 15
            ->innerJoin('p.ProductClasses', 'pc')
70 15
            ->leftJoin('pc.ClassCategory1', 'cc1')
71 15
            ->leftJoin('pc.ClassCategory2', 'cc2')
72 15
            ->leftJoin('p.ProductImage', 'pi')
73 15
            ->innerJoin('pc.ProductStock', 'ps')
74 15
            ->leftJoin('p.ProductTag', 'pt')
75 15
            ->where('p.id = :id')
76 15
            ->orderBy('cc1.sort_no', 'DESC')
77
            ->addOrderBy('cc2.sort_no', 'DESC');
78 15
        $product = $qb
79 15
            ->setParameters([
80
                'id' => $productId,
81 15
            ])
82 15
            ->getQuery()
83
            ->getSingleResult();
84 15
85
        return $product;
86
    }
87
88
    /**
89
     * get query builder.
90
     *
91
     * @param  array $searchData
92
     *
93
     * @return \Doctrine\ORM\QueryBuilder
94 17
     */
95
    public function getQueryBuilderBySearchData($searchData)
96 17
    {
97 17
        $qb = $this->createQueryBuilder('p')
98
            ->andWhere('p.Status = 1');
99
100 17
        // category
101 17
        $categoryJoin = false;
102 3 View Code Duplication
        if (!empty($searchData['category_id']) && $searchData['category_id']) {
103 3
            $Categories = $searchData['category_id']->getSelfAndDescendants();
104
            if ($Categories) {
105 3
                $qb
106 3
                    ->innerJoin('p.ProductCategories', 'pct')
107 3
                    ->innerJoin('pct.Category', 'c')
108 3
                    ->andWhere($qb->expr()->in('pct.Category', ':Categories'))
109 3
                    ->setParameter('Categories', $Categories);
110
                $categoryJoin = true;
111
            }
112
        }
113
114 17
        // name
115 2
        if (isset($searchData['name']) && StringUtil::isNotBlank($searchData['name'])) {
116
            $keywords = preg_split('/[\s ]+/u', str_replace(['%', '_'], ['\\%', '\\_'], $searchData['name']), -1, PREG_SPLIT_NO_EMPTY);
117 2
118 2
            foreach ($keywords as $index => $keyword) {
119
                $key = sprintf('keyword%s', $index);
120 2
                $qb
121
                    ->andWhere(sprintf('NORMALIZE(p.name) LIKE NORMALIZE(:%s) OR 
122
                        NORMALIZE(p.search_word) LIKE NORMALIZE(:%s) OR 
123 2
                        EXISTS (SELECT wpc%d FROM \Eccube\Entity\ProductClass wpc%d WHERE p = wpc%d.Product AND NORMALIZE(wpc%d.code) LIKE NORMALIZE(:%s))',
124 2
                        $key, $key, $index, $index, $index, $index, $key))
125
                    ->setParameter($key, '%'.$keyword.'%');
126
            }
127
        }
128
129
        // Order By
130 17
        // 価格低い順
131 17
        $config = $this->eccubeConfig;
132
        if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_lower']) {
133 5
            //@see http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
134 5
            $qb->addSelect('MIN(pc.price02) as HIDDEN price02_min');
135 5
            $qb->innerJoin('p.ProductClasses', 'pc');
136 5
            $qb->andWhere('pc.visible = true');
137 5
            $qb->groupBy('p.id');
138 5
            $qb->orderBy('price02_min', 'ASC');
139
            $qb->addOrderBy('p.id', 'DESC');
140 12
        // 価格高い順
141 1
        } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_higher']) {
142 1
            $qb->addSelect('MAX(pc.price02) as HIDDEN price02_max');
143 1
            $qb->innerJoin('p.ProductClasses', 'pc');
144 1
            $qb->andWhere('pc.visible = true');
145 1
            $qb->groupBy('p.id');
146 1
            $qb->orderBy('price02_max', 'DESC');
147
            $qb->addOrderBy('p.id', 'DESC');
148 11
        // 新着順
149
        } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_newer']) {
150
            // 在庫切れ商品非表示の設定が有効時対応
151 4
            // @see https://github.com/EC-CUBE/ec-cube/issues/1998
152
            if ($this->getEntityManager()->getFilters()->isEnabled('option_nostock_hidden') == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
153
                $qb->innerJoin('p.ProductClasses', 'pc');
154
                $qb->andWhere('pc.visible = true');
155 4
            }
156 4
            $qb->orderBy('p.create_date', 'DESC');
157
            $qb->addOrderBy('p.id', 'DESC');
158 7
        } else {
159
            if ($categoryJoin === false) {
160 5
                $qb
161 5
                    ->leftJoin('p.ProductCategories', 'pct')
162
                    ->leftJoin('pct.Category', 'c');
163
            }
164 7
            $qb
165
                ->addOrderBy('p.id', 'DESC');
166
        }
167 17
168
        return $this->queries->customize(QueryKey::PRODUCT_SEARCH, $qb, $searchData);
169
    }
170
171
    /**
172
     * get query builder.
173
     *
174
     * @param  array $searchData
175
     *
176
     * @return \Doctrine\ORM\QueryBuilder
177 20
     */
178
    public function getQueryBuilderBySearchDataForAdmin($searchData)
179 20
    {
180 20
        $qb = $this->createQueryBuilder('p')
181
            ->addSelect('pc', 'pi', 'tr', 'ps')
182
            ->innerJoin('p.ProductClasses', 'pc')
183 20
            ->leftJoin('p.ProductImage', 'pi')
184 6
            ->leftJoin('pc.TaxRule', 'tr')
185
            ->leftJoin('pc.ProductStock', 'ps');
186 6
187 6
        // id
188 6
        if (isset($searchData['id']) && StringUtil::isNotBlank($searchData['id'])) {
189
            $id = preg_match('/^\d{0,10}$/', $searchData['id']) ? $searchData['id'] : null;
190
            $qb
191
                ->andWhere('p.id = :id OR p.name LIKE :likeid OR pc.code LIKE :likeid')
192
                ->setParameter('id', $id)
193
                ->setParameter('likeid', '%'.str_replace(['%', '_'], ['\\%', '\\_'], $searchData['id']).'%');
194
        }
195
196
        // code
197
        /*
198
        if (!empty($searchData['code']) && $searchData['code']) {
199
            $qb
200
                ->innerJoin('p.ProductClasses', 'pc')
201
                ->andWhere('pc.code LIKE :code')
202
                ->setParameter('code', '%' . $searchData['code'] . '%');
203
        }
204
205
        // name
206
        if (!empty($searchData['name']) && $searchData['name']) {
207
            $keywords = preg_split('/[\s ]+/u', $searchData['name'], -1, PREG_SPLIT_NO_EMPTY);
208
            foreach ($keywords as $keyword) {
209
                $qb
210
                    ->andWhere('p.name LIKE :name')
211
                    ->setParameter('name', '%' . $keyword . '%');
212 20
            }
213 2
        }
214 2
       */
215
216 2
        // category
217 2 View Code Duplication
        if (!empty($searchData['category_id']) && $searchData['category_id']) {
218 2
            $Categories = $searchData['category_id']->getSelfAndDescendants();
219 2
            if ($Categories) {
220
                $qb
221
                    ->innerJoin('p.ProductCategories', 'pct')
222
                    ->innerJoin('pct.Category', 'c')
223
                    ->andWhere($qb->expr()->in('pct.Category', ':Categories'))
224 20
                    ->setParameter('Categories', $Categories);
225
            }
226 2
        }
227 2
228
        // status
229 View Code Duplication
        if (!empty($searchData['status']) && $searchData['status']) {
230
            $qb
231 20
                ->andWhere($qb->expr()->in('p.Status', ':Status'))
232
                ->setParameter('Status', $searchData['status']);
233 1
        }
234 1
235
        // link_status
236 View Code Duplication
        if (isset($searchData['link_status']) && !empty($searchData['link_status'])) {
237
            $qb
238 20
                ->andWhere($qb->expr()->in('p.Status', ':Status'))
239
                ->setParameter('Status', $searchData['link_status']);
240
        }
241
242
        // stock status
243
        if (isset($searchData['stock_status'])) {
244
            $qb
245 20
                ->andWhere('pc.stock_unlimited = :StockUnlimited AND pc.stock = 0')
246 3
                ->setParameter('StockUnlimited', $searchData['stock_status']);
247 3
        }
248 1
249 1
        // stock status
250 2
        if (isset($searchData['stock']) && !empty($searchData['stock'])) {
251 2
            switch ($searchData['stock']) {
252 2
                case [ProductStock::IN_STOCK]:
253
                    $qb->andWhere('pc.stock_unlimited = true OR pc.stock > 0');
254
                    break;
255
                case [ProductStock::OUT_OF_STOCK]:
256
                    $qb->andWhere('pc.stock_unlimited = false AND pc.stock <= 0');
257
                    break;
258
                default:
259 20
                    // 共に選択された場合は全権該当するので検索条件に含めない
260 1
            }
261
        }
262 1
263 1
        // crate_date
264 View Code Duplication
        if (!empty($searchData['create_date_start']) && $searchData['create_date_start']) {
265
            $date = $searchData['create_date_start'];
266 20
            $qb
267 1
                ->andWhere('p.create_date >= :create_date_start')
268
                ->setParameter('create_date_start', $date);
269 1
        }
270
271 1 View Code Duplication
        if (!empty($searchData['create_date_end']) && $searchData['create_date_end']) {
272 1
            $date = clone $searchData['create_date_end'];
273
            $date = $date
274
                ->modify('+1 days');
275
            $qb
276 20
                ->andWhere('p.create_date < :create_date_end')
277 1
                ->setParameter('create_date_end', $date);
278
        }
279 1
280 1
        // update_date
281 View Code Duplication
        if (!empty($searchData['update_date_start']) && $searchData['update_date_start']) {
282 20
            $date = $searchData['update_date_start'];
283 1
            $qb
284
                ->andWhere('p.update_date >= :update_date_start')
285 1
                ->setParameter('update_date_start', $date);
286
        }
287 1 View Code Duplication
        if (!empty($searchData['update_date_end']) && $searchData['update_date_end']) {
288 1
            $date = clone $searchData['update_date_end'];
289
            $date = $date
290
                ->modify('+1 days');
291
            $qb
292
                ->andWhere('p.update_date < :update_date_end')
293 20
                ->setParameter('update_date_end', $date);
294
        }
295 20
296
        // Order By
297
        $qb
298
            ->orderBy('p.update_date', 'DESC');
299
300
        return $this->queries->customize(QueryKey::PRODUCT_SEARCH_ADMIN, $qb, $searchData);
301
    }
302
}
303