Completed
Pull Request — experimental/3.1 (#2484)
by Kentaro
57:08 queued 35:11
created

TaxRuleRepository::getByRule()   F

Complexity

Conditions 26
Paths > 20000

Size

Total Lines 135
Code Lines 82

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 68
CRAP Score 26.2172

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 26
eloc 82
nc 83268
nop 4
dl 0
loc 135
ccs 68
cts 73
cp 0.9315
crap 26.2172
rs 2
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Annotation\Inject;
29
use Eccube\Annotation\Repository;
30
use Eccube\Application;
31
use Eccube\Entity\BaseInfo;
32
use Eccube\Common\Constant;
33
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
34
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
35
36
/**
37
 * TaxRuleRepository
38
 *
39
 * This class was generated by the Doctrine ORM. Add your own custom
40
 * repository methods below.
41
 *
42
 * @Repository
43
 */
44
class TaxRuleRepository extends AbstractRepository
45
{
46
    /**
47
     * @Inject("config")
48
     * @var array
49
     */
50
    protected $appConfig;
51
52
    /**
53
     * @Inject(BaseInfo::class)
54
     * @var BaseInfo
55
     */
56
    protected $BaseInfo;
57
58
    /**
59
     * @Inject("security.authorization_checker")
60
     * @var AuthorizationChecker
61
     */
62
    protected $authorizationChecker;
63
64
    /**
65
     * @Inject("security.token_storage")
66
     * @var TokenStorage
67
     */
68
    protected $tokenStorage;
69
70
    /**
71
     * @Inject(Application::class)
72
     * @var Application
73
     */
74
    protected $app;
75
76
    private $rules = array();
77
78 10
    public function newTaxRule()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
79
    {
80 10
        $TaxRule = new \Eccube\Entity\TaxRule();
81 10
        $CalcRule = $this->getEntityManager()
82 10
            ->getRepository('Eccube\Entity\Master\Taxrule')
83 10
            ->find(1);
84 10
        $TaxRule->setCalcRule($CalcRule);
85 10
        $TaxRule->setTaxAdjust(0);
86 10
        $TaxRule->setDelFlg(0);
87
88 10
        return $TaxRule;
89
    }
90
91
    /**
92
     * 現在有効な税率設定情報を返す
93
     *
94
     * @param  int|null|\Eccube\Entity\Product        $Product      商品
95
     * @param  int|null|\Eccube\Entity\ProductClass   $ProductClass 商品規格
96
     * @param  int|null|\Eccube\Entity\Master\Pref    $Pref         都道府県
97
     * @param  int|null|\Eccube\Entity\Master\Country $Country      国
98
     * @return \Eccube\Entity\TaxRule                 税設定情報
99
     *
100
     * @throws NoResultException
101
     */
102 292
    public function getByRule($Product = null, $ProductClass = null, $Pref = null, $Country = null)
103
    {
104
        // Pref Country 設定
105 292
        if (!$Pref && !$Country && $this->tokenStorage->getToken() && $this->authorizationChecker->isGranted('ROLE_USER')) {
106
            /* @var $Customer \Eccube\Entity\Customer */
107 27
            $Customer = $this->app->user();
108 27
            $Pref = $Customer->getPref();
109 27
            $Country = $Customer->getCountry();
110
        }
111
112
        // 商品単位税率設定がOFFの場合
113 292
        if ($this->BaseInfo->getOptionProductTaxRule() !== Constant::ENABLED) {
114 282
            $Product = null;
115 282
            $ProductClass = null;
116
        }
117
118
        // Cache Key 設定
119 292
        if ($Product instanceof \Eccube\Entity\Product) {
120 25
            $productId = $Product->getId();
121 282
        } elseif ($Product) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $Product of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
122
            $productId = $Product;
123
        } else {
124 282
            $productId = '0';
125
        }
126 292
        if ($ProductClass instanceof \Eccube\Entity\ProductClass) {
127 24
            $productClassId = $ProductClass->getId();
128 282
        } elseif ($ProductClass) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ProductClass of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
129
            $productClassId = $ProductClass;
130
        } else {
131 282
            $productClassId = '0';
132
        }
133 292
        if ($Pref instanceof \Eccube\Entity\Master\Pref) {
134 28
            $prefId = $Pref->getId();
135 265
        } elseif ($Pref) {
136
            $prefId = $Pref;
137
        } else {
138 265
            $prefId = '0';
139
        }
140 292
        if ($Country instanceof \Eccube\Entity\Master\Country) {
141 2
            $countryId = $Country->getId();
142 292
        } elseif ($Country) {
143
            $countryId = $Country;
144
        } else {
145 292
            $countryId = '0';
146
        }
147 292
        $cacheKey = $productId.':'.$productClassId.':'.$prefId.':'.$countryId;
148
149
        // すでに取得している場合はキャッシュから
150 292
        if (isset($this->rules[$cacheKey])) {
151 290
            return $this->rules[$cacheKey];
152
        }
153
154 292
        $parameters = array();
155 292
        $qb = $this->createQueryBuilder('t')
156 292
            ->where('t.apply_date < :apply_date');
157 292
        $parameters[':apply_date'] = new \DateTime();
158
159
        // Pref
160 292
        if ($Pref) {
161 28
            $qb->andWhere('t.Pref IS NULL OR t.Pref = :Pref');
162 28
            $parameters['Pref'] = $Pref;
163
        } else {
164 265
            $qb->andWhere('t.Pref IS NULL');
165
        }
166
167
        // Country
168 292
        if ($Country) {
169 2
            $qb->andWhere('t.Country IS NULL OR t.Country = :Country');
170 2
            $parameters['Country'] = $Country;
171
        } else {
172 292
            $qb->andWhere('t.Country IS NULL');
173
        }
174
175
        /*
176
         * Product, ProductClass が persist される前に TaxRuleEventSubscriber によってアクセスされる
177
         * 場合があるため、ID の存在もチェックする.
178
         * https://github.com/EC-CUBE/ec-cube/issues/677
179
         */
180
181
        // Product
182 292
        if ($Product && $productId > 0) {
183 25
            $qb->andWhere('t.Product IS NULL OR t.Product = :Product');
184 25
            $parameters['Product'] = $Product;
185
        } else {
186 282
            $qb->andWhere('t.Product IS NULL');
187
        }
188
189
        // ProductClass
190 292
        if ($ProductClass && $productClassId > 0) {
191 24
            $qb->andWhere('t.ProductClass IS NULL OR t.ProductClass = :ProductClass');
192 24
            $parameters['ProductClass'] = $ProductClass;
193
        } else {
194 288
            $qb->andWhere('t.ProductClass IS NULL');
195
        }
196
197
        $TaxRules = $qb
198 292
            ->setParameters($parameters)
199 292
            ->orderBy('t.apply_date', 'DESC') // 実際は usort() でソートする
200 292
            ->getQuery()
201 292
            ->getResult();
202
203
        // 地域設定を優先するが、システムパラメーターなどに設定を持っていくか
204
        // 後に書いてあるほど優先される
205 292
        $priorityKeys = explode(',', $this->appConfig['tax_rule_priority']);
0 ignored issues
show
Unused Code introduced by
$priorityKeys is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
206 292
        $priorityKeys = array();
207 292
        foreach (explode(',', $this->appConfig['tax_rule_priority']) as $key) {
208 292
            $priorityKeys[] = str_replace('_', '', preg_replace('/_id\z/', '', $key));
209
        }
210
211 292
        foreach ($TaxRules as $TaxRule) {
212 292
            $rank = 0;
213 292
            foreach ($priorityKeys as $index => $key) {
214 292
                $arrayProperties = array_change_key_case($TaxRule->toArray());
215 292
                if ($arrayProperties[$key]) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
216
217
                    // 配列の数値添字を重みとして利用する
218 292
                    $rank += 1 << ($index + 1);
219
                }
220
            }
221 292
            $TaxRule->setRank($rank);
222
        }
223
224
        // 適用日降順, rank 降順にソートする
225 292
        usort($TaxRules, function($a, $b) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
226 7
            return $a->compareTo($b);
227 292
        });
228
229 292
        if (!empty($TaxRules)) {
230 292
            $this->rules[$cacheKey] = $TaxRules[0];
231
232 292
            return $TaxRules[0];
233
        } else {
234
            throw new NoResultException();
235
        }
236
    }
237
238
    /**
239
     * getList
240
     *
241
     * @return array|null
242
     */
243 3
    public function getList()
244
    {
245 3
        $qb = $this->createQueryBuilder('t')
246 3
            ->orderBy('t.apply_date', 'DESC')
247 3
            ->where('t.Product IS NULL AND t.ProductClass IS NULL');
248
        $TaxRules = $qb
249 3
            ->getQuery()
250 3
            ->getResult();
251
252 3
        return $TaxRules;
253
    }
254
255
    /**
256
     * getById
257
     * @deprecated Use TaxRuleRepository::find()
258
     *
259
     * @param  int   $id
0 ignored issues
show
introduced by
Expected 1 spaces after parameter type; 3 found
Loading history...
260
     * @return array
261
     */
262 1
    public function getById($id)
263
    {
264
        $criteria = array(
265 1
            'id' => $id,
266
        );
267
268 1
        return $this->findOneBy($criteria);
269
    }
270
271
    /**
272
     * getByTime
273
     *
274
     * @deprecated Use magic finder methods. TaxRuleRepository::findOneByApplyDate()
275
     * @param  string $applyDate
276
     * @return mixed
277
     */
278
    public function getByTime($applyDate)
279
    {
280
        $criteria = array(
281
            'apply_date' => $applyDate,
282
        );
283
284
        return $this->findOneBy($criteria);
285
    }
286
287
    /**
288
     * 税規約の削除.
289
     *
290
     * @param  int|\Eccube\Entity\TaxRule $TaxRule 税規約
291
     * @return void
292
     * @throws NoResultException
293
     */
294 3
    public function delete($TaxRule)
295
    {
296 3
        if (!$TaxRule instanceof \Eccube\Entity\TaxRule) {
297 1
            $TaxRule = $this->find($TaxRule);
298
        }
299 3
        if (!$TaxRule) {
300
            throw new NoResultException;
0 ignored issues
show
introduced by
Use parentheses when instantiating classes
Loading history...
301
        }
302 3
        $TaxRule->setDelFlg(1);
303 3
        $em = $this->getEntityManager();
304 3
        $em->persist($TaxRule);
305 3
        $em->flush();
306
    }
307
308
    /**
309
     * TaxRule のキャッシュをクリアする.
310
     *
311
     * getByRule() をコールすると、結果をキャッシュし、2回目以降はデータベースへアクセスしない.
312
     * このメソッドをコールすると、キャッシュをクリアし、再度データベースを参照して結果を取得する.
313
     */
314 7
    public function clearCache()
315
    {
316 7
        $this->rules = array();
317
    }
318
}
319