Completed
Push — develop ( c1c65f...ad5811 )
by Jens
08:43
created

LineItem::fieldDefinitions()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 19
cts 19
cp 1
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 21
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * @author @jayS-de <[email protected]>
4
 */
5
6
namespace Commercetools\Core\Model\Cart;
7
8
use Commercetools\Core\Model\Channel\ChannelReference;
9
use Commercetools\Core\Model\Common\JsonObject;
10
use Commercetools\Core\Model\Common\LocalizedString;
11
use Commercetools\Core\Model\Common\Money;
12
use Commercetools\Core\Model\Common\Price;
13
use Commercetools\Core\Model\Order\ItemStateCollection;
14
use Commercetools\Core\Model\Product\ProductVariant;
15
use Commercetools\Core\Model\TaxCategory\TaxRate;
16
use Commercetools\Core\Model\CustomField\CustomFieldObject;
17
use Commercetools\Core\Model\Common\TaxedItemPrice;
18
use Commercetools\Core\Model\ProductType\ProductTypeReference;
19
20
/**
21
 * @package Commercetools\Core\Model\Cart
22
 * @link https://dev.commercetools.com/http-api-projects-carts.html#lineitem
23
 * @method string getId()
24
 * @method LineItem setId(string $id = null)
25
 * @method string getProductId()
26
 * @method LineItem setProductId(string $productId = null)
27
 * @method LocalizedString getName()
28
 * @method LineItem setName(LocalizedString $name = null)
29
 * @method ProductVariant getVariant()
30
 * @method LineItem setVariant(ProductVariant $variant = null)
31
 * @method Price getPrice()
32
 * @method LineItem setPrice(Price $price = null)
33
 * @method int getQuantity()
34
 * @method LineItem setQuantity(int $quantity = null)
35
 * @method ItemStateCollection getState()
36
 * @method LineItem setState(ItemStateCollection $state = null)
37
 * @method TaxRate getTaxRate()
38
 * @method LineItem setTaxRate(TaxRate $taxRate = null)
39
 * @method ChannelReference getSupplyChannel()
40
 * @method LineItem setSupplyChannel(ChannelReference $supplyChannel = null)
41
 * @method LocalizedString getProductSlug()
42
 * @method LineItem setProductSlug(LocalizedString $productSlug = null)
43
 * @method ChannelReference getDistributionChannel()
44
 * @method LineItem setDistributionChannel(ChannelReference $distributionChannel = null)
45
 * @method CustomFieldObject getCustom()
46
 * @method LineItem setCustom(CustomFieldObject $custom = null)
47
 * @method Money getTotalPrice()
48
 * @method LineItem setTotalPrice(Money $totalPrice = null)
49
 * @method DiscountedPricePerQuantityCollection getDiscountedPricePerQuantity()
50
 * @method TaxedItemPrice getTaxedPrice()
51
 * @method LineItem setTaxedPrice(TaxedItemPrice $taxedPrice = null)
52
 * @method string getPriceMode()
53
 * @method LineItem setPriceMode(string $priceMode = null)
54
 * @method ProductTypeReference getProductType()
55
 * @method LineItem setProductType(ProductTypeReference $productType = null)
56
 * @method string getLineItemMode()
57
 * @method LineItem setLineItemMode(string $lineItemMode = null)
58
 */
59
class LineItem extends JsonObject
60
{
61
    const PRICE_MODE_PLATFORM = 'Platform';
62
    const PRICE_MODE_EXTERNAL_TOTAL = 'ExternalTotal';
63
    const PRICE_MODE_EXTERNAL_PRICE = 'ExternalPrice';
64
65
    const LINE_ITEM_MODE_STANDARD = 'Standard';
66
    const LINE_ITEM_MODE_GIFT_LINE_ITEM = 'GiftLineItem';
67
68 32
    public function fieldDefinitions()
69
    {
70
        return [
71 32
            'id' => [static::TYPE => 'string'],
72 32
            'productId' => [static::TYPE => 'string'],
73 32
            'name' => [static::TYPE => LocalizedString::class],
74 32
            'productSlug' => [static::TYPE => LocalizedString::class],
75 32
            'variant' => [static::TYPE => ProductVariant::class],
76 32
            'price' => [static::TYPE => Price::class],
77 32
            'taxedPrice' => [static::TYPE => TaxedItemPrice::class],
78 32
            'quantity' => [static::TYPE => 'int'],
79 32
            'state' => [static::TYPE => ItemStateCollection::class],
80 32
            'taxRate' => [static::TYPE => TaxRate::class],
81 32
            'supplyChannel' => [static::TYPE => ChannelReference::class],
82 32
            'distributionChannel' => [static::TYPE => ChannelReference::class],
83 32
            'custom' => [static::TYPE => CustomFieldObject::class],
84 32
            'totalPrice' => [static::TYPE => Money::class],
85
            'discountedPricePerQuantity' => [
86 32
                static::TYPE => DiscountedPricePerQuantityCollection::class
87
            ],
88 32
            'priceMode' => [static::TYPE => 'string'],
89 32
            'lineItemMode' => [static::TYPE => 'string'],
90 32
            'productType' => [static::TYPE => ProductTypeReference::class],
91
        ];
92
    }
93
94
    /**
95
     * @param DiscountedPricePerQuantityCollection $discountedPricePerQuantity
96
     * @return static
97
     */
98
    public function setDiscountedPricePerQuantity(
99
        DiscountedPricePerQuantityCollection $discountedPricePerQuantity = null
100
    ) {
101
        return parent::setDiscountedPricePerQuantity($discountedPricePerQuantity);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Commercetools\Core\Model\Common\JsonObject as the method setDiscountedPricePerQuantity() does only exist in the following sub-classes of Commercetools\Core\Model\Common\JsonObject: Commercetools\Core\Model\Cart\CustomLineItem, Commercetools\Core\Model\Cart\LineItem. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
102
    }
103
104
    /**
105
     * @return Money
106
     */
107
    public function getDiscountedPrice()
108
    {
109
        $centAmount = 0;
110
        $currencyCode = $this->getPrice()->getValue()->getCurrencyCode();
111
        foreach ($this->getDiscountedPricePerQuantity() as $discountedPricePerQuantity) {
112
            $centAmount += $discountedPricePerQuantity->getDiscountedTotal()->getCentAmount();
113
        }
114
        $this->getDiscountedPricePerQuantity()->rewind();
115
        return Money::ofCurrencyAndAmount($currencyCode, $centAmount);
116
    }
117
}
118