Completed
Push — 4.0 ( 87d096...bcc1be )
by Kiyotaka
05:44 queued 11s
created

src/Eccube/Repository/TaxRuleRepository.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.ec-cube.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 Doctrine\ORM\NoResultException;
17
use Eccube\Common\EccubeConfig;
18
use Eccube\Entity\BaseInfo;
19
use Eccube\Entity\Customer;
20
use Eccube\Entity\TaxRule;
21
use Symfony\Bridge\Doctrine\RegistryInterface;
22
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
23
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
24
25
/**
26
 * TaxRuleRepository
27
 *
28
 * This class was generated by the Doctrine ORM. Add your own custom
29
 * repository methods below.
30
 */
31
class TaxRuleRepository extends AbstractRepository
32
{
33
    private $rules = [];
34
35
    /**
36
     * @var BaseInfo
37
     */
38
    protected $baseInfo;
39
40
    /**
41
     * @var AuthorizationCheckerInterface
42
     */
43
    protected $authorizationChecker;
44
45
    /**
46
     * @var TokenStorageInterface
47
     */
48
    protected $tokenStorage;
49
50
    /**
51
     * TaxRuleRepository constructor.
52
     *
53
     * @param RegistryInterface $registry
54
     * @param TokenStorageInterface $tokenStorage
55
     * @param AuthorizationCheckerInterface $authorizationChecker
56
     * @param BaseInfoRepository $baseInfoRepository
57
     * @param EccubeConfig $eccubeConfig
58
     */
59 800
    public function __construct(
60
        RegistryInterface $registry,
61
        TokenStorageInterface $tokenStorage,
62
        AuthorizationCheckerInterface $authorizationChecker,
63
        BaseInfoRepository $baseInfoRepository,
64
        EccubeConfig $eccubeConfig
65
    ) {
66 800
        parent::__construct($registry, TaxRule::class);
67 800
        $this->tokenStorage = $tokenStorage;
68 800
        $this->authorizationChecker = $authorizationChecker;
69 800
        $this->baseInfo = $baseInfoRepository->get();
70 800
        $this->eccubeConfig = $eccubeConfig;
71
    }
72
73 7
    public function newTaxRule()
74
    {
75 7
        $TaxRule = new \Eccube\Entity\TaxRule();
76 7
        $RoundingType = $this->getEntityManager()
77 7
            ->getRepository('Eccube\Entity\Master\RoundingType')
78 7
            ->find(1);
79 7
        $TaxRule->setRoundingType($RoundingType);
80 7
        $TaxRule->setTaxAdjust(0);
81
82 7
        return $TaxRule;
83
    }
84
85
    /**
86
     * 現在有効な税率設定情報を返す
87
     *
88
     * @param  int|null|\Eccube\Entity\Product        $Product      商品
89
     * @param  int|null|\Eccube\Entity\ProductClass   $ProductClass 商品規格
90
     * @param  int|null|\Eccube\Entity\Master\Pref    $Pref         都道府県
91
     * @param  int|null|\Eccube\Entity\Master\Country $Country      国
92
     *
93
     * @return \Eccube\Entity\TaxRule                 税設定情報
94
     *
95
     * @throws NoResultException
96
     */
97 465
    public function getByRule($Product = null, $ProductClass = null, $Pref = null, $Country = null)
98
    {
99
        // Pref Country 設定
100 465
        if (!$Pref && !$Country && $this->tokenStorage->getToken() && $this->authorizationChecker->isGranted('ROLE_USER')) {
101
            /* @var $Customer \Eccube\Entity\Customer */
102 52
            $Customer = $this->tokenStorage->getToken()->getUser();
103
            // FIXME なぜか管理画面でも実行されている.
104 52
            if ($Customer instanceof Customer) {
105 52
                $Pref = $Customer->getPref();
106 52
                $Country = $Customer->getCountry();
107
            }
108
        }
109
110
        // 商品単位税率設定がOFFの場合
111 465
        if (!$this->baseInfo->isOptionProductTaxRule()) {
112 457
            $Product = null;
113 457
            $ProductClass = null;
114
        }
115
116
        // Cache Key 設定
117 465
        if ($Product instanceof \Eccube\Entity\Product) {
118 24
            $productId = $Product->getId();
119 457
        } 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...
120
            $productId = $Product;
121
        } else {
122 457
            $productId = '0';
123
        }
124 465
        if ($ProductClass instanceof \Eccube\Entity\ProductClass) {
125 23
            $productClassId = $ProductClass->getId();
126 457
        } 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...
127
            $productClassId = $ProductClass;
128
        } else {
129 457
            $productClassId = '0';
130
        }
131 465
        if ($Pref instanceof \Eccube\Entity\Master\Pref) {
132 53
            $prefId = $Pref->getId();
133 453
        } elseif ($Pref) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $Pref of type null|integer 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...
134
            $prefId = $Pref;
135
        } else {
136 453
            $prefId = '0';
137
        }
138 465
        if ($Country instanceof \Eccube\Entity\Master\Country) {
139 2
            $countryId = $Country->getId();
140 465
        } elseif ($Country) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $Country of type null|integer 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...
141
            $countryId = $Country;
142
        } else {
143 465
            $countryId = '0';
144
        }
145 465
        $cacheKey = $productId.':'.$productClassId.':'.$prefId.':'.$countryId;
146
147
        // すでに取得している場合はキャッシュから
148 465
        if (isset($this->rules[$cacheKey])) {
149 463
            return $this->rules[$cacheKey];
150
        }
151
152 465
        $parameters = [];
153 465
        $qb = $this->createQueryBuilder('t')
154 465
            ->where('t.apply_date < :apply_date');
155 465
        $parameters[':apply_date'] = new \DateTime();
156
157
        // Pref
158 465
        if ($Pref) {
159 53
            $qb->andWhere('t.Pref IS NULL OR t.Pref = :Pref');
160 53
            $parameters['Pref'] = $Pref;
161
        } else {
162 453
            $qb->andWhere('t.Pref IS NULL');
163
        }
164
165
        // Country
166 465
        if ($Country) {
167 2
            $qb->andWhere('t.Country IS NULL OR t.Country = :Country');
168 2
            $parameters['Country'] = $Country;
169
        } else {
170 465
            $qb->andWhere('t.Country IS NULL');
171
        }
172
173
        /*
174
         * Product, ProductClass が persist される前に TaxRuleEventSubscriber によってアクセスされる
175
         * 場合があるため、ID の存在もチェックする.
176
         * https://github.com/EC-CUBE/ec-cube/issues/677
177
         */
178
179
        // Product
180 465
        if ($Product && $productId > 0) {
181 24
            $qb->andWhere('t.Product IS NULL OR t.Product = :Product');
182 24
            $parameters['Product'] = $Product;
183
        } else {
184 457
            $qb->andWhere('t.Product IS NULL');
185
        }
186
187
        // ProductClass
188 465
        if ($ProductClass && $productClassId > 0) {
189 23
            $qb->andWhere('t.ProductClass IS NULL OR t.ProductClass = :ProductClass');
190 23
            $parameters['ProductClass'] = $ProductClass;
191
        } else {
192 464
            $qb->andWhere('t.ProductClass IS NULL');
193
        }
194
195
        $TaxRules = $qb
196 465
            ->setParameters($parameters)
197 465
            ->orderBy('t.apply_date', 'DESC') // 実際は usort() でソートする
198 465
            ->getQuery()
199 465
            ->getResult();
200
201
        // 地域設定を優先するが、システムパラメーターなどに設定を持っていくか
202
        // 後に書いてあるほど優先される
203 465
        $priorityKeys = [];
204 465
        foreach ($this->eccubeConfig['eccube_tax_rule_priority'] as $priorityKey) {
205 465
            $priorityKeys[] = str_replace('_', '', preg_replace('/_id\z/', '', $priorityKey));
206
        }
207
208 465
        foreach ($TaxRules as $TaxRule) {
209 465
            $sortNo = 0;
210 465
            foreach ($priorityKeys as $index => $key) {
211 465
                $arrayProperties = array_change_key_case($TaxRule->toArray());
212 465
                if ($arrayProperties[$key]) {
213
                    // 配列の数値添字を重みとして利用する
214 465
                    $sortNo += 1 << ($index + 1);
215
                }
216
            }
217 465
            $TaxRule->setSortNo($sortNo);
218
        }
219
220
        // 適用日降順, sortNo 降順にソートする
221 465
        usort($TaxRules, function ($a, $b) {
222 7
            return $a->compareTo($b);
223 465
        });
224
225 465
        if (!empty($TaxRules)) {
226 465
            $this->rules[$cacheKey] = $TaxRules[0];
227
228 465
            return $TaxRules[0];
229
        } else {
230
            throw new NoResultException();
231
        }
232
    }
233
234
    /**
235
     * getList
236
     *
237
     * @return array|null
238
     */
239 3
    public function getList()
240
    {
241 3
        $qb = $this->createQueryBuilder('t')
242 3
            ->orderBy('t.apply_date', 'DESC')
243 3
            ->where('t.Product IS NULL AND t.ProductClass IS NULL');
244
        $TaxRules = $qb
245 3
            ->getQuery()
246 3
            ->getResult();
247
248 3
        return $TaxRules;
249
    }
250
251
    /**
252
     * 税規約の削除.
253
     *
254
     * @param  int|\Eccube\Entity\TaxRule $TaxRule 税規約
255
     *
256
     * @throws NoResultException
257
     */
258
    public function delete($TaxRule)
259
    {
260 1
        if (!$TaxRule instanceof \Eccube\Entity\TaxRule) {
261
            $TaxRule = $this->find($TaxRule);
262
        }
263 1
        if (!$TaxRule) {
264
            throw new NoResultException();
265
        }
266 1
        $em = $this->getEntityManager();
267
        $em->remove($TaxRule);
268
        $em->flush();
269
    }
270
271
    /**
272
     * TaxRule のキャッシュをクリアする.
273
     *
274
     * getByRule() をコールすると、結果をキャッシュし、2回目以降はデータベースへアクセスしない.
275
     * このメソッドをコールすると、キャッシュをクリアし、再度データベースを参照して結果を取得する.
276
     */
277
    public function clearCache()
278
    {
279
        $this->rules = [];
280
    }
281
}
282