Failed Conditions
Pull Request — experimental/3.1 (#2304)
by Kiyotaka
39:27
created

ProductRepository   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 246
Duplicated Lines 16.67 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 94.9%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 41
loc 246
ccs 93
cts 98
cp 0.949
rs 8.6
c 1
b 0
f 0
wmc 37
lcom 1
cbo 6

4 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 19 2
C getQueryBuilderBySearchData() 11 72 15
F getQueryBuilderBySearchDataForAdmin() 17 107 19
A getFavoriteProductQueryBuilderByCustomer() 13 13 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Repository;
26
27
use Doctrine\ORM\NoResultException;
28
use Eccube\Util\Str;
29
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
30
31
/**
32
 * ProductRepository
33
 *
34
 * This class was generated by the Doctrine ORM. Add your own custom
35
 * repository methods below.
36
 */
37
class ProductRepository extends AbstractRepository
38
{
39
    /**
40
     * get Product.
41
     *
42
     * @deprecated Use ProductRepository::find()
43
     * @param  integer $productId
44
     * @return \Eccube\Entity\Product
45
     *
46
     * @throws NotFoundHttpException
47
     */
48
    public function get($productId)
49
    {
50 81
        // Product
51
        try {
52 81
            $qb = $this->createQueryBuilder('p')
53
                ->andWhere('p.id = :id');
54
55
            $product = $qb
56
                ->getQuery()
57
                ->setParameters(array(
58
                    'id' => $productId,
59
                ))
60
                ->getSingleResult();
61
        } catch (NoResultException $e) {
62
            throw new NotFoundHttpException();
63 7
        }
64
65
        return $product;
66
    }
67 7
68 7
    /**
69
     * get query builder.
70
     *
71 7
     * @param  array $searchData
72 7
     * @return \Doctrine\ORM\QueryBuilder
73 7
     */
74
    public function getQueryBuilderBySearchData($searchData)
75 7
    {
76 1
        $qb = $this->createQueryBuilder('p')
77 1
            ->andWhere('p.Status = 1');
78
79
        // category
80 6
        $categoryJoin = false;
81 View Code Duplication
        if (!empty($searchData['category_id']) && $searchData['category_id']) {
82
            $Categories = $searchData['category_id']->getSelfAndDescendants();
83
            if ($Categories) {
84
                $qb
85
                    ->innerJoin('p.ProductCategories', 'pct')
86
                    ->innerJoin('pct.Category', 'c')
87
                    ->andWhere($qb->expr()->in('pct.Category', ':Categories'))
88
                    ->setParameter('Categories', $Categories);
89 14
                $categoryJoin = true;
90
            }
91 14
        }
92 14
93
        // name
94
        if (isset($searchData['name']) && Str::isNotBlank($searchData['name'])) {
95 14
            $keywords = preg_split('/[\s ]+/u', $searchData['name'], -1, PREG_SPLIT_NO_EMPTY);
96 14
97 2
            foreach ($keywords as $index => $keyword) {
98 2
                $key = sprintf('keyword%s', $index);
99
                $qb
100 2
                    ->andWhere(sprintf('NORMALIZE(p.name) LIKE NORMALIZE(:%s) OR NORMALIZE(p.search_word) LIKE NORMALIZE(:%s)', $key, $key))
101 2
                    ->setParameter($key, '%' . $keyword . '%');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
102 2
            }
103 2
        }
104 2
105
        // Order By
106
        // 価格低い順
107
        $config = $this->app['config'];
108
        if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['product_order_price_lower']) {
109 14
            //@see http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
110 1
            $qb->addSelect('MIN(pc.price02) as HIDDEN price02_min');
111
            $qb->innerJoin('p.ProductClasses', 'pc');
112 1
            $qb->groupBy('p');
113 1
            // postgres9.0以下は, groupBy('p.id')が利用できない
114
            // mysqlおよびpostgresql9.1以上であればgroupBy('p.id')にすることで性能向上が期待できる.
115 1
            // @see https://github.com/EC-CUBE/ec-cube/issues/1904
116 1
            // $qb->groupBy('p.id');
117
            $qb->orderBy('price02_min', 'ASC');
118
            $qb->addOrderBy('p.id', 'DESC');
119
            // 価格高い順
120
        } else if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['product_order_price_higher']) {
121
            $qb->addSelect('MAX(pc.price02) as HIDDEN price02_max');
122 14
            $qb->innerJoin('p.ProductClasses', 'pc');
123 14
            $qb->groupBy('p');
124
            $qb->orderBy('price02_max', 'DESC');
125 4
            $qb->addOrderBy('p.id', 'DESC');
126 4
            // 新着順
127 4
        } else if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['product_order_newer']) {
128
            // 在庫切れ商品非表示の設定が有効時対応
129
            // @see https://github.com/EC-CUBE/ec-cube/issues/1998
130
            if ($this->app['orm.em']->getFilters()->isEnabled('nostock_hidden') == true) {
131
                $qb->innerJoin('p.ProductClasses', 'pc');
132 4
            }
133 4
            $qb->orderBy('p.create_date', 'DESC');
134
        } else {
135 10
            if ($categoryJoin === false) {
136
                $qb
137
                    ->leftJoin('p.ProductCategories', 'pct')
138
                    ->leftJoin('pct.Category', 'c');
139
            }
140
            $qb
141
                ->addOrderBy('p.id', 'DESC');
142 10
        }
143 2
144
        return $this->app['eccube.queries']->customize(QueryKey::PRODUCT_SEARCH, $qb, $searchData);
145 8
    }
146
147 6
    /**
148 6
     * get query builder.
149
     *
150
     * @param  array $searchData
151 8
     * @return \Doctrine\ORM\QueryBuilder
152
     */
153
    public function getQueryBuilderBySearchDataForAdmin($searchData)
154 14
    {
155
        $qb = $this->createQueryBuilder('p')
156
            ->innerJoin('p.ProductClasses', 'pc');
157
158
        // id
159 View Code Duplication
        if (isset($searchData['id']) && Str::isNotBlank($searchData['id'])) {
160
            $id = preg_match('/^\d+$/', $searchData['id']) ? $searchData['id'] : null;
161
            $qb
162
                ->andWhere('p.id = :id OR p.name LIKE :likeid OR pc.code LIKE :likeid')
163 17
                ->setParameter('id', $id)
164
                ->setParameter('likeid', '%' . $searchData['id'] . '%');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
165 17
        }
166 17
167
        // code
168
        /*
169 17
        if (!empty($searchData['code']) && $searchData['code']) {
170 6
            $qb
171
                ->innerJoin('p.ProductClasses', 'pc')
172 6
                ->andWhere('pc.code LIKE :code')
173 6
                ->setParameter('code', '%' . $searchData['code'] . '%');
174 6
        }
175
176
        // name
177
        if (!empty($searchData['name']) && $searchData['name']) {
178
            $keywords = preg_split('/[\s ]+/u', $searchData['name'], -1, PREG_SPLIT_NO_EMPTY);
179
            foreach ($keywords as $keyword) {
180
                $qb
181
                    ->andWhere('p.name LIKE :name')
182
                    ->setParameter('name', '%' . $keyword . '%');
183
            }
184
        }
185
       */
186
187
        // category
188 View Code Duplication
        if (!empty($searchData['category_id']) && $searchData['category_id']) {
189
            $Categories = $searchData['category_id']->getSelfAndDescendants();
190
            if ($Categories) {
191
                $qb
192
                    ->innerJoin('p.ProductCategories', 'pct')
193
                    ->innerJoin('pct.Category', 'c')
194
                    ->andWhere($qb->expr()->in('pct.Category', ':Categories'))
195
                    ->setParameter('Categories', $Categories);
196
            }
197
        }
198 17
199 2
        // status
200 2
        if (!empty($searchData['status']) && $searchData['status']->toArray()) {
201
            $qb
202 2
                ->andWhere($qb->expr()->in('p.Status', ':Status'))
203 2
                ->setParameter('Status', $searchData['status']->toArray());
204 2
        }
205 2
206
        // link_status
207
        if (isset($searchData['link_status'])) {
208
            $qb
209
                ->andWhere($qb->expr()->in('p.Status', ':Status'))
210 17
                ->setParameter('Status', $searchData['link_status']);
211
        }
212 1
213 1
        // stock status
214
        if (isset($searchData['stock_status'])) {
215
            $qb
216
                ->andWhere('pc.stock_unlimited = :StockUnlimited AND pc.stock = 0')
217 17
                ->setParameter('StockUnlimited', $searchData['stock_status']);
218
        }
219 1
220 1
        // crate_date
221
        if (!empty($searchData['create_date_start']) && $searchData['create_date_start']) {
222
            $date = $searchData['create_date_start'];
223
            $qb
224 17
                ->andWhere('p.create_date >= :create_date_start')
225
                ->setParameter('create_date_start', $date);
226 1
        }
227 1
228
        if (!empty($searchData['create_date_end']) && $searchData['create_date_end']) {
229
            $date = clone $searchData['create_date_end'];
230
            $date = $date
231 17
                ->modify('+1 days');
232 1
            $qb
233 1
                ->andWhere('p.create_date < :create_date_end')
234
                ->setParameter('create_date_end', $date);
235 1
        }
236 1
237
        // update_date
238
        if (!empty($searchData['update_date_start']) && $searchData['update_date_start']) {
239 17
            $date = $searchData['update_date_start'];
240 1
            $qb
241
                ->andWhere('p.update_date >= :update_date_start')
242 1
                ->setParameter('update_date_start', $date);
243 1
        }
244
        if (!empty($searchData['update_date_end']) && $searchData['update_date_end']) {
245 1
            $date = clone $searchData['update_date_end'];
246 1
            $date = $date
247
                ->modify('+1 days');
248
            $qb
249
                ->andWhere('p.update_date < :update_date_end')
250 17
                ->setParameter('update_date_end', $date);
251 1
        }
252 1
253
254 1
        // Order By
255 1
        $qb
256
            ->orderBy('p.update_date', 'DESC');
257 17
258 1
        return $this->app['eccube.queries']->customize(QueryKey::PRODUCT_SEARCH_ADMIN, $qb, $searchData);
259
    }
260 1
261 1
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$Customer" missing
Loading history...
262
     * get query builder.
263 1
     *
264 1
     * @param $Customer
0 ignored issues
show
introduced by
Missing parameter name
Loading history...
265
     * @return \Doctrine\ORM\QueryBuilder
266
     * @see CustomerFavoriteProductRepository::getQueryBuilderByCustomer()
267
     * @deprecated since 3.0.0, to be removed in 3.1
268
     */
269 View Code Duplication
    public function getFavoriteProductQueryBuilderByCustomer($Customer)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270 17
    {
271
        $qb = $this->createQueryBuilder('p')
272 17
            ->innerJoin('p.CustomerFavoriteProducts', 'cfp')
273
            ->where('cfp.Customer = :Customer AND p.Status = 1')
274
            ->setParameter('Customer', $Customer);
275
276
        // Order By
277
        // XXX Paginater を使用した場合に PostgreSQL で正しくソートできない
278
        $qb->addOrderBy('cfp.create_date', 'DESC');
279
280
        return $this->app['eccube.queries']->customize(QueryKey::PRODUCT_GET_FAVORITE, $qb, ['customer' => $Customer]);
281
    }
282
}
283