Failed Conditions
Pull Request — 4.0 (#3688)
by k-yamamura
07:15
created

StockReduceProcessor   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 94.44%

Importance

Changes 0
Metric Value
dl 0
loc 68
ccs 17
cts 18
cp 0.9444
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 5

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A prepare() 0 7 1
A rollback() 0 7 1
B eachProductOrderItems() 0 28 6
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\Service\PurchaseFlow\Processor;
15
16
use Doctrine\DBAL\LockMode;
17
use Eccube\Entity\ItemHolderInterface;
18
use Eccube\Entity\Order;
19
use Eccube\Entity\ProductStock;
20
use Eccube\Repository\ProductStockRepository;
21
use Eccube\Service\PurchaseFlow\PurchaseContext;
22
23
/**
24
 * 在庫制御.
25
 */
26
class StockReduceProcessor extends AbstractPurchaseProcessor
27
{
28
    /**
29
     * @var ProductStockRepository
30
     */
31
    protected $productStockRepository;
32
33
    /**
34
     * StockReduceProcessor constructor.
35
     *
36
     * @param ProductStockRepository $productStockRepository
37
     */
38 196
    public function __construct(ProductStockRepository $productStockRepository)
39
    {
40 196
        $this->productStockRepository = $productStockRepository;
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function prepare(ItemHolderInterface $itemHolder, PurchaseContext $context)
47
    {
48
        // 在庫を減らす
49 8
        $this->eachProductOrderItems($itemHolder, function ($currentStock, $itemQuantity) {
50 4
            return $currentStock - $itemQuantity;
51 8
        });
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function rollback(ItemHolderInterface $itemHolder, PurchaseContext $context)
58
    {
59
        // 在庫を戻す
60 2
        $this->eachProductOrderItems($itemHolder, function ($currentStock, $itemQuantity) {
61 2
            return $currentStock + $itemQuantity;
62 2
        });
63
    }
64
65 10
    private function eachProductOrderItems(ItemHolderInterface $itemHolder, callable $callback)
66
    {
67
        // Order以外の場合は何もしない
68 10
        if (!$itemHolder instanceof Order) {
69
            return;
70
        }
71
72 10
        foreach ($itemHolder->getProductOrderItems() as $item) {
73
            // 在庫が無制限かチェックし、制限ありなら在庫数をチェック
74 10
            if (!$item->getProductClass()->isStockUnlimited()) {
75
                // 在庫チェックあり
76
                // 在庫に対してロック(select ... for update)を実行
77
                /* @var ProductStock $productStock */
78 6
                $productStock = $this->productStockRepository->find(
79 6
                    $item->getProductClass()->getProductStock()->getId(), LockMode::PESSIMISTIC_WRITE
80
                );
81
            }
82 6
        }
83 6
84 10
        foreach ($itemHolder->getProductOrderItems() as $item) {
85
            // 在庫が無制限かチェックし、制限ありなら在庫を減らす
86
            if (!$item->getProductClass()->isStockUnlimited()) {
87
                $stock = $callback($productStock->getStock(), $item->getQuantity());
0 ignored issues
show
Bug introduced by
The variable $productStock does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
88
                $productStock->setStock($stock);
89
                $item->getProductClass()->setStock($stock);
90
            }
91
        }
92
    }
93
}
94