Completed
Push — master ( 45b214...6fb08c )
by Aimeos
03:09
created

Base::addProduct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016
6
 * @package Controller
7
 * @subpackage Frontend
8
 */
9
10
11
namespace Aimeos\Controller\Frontend\Basket\Decorator;
12
13
14
/**
15
 * Base for basket frontend controller decorators
16
 *
17
 * @package Controller
18
 * @subpackage Frontend
19
 */
20
abstract class Base
21
	extends \Aimeos\Controller\Frontend\Basket\Base
2 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
22
	implements \Aimeos\Controller\Frontend\Common\Decorator\Iface, \Aimeos\Controller\Frontend\Basket\Iface
1 ignored issue
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
23
{
24
	private $controller;
25
26
27
	/**
28
	 * Initializes the controller decorator.
29
	 *
30
	 * @param \Aimeos\Controller\Frontend\Iface $controller Controller object
31
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object with required objects
32
	 */
33
	public function __construct( \Aimeos\Controller\Frontend\Iface $controller, \Aimeos\MShop\Context\Item\Iface $context )
34
	{
35
		$iface = '\Aimeos\Controller\Frontend\Basket\Iface';
36
		if( !( $controller instanceof $iface ) )
37
		{
38
			$msg = sprintf( 'Class "%1$s" does not implement interface "%2$s"', get_class( $controller ), $iface );
39
			throw new \Aimeos\Controller\Frontend\Exception( $msg );
40
		}
41
42
		$this->controller = $controller;
43
44
		parent::__construct( $context );
45
	}
46
47
48
	/**
49
	 * Passes unknown methods to wrapped objects.
50
	 *
51
	 * @param string $name Name of the method
52
	 * @param array $param List of method parameter
53
	 * @return mixed Returns the value of the called method
54
	 * @throws \Aimeos\Controller\Frontend\Exception If method call failed
55
	 */
56
	public function __call( $name, array $param )
57
	{
58
		return @call_user_func_array( array( $this->controller, $name ), $param );
59
	}
60
61
62
	/**
63
	 * Empties the basket and removing all products, addresses, services, etc.
64
	 * @return void
65
	 */
66
	public function clear()
67
	{
68
		$this->controller->clear();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method clear() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
69
		return $this;
70
	}
71
72
73
	/**
74
	 * Returns the basket object.
75
	 *
76
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Basket holding products, addresses and delivery/payment options
77
	 */
78
	public function get()
79
	{
80
		return $this->controller->get();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method get() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
81
	}
82
83
84
	/**
85
	 * Explicitely persists the basket content
86
	 */
87
	public function save()
88
	{
89
		$this->controller->save();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method save() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
90
		return $this;
91
	}
92
93
94
	/**
95
	 * Sets the new basket type
96
	 *
97
	 * @param string $type Basket type
98
	 * @return \Aimeos\Controller\Frontend\Basket\Iface Basket frontend object
99
	 */
100
	public function setType( $type )
101
	{
102
		$this->controller->setType( $type );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method setType() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
103
		return $this;
104
	}
105
106
107
	/**
108
	 * Creates a new order base object from the current basket
109
	 *
110
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base object including products, addresses and services
111
	 */
112
	public function store()
113
	{
114
		return $this->controller->store();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method store() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard, Aimeos\Controller\Frontend\Order\Decorator\Base, Aimeos\Controller\Frontend\Order\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
115
	}
116
117
118
	/**
119
	 * Returns the order base object for the given ID
120
	 *
121
	 * @param string $id Unique ID of the order base object
122
	 * @param integer $parts Constants which parts of the order base object should be loaded
123
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base object including the given parts
124
	 */
125
	public function load( $id, $parts = \Aimeos\MShop\Order\Manager\Base\Base::PARTS_ALL )
126
	{
127
		return $this->controller->load( $id, $parts );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method load() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
128
	}
129
130
131
	/**
132
	 * Adds a categorized product to the basket of the user stored in the session.
133
	 *
134
	 * @param string $prodid ID of the base product to add
135
	 * @param integer $quantity Amount of products that should by added
136
	 * @param array $options Possible options are: 'stock'=>true|false and 'variant'=>true|false
137
	 * 	The 'stock'=>false option allows adding products without being in stock.
138
	 * 	The 'variant'=>false option allows adding the selection product to the basket
139
	 * 	instead of the specific sub-product if the variant-building attribute IDs
140
	 * 	doesn't match a specific sub-product or if the attribute IDs are missing.
141
	 * @param array $variantAttributeIds List of variant-building attribute IDs that identify a specific product
142
	 * 	in a selection products
143
	 * @param array $configAttributeIds  List of attribute IDs that doesn't identify a specific product in a
144
	 * 	selection of products but are stored together with the product (e.g. for configurable products)
145
	 * @param array $hiddenAttributeIds List of attribute IDs that should be stored along with the product in the order
146
	 * @param array $customAttributeValues Associative list of attribute IDs and arbitrary values that should be stored
147
	 * 	along with the product in the order
148
	 * @param string $stocktype Unique code of the stock type to deliver the products from
149
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception If the product isn't available
150
	 * @return void
151
	 */
152
	public function addProduct( $prodid, $quantity = 1, array $options = array(), array $variantAttributeIds = array(),
153
		array $configAttributeIds = array(), array $hiddenAttributeIds = array(), array $customAttributeValues = array(),
154
		$stocktype = 'default' )
155
	{
156
		$this->controller->addProduct(
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method addProduct() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
157
			$prodid, $quantity, $options, $variantAttributeIds, $configAttributeIds,
158
			$hiddenAttributeIds, $customAttributeValues, $stocktype
159
		);
160
	}
161
162
163
	/**
164
	 * Deletes a product item from the basket.
165
	 *
166
	 * @param integer $position Position number (key) of the order product item
167
	 * @return void
168
	 */
169
	public function deleteProduct( $position )
170
	{
171
		$this->controller->deleteProduct( $position );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method deleteProduct() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
172
	}
173
174
175
	/**
176
	 * Edits the quantity of a product item in the basket.
177
	 *
178
	 * @param integer $position Position number (key) of the order product item
179
	 * @param integer $quantity New quantiy of the product item
180
	 * @param array $options Possible options are: 'stock'=>true|false
181
	 * @param array $configAttributeCodes Codes of the product config attributes that should be REMOVED
182
	 * @return void
183
	 */
184
	public function editProduct( $position, $quantity, array $options = array(), array $configAttributeCodes = array() )
185
	{
186
		$this->controller->editProduct( $position, $quantity, $options, $configAttributeCodes );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method editProduct() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
187
	}
188
189
190
	/**
191
	 * Adds the given coupon code and updates the basket.
192
	 *
193
	 * @param string $code Coupon code entered by the user
194
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception if the coupon code is invalid or not allowed
195
	 * @return void
196
	 */
197
	public function addCoupon( $code )
198
	{
199
		$this->controller->addCoupon( $code );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method addCoupon() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
200
	}
201
202
203
	/**
204
	 * Removes the given coupon code and its effects from the basket.
205
	 *
206
	 * @param string $code Coupon code entered by the user
207
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception if the coupon code is invalid
208
	 * @return void
209
	 */
210
	public function deleteCoupon( $code )
211
	{
212
		$this->controller->deleteCoupon( $code );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method deleteCoupon() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
213
	}
214
215
216
	/**
217
	 * Sets the address of the customer in the basket.
218
	 *
219
	 * @param string $type Address type constant from \Aimeos\MShop\Order\Item\Base\Address\Base
220
	 * @param \Aimeos\MShop\Common\Item\Address\Iface|array|null $value Address object or array with key/value pairs of address or null to remove address from basket
221
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception If the billing or delivery address is not of any required type of
222
	 * 	if one of the keys is invalid when using an array with key/value pairs
223
	 * @return void
224
	 */
225
	public function setAddress( $type, $value )
226
	{
227
		$this->controller->setAddress( $type, $value );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method setAddress() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
228
	}
229
230
231
	/**
232
	 * Sets the delivery/payment service item based on the service ID.
233
	 *
234
	 * @param string $type Service type code like 'payment' or 'delivery'
235
	 * @param string $id Unique ID of the service item
236
	 * @param array $attributes Associative list of key/value pairs containing the attributes selected or
237
	 * 	entered by the customer when choosing one of the delivery or payment options
238
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception If there is no price to the service item attached
239
	 * @return void
240
	 */
241
	public function setService( $type, $id, array $attributes = array() )
242
	{
243
		$this->controller->setService( $type, $id, $attributes );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method setService() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
244
	}
245
246
247
	/**
248
	 * Returns the frontend controller
249
	 *
250
	 * @return \Aimeos\Controller\Frontend\Basket\Iface Frontend controller object
251
	 */
252
	protected function getController()
253
	{
254
		return $this->controller;
255
	}
256
}
257